From cf12ea51c77531ea36761de9b6e53ed95b90824f Mon Sep 17 00:00:00 2001 From: Zhou Wei <1183042833@qq.com> Date: Wed, 28 Jul 2021 17:52:27 +0800 Subject: [PATCH] Support C++ import python on windows for paddle (#34312) * Support C++ import python on windows for paddle * Support C++ import python on windows for paddle --- python/paddle/dataset/image.py | 6 +- python/paddle/fluid/__init__.py | 8 ++- .../fluid/tests/unittests/CMakeLists.txt | 4 ++ .../fluid/tests/unittests/cc_imp_py_test.cc | 60 +++++++++++++++++++ .../tests/unittests/test_install_check.py | 13 +++- 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 python/paddle/fluid/tests/unittests/cc_imp_py_test.cc diff --git a/python/paddle/dataset/image.py b/python/paddle/dataset/image.py index 4824fe30e94..4fd7dc0d37f 100644 --- a/python/paddle/dataset/image.py +++ b/python/paddle/dataset/image.py @@ -39,8 +39,12 @@ import numpy as np if six.PY3: import subprocess import sys + if sys.platform == 'win32': + interpreter = sys.exec_prefix + "\\" + "python.exe" + else: + interpreter = sys.executable import_cv2_proc = subprocess.Popen( - [sys.executable, "-c", "import cv2"], + [interpreter, "-c", "import cv2"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = import_cv2_proc.communicate() diff --git a/python/paddle/fluid/__init__.py b/python/paddle/fluid/__init__.py index b8f74048320..c761057ff8b 100644 --- a/python/paddle/fluid/__init__.py +++ b/python/paddle/fluid/__init__.py @@ -247,7 +247,13 @@ def __bootstrap__(): ] core.init_gflags(["--tryfromenv=" + ",".join(read_env_flags)]) - core.init_glog(sys.argv[0]) + # Note(zhouwei25): sys may not have argv in some cases, + # Such as: use Python/C API to call Python from C++ + try: + core.init_glog(sys.argv[0]) + except Exception: + sys.argv = [""] + core.init_glog(sys.argv[0]) # don't init_p2p when in unittest to save time. core.init_devices() diff --git a/python/paddle/fluid/tests/unittests/CMakeLists.txt b/python/paddle/fluid/tests/unittests/CMakeLists.txt index 3c5d4403e8b..32bde0159e7 100644 --- a/python/paddle/fluid/tests/unittests/CMakeLists.txt +++ b/python/paddle/fluid/tests/unittests/CMakeLists.txt @@ -670,6 +670,10 @@ if (WITH_XPU_BKCL) py_test(test_collective_allreduce_api_xpu SRCS "test_collective_allreduce_api.py") endif() +if(WIN32) + cc_test(cc_imp_py_test SRCS cc_imp_py_test.cc DEPS python) +endif() + if (WITH_ASCEND_CL) add_subdirectory(npu) endif() diff --git a/python/paddle/fluid/tests/unittests/cc_imp_py_test.cc b/python/paddle/fluid/tests/unittests/cc_imp_py_test.cc new file mode 100644 index 00000000000..8609aff1fa5 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/cc_imp_py_test.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "Python.h" + +TEST(CC, IMPORT_PY) { + // Initialize python environment + Py_Initialize(); + ASSERT_TRUE(Py_IsInitialized()); + + // 1. C/C++ Run Python simple string + ASSERT_FALSE(PyRun_SimpleString("import paddle")); + ASSERT_FALSE(PyRun_SimpleString("print(paddle.to_tensor(1))")); + + // 2. C/C++ Run Python funciton + PyRun_SimpleString("import sys"); + PyRun_SimpleString("import os"); + PyRun_SimpleString("sys.path.append(os.getcwd())"); + PyObject* pModule = PyImport_ImportModule("test_install_check"); + ASSERT_TRUE(pModule != NULL); + + PyObject* pTestInt = PyObject_GetAttrString(pModule, "TestInt"); + ASSERT_TRUE(pTestInt != NULL); + PyObject* pArg1 = PyObject_CallObject(pTestInt, NULL); + ASSERT_TRUE(pArg1 != NULL); + int result; + ASSERT_TRUE(PyArg_Parse(pArg1, "i", &result)); + ASSERT_EQ(result, 100); + + PyObject* pTestString = PyObject_GetAttrString(pModule, "TestString"); + ASSERT_TRUE(pTestString != NULL); + PyObject* pArg2 = PyObject_CallObject(pTestString, NULL); + ASSERT_TRUE(pArg2 != NULL); + char* cwd; + ASSERT_TRUE(PyArg_Parse(pArg2, "s", &cwd)); + + // 3. C/C++ Run Python file + std::string file_name(cwd); + file_name.append("/test_install_check.py"); + FILE* fp = _Py_fopen(file_name.c_str(), "r+"); + ASSERT_TRUE(fp != NULL); + ASSERT_FALSE(PyRun_SimpleFile(fp, file_name.c_str())); + + // Uninitialize python environment + Py_Finalize(); + ASSERT_FALSE(Py_IsInitialized()); +} diff --git a/python/paddle/fluid/tests/unittests/test_install_check.py b/python/paddle/fluid/tests/unittests/test_install_check.py index 83e17406c10..15f2b5f3b7e 100644 --- a/python/paddle/fluid/tests/unittests/test_install_check.py +++ b/python/paddle/fluid/tests/unittests/test_install_check.py @@ -12,19 +12,26 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function import unittest import paddle -import paddle.fluid as fluid +import os class TestInstallCheck(unittest.TestCase): def test_paddle_fluid(self): - fluid.install_check.run_check() + paddle.fluid.install_check.run_check() def test_paddle_utils(self): paddle.utils.run_check() +def TestInt(): + return 100 + + +def TestString(): + return os.getcwd() + + if __name__ == '__main__': unittest.main() -- GitLab