Skip to content

[BUG]: staticly import Python modules in C++ global scope #4263

Description

@XuehaiPan

Required prerequisites

Problem description

Failed to load a .pyd library if it contains global imports with Python 3.8-3.10 (Python 3.6-3.7 works fine). See https://github.com/metaopt/optree/actions/runs/3288272968/jobs/5418431116 for more details.

 + python -c "import optree"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\runneradmin\AppData\Local\Temp\cibw-run-in9p445l\cp38-win_amd64\venv-test\lib\site-packages\optree\__init__.py", line 17, in <module>
from optree.ops import (
File "C:\Users\runneradmin\AppData\Local\Temp\cibw-run-in9p445l\cp38-win_amd64\venv-test\lib\site-packages\optree\ops.py", line 24, in <module>
import optree._C as _C
ImportError: DLL load failed while importing _C: A dynamic link library (DLL) initialization routine failed.

Related code:

https://github.com/metaopt/optree/blob/fa1bb70f2e92f5a3c110c00fc1790dd20d36b72d/include/utils.h#L51-L56

For Python 3.8-3.10, the import fails if there are C++ global-level imports:

namespacepy= pybind11;
const py::module_ collections_module = py::module_::import("collections");
voidfoo(py::handle) {
const py::object OrderedDict = collections_module.attr("OrderedDict");
}

Everything works fine if I change this into a function static variable:

namespacepy= pybind11;
voidfoo(py::handle) {
staticconst py::module_ collections_module = py::module_::import("collections");
const py::object OrderedDict = collections_module.attr("OrderedDict");
}

Reproducible example code

Directory structure:

.
├── CMakeLists.txt
├── test.cpp
└── third-party
└── pybind11
├── include
...

Source files:

// test.cpp
#include<pybind11/pybind11.h>namespacetest {
namespacepy= pybind11;
const py::module_ collections_module = py::module_::import("collections");
voidBuildModule(py::module& mod) {}
} // namespace testPYBIND11_MODULE(_C, mod) { test::BuildModule(mod); }
# CMakeLists.txtcmake_minimum_required(VERSION3.4)
project(test LANGUAGESCXX)
if(NOTCMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_STANDARD 14)
find_package(ThreadsREQUIRED) # -pthreadfind_package(OpenMPREQUIRED) # -Xpreprocessor -fopenmpset(CMAKE_POSITION_INDEPENDENT_CODEON) # -fPICset(CMAKE_CXX_VISIBILITY_PRESET hidden) # -fvisibility=hiddenif(MSVC)
string(APPENDCMAKE_CXX_FLAGS" /Wall")
string(APPENDCMAKE_CXX_FLAGS_DEBUG" /Zi")
string(APPENDCMAKE_CXX_FLAGS_RELEASE" /O2 /Ob2")
else()
string(APPENDCMAKE_CXX_FLAGS" -Wall")
string(APPENDCMAKE_CXX_FLAGS_DEBUG" -g -Og")
string(APPENDCMAKE_CXX_FLAGS_RELEASE" -O3")
endif()
if(NOTDEFINED PYTHON_EXECUTABLE)
if(WIN32)
set(PYTHON_EXECUTABLE "python.exe")
 else()
set(PYTHON_EXECUTABLE "python")
 endif()
endif()
add_subdirectory(third_party/pybind11)
include_directories(third_party/pybind11/include)
include_directories("${CMAKE_SOURCE_DIR}")
set(csrc test.cpp)
pybind11_add_module(_CTHIN_LTO"${csrc}")
target_link_libraries(_CPUBLIC)

Command-line and results:

Python 3.7:

$ conda create -n py37 python=3.7 -y
$ conda activate py37
$ mkdir build-py37
$ cd build-py37
$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG-- Building for: Visual Studio 17 2022-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.-- The CXX compiler identification is MSVC 19.33.31629.0-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx64/x64/cl.exe - skipped-- Detecting CXX compile features-- Detecting CXX compile features - done-- Performing Test CMAKE_HAVE_LIBC_PTHREAD-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed-- Looking for pthread_create in pthreads-- Looking for pthread_create in pthreads - not found-- Looking for pthread_create in pthread-- Looking for pthread_create in pthread - not found-- Found Threads: TRUE -- Found OpenMP_CXX: -openmp (found version "2.0") -- Found OpenMP: TRUE (found version "2.0") -- pybind11 v2.11.0 dev1-- Found PythonInterp: python.exe (found suitable version "3.7.13", minimum required is "3.6") -- Found PythonLibs: C:/Users/PanXuehai/Miniconda3/envs/py37/libs/python37.lib-- Performing Test HAS_MSVC_GL_LTCG-- Performing Test HAS_MSVC_GL_LTCG - Success-- Configuring done-- Generating done-- Build files have been written to: C:/Users/PanXuehai/Projects/test/build-py37
$ cmake --build .exit with code 0
$ cd Debug
$ ls Directory: C:\Users\PanXuehai\Projects\test\build-py37\Debug_C.cp37-win_amd64.pyd _C.exp _C.lib _C.pdb
$ python -c 'import collections; import _C'exit with code 0

Python 3.10:

$ conda create -n py310 python=3.10 -y
$ conda activate py310
$ mkdir build-py310
$ cd build-py310
$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG-- Building for: Visual Studio 17 2022-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.-- The CXX compiler identification is MSVC 19.33.31629.0-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx64/x64/cl.exe - skipped-- Detecting CXX compile features-- Detecting CXX compile features - done-- Performing Test CMAKE_HAVE_LIBC_PTHREAD-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed-- Looking for pthread_create in pthreads-- Looking for pthread_create in pthreads - not found-- Looking for pthread_create in pthread-- Looking for pthread_create in pthread - not found-- Found Threads: TRUE -- Found OpenMP_CXX: -openmp (found version "2.0") -- Found OpenMP: TRUE (found version "2.0") -- pybind11 v2.11.0 dev1-- Found PythonInterp: python.exe (found suitable version "3.10.6", minimum required is "3.6") -- Found PythonLibs: C:/Users/PanXuehai/Miniconda3/envs/py38/libs/python310.lib-- Performing Test HAS_MSVC_GL_LTCG-- Performing Test HAS_MSVC_GL_LTCG - Success-- Configuring done-- Generating done-- Build files have been written to: C:/Users/PanXuehai/Projects/test/build-py310
$ cmake --build .exit with code 0
$ cd Debug
$ ls Directory: C:\Users\PanXuehai\Projects\test\build-py310\Debug_C.cp310-win_amd64.pyd _C.exp _C.lib _C.pdb
$ python -c 'import collections; import _C'Traceback (most recent call last): File "<string>", line 1, in <module>ImportError: DLL load failed while importing _C: A dynamic link library (DLL) initialization routine failed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNew bug, unverified

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions