Skip to content

Commit 51c8418

Browse files
committed
update makefile for mac
1 parent 0cf379a commit 51c8418

File tree

3 files changed

+83
-105
lines changed

3 files changed

+83
-105
lines changed

.github/workflows/mac.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ jobs:
1515
- uses: actions/checkout@v3
1616

1717
- name: install dependency
18-
run: brew install llvm
18+
run: brew install libomp
1919

2020
- name: make
2121
run: |
22-
export CC=$(brew --prefix llvm)/bin/clang
23-
export CXX=$(brew --prefix llvm)/bin/clang++
24-
export LDFLAGS="-L"$(brew --prefix llvm)/lib
25-
export CPPFLAGS="-I"$(brew --prefix llvm)/include
26-
make -j4 AVX=0 INC_PATH=$(brew --prefix llvm)/include LIB_PATH=$(brew --prefix llvm)/lib
22+
export LDFLAGS="-L"$(brew --prefix libomp)/lib
23+
export CPPFLAGS="-I"$(brew --prefix libomp)/include
24+
make -j4
2725
2826
- name: test
2927
run: ./PCAone --help

Makefile

Lines changed: 54 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
######################### configure ################
22

3+
VERSION=0.5.0
4+
# detect OS architecture and add flags
5+
Platform := $(shell uname -s)
6+
7+
$(info "building PCAone on ${Platform} -- version ${VERSION}")
8+
39
# MKLROOT=/opt/intel/oneapi/mkl/latest
410
MKLROOT =
511
# /opt/intel/oneapi/compiler/latest/lib/
@@ -8,33 +14,19 @@ ONEAPI_OMP5 := $(ONEAPI_COMPILER)/lib/libiomp5.a
814
# make sure libiomp5 can be found on mac
915
# ln -s /opt/intel/oneapi/compiler/latest/mac/compiler/lib/libiomp5.dylib /opt/intel/oneapi/mkl/latest/lib/
1016

17+
# for MacOS use accelerate framework in default
1118
# install openblas lapack on mac with brew install openblas lapack
12-
# OPENBLAS_ROOT = /usr/local/opt/openblas
13-
# LAPACK_ROOT = /usr/local/opt/lapack
14-
OPENBLAS_ROOT =
15-
LAPACK_ROOT =
16-
17-
# for MacOS
18-
# use accelerate framework as blas lib
19-
ACCELERATE_ROOT =
19+
OPENBLAS_ROOT =
20+
LAPACK_ROOT := ${OPENBLAS_ROOT}
2021

21-
# by default dynamical linking
22-
STATIC = 0
23-
# only if static = 1, IOMP5 works
24-
IOMP5 = 1
25-
26-
# static libz
27-
STATIC_LIBZ := /usr/lib64/libz.a # /usr/lib/x86_64-linux-gnu/libz.a
2822

23+
STATIC = 0 # by default dynamical linking
24+
IOMP5 = 1 # use libiomp5 for mkl
25+
AVX = 1 # enable avx2 fma
26+
DEBUG = 0 # debug
2927

3028
########################### end ###########################
3129

32-
VERSION=0.5.0
33-
# detect OS architecture and add flags
34-
Platform := $(shell uname -s)
35-
36-
$(info "building PCAone on ${Platform} -- version ${VERSION}")
37-
3830

3931
####### INC, LPATHS, LIBS, MYFLAGS
4032
program = PCAone
@@ -43,44 +35,23 @@ CXXSTD = c++17 # default c++17 if not set by the user
4335
CXXFLAGS += -O3 -Wall -std=$(CXXSTD) -m64 -fPIC
4436
MYFLAGS = -DVERSION=\"$(VERSION)\"
4537
# CURRENT_DIR = $(shell pwd)
46-
INC_PATH = /usr/local/include
47-
LIB_PATH = /usr/local/lib
4838
INC = -I./external -I./external/zstd/lib
4939
PCALIB = libpcaone.a
50-
AVX = 1
51-
DEBUG = 0
5240

53-
ifeq ($(strip $(AVX)),1)
54-
$(info "use -mavx2 for PCAone")
55-
CXXFLAGS += -mavx2 -mfma
41+
ifeq ($(Platform), Darwin)
42+
CXXFLAGS += -march=native
43+
else
44+
ifeq ($(strip $(AVX)),1)
45+
$(info "use -mavx2 for PCAone")
46+
CXXFLAGS += -mavx2 -mfma
47+
endif
5648
endif
5749

5850
ifeq ($(strip $(DEBUG)),1)
5951
$(info "use -mavx2 for PCAone")
6052
MYFLAGS += -DDEBUG
6153
endif
6254

63-
ifeq ($(strip $(STATIC)),1)
64-
ifeq ($(Platform), Darwin)
65-
SLIBS += /usr/local/opt/zlib/lib/libz.a
66-
ifeq ($(strip $(IOMP5)), 1)
67-
SLIBS += /usr/local/opt/gcc/lib/gcc/11/libgomp.a # gcc need libgomp.a
68-
CXXFLAGS += -static-libgcc
69-
MYFLAGS += -fopenmp
70-
else
71-
SLIBS += /usr/local/lib/libomp.a # clang needs libomp.a
72-
CXXFLAGS += -stdlib=libc++
73-
# CFLAGS += -Xpreprocessor -fopenmp
74-
endif
75-
else
76-
SLIBS += ${STATIC_LIBZ}
77-
# CXXFLAGS += -static-libgcc -static-libstdc++
78-
CXXFLAGS += -static
79-
endif
80-
else
81-
DLIBS += -lz
82-
endif
83-
8455

8556
ifeq ($(Platform),Linux)
8657
###### for linux
@@ -90,60 +61,63 @@ ifeq ($(Platform),Linux)
9061
INC += -I${MKLROOT}/include/
9162
ifeq ($(strip $(STATIC)),1)
9263
ifeq ($(strip $(IOMP5)), 1)
93-
SLIBS += -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a ${ONEAPI_OMP5} -Wl,--end-group -L${ONEAPI_COMPILER}/lib -lpthread
64+
SLIBS += -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a ${ONEAPI_OMP5} -Wl,--end-group -L${ONEAPI_COMPILER}/lib
9465
else
95-
SLIBS += -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_gnu_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lgomp -lpthread
66+
SLIBS += -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_gnu_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lgomp
9667
endif
9768
else
98-
DLIBS += -Wl,--no-as-needed -Wl,-rpath,${ONEAPI_COMPILER}/lib,-rpath,${MKLROOT}/lib/intel64 -L${ONEAPI_COMPILER}/lib -L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread
69+
DLIBS += -Wl,--no-as-needed -Wl,-rpath,${ONEAPI_COMPILER}/lib,-rpath,${MKLROOT}/lib/intel64 -L${ONEAPI_COMPILER}/lib -L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5
9970
endif
10071

10172
else ifneq ($(strip $(OPENBLAS_ROOT)),)
10273
MYFLAGS += -DWITH_OPENBLAS -DEIGEN_USE_BLAS -DEIGEN_USE_LAPACKE
10374
INC += -I${OPENBLAS_ROOT}/include -I${LAPACK_ROOT}/include
10475
LPATHS += -L${OPENBLAS_ROOT}/lib -L${LAPACK_ROOT}/lib
105-
DLIBS += -llapack -llapacke -lopenblas -lgfortran -lgomp -lpthread
76+
DLIBS += -llapack -llapacke -lopenblas -lgfortran -lgomp
10677

10778
else
108-
DLIBS += -lgomp -lpthread
79+
DLIBS += -lgomp
10980
endif
11081

11182
else ifeq ($(Platform),Darwin)
11283
###### for mac
11384
MYFLAGS += -Xpreprocessor -fopenmp
114-
INC += -I$(INC_PATH)
115-
ifneq ($(strip $(MKLROOT)),)
116-
MYFLAGS += -DWITH_MKL -DEIGEN_USE_MKL_ALL
117-
INC += -I${MKLROOT}/include/
118-
LPATHS += -L${MKLROOT}/lib
85+
86+
ifneq ($(strip $(OPENBLAS_ROOT)),)
87+
MYFLAGS += -DWITH_OPENBLAS -DEIGEN_USE_BLAS -DEIGEN_USE_LAPACKE
11988
ifeq ($(strip $(STATIC)),1)
120-
ifeq ($(strip $(IOMP5)), 1)
121-
SLIBS += ${MKLROOT}/lib/libmkl_intel_lp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread
122-
else
123-
SLIBS += ${MKLROOT}/lib/libmkl_intel_lp64.a ${MKLROOT}/lib/libmkl_sequential.a ${MKLROOT}/lib/libmkl_core.a -lpthread
124-
endif
89+
# SLIBS += /usr/local/opt/gcc/lib/gcc/11/libgomp.a # gcc need libgomp.a
90+
SLIBS += /opt/homebrew/opt/openblas/lib/libopenblas.a /opt/homebrew/opt/libomp/lib/libomp.a -L/opt/homebrew/opt/gcc/lib/gcc/14/ -lgfortran
12591
else
126-
DLIBS += -Wl,-rpath,${MKLROOT}/lib -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread
92+
DLIBS += -lopenblas -lomp
12793
endif
12894

129-
else ifneq ($(strip $(OPENBLAS_ROOT)),)
130-
MYFLAGS += -DWITH_OPENBLAS -DEIGEN_USE_BLAS -DEIGEN_USE_LAPACKE
131-
INC += -I${OPENBLAS_ROOT}/include -I${LAPACK_ROOT}/include
132-
LPATHS += -L${OPENBLAS_ROOT}/lib -L${LAPACK_ROOT}/lib
133-
DLIBS += -llapack -llapacke -lopenblas -lgfortran -lgomp -lpthread
134-
135-
else ifneq ($(strip $(ACCELERATE_ROOT)),)
95+
else
13696
MYFLAGS += -DEIGEN_USE_BLAS
137-
INC += -I${ACCELERATE_ROOT}/include
138-
LPATHS += -L${ACCELERATE_ROOT}/lib
139-
DLIBS += -Wl,-rpath,${ACCELERATE_ROOT}/lib -llapack -lblas -lgomp -lpthread
97+
ifeq ($(strip $(STATIC)),1)
98+
SLIBS += /opt/homebrew/opt/libomp/lib/libomp.a -framework Accelerate
99+
else
100+
DLIBS += -lomp -framework Accelerate
101+
endif
140102

141-
else
142-
DLIBS += -lomp -lpthread -L$(LIB_PATH)
143103
endif
144104

145105
endif
146106

107+
## libz
108+
ifeq ($(strip $(STATIC)),1)
109+
ifeq ($(Platform), Darwin)
110+
SLIBS += /opt/homebrew/opt/zlib/lib/libz.a
111+
# CXXFLAGS += -stdlib=libc++
112+
else
113+
SLIBS += /usr/lib64/libz.a # /usr/lib/x86_64-linux-gnu/libz.a
114+
CXXFLAGS += -static
115+
# CXXFLAGS += -static-libgcc -static-libstdc++
116+
endif
117+
else
118+
DLIBS += -lz
119+
endif
120+
147121
# OBJ = $(patsubst %.cpp, %.o, $(wildcard ./src/*.cpp))
148122
# tar OBJ as libpcaone.a
149123
OBJ = src/Arnoldi.o src/Halko.o src/Data.o src/Utils.o src/Cmd.o \
@@ -153,17 +127,17 @@ OBJ = src/Arnoldi.o src/Halko.o src/Data.o src/Utils.o src/Cmd.o \
153127

154128
SLIBS += ./external/bgen/bgenlib.a ./external/zstd/lib/libzstd.a
155129

156-
LIBS += ${SLIBS} ${DLIBS} -ldl -lm
130+
LIBS += ${SLIBS} ${DLIBS} -lpthread -ldl -lm
157131

158132
.PHONY: all clean ld_matrix ld_r2 ld_prune ld_clump ld_tests
159133

160134
all: ${program}
161135

162136
${program}: zstdlib bgenlib pcaonelib src/Main.o
163-
$(CXX) $(CXXFLAGS) -o $(program) src/Main.o ${PCALIB} ${LPATHS} ${LIBS}
137+
$(CXX) $(CXXFLAGS) -o $(program) src/Main.o ${PCALIB} ${LPATHS} ${LIBS} ${LDFLAGS}
164138

165139
%.o: %.cpp
166-
${CXX} ${CXXFLAGS} ${MYFLAGS} -o $@ -c $< ${INC}
140+
${CXX} ${CXXFLAGS} ${MYFLAGS} -o $@ -c $< ${INC} ${CPPFLAGS}
167141

168142
zstdlib:
169143
(cd ./external/zstd/lib/; $(MAKE) lib-nomt)

README.org

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,27 @@ build PCAone from the source code, the following dependencies are required:
168168
- GNU make
169169
- zlib
170170

171-
We *recommend* building the software from source with MKL as backend to maximize the performance. For MacOS users, we recommend =llvm= by =brew install llvm= instead of the default =clang= shipped with MacOS. Check out the [[https://github.com/Zilong-Li/PCAone/blob/dev/.github/workflows/mac.yml#L21][mac workflow]].
171+
On Linux, we *recommend* building the software from source with MKL as backend to maximize the performance.
172172

173173
*** With MKL or OpenBLAS as backend
174174

175-
Build PCAone dynamically with MKL can maximize the performance since the
176-
faster threading layer =libiomp5= will be linked at runtime. One can obtain
177-
the MKL by one of the following option:
175+
Build PCAone dynamically with MKL can maximize the performance for large
176+
dataset particularly, because the faster threading layer =libiomp5= will be
177+
linked at runtime. There are two options to obtain MKL library:
178178

179-
- install =mkl= by conda
179+
- download =MKL= from [[https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl.html][the website]]
180180

181-
#+begin_src sh
181+
After having =MKL= installed, find the =MKL= root path and replace the path below with your own.
182+
183+
#+begin_src shell
184+
make -j4 MKLROOT=/opt/intel/oneapi/mkl/latest ONEAPI_COMPILER=/opt/intel/oneapi/compiler/latest
185+
#+end_src
186+
187+
Alternatively, for advanced user, modify variables directly in =Makefile= and run =make= to use MKL or OpenBlas as backend.
188+
189+
- install =MKL= by conda
190+
191+
#+begin_src shell
182192
conda install -c conda-forge -c anaconda -y mkl mkl-include intel-openmp
183193
git clone https://github.com/Zilong-Li/PCAone.git
184194
cd PCAone
@@ -187,19 +197,6 @@ make -j4 MKLROOT=${CONDA_PREFIX}
187197
./PCAone -h
188198
#+end_src
189199

190-
- download =mkl= from [[https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl.html][the website]]
191-
192-
After having =mkl= installed, find the =mkl= root path and replace the path
193-
below with your own.
194-
195-
#+begin_src shell
196-
# if libiomp5 is not in the mklroot path, please link it to $MKLROOT/lib folder
197-
make -j4 MKLROOT=/path/to/mklroot
198-
#+end_src
199-
200-
Alternatively, for advanced user, modify variables directly in =Makefile=
201-
and run =make= to use MKL or OpenBlas as backend.
202-
203200
*** Without MKL or OpenBLAS dependency
204201

205202
If you don't want any optimized math library as backend, just run:
@@ -213,6 +210,15 @@ make -j4
213210

214211
If this doesn't work because the server is too outdated, run =make clean && make -j4 AVX=0= instead.
215212

213+
*** For MacOS users, check out the [[https://github.com/Zilong-Li/PCAone/blob/dev/.github/workflows/mac.yml#L21][mac workflow]].
214+
215+
#+begin_src shell
216+
brew install libomp
217+
export LDFLAGS="-L"$(brew --prefix libomp)/lib
218+
export CPPFLAGS="-I"$(brew --prefix libomp)/include
219+
make -j4
220+
#+end_src
221+
216222
\newpage
217223

218224
* Documentation

0 commit comments

Comments
 (0)