Я провел небольшое исследование, и Cython показался мне лучшим вариантом для этой задачи, поэтому я приступил к работе и создал 5 файлов:
- заголовок C++, определяющий класс, который собирает входные аргументы, и функцию main, которая ранее компилировалась с помощью make-файла как метод класса;
- файл .cpp, содержащий фактические функции;
- файл .pxd для определений в Cython;
- файл .pyx, обертывающий класс из пункта 1;
- файл setup.py для компиляции всего.
< /ol>
Когда я выполняю python setup.py build_ext --inplace, я получаю следующий результат:Как видите, у меня есть несколько предупреждений о неиспользуемых переменных (я считаю, что переменная «ntasks» особенно актуальна), но код компилируется без проблем. Затем в интерпретаторе Python я пытаюсь импортировать класс оболочки с помощью from pyGridSPT import pyGridSPTField, однако получаю следующую ошибку:Код: Выделить всё
running build_ext building 'pyGridSPT' extension creating build creating build/temp.macosx-10.9-universal2-cpython-311 g++-13 -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch arm64 -arch x86_64 -g -I/opt/homebrew/include -I/Users/matteo/Documents/work/VENV_pybird/include -I/Library/Frameworks/Python.framework/Versions/3.11/include/python3.11 -c gridSPT_lib_wrapper.cpp -o build/temp.macosx-10.9-universal2-cpython-311/gridSPT_lib_wrapper.o -fopenmp -lgsl -lgslcblas -lfftw3f_omp -lfftw3f g++-13: warning: this compiler does not support x86 ('-arch' option ignored) In file included from gridSPT_lib.cpp:13, from gridSPT_lib_wrapper.cpp:1237: fielddata_v2.hpp: In instantiation of 'void FieldData::apply_filter_standard(int) [with T = float]': gridSPT_lib.cpp:138:39: required from here fielddata_v2.hpp:632:21: warning: unused variable 'ntasks' [-Wunused-variable] 632 | int ntasks = omp_get_num_threads(); | ^~~~~~ fielddata_v2.hpp: In instantiation of 'void FieldData::apply_filter_standard_iso(int) [with T = float]': gridSPT_lib.cpp:140:43: required from here fielddata_v2.hpp:683:21: warning: unused variable 'ntasks' [-Wunused-variable] 683 | int ntasks = omp_get_num_threads(); | ^~~~~~ fielddata_v2.hpp: In instantiation of 'void FieldData::apply_filter_23() [with T = float]': gridSPT_lib.cpp:142:33: required from here fielddata_v2.hpp:531:21: warning: unused variable 'ntasks' [-Wunused-variable] 531 | int ntasks = omp_get_num_threads(); | ^~~~~~ fielddata_v2.hpp: In instantiation of 'void FieldData::apply_filter_23_iso() [with T = float]': gridSPT_lib.cpp:144:37: required from here fielddata_v2.hpp:582:21: warning: unused variable 'ntasks' [-Wunused-variable] 582 | int ntasks = omp_get_num_threads(); | ^~~~~~ fielddata_v2.hpp: In instantiation of 'FieldData operator*(T, const FieldData&) [with T = float]': gridSPT_lib.cpp:161:32: required from here fielddata_v2.hpp:370:17: warning: unused variable 'ng' [-Wunused-variable] 370 | long long int ng = b.get_size(); | ^~ creating build/lib.macosx-10.9-universal2-cpython-311 g++-13 -bundle -undefined dynamic_lookup -arch arm64 -arch x86_64 -g build/temp.macosx-10.9-universal2-cpython-311/gridSPT_lib_wrapper.o -L/opt/homebrew/lib -o build/lib.macosx-10.9-universal2-cpython-311/pyGridSPT.cpython-311-darwin.so g++-13: warning: this compiler does not support x86 ('-arch' option ignored) copying build/lib.macosx-10.9-universal2-cpython-311/pyGridSPT.cpython-311-darwin.so ->Я искал в Интернете, но не нашел ничего полезного. Кажется, это проблема только в MacOS, но во всех случаях это, похоже, проблема, связанная с использованием родного Apple clang (чего я уже избегаю, я использую g++, установленный с помощью Brew ).Код: Выделить всё
Traceback (most recent call last): File "", line 1, in ImportError: dlopen(/Users/matteo/Documents/work/repo/GridSPT/GridBSPT_RSD/second_order/python/pyGridSPT.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '_GOMP_loop_end_nowait'
Из исключения я думаю, что проблема связана с тем, как openmp обрабатывается во время компиляции, однако у меня нет опыта компиляции, кроме указания путей к библиотекам. , поэтому я не уверен, как это вообще отладить. Возможно, я тоже допустил ошибку в своем классе C++, так как я новичок в C/C++.
Для справки, вот как выглядит make-файл (компилируется без проблем, двоичный файл работает безупречно):И вот как я написал свой setup.py:Код: Выделить всё
#------------------------------------------------------ TARGET1 = gridSPT_RSD.exe #------------------------------------------------------ # Default Parameters #------------------------------------------------------ #CC = icpc -std=c++11 #CC = icpc #OPT = -O3 -I/usr/local/include -fopenmp #INC1 = fielddata_v2.hpp vectorfield_v2.hpp util.hpp #LIB = -fopenmp -lgsl -lgslcblas -lsrfftw_threads -lsfftw_threads -lsrfftw -lsfftw -L/usr/local/lib CC = g++-13 GSL_DIR = /opt/homebrew/ FFTW_DIR = /opt/homebrew/ OPT = -O3 -g -I${GSL_DIR}/include -I${FFTW_DIR}/include -fopenmp INC = fielddata_v2_fftw3.hpp vectorfield_v2.hpp util.hpp LIB = -fopenmp -L${GSL_DIR}/lib -L${FFTW_DIR}/lib -lgsl -lgslcblas -lfftw3f_omp -lfftw3f #--- # Source Files #--- OBJ1 = main_PT_RSD.o #------------------------------------------------------ # rules #------------------------------------------------------ gridPT : $(TARGET1) $(TARGET1): $(OBJ1) $(CC) $(OPT) -o $(TARGET1) $(OBJ1) $(LIB) .cpp.o: $(CC) -c $< $(OPT) $(OBJ1): $(INC1) clean: rm -f $(TARGET1) rm -f $(OBJ1) rm -f *~ #-----------------------------------------------------Дайте мне знать, если мне нужно предоставить более подробную информацию.Код: Выделить всё
# compile with: python setup.py build_ext --inplace # remove build folder before recompiling import os from setuptools import Extension, setup from Cython.Build import cythonize from distutils import sysconfig # MacOS (specify compiler installed with brew) os.environ["CC"] = "g++-13" sysconfig.get_config_vars()["CC"] = "g++-13" sysconfig.get_config_vars()["CXX"] = "g++-13" sysconfig.get_config_vars()["MACOSX_DEPLOYMENT_TARGET"] = "11" # external libaries extension = Extension( "pyGridSPT", sources=["gridSPT_lib_wrapper.pyx"], include_dirs=["/opt/homebrew/include"], library_dirs=["/opt/homebrew/lib"], language="c++", extra_compile_args=[ "-fopenmp", "-lgsl", "-lgslcblas", "-lfftw3f_omp", "-lfftw3f" ] ) setup(ext_modules=cythonize([extension]))
Что я пробовал: - создал файлы, необходимые для оболочки на основе Cython;
- попробовал отразить make-файл кода C++ в setup.py.
- оболочка успешно компилируется;
- оболочку можно без проблем импортировать в Python.
- оболочка успешно скомпилировалась (с предупреждениями);
оболочку невозможно импортировать в Python из-за отсутствия символов (вероятно, что-то связано с openmp). li>
Подробнее здесь: https://stackoverflow.com/questions/784 ... ing-python