1+ # Copyright 2025 Google LLC
2+ #
3+ # Licensed under the Apache License, Version 2.0 (the "License");
4+ # you may not use this file except in compliance with the License.
5+ # You may obtain a copy of the License at
6+ #
7+ # https://www.apache.org/licenses/LICENSE-2.0
8+ #
9+ # Unless required by applicable law or agreed to in writing, software
10+ # distributed under the License is distributed on an "AS IS" BASIS,
11+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ # See the License for the specific language governing permissions and
13+ # limitations under the License.
14+
15+ # Version info for the copy of Eigen we will download and build locally.
116EIGEN_PREFIX = "3bb6a48d8c171cf20b5f8e48bfb4e424fbd4f79e"
217EIGEN_URL = "https://gitlab.com/libeigen/eigen/-/archive/"
318
19+ # Default build targets. Additional may be added conditionally below.
420TARGETS = qsim
521TESTS = run-cxx-tests
622
7- CXX =g++
8- NVCC =nvcc
9- HIPCC =hipcc
23+ # By default, we also build the pybind11-based Python interface.
24+ PYBIND11 ?= true
1025
11- CXXFLAGS = -O3 -fopenmp
12- ARCHFLAGS = -march=native
13- NVCCFLAGS = -O3
14- HIPCCFLAGS = -O3
26+ ifeq ( $( PYBIND11 ) , true)
27+ TARGETS += pybind
28+ TESTS += run-py-tests
29+ endif
1530
16- # CUQUANTUM_ROOT should be set.
17- CUSTATEVECFLAGS = -I$(CUQUANTUM_ROOT ) /include -L${CUQUANTUM_ROOT}/lib -L$(CUQUANTUM_ROOT ) /lib64 -lcustatevec -lcublas
31+ # Default options for Pytest (only used if the pybind interface is built).
32+ PYTESTFLAGS ?= -v
33+
34+ # Default C++ compilers and compiler flags. Can be overriden via env variables.
35+ CXX ?= g++
36+ NVCC ?= nvcc
37+ HIPCC ?= hipcc
38+
39+ CXXFLAGS ?= -O3 -std=c++17 -fopenmp
40+ NVCCFLAGS ?= -O3 --std c++17 -Wno-deprecated-gpu-targets
41+ HIPCCFLAGS ?= -O3
42+
43+ # Determine whether we can include CUDA and cuStateVec support. We build for
44+ # CUDA if (i) we find $NVCC or (ii) $CUDA_PATH is set. For cuStateVec, there's
45+ # no way to find the cuQuantum libraries other than by being told, so we rely
46+ # on the user or calling environment to set variable $CUQUANTUM_ROOT.
47+
48+ ifneq (,$(shell which $(NVCC ) ) )
49+ # nvcc adds appropriate -I and -L flags, so nothing more is needed here.
50+ TARGETS += qsim-cuda
51+ TESTS += run-cuda-tests
52+ else
53+ ifneq (,$(strip $(CUDA_PATH)))
54+ # $CUDA_PATH is set. Check that the path truly does exist.
55+ ifneq (,$(strip $(wildcard $(CUDA_PATH)/.)))
56+ # $CUDA_PATH is set, but we know we didn't find nvcc on the user's
57+ # $PATH or as an absolute path (if $NVCC was set to a full path).
58+ # Try the safest choice for finding nvcc & give up if that fails.
59+ NVCC = $(CUDA_PATH ) /bin/nvcc
60+ ifneq (,$(strip $(wildcard $(NVCC))))
61+ CXXFLAGS += -I$(CUDA_PATH ) /include -L$(CUDA_PATH ) /lib64
62+ TARGETS += qsim-cuda
63+ TESTS += run-cuda-tests
64+ else
65+ $(warning nvcc not found, so cannot build CUDA interfaces)
66+ endif
67+ else
68+ $(warning $$CUDA_PATH is set, but the path does not seem to exist)
69+ endif
70+ endif
71+ endif
1872
19- PYBIND11 = true
73+ ifneq (,$(strip $(CUQUANTUM_ROOT ) ) )
74+ # $CUQUANTUM_ROOT is set. Check that the path truly does exist.
75+ ifneq (,$(strip $(wildcard $(CUQUANTUM_ROOT)/.)))
76+ CUSVFLAGS = -I$(CUQUANTUM_ROOT ) /include
77+ CUSVFLAGS += -L${CUQUANTUM_ROOT}/lib -L$(CUQUANTUM_ROOT ) /lib64
78+ CUSVFLAGS += -lcustatevec -lcublas
79+ CUSTATEVECFLAGS ?= $(CUSVFLAGS )
80+ TARGETS += qsim-custatevec
81+ TESTS += run-custatevec-tests
82+ else
83+ $(warning $$CUQUANTUM_ROOT is set, but the path does not seem to exist)
84+ endif
85+ endif
2086
21- export CXX
22- export CXXFLAGS
23- export ARCHFLAGS
24- export NVCC
25- export NVCCFLAGS
26- export CUSTATEVECFLAGS
27- export HIPCC
28- export HIPCCFLAGS
87+ # Export all variables to subprocesses without having to export them individually.
88+ .EXPORT_ALL_VARIABLES :
2989
30- ifeq ($(PYBIND11 ) , true)
31- TARGETS += pybind
32- TESTS += run-py-tests
33- endif
90+ # The rest is build rules and make targets.
3491
3592.PHONY : all
3693all : $(TARGETS )
@@ -44,7 +101,7 @@ qsim-cuda:
44101 $(MAKE ) -C apps/ qsim-cuda
45102
46103.PHONY : qsim-custatevec
47- qsim-custatevec :
104+ qsim-custatevec : | check-cuquantum-root-set
48105 $(MAKE ) -C apps/ qsim-custatevec
49106
50107.PHONY : qsim-hip
@@ -64,7 +121,7 @@ cuda-tests:
64121 $(MAKE ) -C tests/ cuda-tests
65122
66123.PHONY : custatevec-tests
67- custatevec-tests :
124+ custatevec-tests : | check-cuquantum-root-set
68125 $(MAKE ) -C tests/ custatevec-tests
69126
70127.PHONY : hip-tests
@@ -87,25 +144,37 @@ run-custatevec-tests: custatevec-tests
87144run-hip-tests : hip-tests
88145 $(MAKE ) -C tests/ run-hip-tests
89146
90- PYTESTS = $(shell find qsimcirq_tests/ -name ' * _test.py' )
147+ PYTESTS : = $(wildcard qsimcirq_tests/* _test.py)
91148
92149.PHONY : run-py-tests
93150run-py-tests : pybind
94- for exe in $( PYTESTS) ; do if ! python3 -m pytest $$ exe; then exit 1; fi ; done
151+ python3 -m pytest $(PYTESTFLAGS ) $(PYTESTS )
152+
153+ .PHONY : run-tests tests
154+ run-tests tests : $(TESTS )
95155
96- .PHONY : run-tests
97- run-tests : $(TESTS )
156+ .PHONY : check-cuquantum-root-set
157+ check-cuquantum-root-set :
158+ @if [[ -z " $( CUQUANTUM_ROOT) " ]]; then \
159+ echo Error: ' $$CUQUANTUM_ROOT must be set in order to use cuStateVec.' \
160+ exit 1 \
161+ fi
98162
99163eigen :
100- $(shell\
101- rm -rf eigen; \
102- wget $(EIGEN_URL ) /$(EIGEN_PREFIX ) /eigen-$(EIGEN_PREFIX ) .tar.gz; \
103- tar -xf eigen-$(EIGEN_PREFIX ) .tar.gz && mv eigen-$(EIGEN_PREFIX ) eigen; \
104- rm eigen-$(EIGEN_PREFIX ) .tar.gz; )
164+ -rm -rf eigen
165+ wget $(EIGEN_URL ) /$(EIGEN_PREFIX ) /eigen-$(EIGEN_PREFIX ) .tar.gz
166+ tar -xzf eigen-$(EIGEN_PREFIX ) .tar.gz && mv eigen-$(EIGEN_PREFIX ) eigen
167+ rm eigen-$(EIGEN_PREFIX ) .tar.gz
105168
106169.PHONY : clean
107170clean :
108- rm -rf eigen;
171+ - rm -rf eigen
109172 -$(MAKE ) -C apps/ clean
110173 -$(MAKE ) -C tests/ clean
111174 -$(MAKE ) -C pybind_interface/ clean
175+
176+ LOCAL_VARS = TARGETS TESTS PYTESTS PYTESTFLAGS CXX CXXFLAGS NVCC NVCCFLAGS $\
177+ HIPCC HIPCCFLAGS CUDA_PATH CUQUANTUM_ROOT CUSTATEVECFLAGS
178+
179+ .PHONY : print-vars
180+ print-vars : ; @$(foreach n,$(sort $(LOCAL_VARS ) ) ,echo $n=$($n ) ;)
0 commit comments