Repository: microsoft/onnxruntime
File: onnxruntime/test/shared_lib/test_model_builder_api.cc (C++)

Code before:
                         592.0f, 640.0f, 688.0f, 736.0f, 784.0f, 832.0f, 880.0f, 928.0f};
    }

    TestInference<float>(session, inputs, "Z", expected_dims, expected_output);

    api.ReleaseSession(session.release());

    ASSERT_EQ(deleter.weights.size(), size_t(0)) << "All weights should have been freed";

    // make sure the saved model can be loaded
    Ort::Session session2(*ort_env, saved_model_path, Ort::SessionOptions());

    // make sure entries for the internal domains were added to the opset imports in the saved model
    std::vector<char> buffer(std::filesystem::file_size(saved_model_path));

    std::ifstream file(saved_model_path, std::ios::binary);
    ASSERT_TRUE(file.read(buffer.data(), buffer.size()));
    auto end_data = buffer.data() + buffer.size();
    ASSERT_NE(std::search(buffer.data(), end_data,
                          onnxruntime::kMSInternalNHWCDomain,
                          onnxruntime::kMSInternalNHWCDomain + strlen(onnxruntime::kMSInternalNHWCDomain)),
              end_data);
    ASSERT_NE(std::search(buffer.data(), end_data,
                          onnxruntime::kMSNchwcDomain,
                          onnxruntime::kMSNchwcDomain + strlen(onnxruntime::kMSNchwcDomain)),
              end_data);
  };

  run_test(false);
  run_test(true);  // use Constant node for initializer
}

TEST(ModelEditorAPITest, Basic_CxxApi) {
  // initializers that are used directly by the model. as there's no copy they must remain valid
  std::vector<std::unique_ptr<std::vector<float>>> weights;

  Ort::Graph graph;

  //
  // Create OrtModel with a Gemm. X input is 3x4, Y input is 4x8, Z output is 3x8.
  // X is model input. Y is initializer.
  // Set the alpha attribute of the Gemm node to 2.0 to test attribute handling.
  //

  std::vector<ValueInfo> graph_inputs;
  std::vector<ValueInfo> graph_outputs;

  // model input. it's {3, 4} but use a symbolic dim to test that works.
  std::vector<int64_t> input_dims({-1, 4});
  std::vector<std::string> input_symbolic_dims({"multiple_of_3", ""});
  TensorTypeAndShapeInfo input_tensor_info(ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,

Review comment (suggestion):
A little terser (concise is nice):
```diff
-   auto end_data = buffer.data() + buffer.size();
-   ASSERT_NE(std::search(buffer.data(), end_data,
-                         onnxruntime::kMSInternalNHWCDomain,
-                         onnxruntime::kMSInternalNHWCDomain + strlen(onnxruntime::kMSInternalNHWCDomain)),
-             end_data);
-   ASSERT_NE(std::search(buffer.data(), end_data,
-                         onnxruntime::kMSNchwcDomain,
-                         onnxruntime::kMSNchwcDomain + strlen(onnxruntime::kMSNchwcDomain)),
-             end_data);
+   std::string_view buffer_view(buffer.data(), buffer.size());
+   ASSERT_NE(buffer_view.find(onnxruntime::kMSInternalNHWCDomain), std::string_view::npos);
+   ASSERT_NE(buffer_view.find(onnxruntime::kMSNchwcDomain), std::string_view::npos);
```

Code after:
                         592.0f, 640.0f, 688.0f, 736.0f, 784.0f, 832.0f, 880.0f, 928.0f};
    }

    TestInference<float>(session, inputs, "Z", expected_dims, expected_output);

    api.ReleaseSession(session.release());

    ASSERT_EQ(deleter.weights.size(), size_t(0)) << "All weights should have been freed";

    // make sure the saved model can be loaded
    Ort::Session session2(*ort_env, saved_model_path, Ort::SessionOptions());

    // make sure entries for the internal domains were added to the opset imports in the saved model
    std::vector<char> buffer(std::filesystem::file_size(saved_model_path));

    std::ifstream file(saved_model_path, std::ios::binary);
    ASSERT_TRUE(file.read(buffer.data(), buffer.size()));

    std::string_view buffer_view(buffer.data(), buffer.size());
    ASSERT_NE(buffer_view.find(onnxruntime::kMSInternalNHWCDomain), std::string_view::npos);
    ASSERT_NE(buffer_view.find(onnxruntime::kMSNchwcDomain), std::string_view::npos);
  };

  run_test(false);
  run_test(true);  // use Constant node for initializer
}

TEST(ModelEditorAPITest, Basic_CxxApi) {
  // initializers that are used directly by the model. as there's no copy they must remain valid
  std::vector<std::unique_ptr<std::vector<float>>> weights;

  Ort::Graph graph;

  //
  // Create OrtModel with a Gemm. X input is 3x4, Y input is 4x8, Z output is 3x8.
  // X is model input. Y is initializer.
  // Set the alpha attribute of the Gemm node to 2.0 to test attribute handling.
  //

  std::vector<ValueInfo> graph_inputs;
  std::vector<ValueInfo> graph_outputs;

  // model input. it's {3, 4} but use a symbolic dim to test that works.
  std::vector<int64_t> input_dims({-1, 4});
  std::vector<std::string> input_symbolic_dims({"multiple_of_3", ""});
  TensorTypeAndShapeInfo input_tensor_info(ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,
                                           input_dims,
                                           &input_symbolic_dims);
  auto input_type_info = TypeInfo::CreateTensorInfo(input_tensor_info.GetConst());
  graph_inputs.emplace_back("X", input_type_info.GetConst());