diff --git a/cmake/external/onnxruntime_external_deps.cmake b/cmake/external/onnxruntime_external_deps.cmake index 3095968795d1a..c9a5270492222 100644 --- a/cmake/external/onnxruntime_external_deps.cmake +++ b/cmake/external/onnxruntime_external_deps.cmake @@ -598,10 +598,6 @@ if(NOT (onnx_FOUND OR ONNX_FOUND)) # building ONNX from source endif() endif() -if (onnxruntime_RUN_ONNX_TESTS) - add_definitions(-DORT_RUN_EXTERNAL_ONNX_TESTS) -endif() - if(onnxruntime_ENABLE_DLPACK) message(STATUS "dlpack is enabled.") diff --git a/onnxruntime/test/framework/inference_session_test.cc b/onnxruntime/test/framework/inference_session_test.cc index bc01135fbbf1e..6131eff92ac78 100644 --- a/onnxruntime/test/framework/inference_session_test.cc +++ b/onnxruntime/test/framework/inference_session_test.cc @@ -588,93 +588,6 @@ TEST(InferenceSessionTests, RequestLoadCancellation) { } } -#ifdef ORT_RUN_EXTERNAL_ONNX_TESTS -static bool Compare(const InputDefList& f_arg, const InputDefList& s_arg) { - if (f_arg.size() != s_arg.size()) { - std::cout << "Sizes differ: f_arg size: " << f_arg.size() << " s_arg size: " << s_arg.size() << std::endl; - return false; - } - - for (size_t i = 0; i < f_arg.size(); ++i) { - const onnxruntime::NodeArg* x = f_arg[i]; - const onnxruntime::NodeArg* y = s_arg[i]; - if ((x->Shape() == nullptr) ^ (y->Shape() == nullptr)) { - return false; - } - if (!x->Shape()) { - continue; - } - auto x_shape = utils::GetTensorShapeFromTensorShapeProto(*x->Shape()); - auto y_shape = utils::GetTensorShapeFromTensorShapeProto(*y->Shape()); - if (x->Name() == y->Name() && x_shape == y_shape && *x->Type() == *y->Type()) { - continue; - } - return false; - } - - return true; -} - -TEST(InferenceSessionTests, ModelMetadata) { - SessionOptions so; - - so.session_logid = "InferenceSessionTests.ModelMetadata"; - InferenceSession session_object{so, GetEnvironment()}; - auto model_uri = ORT_TSTR("../models/opset8/test_squeezenet/model.onnx"); - ASSERT_STATUS_OK(session_object.Load(model_uri)); - - std::shared_ptr p_model; - ASSERT_STATUS_OK(onnxruntime::Model::Load(model_uri, p_model, nullptr, DefaultLoggingManager().DefaultLogger())); - const onnxruntime::Graph& graph = p_model->MainGraph(); - - // 1. first test the model meta - { - auto retval = session_object.GetModelMetadata(); - ASSERT_TRUE(retval.first.IsOK()); - const ModelMetadata* m = retval.second; - ASSERT_TRUE(m->custom_metadata_map == p_model->MetaData() && - m->description == p_model->DocString() && - m->domain == p_model->Domain() && - m->graph_name == graph.Name() && - m->producer_name == p_model->ProducerName() && - m->version == p_model->ModelVersion()); - } - - { - // 2. test inputs - auto& inputs = graph.GetInputs(); - auto weights = graph.GetAllInitializedTensors(); - - // skip the weights - InputDefList inputs_no_weights; - for (auto& elem : inputs) { - if (weights.find(elem->Name()) != weights.end()) { - continue; - } else { - inputs_no_weights.push_back(elem); - } - } - - auto retval = session_object.GetModelInputs(); - std::cout << "weights size: " << weights.size() - << " inputs.size(): " << inputs.size() - << " from session: " << retval.second->size() << std::endl; - ASSERT_TRUE(retval.first.IsOK()); - ASSERT_TRUE(Compare(inputs_no_weights, *retval.second)); - } - - // 3. test outputs - { - auto retval = session_object.GetModelOutputs(); - ASSERT_TRUE(retval.first.IsOK()); - - auto& outputs = graph.GetOutputs(); - retval = session_object.GetModelOutputs(); - ASSERT_TRUE(retval.first.IsOK()); - ASSERT_TRUE(Compare(outputs, *retval.second)); - } -} -#endif TEST(InferenceSessionTests, CheckRunLogger) { if constexpr (!SessionOptions::DEFAULT_USE_PER_SESSION_THREADS) { GTEST_SKIP() << "Skipping the test"; diff --git a/onnxruntime/test/ir/onnx_model_test.cc b/onnxruntime/test/ir/onnx_model_test.cc index 9327d86966981..55fc4f42bec64 100644 --- a/onnxruntime/test/ir/onnx_model_test.cc +++ b/onnxruntime/test/ir/onnx_model_test.cc @@ -26,44 +26,6 @@ class ONNXModelsTest : public ::testing::Test { std::unique_ptr logger_; }; -#ifdef ORT_RUN_EXTERNAL_ONNX_TESTS -// Tests that Resolve() properly clears the state of topological sorted nodes, -// inputs, outputs and valueInfo. -// Assumes the graph passed in has been previously resolved. -static void TestResolve(onnxruntime::Graph& graph) { - GraphViewer graph_viewer(graph); - auto& nodes_before = graph_viewer.GetNodesInTopologicalOrder(); - auto& inputs_before = graph.GetInputs(); - auto& outputs_before = graph.GetOutputs(); - auto& value_info_before = graph.GetValueInfo(); - - // Touch the graph to force Resolve() to recompute. - graph.SetGraphResolveNeeded(); - graph.SetGraphProtoSyncNeeded(); - ASSERT_STATUS_OK(graph.Resolve()); - - GraphViewer graph_viewer_2(graph); - auto& nodes_after = graph_viewer_2.GetNodesInTopologicalOrder(); - auto& inputs_after = graph.GetInputs(); - auto& outputs_after = graph.GetOutputs(); - auto& value_info_after = graph.GetValueInfo(); - - // Multiple calls to Resolve() should not alter the sorted nodes, - // inputs, outputs and valueInfo. The internal state should be - // cleared. - EXPECT_EQ(nodes_before, nodes_after); - EXPECT_EQ(inputs_before, inputs_after); - EXPECT_EQ(outputs_before, outputs_after); - EXPECT_EQ(value_info_before, value_info_after); -} - -TEST_F(ONNXModelsTest, squeeze_net) { - // NOTE: this requires the current directory to be where onnxruntime_ir_UT.exe is located - std::shared_ptr model; - ASSERT_STATUS_OK(Model::Load(ORT_TSTR("../models/opset8/test_squeezenet/model.onnx"), model, nullptr, *logger_)); - TestResolve(model->MainGraph()); -} -#endif TEST_F(ONNXModelsTest, non_existing_model) { // NOTE: this requires the current directory to be where onnxruntime_ir_UT.exe is located @@ -96,76 +58,6 @@ class ONNXModelsTest1 : public ::testing::TestWithParam { return oss.str(); } }; -#ifdef ORT_RUN_EXTERNAL_ONNX_TESTS -TEST_F(ONNXModelsTest, bvlc_alexnet_1) { - using ::google::protobuf::io::CodedInputStream; - using ::google::protobuf::io::FileInputStream; - using ::google::protobuf::io::ZeroCopyInputStream; - int fd; - ASSERT_STATUS_OK(Env::Default().FileOpenRd(ORT_TSTR("../models/opset8/test_bvlc_alexnet/model.onnx"), fd)); - ASSERT_TRUE(fd > 0); - std::unique_ptr raw_input(new FileInputStream(fd)); - std::unique_ptr coded_input(new CodedInputStream(raw_input.get())); - // Allows protobuf library versions < 3.2.0 to parse messages greater than 64MB. - coded_input->SetTotalBytesLimit(INT_MAX); - ModelProto model_proto; - bool result = model_proto.ParseFromCodedStream(coded_input.get()); - coded_input.reset(); - raw_input.reset(); - EXPECT_TRUE(result); - ASSERT_STATUS_OK(Env::Default().FileClose(fd)); - - std::shared_ptr model; - ASSERT_STATUS_OK(Model::Load(ORT_TSTR("../models/opset8/test_bvlc_alexnet/model.onnx"), model, nullptr, - *logger_)); - - // Check the graph input/output/value_info should have the same size as specified in the model file. - EXPECT_EQ(static_cast(model_proto.graph().value_info_size()), model->MainGraph().GetValueInfo().size()); - EXPECT_EQ(static_cast(model_proto.graph().input_size()), model->MainGraph().GetInputs().size() + model->MainGraph().GetAllInitializedTensors().size()); - EXPECT_EQ(static_cast(model_proto.graph().output_size()), model->MainGraph().GetOutputs().size()); - TestResolve(model->MainGraph()); -} - -TEST_P(ONNXModelsTest1, LoadFromFile) { - std::shared_ptr model; - ASSERT_STATUS_OK(Model::Load(GetModelFileName(), model, nullptr, - *logger_)); - TestResolve(model->MainGraph()); -} - -TEST_P(ONNXModelsTest1, LoadFromProtobuf) { - using ::google::protobuf::io::CodedInputStream; - using ::google::protobuf::io::FileInputStream; - using ::google::protobuf::io::ZeroCopyInputStream; - int fd; - ASSERT_STATUS_OK(Env::Default().FileOpenRd(GetModelFileName(), fd)); - ASSERT_TRUE(fd > 0); - std::unique_ptr raw_input(new FileInputStream(fd)); - std::unique_ptr coded_input(new CodedInputStream(raw_input.get())); - coded_input->SetTotalBytesLimit(INT_MAX); - ModelProto model_proto; - bool result = model_proto.ParseFromCodedStream(coded_input.get()); - coded_input.reset(); - raw_input.reset(); - ASSERT_TRUE(result); - ASSERT_STATUS_OK(Env::Default().FileClose(fd)); - std::shared_ptr model; - ASSERT_STATUS_OK(Model::Load(std::move(model_proto), model, nullptr, - *logger_)); - TestResolve(model->MainGraph()); -} - -#ifndef DISABLE_CONTRIB_OPS -INSTANTIATE_TEST_SUITE_P(ONNXModelsTests, - ONNXModelsTest1, - ::testing::Values(ORT_TSTR("bvlc_alexnet"), ORT_TSTR("bvlc_googlenet"), ORT_TSTR("bvlc_reference_caffenet"), ORT_TSTR("bvlc_reference_rcnn_ilsvrc13"), ORT_TSTR("densenet121"), ORT_TSTR("emotion_ferplus"), ORT_TSTR("inception_v1"), ORT_TSTR("inception_v2"), ORT_TSTR("mnist"), ORT_TSTR("resnet50"), ORT_TSTR("shufflenet"), ORT_TSTR("squeezenet"), ORT_TSTR("tiny_yolov2"), ORT_TSTR("vgg19"), ORT_TSTR("zfnet512"))); -#else -INSTANTIATE_TEST_SUITE_P(ONNXModelsTests, - ONNXModelsTest1, - ::testing::Values(ORT_TSTR("bvlc_alexnet"), ORT_TSTR("bvlc_googlenet"), ORT_TSTR("bvlc_reference_caffenet"), ORT_TSTR("bvlc_reference_rcnn_ilsvrc13"), ORT_TSTR("densenet121"), ORT_TSTR("emotion_ferplus"), ORT_TSTR("inception_v1"), ORT_TSTR("inception_v2"), ORT_TSTR("mnist"), ORT_TSTR("resnet50"), ORT_TSTR("shufflenet"), ORT_TSTR("squeezenet"), ORT_TSTR("vgg19"), ORT_TSTR("zfnet512"))); -#endif - -#endif // test a model that conforms to ONNX IR v4 where there are initializers that are not graph inputs. // a NodeArg should be created for all initializers in this case. diff --git a/onnxruntime/test/optimizer/resnet50_fusion_test.cc b/onnxruntime/test/optimizer/resnet50_fusion_test.cc index 5cb0206156a84..7e6677c8e1ddf 100644 --- a/onnxruntime/test/optimizer/resnet50_fusion_test.cc +++ b/onnxruntime/test/optimizer/resnet50_fusion_test.cc @@ -16,7 +16,6 @@ namespace onnxruntime { namespace test { -// #define ORT_RUN_EXTERNAL_ONNX_TESTS // #define MLAS_F16VEC_INTRINSICS_SUPPORTED #define MODEL_FOLDER ORT_TSTR("testdata/transform/") @@ -28,54 +27,7 @@ class ResNet50FusionTests : public ::testing::Test { } std::unique_ptr logger; }; -#if defined(ORT_RUN_EXTERNAL_ONNX_TESTS) -TEST_F(ResNet50FusionTests, FuseConvIntegrationTest) { - std::basic_string fp32_model_path = ORT_TSTR("../models/opset10/Resnet50_Fusion_Testing/resnet50.onnx"); - std::shared_ptr fp32_model; - std::basic_string fp16_model_path = ORT_TSTR("../models/opset10/Resnet50_Fusion_Testing_fp16/resnet50.fp16.onnx"); - std::shared_ptr fp16_model; - if (Model::Load(fp32_model_path, fp32_model, nullptr, *logger) != Status::OK()) { - GTEST_SKIP() << "Failed to load model: " << fp32_model_path; - } - if (Model::Load(fp16_model_path, fp16_model, nullptr, *logger) != Status::OK()) { - GTEST_SKIP() << "Failed to load model: " << fp16_model_path; - } - // ASSERT_STATUS_OK(Model::Load(fp32_model_path, fp32_model, nullptr, *logger)); - Graph& fp32_graph = fp32_model->MainGraph(); - for (auto& node : fp32_model->MainGraph().Nodes()) { - node.SetExecutionProviderType(kCpuExecutionProvider); - } - Graph& fp16_graph = fp16_model->MainGraph(); - for (auto& node : fp16_model->MainGraph().Nodes()) { - node.SetExecutionProviderType(kCpuExecutionProvider); - } - // std::cout << "-------Op Counts Before Fusion---------" << std::endl; - std::map fp32_op_count = CountOpsInGraph(fp32_graph); - std::map fp16_op_count = CountOpsInGraph(fp16_graph); - for (auto& op : fp32_op_count) { - // std::cout << op.first << " " << op.second << std::endl; - ASSERT_EQ(op.second, fp16_op_count[op.first]); - } - onnxruntime::GraphTransformerManager graph_transformation_mgr_32{5}; - ASSERT_STATUS_OK(graph_transformation_mgr_32.Register(std::make_unique(), TransformerLevel::Level3)); - ASSERT_STATUS_OK(graph_transformation_mgr_32.Register(std::make_unique(), TransformerLevel::Level3)); - ASSERT_STATUS_OK(graph_transformation_mgr_32.ApplyTransformers(fp32_graph, TransformerLevel::Level3, *logger)); - ASSERT_STATUS_OK(Model::Save(*fp32_model, ORT_TSTR("resnet50_fused.onnx"))); - - onnxruntime::GraphTransformerManager graph_transformation_mgr_16{5}; - ASSERT_STATUS_OK(graph_transformation_mgr_16.Register(std::make_unique(), TransformerLevel::Level3)); - ASSERT_STATUS_OK(graph_transformation_mgr_16.Register(std::make_unique(), TransformerLevel::Level3)); - ASSERT_STATUS_OK(graph_transformation_mgr_16.ApplyTransformers(fp16_graph, TransformerLevel::Level3, *logger)); - ASSERT_STATUS_OK(Model::Save(*fp16_model, ORT_TSTR("resnet50_fp16_fused.onnx"))); - // std::cout << "-------Op Counts After Fusion---------" << std::endl; - fp32_op_count = CountOpsInGraph(fp32_graph); - fp16_op_count = CountOpsInGraph(fp16_graph); - // for (auto& op : fp32_op_count) { - // ASSERT_EQ(op.second, fp16_op_count[op.first]); - // } -} -#endif // defined(ORT_RUN_EXTERNAL_ONNX_TESTS) TEST_F(ResNet50FusionTests, FuseConvAddReluUnitTest) { constexpr const ORTCHAR_T* model_uri = MODEL_FOLDER "fusion/conv_add_relu_fp16.onnx"; std::shared_ptr p_model; diff --git a/onnxruntime/test/providers/cpu/model_tests.cc b/onnxruntime/test/providers/cpu/model_tests.cc index a17982ecb5eab..cf49601e6c671 100644 --- a/onnxruntime/test/providers/cpu/model_tests.cc +++ b/onnxruntime/test/providers/cpu/model_tests.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "core/session/onnxruntime_c_api.h" @@ -64,6 +65,157 @@ using namespace onnxruntime::common; namespace onnxruntime { namespace test { + +// Models verified to exist in both VM and Zoo with identical checksums +// These 20 unique models have been confirmed as public (33 instances across opsets) +static const std::unordered_set VERIFIED_PUBLIC_MODELS = { + "AlexNet", + "BERT-Squad", + "CaffeNet", + "DenseNet-121", + "Emotion FERPlus", + "Faster R-CNN R-50-FPN", + "GoogleNet", + "Inception-1", + "Inception-2", + "Mask R-CNN R-50-FPN", + "MNIST", + "MobileNet v2-7", + "R-CNN ILSVRC13", + "ShuffleNet-v1", + "SqueezeNet 1.0", + "SqueezeNet 1.1", + "SSD", + "VGG 19-caffe2", + "YOLOv3", + "ZFNet-512"}; + +// All ONNX Model Zoo models (always safe as they're public) +// Total: 158 models from https://github.com/onnx/models +static const std::unordered_set ONNX_ZOO_MODELS = { + // Verified models (20 unique) + "AlexNet", + "BERT-Squad", + "CaffeNet", + "DenseNet-121", + "Emotion FERPlus", + "Faster R-CNN R-50-FPN", + "GoogleNet", + "Inception-1", + "Inception-2", + "Mask R-CNN R-50-FPN", + "MNIST", + "MobileNet v2-7", + "R-CNN ILSVRC13", + "ShuffleNet-v1", + "SqueezeNet 1.0", + "SqueezeNet 1.1", + "SSD", + "VGG 19-caffe2", + "YOLOv3", + "ZFNet-512", + // Additional Zoo-only models (138) + "AlexNet-int8", + "BERT-Squad-int8", + "BiDAF", + "BiDAF-int8", + "CaffeNet-int8", + "CaffeNet-qdq", + "Candy", + "DenseNet-121-12", + "DenseNet-121-12-int8", + "EfficientNet-Lite4", + "EfficientNet-Lite4-int8", + "EfficientNet-Lite4-qdq", + "Emotion FERPlus int8", + "FCN ResNet-50", + "FCN ResNet-50-int8", + "FCN ResNet-50-qdq", + "FCN ResNet-101", + "Faster R-CNN R-50-FPN-fp32", + "Faster R-CNN R-50-FPN-int8", + "Faster R-CNN R-50-FPN-qdq", + "GoogleNet-int8", + "GoogleNet-qdq", + "GPT-2", + "GPT-2-LM-HEAD", + "Inception-1-int8", + "Inception-1-qdq", + "LResNet100E-IR", + "LResNet100E-IR-int8", + "Mask R-CNN R-50-FPN-fp32", + "Mask R-CNN R-50-FPN-int8", + "Mask R-CNN R-50-FPN-qdq", + "MNIST-12", + "MNIST-12-int8", + "MobileNet v2-1.0", + "MobileNet v2-1.0-fp32", + "MobileNet v2-1.0-int8", + "MobileNet v2-1.0-qdq", + "Mosaic", + "Pointilism", + "Rain Princess", + "ResNet18", + "ResNet18-v2", + "ResNet34", + "ResNet34-v2", + "ResNet50", + "ResNet50-caffe2", + "ResNet50-fp32", + "ResNet50-int8", + "ResNet50-qdq", + "ResNet50-v2", + "ResNet101", + "ResNet101-v2", + "ResNet101_DUC_HDC", + "ResNet101_DUC_HDC-12", + "ResNet101_DUC_HDC-12-int8", + "ResNet152", + "ResNet152-v2", + "ResNet-preproc", + "RetinaNet (ResNet101 backbone)", + "RoBERTa-BASE", + "RoBERTa-SequenceClassification", + "ShuffleNet-v2", + "ShuffleNet-v2-fp32", + "ShuffleNet-v2-int8", + "ShuffleNet-v2-qdq", + "SqueezeNet 1.0-int8", + "SqueezeNet 1.0-qdq", + "SSD-int8", + "SSD-qdq", + "SSD-MobilenetV1", + "SSD-MobilenetV1-12", + "SSD-MobilenetV1-12-int8", + "SSD-MobilenetV1-12-qdq", + "Super_Resolution", + "T5-decoder-with-lm-head", + "T5-encoder", + "Tiny YOLOv2", + "Tiny YOLOv3", + "Udnie", + "VGG 16", + "VGG 16-bn", + "VGG 16-fp32", + "VGG 16-int8", + "VGG 16-qdq", + "VGG 19", + "VGG 19-bn", + "version-RFB-320", + "version-RFB-320-int8", + "version-RFB-640", + "YOLOv2", + "YOLOv3-12", + "YOLOv3-12-int8", + "YOLOv4", + "ZFNet-512-int8", + "ZFNet-512-qdq"}; + +// Helper function to check if a model is allowed +inline bool IsModelAllowed(const std::string& model_name) { + return ONNX_ZOO_MODELS.count(model_name) > 0; +} + // parameter is provider_name + "_" + model_path class ModelTest : public testing::TestWithParam> {}; @@ -656,15 +808,12 @@ ::std::vector<::std::basic_string> GetParameterStrings() { // Same as the above, except this one is for large models #if defined(NDEBUG) || defined(RUN_MODELTEST_IN_DEBUG_MODE) #ifdef _WIN32 - ORT_STRING_VIEW model_test_root_path = ORT_TSTR("..\\models"); - // thus, only the root path should be mounted. ORT_STRING_VIEW model_zoo_path = ORT_TSTR("..\\models\\zoo"); #else - ORT_STRING_VIEW model_test_root_path = ORT_TSTR("../models"); ORT_STRING_VIEW model_zoo_path = ORT_TSTR("../models/zoo"); #endif for (auto p : kvp.second) { - paths.push_back(ConcatPathComponent(model_test_root_path, p)); + // ONLY use Model Zoo path - guaranteed public models with public test data paths.push_back(ConcatPathComponent(model_zoo_path, p)); } #endif @@ -750,6 +899,13 @@ ::std::vector<::std::basic_string> GetParameterStrings() { std::basic_string test_case_name = path.parent_path().filename().native(); if (test_case_name.compare(0, 5, ORT_TSTR("test_")) == 0) test_case_name = test_case_name.substr(5); + + // Check if model is in the public whitelist + std::string model_name_str = ToUTF8String(test_case_name); + if (!IsModelAllowed(model_name_str)) { + continue; // Skip models not in whitelist + } + if (all_disabled_tests.find(test_case_name) != all_disabled_tests.end()) continue; diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 786c0ba713b85..b7a9da8e1b658 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -1901,14 +1901,6 @@ TEST(CApiTest, test_pyop_kwarg) { } #endif -#ifdef ORT_RUN_EXTERNAL_ONNX_TESTS -TEST(CApiTest, create_session_without_session_option) { - constexpr PATH_TYPE model_uri = TSTR("../models/opset8/test_squeezenet/model.onnx"); - Ort::Session ret(*ort_env, model_uri, Ort::SessionOptions{nullptr}); - ASSERT_NE(nullptr, ret); -} -#endif - #ifdef REDUCED_OPS_BUILD TEST(ReducedOpsBuildTest, test_excluded_ops) { // In reduced ops build, test a model containing ops not included in required_ops.config cannot be loaded.