diff --git a/docs/PyOp.md b/docs/PyOp.md index 2380d48eab..0764ff8b3d 100644 --- a/docs/PyOp.md +++ b/docs/PyOp.md @@ -57,9 +57,8 @@ class Multi_1: ret = S + P return ret + self.W1, ret + self.W2, ret + self.W3 class Multi_2: - def compute(self, H, N, E): - r1, r2 = H + N, N + E - return r1, r2 + def compute(self, *kwargs): + return sum(kwargs[0:-1]), sum(kwargs[1:]) ``` ### Step 4 Copy mymodule.py into Python sys.path, then run the model with onnxruntime python API. On Windows, please set PYTHONHOME beforehand. It should point to directory where the python is installed, such as C:\Python37 or C:\ProgramData\Anaconda3\envs\myconda1 if it is in conda. diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 0dbbe219d4..e21fc9675c 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -144,6 +144,8 @@ static constexpr PATH_TYPE MODEL_WITH_CUSTOM_MODEL_METADATA = TSTR("testdata/mod #ifdef ENABLE_LANGUAGE_INTEROP_OPS static constexpr PATH_TYPE PYOP_FLOAT_MODEL_URI = TSTR("testdata/pyop_1.onnx"); +static constexpr PATH_TYPE PYOP_MULTI_MODEL_URI = TSTR("testdata/pyop_2.onnx"); +static constexpr PATH_TYPE PYOP_KWARG_MODEL_URI = TSTR("testdata/pyop_3.onnx"); #endif class CApiTestWithProvider : public testing::Test, public ::testing::WithParamInterface { @@ -359,8 +361,10 @@ TEST(CApiTest, test_custom_op_library) { } #if defined(ENABLE_LANGUAGE_INTEROP_OPS) -TEST(CApiTest, test_pyop) { - std::cout << "Test model with pyop" << std::endl; +std::once_flag my_module_flag; + +void PrepareModule() +{ std::ofstream module("mymodule.py"); module << "class MyKernel:" << std::endl; module << "\t" @@ -371,7 +375,29 @@ TEST(CApiTest, test_pyop) { << "def compute(self,x):" << std::endl; module << "\t\t" << "return x*2" << std::endl; + module << "class MyKernel_2:" << std::endl; + module << "\t" + << "def __init__(self,A,B):" << std::endl; + module << "\t\t" + << "self.a,self.b = A,B" << std::endl; + module << "\t" + << "def compute(self,x):" << std::endl; + module << "\t\t" + << "return x*4" << std::endl; + module << "class MyKernel_3:" << std::endl; + module << "\t" + << "def __init__(self,A,B):" << std::endl; + module << "\t\t" + << "self.a,self.b = A,B" << std::endl; + module << "\t" + << "def compute(self,*kwargs):" << std::endl; + module << "\t\t" + << "return kwargs[0]*5" << std::endl; module.close(); +} + +TEST(CApiTest, test_pyop) { + std::call_once(my_module_flag, PrepareModule); std::vector inputs(1); Input& input = inputs[0]; input.name = "X"; @@ -381,6 +407,30 @@ TEST(CApiTest, test_pyop) { std::vector expected_values_y = {2.0f, 4.0f, 6.0f, 8.0f}; TestInference(*ort_env, PYOP_FLOAT_MODEL_URI, inputs, "Y", expected_dims_y, expected_values_y, 0, nullptr, nullptr); } + +TEST(CApiTest, test_pyop_multi) { + std::call_once(my_module_flag, PrepareModule); + std::vector inputs(1); + Input& input = inputs[0]; + input.name = "X"; + input.dims = {2, 2}; + input.values = {1.0f, 2.0f, 3.0f, 4.0f}; + std::vector expected_dims_y = {2, 2}; + std::vector expected_values_y = {8.0f, 16.0f, 24.0f, 32.0f}; + TestInference(*ort_env, PYOP_MULTI_MODEL_URI, inputs, "Z", expected_dims_y, expected_values_y, 0, nullptr, nullptr); +} + +TEST(CApiTest, test_pyop_kwarg) { + std::call_once(my_module_flag, PrepareModule); + std::vector inputs(1); + Input& input = inputs[0]; + input.name = "X"; + input.dims = {2, 2}; + input.values = {1.0f, 2.0f, 3.0f, 4.0f}; + std::vector expected_dims_y = {2, 2}; + std::vector expected_values_y = {25.0f, 50.0f, 75.0f, 100.0f}; + TestInference(*ort_env, PYOP_KWARG_MODEL_URI, inputs, "Z", expected_dims_y, expected_values_y, 0, nullptr, nullptr); +} #endif #ifdef ORT_RUN_EXTERNAL_ONNX_TESTS diff --git a/onnxruntime/test/testdata/pyop_2.onnx b/onnxruntime/test/testdata/pyop_2.onnx new file mode 100644 index 0000000000..51d4e91133 --- /dev/null +++ b/onnxruntime/test/testdata/pyop_2.onnx @@ -0,0 +1,31 @@ + +pyop_model: + +XY"PyOp* +A"1* +B"2* +C"3* + +class_name"MyKernel* + input_types@* +module"mymodule* + output_types@: pyop_multi_1 + +YZ"PyOp* +A"1* + +B"11* + +class_name" +MyKernel_2* + input_types@* +module"mymodule* + output_types@: pyop_multi_2multi_pyop_graphZ +X +  + +b +Z +  + +B \ No newline at end of file diff --git a/onnxruntime/test/testdata/pyop_3.onnx b/onnxruntime/test/testdata/pyop_3.onnx new file mode 100644 index 0000000000..6b69f58c11 --- /dev/null +++ b/onnxruntime/test/testdata/pyop_3.onnx @@ -0,0 +1,30 @@ + +pyop_model: + +XY"PyOp* +A"1* +B"2* + +class_name" +MyKernel_3* + input_types@* +module"mymodule* + output_types@: pyop_kwarg_1 + +YZ"PyOp* +A"2* +B"1* + +class_name" +MyKernel_3* + input_types@* +module"mymodule* + output_types@: pyop_kwarg_2multi_pyop_graphZ +X +  + +b +Z +  + +B \ No newline at end of file