Избегайте несоответствия OpenMP RTL, если в cmake используются MKL и OpenMP - PullRequest
0 голосов
/ 21 февраля 2020

Я наткнулся на проблему, которую не мог сразу решить, прочитав документацию FindBLAS и FindOpenMP. Может быть, у кого-то есть подсказка для меня. Допустим, у меня есть проект, который импортирует целевой интерфейс A с зависимостью BLAS. FindBLAS определяет, что MKL хорошо подходит. Теперь в моем CMakeLists.txt я создаю другую цель B, которая требует OpenMP. Затем я связываю A с B. Моя конкретная проблема заключается в том, что на Linux с G CC в качестве компилятора FindBLAS использует реализацию Intel OpenMP и соответственно устанавливает уровень интерфейса MKL (что также предлагается в MKL Link Advisor). FindOpenMP, конечно, прибегает к libgomp для ссылок. Во время линковки я в конечном итоге использую обе библиотеки времени выполнения, то есть libgomp и libiomp, что я считаю несколько опасным. Вот сокращенный CMakeLists.txt, который иллюстрирует проблему:

cmake_minimum_required(VERSION 3.12)
project(test LANGUAGES C CXX)

find_package(BLAS REQUIRED)
find_package(OpenMP REQUIRED)

# Dummy interface libary A that depends on MKL
add_library(a INTERFACE)
target_include_directories(a INTERFACE include/)
target_link_libraries(a INTERFACE "${BLAS_LIBRARIES}")
target_link_options(a INTERFACE "${LINKER_FLAGS}")

# target B that depends on OpenMP and A
add_executable(b src/b.cc)
target_link_libraries(b PRIVATE OpenMP::OpenMP_CXX a)

Вывод выглядит следующим образом:

– The C compiler identification is GNU 9.1.0
– The CXX compiler identification is GNU 9.1.0
– Check for working C compiler: /opt/bwhpc/common/compiler/gnu/9.1.0/bin/gcc
– Check for working C compiler: /opt/bwhpc/common/compiler/gnu/9.1.0/bin/gcc – works
– Detecting C compiler ABI info
– Detecting C compiler ABI info - done
– Detecting C compile features
– Detecting C compile features - done
– Check for working CXX compiler: /opt/bwhpc/common/compiler/gnu/9.1.0/bin/g++
– Check for working CXX compiler: /opt/bwhpc/common/compiler/gnu/9.1.0/bin/g++ – works
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Detecting CXX compile features
– Detecting CXX compile features - done
– Looking for sgemm_
– Looking for sgemm_ - not found
– Looking for pthread.h
– Looking for pthread.h - found
– Looking for pthread_create
– Looking for pthread_create - not found
– 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 - found
– Found Threads: TRUE
– Looking for sgemm_
– Looking for sgemm_ - found
– Found BLAS: /opt/bwhpc/common/compiler/intel/compxe.2018.5.274/compilers_and_libraries_2018.5.274/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so;/opt/bwhpc/common/compiler/intel/compxe.2018.5.274/compilers_and_libraries_2018.5.274/linux/mkl/lib/intel64_lin/libmkl_intel_thread.so;/opt/bwhpc/common/compiler/intel/compxe.2018.5.274/compilers_and_libraries_2018.5.274/linux/mkl/lib/intel64_lin/libmkl_core.so;/opt/bwhpc/common/compiler/intel/compxe.2018.5.274/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64_lin/libiomp5.so;-lpthread;-lm;-ldl
– Found OpenMP_C: -fopenmp (found version “4.5”)
– Found OpenMP_CXX: -fopenmp (found version “4.5”)
– Found OpenMP: TRUE (found version “4.5”)
– Configuring done
– Generating done

И доходность здания:

$ VERBOSE=1 make
/pfs/data1/software_uc1/bwhpc/common/devel/cmake/3.14.0/bin/cmake -S/home/hd/hd_hd/hd_em426/psidm2 -B/home/hd/hd_hd/hd_em426/psidm2/build --check-build-system CMakeFiles/Makefile.cmake 0
/pfs/data1/software_uc1/bwhpc/common/devel/cmake/3.14.0/bin/cmake -E cmake_progress_start /home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles /home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory /pfs/data2/home/hd/hd_hd/hd_em426/psidm2/build' make -f CMakeFiles/b.dir/build.make CMakeFiles/b.dir/depend make[2]: Entering directory /pfs/data2/home/hd/hd_hd/hd_em426/psidm2/build’
cd /home/hd/hd_hd/hd_em426/psidm2/build && /pfs/data1/software_uc1/bwhpc/common/devel/cmake/3.14.0/bin/cmake -E cmake_depends “Unix Makefiles” /home/hd/hd_hd/hd_em426/psidm2 /home/hd/hd_hd/hd_em426/psidm2 /home/hd/hd_hd/hd_em426/psidm2/build /home/hd/hd_hd/hd_em426/psidm2/build /home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/b.dir/DependInfo.cmake --color=
Dependee “/home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/b.dir/DependInfo.cmake” is newer than depender “/home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/b.dir/depend.internal”.
Dependee “/home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/CMakeDirectoryInformation.cmake” is newer than depender “/home/hd/hd_hd/hd_em426/psidm2/build/CMakeFiles/b.dir/depend.internal”.
Scanning dependencies of target b
make[2]: Leaving directory /pfs/data2/home/hd/hd_hd/hd_em426/psidm2/build' make -f CMakeFiles/b.dir/build.make CMakeFiles/b.dir/build make[2]: Entering directory /pfs/data2/home/hd/hd_hd/hd_em426/psidm2/build’
[ 50%] Building CXX object CMakeFiles/b.dir/src/b.cc.o
/opt/bwhpc/common/compiler/gnu/9.1.0/bin/g++ -I/home/hd/hd_hd/hd_em426/psidm2/include -fopenmp -o CMakeFiles/b.dir/src/b.cc.o -c /home/hd/hd_hd/hd_em426/psidm2/src/b.cc
[100%] Linking CXX executable b
/pfs/data1/software_uc1/bwhpc/common/devel/cmake/3.14.0/bin/cmake -E cmake_link_script CMakeFiles/b.dir/link.txt --verbose=1
/opt/bwhpc/common/compiler/gnu/9.1.0/bin/g++ CMakeFiles/b.dir/src/b.cc.o -o b /pfs/data1/software_uc1/bwhpc/common/compiler/gnu/9.1.0/lib64/libgomp.so -lpthread -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core /opt/bwhpc/common/compiler/intel/compxe.2018.5.274/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64_lin/libiomp5.so -lpthread -lm -ldl

Так что я думаю мой вопрос: это предполагаемое поведение FindBLAS? Не лучше ли для FindBLAS выбрать интерфейс GNU MKL и использовать libgomp, если он обнаруживает компилятор GNU, так что смешивание с FindOpenMP не приводит к проблеме, описанной выше?

1 Ответ

0 голосов
/ 24 февраля 2020

Среда выполнения OpenMP LLVM (и Intel) имеет прокладки, которые позволяют скомпилированному коду G CC OPenMP * выполняться. Поэтому ваше лучшее решение, вероятно, будет делать это: связать с libiomp5 повсюду.

Вы абсолютно правы, избегая включения обеих библиотек в процесс. Это может привести к избыточной подписке (больше потоков, чем к логическим ЦПУ) и низкой производительности, помимо возможного некорректного выполнения.

* Могут возникнуть проблемы, если вы используете разгрузку на другие устройства, такие как графические процессоры, но только для процессора, код G CC Совместимость является критической целью для среды выполнения LLVM / Intel, именно для того, чтобы вы могли легко решить эту проблему.

...