diff --git a/docs/ops/detection/RegionYolo_1.md b/docs/ops/detection/RegionYolo_1.md index f5a4067ad73..c4eece6ff8b 100644 --- a/docs/ops/detection/RegionYolo_1.md +++ b/docs/ops/detection/RegionYolo_1.md @@ -62,10 +62,10 @@ * **Description**: *do_softmax* is a flag that specifies the inference method and affects how the number of regions is determined. It also affects output shape. If it is 0, then output shape is 4D, and 2D otherwise. * **Range of values**: - * *False* - do not perform softmax - * *True* - perform softmax + * *false* - do not perform softmax + * *true* - perform softmax * **Type**: `boolean` - * **Default value**: True + * **Default value**: true * **Required**: *no* * *mask* diff --git a/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp b/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp index 5ee3156d97e..cbd7e441699 100644 --- a/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp +++ b/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp @@ -1072,7 +1072,7 @@ std::shared_ptr V10Parser::LayerCreator::c auto axis = GetIntAttr(dn, "axis"); auto classes = GetUIntAttr(dn, "classes"); auto coords = GetUIntAttr(dn, "coords"); - auto do_softmax = GetIntAttr(dn, "do_softmax"); + auto do_softmax = GetBoolAttr(dn, "do_softmax"); auto end_axis = GetIntAttr(dn, "end_axis"); auto num = GetUIntAttr(dn, "num"); auto mask = getParameters(dn, "mask", {}); diff --git a/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp b/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp index c3e846eceba..a0707404afa 100644 --- a/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp +++ b/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // diff --git a/inference-engine/src/transformations/src/transformations/serialize.cpp b/inference-engine/src/transformations/src/transformations/serialize.cpp index 1869e9f6206..6d1782589d0 100644 --- a/inference-engine/src/transformations/src/transformations/serialize.cpp +++ b/inference-engine/src/transformations/src/transformations/serialize.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -41,9 +41,10 @@ struct Edge { // Here operation type names are translated from ngraph convention to IR // convention. Most of them are the same, but there are exceptions, e.g // Constant (ngraph name) and Const (IR name). If there will be more -// discrepancies discoverd, translations needs to be added here. +// discrepancies discovered, translations needs to be added here. const std::unordered_map translate_type_name_translator = { {"Constant", "Const"}, + {"PRelu", "PReLU"}, {"Relu", "ReLU"}, {"Softmax", "SoftMax"}}; @@ -55,6 +56,21 @@ std::string translate_type_name(const std::string& name) { return name; } +// Some of the operators were added to wrong opsets. This is a mapping +// that allows such operators to be serialized with proper opsets. +// If new operators are discovered that have the same problem, the mapping +// needs to be updated here. The keys contain op name and version in NodeTypeInfo. +const std::unordered_map + special_operator_to_opset_assignments = {{ngraph::Node::type_info_t("ShuffleChannels", 0), "opset3"}}; + +std::string get_special_opset_for_op(const ngraph::Node::type_info_t& type_info) { + auto found = special_operator_to_opset_assignments.find(type_info); + if (found != end(special_operator_to_opset_assignments)) { + return found->second; + } + return ""; +} + class XmlSerializer : public ngraph::AttributeVisitor { pugi::xml_node& m_xml_node; std::ostream& m_bin_data; @@ -212,8 +228,6 @@ const std::vector create_edge_mapping( return edges; } - - std::string get_opset_name( const ngraph::Node* n, const std::map& custom_opsets) { @@ -221,6 +235,10 @@ std::string get_opset_name( ngraph::get_opset1(), ngraph::get_opset2(), ngraph::get_opset3(), ngraph::get_opset4(), ngraph::get_opset5()}; + auto special_opset = get_special_opset_for_op(n->get_type_info()); + if (!special_opset.empty()) { + return special_opset; + } // return the oldest opset name where node type is present for (int idx = 0; idx < opsets.size(); idx++) { if (opsets[idx].get().contains_op_type(n)) { @@ -239,7 +257,6 @@ std::string get_opset_name( return "experimental"; } - std::string get_output_precision_name(ngraph::Output& o) { auto elem_type = o.get_element_type(); switch (elem_type) { diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/broadcast.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/broadcast.cpp new file mode 100644 index 00000000000..b4cbe86bbe3 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/broadcast.cpp @@ -0,0 +1,33 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/broadcast.hpp" + +using namespace LayerTestsDefinitions; + +namespace { +TEST_P(BroadcastLayerTest, Serialize) { Serialize(); } +const std::vector inputPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::I32, + InferenceEngine::Precision::BOOL}; + +// NUMPY MODE + +std::vector> inShapesNumpy = {{3, 1}, {1, 4, 1}}; + +std::vector> targetShapesNumpy = {{2, 3, 6}, {1, 4, 4}}; + +const auto numpyBroadcastParams1 = ::testing::Combine( + ::testing::Values(targetShapesNumpy[0]), + ::testing::Values(ngraph::AxisSet{}), // not used in numpy mode + ::testing::Values(ngraph::op::BroadcastType::NUMPY), + ::testing::Values(inShapesNumpy[0]), ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)); + +INSTANTIATE_TEST_CASE_P(smoke_Broadcast1Serialization, BroadcastLayerTest, + numpyBroadcastParams1, + BroadcastLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/normalize_l2.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/normalize_l2.cpp new file mode 100644 index 00000000000..64f64f8cdce --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/normalize_l2.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/normalize_l2.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace InferenceEngine; +using namespace LayerTestsDefinitions; + +namespace { + TEST_P(NormalizeL2LayerTest, Serialize) { + Serialize(); +} + +const std::vector> axes = { + {1}, +}; +const std::vector eps = { 1e-4f }; + +const std::vector epsMode = { + ngraph::op::EpsMode::ADD, + ngraph::op::EpsMode::MAX, +}; + +const std::vector netPrecisions = { + Precision::FP32, + Precision::BF16 +}; + +INSTANTIATE_TEST_CASE_P(smoke_NormalizeL2Serialization, NormalizeL2LayerTest, + testing::Combine( + testing::ValuesIn(axes), + testing::ValuesIn(eps), + testing::ValuesIn(epsMode), + testing::Values(std::vector{1, 32, 17}), + testing::ValuesIn(netPrecisions), + testing::Values(CommonTestUtils::DEVICE_CPU)), + NormalizeL2LayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/pad.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/pad.cpp new file mode 100644 index 00000000000..dd0d9129264 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/pad.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/pad.hpp" + +using namespace LayerTestsDefinitions; + +namespace { +TEST_P(PadLayerTest, Serialize) { Serialize(); } + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16}; + +const std::vector> padsBegin2D = { + {0, 0}, {1, 1}, {2, 0}, {0, 3}}; +const std::vector> padsEnd2D = { + {0, 0}, {1, 1}, {0, 1}, {3, 2}}; +const std::vector argPadValue = {0.f, 1.f, 2.f, -1.f}; + +const std::vector padMode = { + ngraph::helpers::PadMode::EDGE, ngraph::helpers::PadMode::REFLECT, + ngraph::helpers::PadMode::SYMMETRIC}; + +const auto pad2DConstparams = testing::Combine( + testing::ValuesIn(padsBegin2D), testing::ValuesIn(padsEnd2D), + testing::ValuesIn(argPadValue), + testing::Values(ngraph::helpers::PadMode::CONSTANT), + testing::ValuesIn(netPrecisions), + testing::Values(InferenceEngine::Precision::UNSPECIFIED), + testing::Values(InferenceEngine::Precision::UNSPECIFIED), + testing::Values(InferenceEngine::Layout::ANY), + testing::Values(std::vector{13, 5}), + testing::Values(CommonTestUtils::DEVICE_CPU)); + +INSTANTIATE_TEST_CASE_P(smoke_Pad2DConstSerialization, PadLayerTest, pad2DConstparams, + PadLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/prelu.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/prelu.cpp new file mode 100644 index 00000000000..bb46c446c8a --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/prelu.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include "shared_test_classes/single_layer/activation.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace LayerTestsDefinitions; +using namespace ngraph::helpers; +namespace { + TEST_P(ActivationLayerTest, Serialize) { + Serialize(); + } + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 +}; + +const std::map>> activationTypes = { + {ActivationTypes::PReLu, {{-0.01f}}}, +}; + +std::map, std::vector>> basic = { + {{1, 50}, {{}}}, + {{1, 128}, {{}}}, +}; + +const auto basicCases = ::testing::Combine( + ::testing::ValuesIn(CommonTestUtils::combineParams(activationTypes)), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::ValuesIn(CommonTestUtils::combineParams(basic)), + ::testing::Values(CommonTestUtils::DEVICE_CPU) +); + +INSTANTIATE_TEST_CASE_P(smoke_ActivationPreluSerialization, + ActivationLayerTest, basicCases, ActivationLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/region_yolo.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/region_yolo.cpp new file mode 100644 index 00000000000..bcdf4603cf5 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/region_yolo.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/region_yolo.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + TEST_P(RegionYoloLayerTest, Serialize) { + Serialize(); + } + + + const std::vector inShapes_v3 = { + {1, 255, 52, 52}, + {1, 255, 26, 26}, + {1, 255, 13, 13} + }; + const std::vector> masks = { + {0, 1, 2}, + {3, 4, 5}, + {6, 7, 8} + }; + + const std::vector do_softmax = {true, false}; + const std::vector classes = {80, 20}; + const std::vector num_regions = {5, 9}; + const size_t coords = 4; + const int start_axis = 1; + const int end_axis = 3; + + INSTANTIATE_TEST_CASE_P(smoke_RegionYolov3Serialization, RegionYoloLayerTest, + ::testing::Combine( + ::testing::ValuesIn(inShapes_v3), + ::testing::Values(classes[0]), + ::testing::Values(coords), + ::testing::Values(num_regions[1]), + ::testing::Values(do_softmax[1]), + ::testing::Values(masks[2]), + ::testing::Values(start_axis), + ::testing::Values(end_axis), + ::testing::Values(InferenceEngine::Precision::FP32), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + RegionYoloLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/reshape.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/reshape.cpp new file mode 100644 index 00000000000..56a73ea99a9 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/reshape.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/reshape.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + TEST_P(ReshapeLayerTest, Serialize) { + Serialize(); + } + + const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 + }; + + INSTANTIATE_TEST_CASE_P(smoke_ReshapeSerialization, ReshapeLayerTest, + ::testing::Combine( + ::testing::Values(true), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(std::map({{CONFIG_KEY(DYN_BATCH_ENABLED), CONFIG_VALUE(YES)}}))), + ReshapeLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/shuffle_channels.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/shuffle_channels.cpp new file mode 100644 index 00000000000..60d0194aa04 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/shuffle_channels.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/shuffle_channels.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + TEST_P(ShuffleChannelsLayerTest, Serialize) { + Serialize(); + } + +const std::vector netPrecisions = { + InferenceEngine::Precision::I8, + InferenceEngine::Precision::U8, + InferenceEngine::Precision::I16, + InferenceEngine::Precision::I32, + InferenceEngine::Precision::FP32 +}; + +const std::vector axes = {0, 1, 2, 3}; +const std::vector negativeAxes = {-4, -3, -2, -1}; +const std::vector groups = {1, 2, 3}; + +const auto shuffleChannelsParams4D = ::testing::Combine( + ::testing::ValuesIn(axes), + ::testing::ValuesIn(groups) +); + +const auto shuffleChannelsParamsNegativeAxis4D = ::testing::Combine( + ::testing::ValuesIn(negativeAxes), + ::testing::ValuesIn(groups) +); + +INSTANTIATE_TEST_CASE_P(smoke_ShuffleChannelsSerialization, ShuffleChannelsLayerTest, + ::testing::Combine( + shuffleChannelsParams4D, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({6, 6, 6, 6})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ShuffleChannelsLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/variadic_split.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/variadic_split.cpp index d0ce2f9748e..e46f8b9761b 100644 --- a/inference-engine/tests/functional/inference_engine/serialization/single_layer/variadic_split.cpp +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/variadic_split.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Intel Corporation +// Copyright (C) 2019-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -24,7 +24,7 @@ namespace { {1, 16, 5, 8}, }; - INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, VariadicSplitLayerTest, + INSTANTIATE_TEST_CASE_P(smoke_VariadicSplitSerialization, VariadicSplitLayerTest, ::testing::Combine( ::testing::ValuesIn(numSplits), ::testing::Values(0, 1, 2, 3), diff --git a/inference-engine/tests/functional/shared_test_classes/src/single_layer/broadcast.cpp b/inference-engine/tests/functional/shared_test_classes/src/single_layer/broadcast.cpp index b9aba40f0bd..fc4aad99260 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/single_layer/broadcast.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/single_layer/broadcast.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // diff --git a/inference-engine/tests/functional/shared_test_classes/src/single_layer/normalize_l2.cpp b/inference-engine/tests/functional/shared_test_classes/src/single_layer/normalize_l2.cpp index 5562bba1b29..cf31b316e10 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/single_layer/normalize_l2.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/single_layer/normalize_l2.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // diff --git a/ngraph/core/src/op/util/attr_types.cpp b/ngraph/core/src/op/util/attr_types.cpp index 6fd7bbe0d1c..60af609c673 100644 --- a/ngraph/core/src/op/util/attr_types.cpp +++ b/ngraph/core/src/op/util/attr_types.cpp @@ -31,10 +31,10 @@ namespace ngraph NGRAPH_API EnumNames& EnumNames::get() { static auto enum_names = EnumNames("op::PadMode", - {{"CONSTANT", op::PadMode::CONSTANT}, - {"EDGE", op::PadMode::EDGE}, - {"REFLECT", op::PadMode::REFLECT}, - {"SYMMETRIC", op::PadMode::SYMMETRIC}}); + {{"constant", op::PadMode::CONSTANT}, + {"edge", op::PadMode::EDGE}, + {"reflect", op::PadMode::REFLECT}, + {"symmetric", op::PadMode::SYMMETRIC}}); return enum_names; } @@ -95,11 +95,11 @@ namespace ngraph { static auto enum_names = EnumNames("op::BroadcastType", - {{"NONE", op::BroadcastType::NONE}, - {"NUMPY", op::BroadcastType::NUMPY}, - {"EXPLICIT", op::BroadcastType::EXPLICIT}, - {"PDPD", op::BroadcastType::PDPD}, - {"BIDIRECTIONAL", op::BroadcastType::BIDIRECTIONAL}}); + {{"none", op::BroadcastType::NONE}, + {"numpy", op::BroadcastType::NUMPY}, + {"explicit", op::BroadcastType::EXPLICIT}, + {"pdpd", op::BroadcastType::PDPD}, + {"bidirectional", op::BroadcastType::BIDIRECTIONAL}}); return enum_names; } @@ -162,15 +162,21 @@ namespace ngraph op::AutoBroadcastType op::AutoBroadcastSpec::type_from_string(const std::string& type) const { + auto lowercase_type = type; + std::transform(lowercase_type.begin(), + lowercase_type.end(), + lowercase_type.begin(), + [](char c) { return std::tolower(c); }); + static const std::map allowed_values = { - {"NONE", AutoBroadcastType::NONE}, - {"NUMPY", AutoBroadcastType::NUMPY}, - {"PDPD", AutoBroadcastType::PDPD}, - {"EXPLICIT", AutoBroadcastType::EXPLICIT}}; + {"none", AutoBroadcastType::NONE}, + {"numpy", AutoBroadcastType::NUMPY}, + {"pdpd", AutoBroadcastType::PDPD}, + {"explicit", AutoBroadcastType::EXPLICIT}}; - NGRAPH_CHECK(allowed_values.count(type) > 0, "Invalid 'type' value passed in."); + NGRAPH_CHECK(allowed_values.count(lowercase_type) > 0, "Invalid 'type' value passed in."); - return allowed_values.at(type); + return allowed_values.at(lowercase_type); } bool AttributeAdapter::visit_attributes(AttributeVisitor& visitor) diff --git a/ngraph/test/backend/auto_broadcast.in.cpp b/ngraph/test/backend/auto_broadcast.in.cpp index 2a6bf1afa47..332e4171d8b 100644 --- a/ngraph/test/backend/auto_broadcast.in.cpp +++ b/ngraph/test/backend/auto_broadcast.in.cpp @@ -183,3 +183,35 @@ NGRAPH_TEST(${BACKEND_NAME}, auto_bcast_string_cast) FAIL() << "AutoBroadcastType checking failed for unexpected reason"; } } + +NGRAPH_TEST(${BACKEND_NAME}, auto_bcast_string_cast_lowercase_attrs) +{ + auto a = make_shared(element::f32, Shape{1}); + auto b = make_shared(element::f32, Shape{1}); + + auto add = make_shared(a, b, "numpy"); + ASSERT_EQ(add->get_autob(), op::AutoBroadcastType::NUMPY); + + add = make_shared(a, b, "none"); + ASSERT_EQ(add->get_autob(), op::AutoBroadcastType::NONE); + + add = make_shared(a, b, "pdpd"); + ASSERT_EQ(add->get_autob(), op::AutoBroadcastType::PDPD); + + add = make_shared(a, b, "explicit"); + ASSERT_EQ(add->get_autob(), op::AutoBroadcastType::EXPLICIT); + + try + { + add = make_shared(a, b, "unknown"); + FAIL() << "Unknown AutoBroadcastType not detected."; + } + catch (const ngraph_error& error) + { + EXPECT_HAS_SUBSTRING(error.what(), std::string("Invalid 'type' value passed in.")); + } + catch (...) + { + FAIL() << "AutoBroadcastType checking failed for unexpected reason"; + } +}