Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 524 - Fix OpenMP on Linux (and Windows) #550

Merged
merged 11 commits into from
Jan 28, 2020
23 changes: 19 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ if(NOT "${OpenMP_FOUND}" OR NOT "${OpenMP_CXX_FOUND}")
endif()

if(OPENMP_FOUND)
set(AER_COMPILE_FLAGS "${AER_COMPILE_FLAGS} ${OpenMP_CXX_FLAGS}")
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} ${OpenMP_CXX_FLAGS}")
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
if(APPLE)
# On Apple and clang, we do need to link against the library unless we are building
# the Terra Addon, see issue: https://github.com/Qiskit/qiskit-aer/issues/1
Expand All @@ -143,13 +143,21 @@ if(OPENMP_FOUND)
endif()
endif()
message(STATUS "OpenMP found!")
message(STATUS "OpenMP_CXX_FLAGS = ${OpenMP_CXX_FLAGS}")
message(STATUS "OpenMP_EXE_LINKER_FLAGS = ${OpenMP_EXE_LINKER_FLAGS}")
else()
message(STATUS "WARNING: No OpenMP support found!")
endif()

message(STATUS "Looking for NLOHMANN Json library...")
set(NLOHMANN_JSON_PATH ${AER_SIMULATOR_CPP_EXTERNAL_LIBS})
find_package(nlohmann_json REQUIRED)

if(STATIC_LINKING)
message(STATUS "Using static linking with Threads...")
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG True)
endif()
find_package(Threads)

if(STATIC_LINKING)
Expand Down Expand Up @@ -212,6 +220,13 @@ get_muparserx_source_code()
# I keep this disabled on purpose, just in case I need to debug muparserx related problems
# file(GLOB MUPARSERX_SOURCES "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/headers/muparserx/parser/*.cpp")

# Windows don't have a DL library (dlopen, dlclose, etc...)
if(NOT MSVC)
find_library(DL_LIB NAMES dl)
if(${DL_LIB} MATCHES "DL_LIB-NOTFOUND")
message(FATAL_ERROR "No dl lib found")
endif()
endif()

# Set dependent libraries
set(AER_LIBRARIES
Expand All @@ -220,7 +235,7 @@ set(AER_LIBRARIES
nlohmann_json
Threads::Threads
${SPDLOG_LIB}
${CMAKE_DL_LIBS}
${DL_LIB}
${MUPARSERX_LIB})

# Cython build is only enabled if building through scikit-build.
Expand All @@ -234,7 +249,7 @@ else() # Standalone build
set_target_properties(qasm_simulator PROPERTIES
LINKER_LANGUAGE CXX
CXX_STANDARD 14
COMPILE_FLAGS ${AER_COMPILE_FLAGS}
COMPILE_FLAGS ${AER_COMPILER_FLAGS}
LINK_FLAGS ${AER_LINKER_FLAGS}
RUNTIME_OUTPUT_DIRECTORY_DEBUG Debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE Release)
Expand Down
32 changes: 20 additions & 12 deletions cmake/FindPybind11.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,7 @@ function(basic_pybind11_add_module target_name)

# This sets various properties (python include dirs) and links to python libs
target_include_directories(${target_name} PRIVATE ${PYTHON_INCLUDE_DIRS})
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}")

target_include_directories(${target_name} PRIVATE ${PYBIND_INCLUDE_DIRS})
set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
set_target_properties(${target_name} PROPERTIES CXX_STANDARD 14)

if(WIN32 OR CYGWIN)
# Link against the Python shared library on Windows
Expand All @@ -64,7 +57,7 @@ function(basic_pybind11_add_module target_name)
# into Blender or Maya later on, this will cause segfaults when multiple
# conflicting Python instances are active at the same time (even when they
# are of the same version).

# Windows is not affected by this issue since it handles DLL imports
# differently. The solution for Linux and Mac OS is simple: we just don't
# link against the Python library. The resulting shared library will have
Expand All @@ -80,9 +73,24 @@ function(basic_pybind11_add_module target_name)
# See: Two-Leve namespace symbol resolution
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} -undefined dynamic_lookup -flat_namespace")
endif()
set_target_properties(${target_name} PROPERTIES
LINK_FLAGS ${AER_LINKER_FLAGS}
COMPILE_FLAGS ${AER_COMPILE_FLAGS}
MACOSX_RPATH ON)
if(ARG_SHARED)
set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON)
endif()
endif()
# -fvisibility=hidden is required to allow multiple modules compiled against
# different pybind versions to work properly, and for some features (e.g.
# py::module_local). We force it on everything inside the `pybind11`
# namespace; also turning it on for a pybind module compilation here avoids
# potential warnings or issues from having mixed hidden/non-hidden types.
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}")
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
set_target_properties(${target_name} PROPERTIES
CXX_STANDARD 14
LINKER_LANGUAGE CXX)
# Warning: Do not merge PROPERTIES when one of the variables can be empty, it breaks
# the rest of the properties so they are not properly added.
set_target_properties(${target_name} PROPERTIES LINK_FLAGS ${AER_LINKER_FLAGS})
set_target_properties(${target_name} PROPERTIES COMPILE_FLAGS ${AER_COMPILER_FLAGS})
endfunction()
82 changes: 64 additions & 18 deletions cmake/cython_utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ set(CYTHON_INSTALL_DIR "qiskit/providers/aer/backends")

function(add_cython_module module)
add_cython_target(${module} ${module}.pyx CXX)
add_library(${module} MODULE ${module} ${ARGV1})
set_target_properties(${module} PROPERTIES
LINKER_LANGUAGE CXX
CXX_STANDARD 14)

# Avoid warnings in cython cpp generated code
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
Expand All @@ -37,25 +33,74 @@ function(add_cython_module module)
set_source_files_properties(${module}.cxx PROPERTIES COMPILE_FLAGS /w)
endif()

if(APPLE)
set_target_properties(${module} PROPERTIES
LINK_FLAGS ${AER_LINKER_FLAGS})
set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS SYSTEM THIN_LTO)
cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
if(ARG_MODULE AND ARG_SHARED)
message(FATAL_ERROR "Can't be both MODULE and SHARED")
elseif(ARG_SHARED)
set(lib_type SHARED)
else()
set(lib_type MODULE)
endif()

if(ARG_EXCLUDE_FROM_ALL)
set(exclude_from_all EXCLUDE_FROM_ALL)
endif()

add_library(${module} ${lib_type} ${exclude_from_all} ${module} ${ARG_UNPARSED_ARGUMENTS})

# We only need to pass the linter once, as the codebase is the same for
# all controllers
# add_linter(target)
target_include_directories(${module}
PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR}
PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS}
PRIVATE ${PYTHON_INCLUDE_DIRS}
PRIVATE ${NumPy_INCLUDE_DIRS}
PRIVATE ${CYTHON_USER_INCLUDE_DIRS})

target_link_libraries(${module}
${AER_LIBRARIES}
${PYTHON_LIBRARIES}
${CYTHON_USER_LIB_DIRS})
target_include_directories(${module} PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR})
target_include_directories(${module} PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS})
target_include_directories(${module} PRIVATE ${PYTHON_INCLUDE_DIRS})
target_include_directories(${module} PRIVATE ${NumPy_INCLUDE_DIRS})
target_include_directories(${module} PRIVATE ${CYTHON_USER_INCLUDE_DIRS})

target_link_libraries(${module} ${AER_LIBRARIES} ${CYTHON_USER_LIB_DIRS})

if(WIN32 OR CYGWIN)
# Link against the Python shared library on Windows
target_link_libraries(${module} ${PYTHON_LIBRARIES})
elseif(APPLE)
# It's quite common to have multiple copies of the same Python version
# installed on one's system. E.g.: one copy from the OS and another copy
# that's statically linked into an application like Blender or Maya.
# If we link our plugin library against the OS Python here and import it
# into Blender or Maya later on, this will cause segfaults when multiple
# conflicting Python instances are active at the same time (even when they
# are of the same version).

# Windows is not affected by this issue since it handles DLL imports
# differently. The solution for Linux and Mac OS is simple: we just don't
# link against the Python library. The resulting shared library will have
# missing symbols, but that's perfectly fine -- they will be resolved at
# import time.
# Set some general flags
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} -undefined dynamic_lookup")
else()
# -flat_namespace linker flag is needed otherwise dynamic symbol resolution doesn't work as expected with GCC.
# Symbols with the same name exist in different .so, so the loader just takes the first one it finds,
# which is usually the one from the first .so loaded.
# See: Two-Leve namespace symbol resolution
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} -undefined dynamic_lookup -flat_namespace")
endif()
if(ARG_SHARED)
set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON)
endif()
endif()

set_target_properties(${module} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
set_target_properties(${module} PROPERTIES SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}")
set_target_properties(${module} PROPERTIES
CXX_STANDARD 14
LINKER_LANGUAGE CXX)
# Warning: Do not merge PROPERTIES when one of the variables can be empty, it breaks
# the rest of the properties so they are not properly added.
set_target_properties(${module} PROPERTIES LINK_FLAGS ${AER_LINKER_FLAGS})
set_target_properties(${module} PROPERTIES COMPILE_FLAGS ${AER_COMPILER_FLAGS})

python_extension_module(${module}
FORWARD_DECL_MODULES_VAR fdecl_module_list)
Expand All @@ -64,6 +109,7 @@ function(add_cython_module module)
FORWARD_DECL_MODULES_LIST ${fdecl_module_list})

include_directories(${modules_INCLUDE_DIRS})

# TODO Where to put the target files
install(TARGETS ${module} LIBRARY DESTINATION ${CYTHON_INSTALL_DIR})
endfunction()
3 changes: 0 additions & 3 deletions qiskit/providers/aer/backends/wrappers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ find_package(Pybind11 REQUIRED)
# dependencies we can, so some of these dependencies are linked statically into our
# shared library.
string(REPLACE " -static " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
if(APPLE OR LINUX)
string(CONCAT CMAKE_CXX_FLAGS "-fvisibility=hidden")
endif()

# Controllers
basic_pybind11_add_module(controller_wrappers bindings.cc)
Expand Down
16 changes: 0 additions & 16 deletions qiskit/providers/aer/openpulse/cy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,6 @@ include(cython_utils)
# shared library.
string(REPLACE " -static " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# Set some general flags
if(APPLE)
message(STATUS "On Mac, we force linking with undefined symbols for Python library, they will be
solved at runtime by the loader")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(AER_LINKER_FLAGS "-undefined dynamic_lookup")
else()
# -flat_namespace linker flag is needed otherwise dynamic symbol resolution doesn't work as expected with GCC.
# Symbols with the same name exist in different .so, so the loader just takes the first one it finds,
# which is usually the one from the first .so loaded.
# See: Two-Leve namespace symbol resolution
set(AER_LINKER_FLAGS "-undefined dynamic_lookup -flat_namespace")
endif()
unset(PYTHON_LIBRARIES)
endif()

set(CYTHON_INSTALL_DIR "qiskit/providers/aer/openpulse/cy/")
add_cython_module(channel_value)
add_cython_module(measure)
Expand Down
16 changes: 0 additions & 16 deletions qiskit/providers/aer/openpulse/qutip_lite/cy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,6 @@ include(cython_utils)
# shared library.
string(REPLACE " -static " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# Set some general flags
if(APPLE)
message(STATUS "On Mac, we force linking with undefined symbols for Python library, they will be
solved at runtime by the loader")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(AER_LINKER_FLAGS "-undefined dynamic_lookup")
else()
# -flat_namespace linker flag is needed otherwise dynamic symbol resolution doesn't work as expected with GCC.
# Symbols with the same name exist in different .so, so the loader just takes the first one it finds,
# which is usually the one from the first .so loaded.
# See: Two-Leve namespace symbol resolution
set(AER_LINKER_FLAGS "-undefined dynamic_lookup -flat_namespace")
endif()
unset(PYTHON_LIBRARIES)
endif()

set(CYTHON_INSTALL_DIR "qiskit/providers/aer/openpulse/qutip_lite/cy")
add_cython_module(spconvert src/zspmv.cpp)
add_cython_module(spmath src/zspmv.cpp)
Expand Down
16 changes: 0 additions & 16 deletions src/simulators/open_pulse/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,6 @@ include(cython_utils)
# shared library.
string(REPLACE " -static " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# Set some general flags
if(APPLE)
message(STATUS "On Mac, we force linking with undefined symbols for Python library, they will be
solved at runtime by the loader")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(AER_LINKER_FLAGS "-undefined dynamic_lookup")
else()
# -flat_namespace linker flag is needed otherwise dynamic symbol resolution doesn't work as expected with GCC.
# Symbols with the same name exist in different .so, so the loader just takes the first one it finds,
# which is usually the one from the first .so loaded.
# See: Two-Leve namespace symbol resolution
set(AER_LINKER_FLAGS "-undefined dynamic_lookup -flat_namespace")
endif()
unset(PYTHON_LIBRARIES)
endif()

set(CYTHON_INSTALL_DIR "qiskit/providers/aer/openpulse/cy/")
add_cython_module(numeric_integrator_wrapper numeric_integrator.cpp)
add_cython_module(test_python_to_cpp)
Binary file modified src/third-party/linux/lib/muparserx.7z
Binary file not shown.