|
10 | 10 | #include <gtest/gtest.h> |
11 | 11 |
|
12 | 12 | #include "core/session/onnxruntime_cxx_api.h" |
| 13 | +#include "core/session/onnxruntime_session_options_config_keys.h" |
13 | 14 |
|
14 | 15 | #include "test/autoep/test_autoep_utils.h" |
15 | 16 | #include "test/shared_lib/utils.h" |
@@ -184,6 +185,62 @@ TEST(OrtEpLibrary, PluginEp_VirtGpu_GenEpContextModel) { |
184 | 185 | ASSERT_TRUE(std::filesystem::exists(output_model_file)); |
185 | 186 | } |
186 | 187 | } |
| 188 | + |
| 189 | +// Uses the original compiling approach with session option configs (instead of explicit compile API). |
| 190 | +// Test that ORT does not overwrite an output model if it already exists. |
| 191 | +// Notably, this tests the case in which ORT automatically generates the output model name. |
| 192 | +TEST(OrtEpLibrary, PluginEp_GenEpContextModel_ErrorOutputModelExists_AutoGenOutputModelName) { |
| 193 | + const ORTCHAR_T* input_model_file = ORT_TSTR("testdata/mul_1.onnx"); |
| 194 | + const ORTCHAR_T* expected_output_model_file = ORT_TSTR("testdata/mul_1_ctx.onnx"); |
| 195 | + std::filesystem::remove(expected_output_model_file); |
| 196 | + |
| 197 | + RegisteredEpDeviceUniquePtr example_ep; |
| 198 | + Utils::RegisterAndGetExampleEp(*ort_env, Utils::example_ep_info, example_ep); |
| 199 | + Ort::ConstEpDevice plugin_ep_device(example_ep.get()); |
| 200 | + std::unordered_map<std::string, std::string> ep_options; |
| 201 | + |
| 202 | + // Compile a model and let ORT set the output model name. This should succeed. |
| 203 | + { |
| 204 | + Ort::SessionOptions so; |
| 205 | + so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1"); |
| 206 | + // Don't specify an output model path to let ORT automatically generate it! |
| 207 | + // so.AddConfigEntry(kOrtSessionOptionEpContextFilePath, ""); |
| 208 | + |
| 209 | + so.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options); |
| 210 | + |
| 211 | + Ort::Session session(*ort_env, input_model_file, so); |
| 212 | + ASSERT_TRUE(std::filesystem::exists(expected_output_model_file)); // check compiled model was generated. |
| 213 | + } |
| 214 | + |
| 215 | + auto modify_time_1 = std::filesystem::last_write_time(expected_output_model_file); |
| 216 | + |
| 217 | + // Try compiling the model again. ORT should return an error because the output model already exists. |
| 218 | + // Original compiled model should not be modified. |
| 219 | + { |
| 220 | + Ort::SessionOptions so; |
| 221 | + so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1"); |
| 222 | + // Don't specify an output model path to let ORT automatically generate it! |
| 223 | + // so.AddConfigEntry(kOrtSessionOptionEpContextFilePath, ""); |
| 224 | + |
| 225 | + so.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options); |
| 226 | + |
| 227 | + try { |
| 228 | + Ort::Session session(*ort_env, input_model_file, so); |
| 229 | + FAIL(); // Should not get here! |
| 230 | + } catch (const Ort::Exception& excpt) { |
| 231 | + ASSERT_EQ(excpt.GetOrtErrorCode(), ORT_FAIL); |
| 232 | + ASSERT_THAT(excpt.what(), |
| 233 | + testing::HasSubstr("exists already. " |
| 234 | + "Please remove the EP context model if you want to re-generate it.")); |
| 235 | + |
| 236 | + ASSERT_TRUE(std::filesystem::exists(expected_output_model_file)); |
| 237 | + auto modify_time_2 = std::filesystem::last_write_time(expected_output_model_file); |
| 238 | + ASSERT_EQ(modify_time_2, modify_time_1); // Check that file was not modified |
| 239 | + } |
| 240 | + } |
| 241 | + |
| 242 | + std::filesystem::remove(expected_output_model_file); |
| 243 | +} |
187 | 244 | } // namespace test |
188 | 245 | } // namespace onnxruntime |
189 | 246 |
|
|
0 commit comments