Skip to content

Commit de65341

Browse files
Merge pull request #643 from basnijholt/apple-silicon
Make qsimcirq Apple Silicon (M1, M2, ARM64) compatible and improve build scripts
2 parents b73b5bb + 34ca2a5 commit de65341

File tree

14 files changed

+157
-97
lines changed

14 files changed

+157
-97
lines changed

.github/workflows/release_wheels.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ jobs:
1212
fail-fast: false
1313
matrix:
1414
include:
15-
- os: macos-12
15+
- os: macos-12 # x86_64
1616
name: mac
1717
cibw:
1818
build: "cp37* cp38* cp39* cp310* cp311*"
19+
- os: macos-13-large # Apple Silicon
20+
name: mac_arm64
21+
cibw:
22+
build: "cp37* cp38* cp39* cp310* cp311*"
1923
- os: ubuntu-20.04
2024
name: manylinux2014
2125
cibw:
@@ -32,7 +36,7 @@ jobs:
3236
CIBW_SKIP: "*musllinux*"
3337
CIBW_ARCHS: "${{ matrix.cibw.arch || 'auto' }}"
3438
CIBW_MANYLINUX_X86_64_IMAGE: "${{ matrix.cibw.manylinux_image }}"
35-
CIBW_BEFORE_BUILD_MACOS: "brew install libomp llvm"
39+
CIBW_BEFORE_BUILD_MACOS: "brew install libomp llvm && brew link --overwrite python@3.11 && brew link --force libomp"
3640
CIBW_REPAIR_WHEEL_COMMAND_MACOS: "delocate-listdeps {wheel} && delocate-wheel --verbose --require-archs {delocate_archs} -w {dest_dir} {wheel}"
3741
# to install latest delocate package
3842
CIBW_DEPENDENCY_VERSIONS: "latest"

.github/workflows/testing_wheels.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
include:
20-
- os: macos-12
20+
- os: macos-12 # x86_64
2121
name: mac
2222
cibw:
2323
build: "cp37* cp38* cp39* cp310* cp311*"
24+
- os: macos-13-large # Apple Silicon
25+
name: mac_arm64
26+
cibw:
27+
build: "cp37* cp38* cp39* cp310* cp311*"
2428
- os: ubuntu-20.04
2529
name: manylinux2014
2630
cibw:
@@ -37,7 +41,7 @@ jobs:
3741
CIBW_SKIP: "*musllinux*"
3842
CIBW_ARCHS: "${{ matrix.cibw.arch || 'auto' }}"
3943
CIBW_MANYLINUX_X86_64_IMAGE: "${{ matrix.cibw.manylinux_image }}"
40-
CIBW_BEFORE_BUILD_MACOS: "brew install libomp llvm"
44+
CIBW_BEFORE_BUILD_MACOS: "brew install libomp llvm && brew link --overwrite python@3.11 && brew link --force libomp"
4145
CIBW_REPAIR_WHEEL_COMMAND_MACOS: "delocate-listdeps {wheel} && delocate-wheel --verbose --require-archs {delocate_archs} -w {dest_dir} {wheel}"
4246
# to install latest delocate package
4347
CIBW_DEPENDENCY_VERSIONS: "latest"

CMakeLists.txt

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,51 @@
1+
set(CMAKE_CXX_STANDARD 11)
12
cmake_minimum_required(VERSION 3.11)
23

3-
execute_process(COMMAND which nvcc OUTPUT_VARIABLE has_nvcc)
4-
if(has_nvcc STREQUAL "")
5-
execute_process(COMMAND which hipcc OUTPUT_VARIABLE has_hipcc)
6-
if(has_hipcc STREQUAL "")
7-
project(qsim)
8-
else()
9-
project(qsim LANGUAGES CXX HIP)
10-
ADD_SUBDIRECTORY(pybind_interface/hip)
4+
# Set APPLE_ARM to TRUE if running on Apple Silicon
5+
if(APPLE)
6+
execute_process(COMMAND uname -m OUTPUT_VARIABLE OSX_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
7+
if (OSX_ARCH STREQUAL "arm64")
8+
set(APPLE_ARM TRUE)
9+
else() # x86_64
10+
set(APPLE_ARM FALSE)
1111
endif()
1212
else()
13-
project(qsim LANGUAGES CXX CUDA)
14-
ADD_SUBDIRECTORY(pybind_interface/cuda)
15-
if(DEFINED ENV{CUQUANTUM_ROOT})
16-
ADD_SUBDIRECTORY(pybind_interface/custatevec)
13+
set(APPLE_ARM FALSE)
14+
endif(APPLE)
15+
16+
# Set the project name and language
17+
if(APPLE)
18+
project(qsim LANGUAGES CXX)
19+
else()
20+
execute_process(COMMAND which nvcc OUTPUT_VARIABLE has_nvcc OUTPUT_STRIP_TRAILING_WHITESPACE)
21+
if(has_nvcc)
22+
project(qsim LANGUAGES CXX CUDA)
23+
else()
24+
execute_process(COMMAND which hipcc OUTPUT_VARIABLE has_hipcc OUTPUT_STRIP_TRAILING_WHITESPACE)
25+
if(has_hipcc)
26+
project(qsim LANGUAGES CXX HIP)
27+
else()
28+
project(qsim LANGUAGES CXX)
29+
endif()
1730
endif()
1831
endif()
1932

20-
ADD_SUBDIRECTORY(pybind_interface/sse)
21-
ADD_SUBDIRECTORY(pybind_interface/avx512)
22-
ADD_SUBDIRECTORY(pybind_interface/avx2)
33+
find_package(OpenMP REQUIRED)
34+
35+
# Add subdirectories based on the architecture or available compilers
2336
ADD_SUBDIRECTORY(pybind_interface/basic)
2437
ADD_SUBDIRECTORY(pybind_interface/decide)
38+
if(NOT APPLE_ARM)
39+
if(has_nvcc)
40+
ADD_SUBDIRECTORY(pybind_interface/cuda)
41+
if(DEFINED ENV{CUQUANTUM_ROOT})
42+
ADD_SUBDIRECTORY(pybind_interface/custatevec)
43+
endif()
44+
elseif(has_hipcc)
45+
ADD_SUBDIRECTORY(pybind_interface/hip)
46+
endif()
47+
48+
ADD_SUBDIRECTORY(pybind_interface/sse)
49+
ADD_SUBDIRECTORY(pybind_interface/avx512)
50+
ADD_SUBDIRECTORY(pybind_interface/avx2)
51+
endif()

pybind_interface/GetPybind11.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ FetchContent_Declare(
88
)
99
FetchContent_GetProperties(pybind11)
1010
find_package(pybind11 "${MIN_PYBIND_VERSION}" CONFIG)
11+
12+
if (pybind11_FOUND)
13+
message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
14+
# The pybind11_add_module doesn't correctly set the CXX_INCLUDES properly if a system pybind11 is found.
15+
# Using `include_directories(${pybind11_INCLUDE_DIRS})` doesn't result in anything in
16+
# CXX_INCLUDES. e.g., `pybind_interface/basic/CMakeFiles/qsim_basic.dir/flags.make` would only
17+
# have `CXX_INCLUDES = -isystem $PREFIX/include/python3.11` and would miss `$PREFIX/include`.
18+
# This problem would result in `fatal error: pybind11/complex.h: No such file or directory`
19+
# This is a hack to get around that by passing `-I/path/to/include` to CXX_FLAGS
20+
# Iterate over each include directory and add it as a compile option
21+
foreach(INCLUDE_DIR ${pybind11_INCLUDE_DIRS})
22+
add_compile_options("-I${INCLUDE_DIR}")
23+
endforeach()
24+
endif()
25+
1126
if((NOT pybind11_FOUND) AND (NOT pybind11_POPULATED)) # check first on system path, then attempt git fetch
1227
FetchContent_Populate(pybind11)
1328
add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR})

pybind_interface/avx2/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(qsim)
44
IF (WIN32)
55
set(CMAKE_CXX_FLAGS "/arch:AVX2 /O2 /openmp")
66
ELSE()
7-
set(CMAKE_CXX_FLAGS "-mavx2 -mfma -O3 -fopenmp")
7+
set(CMAKE_CXX_FLAGS "-mavx2 -mfma -O3")
88
ENDIF()
99

1010
if(APPLE)
@@ -14,3 +14,5 @@ if(APPLE)
1414
endif()
1515
INCLUDE(../GetPybind11.cmake)
1616
pybind11_add_module(qsim_avx2 pybind_main_avx2.cpp)
17+
18+
target_link_libraries(qsim_avx2 PUBLIC OpenMP::OpenMP_CXX)

pybind_interface/avx512/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ project(qsim)
55
IF (WIN32)
66
set(CMAKE_CXX_FLAGS "/arch:AVX512 /O2 /openmp")
77
ELSE()
8-
set(CMAKE_CXX_FLAGS "-mavx512f -mbmi2 -O3 -fopenmp")
8+
set(CMAKE_CXX_FLAGS "-mavx512f -mbmi2 -O3")
99
ENDIF()
1010

1111
if(APPLE)
@@ -16,3 +16,5 @@ endif()
1616

1717
INCLUDE(../GetPybind11.cmake)
1818
pybind11_add_module(qsim_avx512 pybind_main_avx512.cpp)
19+
20+
target_link_libraries(qsim_avx512 PUBLIC OpenMP::OpenMP_CXX)

pybind_interface/basic/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
cmake_minimum_required(VERSION 3.11)
22
project(qsim)
33

4-
IF (WIN32)
4+
if(WIN32)
55
set(CMAKE_CXX_FLAGS "/O2 /openmp")
6-
ELSE()
7-
set(CMAKE_CXX_FLAGS "-O3 -fopenmp")
8-
ENDIF()
6+
else()
7+
set(CMAKE_CXX_FLAGS "-O3")
8+
endif()
99

1010

1111
if(APPLE)
@@ -16,3 +16,5 @@ endif()
1616

1717
INCLUDE(../GetPybind11.cmake)
1818
pybind11_add_module(qsim_basic pybind_main_basic.cpp)
19+
20+
target_link_libraries(qsim_basic PUBLIC OpenMP::OpenMP_CXX)

pybind_interface/cuda/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
cmake_minimum_required(VERSION 3.11)
22
project(qsim LANGUAGES CXX CUDA)
33

4-
IF (WIN32)
4+
if(WIN32)
55
set(CMAKE_CXX_FLAGS "/O2 /openmp")
6-
ELSE()
7-
set(CMAKE_CXX_FLAGS "-O3 -fopenmp")
8-
ENDIF()
6+
else()
7+
set(CMAKE_CXX_FLAGS "-O3")
8+
endif()
99

1010

1111
if(APPLE)
@@ -26,3 +26,5 @@ set_target_properties(qsim_cuda PROPERTIES
2626
SUFFIX "${PYTHON_MODULE_EXTENSION}"
2727
)
2828
set_source_files_properties(pybind_main_cuda.cpp PROPERTIES LANGUAGE CUDA)
29+
30+
target_link_libraries(qsim_cuda PUBLIC OpenMP::OpenMP_CXX)

pybind_interface/custatevec/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
cmake_minimum_required(VERSION 3.11)
1616
project(qsim LANGUAGES CXX CUDA)
1717

18-
IF (WIN32)
18+
if(WIN32)
1919
set(CMAKE_CXX_FLAGS "/O2 /openmp")
20-
ELSE()
21-
set(CMAKE_CXX_FLAGS "-O3 -fopenmp")
22-
ENDIF()
20+
else()
21+
set(CMAKE_CXX_FLAGS "-O3")
22+
endif()
2323

2424
if(APPLE)
2525
set(CMAKE_CXX_STANDARD 14)
@@ -44,3 +44,5 @@ set_target_properties(qsim_custatevec PROPERTIES
4444
SUFFIX "${PYTHON_MODULE_EXTENSION}"
4545
)
4646
set_source_files_properties(pybind_main_custatevec.cpp PROPERTIES LANGUAGE CUDA)
47+
48+
target_link_libraries(qsim_custatevec PUBLIC OpenMP::OpenMP_CXX)
Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,48 @@
11
cmake_minimum_required(VERSION 3.11)
22

3-
execute_process(COMMAND which nvcc OUTPUT_VARIABLE has_nvcc)
4-
if(has_nvcc STREQUAL "")
5-
execute_process(COMMAND which hipcc OUTPUT_VARIABLE has_hipcc)
6-
if(has_hipcc STREQUAL "")
7-
project(qsim)
8-
else()
9-
project(qsim LANGUAGES CXX HIP)
10-
endif()
3+
if(WIN32)
4+
set(CMAKE_CXX_FLAGS "/O2 /openmp")
115
else()
12-
project(qsim LANGUAGES CXX CUDA)
6+
set(CMAKE_CXX_FLAGS "-O3")
137
endif()
148

15-
IF (WIN32)
16-
set(CMAKE_CXX_FLAGS "/O2 /openmp")
17-
ELSE()
18-
set(CMAKE_CXX_FLAGS "-O3 -fopenmp")
19-
ENDIF()
20-
21-
if(APPLE)
9+
if(APPLE AND NOT APPLE_ARM)
2210
set(CMAKE_CXX_STANDARD 14)
2311
include_directories("/usr/local/include" "/usr/local/opt/llvm/include")
2412
link_directories("/usr/local/lib" "/usr/local/opt/llvm/lib")
2513
endif()
2614

27-
INCLUDE(../GetPybind11.cmake)
28-
29-
if(has_nvcc STREQUAL "")
30-
if(has_hipcc STREQUAL "")
31-
pybind11_add_module(qsim_decide decide.cpp)
32-
else()
15+
include(../GetPybind11.cmake)
16+
17+
# Configure based on the detected platform
18+
if(has_nvcc)
19+
find_package(CUDA REQUIRED)
20+
cuda_add_library(qsim_decide MODULE decide.cpp)
21+
if(DEFINED ENV{CUQUANTUM_ROOT})
22+
target_compile_options(qsim_decide PRIVATE
23+
$<$<COMPILE_LANGUAGE:CUDA>:-D__CUSTATEVEC__>
24+
)
25+
endif()
26+
find_package(Python3 3.7 REQUIRED COMPONENTS Interpreter Development)
27+
include_directories(${PYTHON_INCLUDE_DIRS} ${pybind11_SOURCE_DIR}/include)
28+
set_target_properties(qsim_decide PROPERTIES
29+
PREFIX "${PYTHON_MODULE_PREFIX}"
30+
SUFFIX "${PYTHON_MODULE_EXTENSION}"
31+
)
32+
set_source_files_properties(decide.cpp PROPERTIES LANGUAGE CUDA)
33+
elseif(has_hipcc)
3334
list(APPEND CMAKE_MODULE_PATH "/opt/rocm/lib/cmake/hip")
3435
find_package(HIP REQUIRED)
35-
find_package(PythonLibs 3.7 REQUIRED)
36-
37-
include_directories(${PYTHON_INCLUDE_DIRS} ${pybind11_SOURCE_DIR}/include)
38-
3936
hip_add_library(qsim_decide MODULE decide.cpp)
40-
37+
set_source_files_properties(decide.cpp PROPERTIES LANGUAGE HIP)
38+
find_package(Python3 3.7 REQUIRED COMPONENTS Interpreter Development)
39+
include_directories(${PYTHON_INCLUDE_DIRS} ${pybind11_SOURCE_DIR}/include)
4140
set_target_properties(qsim_decide PROPERTIES
42-
PREFIX "${PYTHON_MODULE_PREFIX}"
43-
SUFFIX "${PYTHON_MODULE_EXTENSION}"
41+
PREFIX "${PYTHON_MODULE_PREFIX}"
42+
SUFFIX "${PYTHON_MODULE_EXTENSION}"
4443
)
45-
set_source_files_properties(decide.cpp PROPERTIES LANGUAGE HIP)
46-
endif()
4744
else()
48-
find_package(PythonLibs 3.7 REQUIRED)
49-
find_package(CUDA REQUIRED)
50-
51-
include_directories(${PYTHON_INCLUDE_DIRS} ${pybind11_SOURCE_DIR}/include)
52-
53-
cuda_add_library(qsim_decide MODULE decide.cpp)
54-
55-
if(DEFINED ENV{CUQUANTUM_ROOT})
56-
target_compile_options(qsim_decide PRIVATE
57-
$<$<COMPILE_LANGUAGE:CUDA>:-D__CUSTATEVEC__>
58-
)
59-
endif()
60-
61-
set_target_properties(qsim_decide PROPERTIES
62-
PREFIX "${PYTHON_MODULE_PREFIX}"
63-
SUFFIX "${PYTHON_MODULE_EXTENSION}"
64-
)
65-
set_source_files_properties(decide.cpp PROPERTIES LANGUAGE CUDA)
45+
pybind11_add_module(qsim_decide decide.cpp)
6646
endif()
47+
48+
target_link_libraries(qsim_decide PUBLIC OpenMP::OpenMP_CXX)

0 commit comments

Comments
 (0)