-
Notifications
You must be signed in to change notification settings - Fork 124
Expand file tree
/
Copy pathinclude.mk
More file actions
269 lines (243 loc) · 12.7 KB
/
Copy pathinclude.mk
File metadata and controls
269 lines (243 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
SHELL = /bin/bash
##
# Users can set CPPFLAGS, CFLAGS, LIBS to reference external packages. These
# can be set in environment of config.local.mk. LDLIBS should not be modified,
# as it is not seen my kyoto configure.
##
# if include.local.mk exists, include it first to set various options
# it should not be checked into git
includeLocal = ${rootPath}/include.local.mk
ifneq ($(wildcard ${includeLocal}),)
include ${includeLocal}
endif
# special handling to get C++ ABI right on UCSC Centos 6 servers
ifeq (${CXX_ABI_DEF},)
ifneq ($(wildcard /etc/redhat-release),)
ifeq ($(shell hostname -d), gi.ucsc.edu)
export CXX_ABI_DEF = -D_GLIBCXX_USE_CXX11_ABI=0
endif
endif
endif
#Location of sonLib
BINDIR = ${rootPath}/bin
LIBDIR = ${rootPath}/lib
INCLDIR = ${rootPath}/include
#Modify this variable to set the location of sonLib
sonLibRootDir ?= ${rootPath}/submodules/sonLib
sonLibDir=${sonLibRootDir}/lib
include ${sonLibRootDir}/include.mk
#Turn asserts back on in spite of sonLib
#https://github.com/ComparativeGenomicsToolkit/cactus/issues/235
CFLAGS += -UNDEBUG
# Hack to include xml2
ifeq (${CACTUS_LIBXML2_INCLUDE_PATH},)
CACTUS_LIBXML2_INCLUDE_PATH = /usr/include/libxml2
endif
CFLAGS+= -I${CACTUS_LIBXML2_INCLUDE_PATH}
ifndef TARGETOS
TARGETOS := $(shell uname -s)
endif
# Control variable for jemalloc
# Disable on Mac, disable when address sanitizer is active, disable for legacy arch builds
jemalloc = on
ifeq ($(TARGETOS), Darwin)
jemalloc = off
endif
ifeq (${CGL_DEBUG},ultra)
jemalloc = off
endif
ifdef CACTUS_LEGACY_ARCH
jemalloc = off
endif
# Control variable for building lastz with profile-guided optimisation.
# Worth 8-16% on top of the source optimisations in the pinned lastz, most of it
# on the --notransition bucket, where the source changes help least -- the two are
# complementary. Costs about 30 s of build time and needs no external data: the
# training input is generated by build-tools/lastzPgoTrain. gcc only; clang wants
# -fprofile-instr-* and an llvm-profdata merge step, which is not implemented here.
# A failure anywhere in the PGO path falls back to a plain lastz build.
lastzPgo = on
ifeq ($(TARGETOS), Darwin)
lastzPgo = off
endif
ifeq (${CGL_DEBUG},ultra)
lastzPgo = off
endif
ifdef CACTUS_LEGACY_ARCH
lastzPgo = off
endif
# Hack to include openmp on os x after "brew install lomp
ifeq ($(TARGETOS), Darwin)
CFLAGS+= -Xpreprocessor -fopenmp -lomp
else
CFLAGS+= -fopenmp
endif
# Hack in ARM support
# Toggle on if "arm" is set, or if uname -m returns aarch64
ifeq ($(shell uname -m || true), aarch64)
arm=1
endif
ifeq ($(shell arch || true), aarch64)
arm=1
endif
ifeq ($(shell arch || true), arm64)
arm=1
endif
# CPU baseline for the code we generate. A plain "make" is portable. Opt into a
# machine-specific build, for binaries that will only ever run on the machine that compiled
# them:
# CACTUS_NATIVE_BUILD=1 make
# or, per-checkout and with no shell state to remember, put
# CACTUS_NATIVE_BUILD = 1
# in include.local.mk, which is included at the top of this file, before the choice below is
# made. To pin an exact baseline by hand -- this beats both knobs, since CACTUS_ARCH_FLAGS
# is taken with ?= below:
# CACTUS_ARCH_FLAGS="-march=x86-64-v3 -mtune=znver3" make
#
# x86-64-v3 rather than the bare -mavx2 this used to be. That is not a portability change:
# the release has required AVX2 since 2021, and the shipped v3.3.0 cactus_consolidated proves
# it -- simd_abpoa_align_sequence_to_subgraph and paf_write_to_buffer carry unguarded AVX2,
# so it already SIGILLs on anything pre-Haswell. v3 is exactly that AVX2 baseline plus the
# rest of the same CPU generation (FMA, BMI1/2, LZCNT, MOVBE, F16C), which every AVX2-capable
# CPU has. Measured: minigraph 1.3% faster, lastz 2.1%, output byte-identical in both.
#
# The psABI level names -march=x86-64-v2/v3/v4 only arrived in gcc 11 and clang 12, and an
# -march value the compiler does not recognise is a hard error rather than a warning, so
# anything older falls back to the bare -mavx2 this baseline replaced. That matters now that
# portable is what a plain "make" gets: before, x86-64-v3 was reached only by builds we ship,
# which are built on 22.04, whereas the README still names Ubuntu 20.04, whose gcc is 9. The
# fallback is safe to take silently because it cannot weaken the portability contract -- both
# spellings require AVX2 and nothing newer, so the oldest CPU that can run the result is the
# same either way. What is lost is the rest of the v3 generation, i.e. the 1-2% above.
# "make arch-flags" prints which one you got.
#
# Deliberately NOT x86-64-v4. AVX-512 would emit binaries that will not run on the
# Skylake-class machines we develop and test on, and it is worth little anyway: abPOA is the
# only hand-vectorised code in the tree, and doubling its vector width 128->256 bits bought
# 8.8%, so 256->512 would be a few percent at best, before AVX-512 downclocking.
#
# No -mtune here. -mtune=skylake measured a further 2.7% on minigraph and emits no new
# instructions, so it costs no portability -- but it is a bet on one microarchitecture that
# may go the other way on AMD, which we have not measured. Set it per-cluster with
# CACTUS_ARCH_FLAGS.
#
# Two baselines. PORTABLE is the default; NATIVE is opt-in.
#
# PORTABLE, because a development build is not usually run where it was built. Compiling on a
# cluster head node and running on whatever worker picks up the job is the normal case, and an
# -march=native binary SIGILLs on any worker older than the head node -- which is most of a
# heterogeneous cluster, and a confusing failure to read when it happens. It is also what the
# README tells a from-source user to type, so what a bare "make" emits has to be the safe
# thing. NATIVE is for binaries that stay on the machine that built them.
#
# CACTUS_PORTABLE_BUILD=1 forces PORTABLE and beats CACTUS_NATIVE_BUILD, so makeBinRelease and
# the Dockerfile -- which both still set it -- ship the portable baseline even when a developer
# has the native knob exported. Both are now defence in depth rather than the only barrier --
# a docker build inherits nothing from the shell that started it, and makeBinRelease unsets
# the arch knobs itself -- but what we distribute is worth saying twice, and the portable value
# lives in exactly one place either way and cannot drift.
#
# -march=native is not reliably faster: measured here it gained 4.6% on minigraph and lost
# 5.7% on lastz, the loss isolating to -mtune, which native implies. So it is worth asking
# for only when the binaries stay put; measure on your own hardware if it matters.
#
# NATIVE is just PORTABLE on ARM: Apple's clang spells it -mcpu=native and rejects
# -march=native. Same under CACTUS_LEGACY_ARCH, which exists precisely to be portable. On
# both, CACTUS_NATIVE_BUILD=1 is accepted and changes nothing.
ifdef arm
# flags to build abpoa
export armv8 = 1
export aarch64 = 1
# flags to include simde abpoa in cactus on ARM
CACTUS_PORTABLE_ARCH_FLAGS = -march=armv8-a+simd
CACTUS_NATIVE_ARCH_FLAGS = ${CACTUS_PORTABLE_ARCH_FLAGS}
else ifdef CACTUS_LEGACY_ARCH
export sse2 = 1
CACTUS_PORTABLE_ARCH_FLAGS = -msse2
CACTUS_NATIVE_ARCH_FLAGS = ${CACTUS_PORTABLE_ARCH_FLAGS}
else
# flags to build abpoa
export avx2 = 1
# flags to include simde abpoa in cactus on X86
archV3 := $(shell ${CC} -march=x86-64-v3 -E -x c /dev/null > /dev/null 2>&1 && echo 1)
CACTUS_PORTABLE_ARCH_FLAGS = $(if ${archV3},-march=x86-64-v3,-mavx2)
CACTUS_NATIVE_ARCH_FLAGS = -march=native
endif
# PORTABLE tested first, so it beats the native knob: a shipping build stays portable however
# CACTUS_NATIVE_BUILD is set. An explicit CACTUS_ARCH_FLAGS still wins over both -- see the
# ?= below, which is what allows that and so must stay on every branch.
#
# The native knob is tested for exactly 1, not with ifdef, which is true of any non-empty
# value: CACTUS_NATIVE_BUILD=0 under ifdef would select native. The same misparse of
# CACTUS_PORTABLE_BUILD lands on the portable side, which is why that one can stay an ifdef,
# but here it would hand you the dangerous answer for a value that plainly means "no".
# Anything but 1, unset and 0 included, is portable.
ifdef CACTUS_PORTABLE_BUILD
CACTUS_ARCH_FLAGS ?= ${CACTUS_PORTABLE_ARCH_FLAGS}
else ifeq ($(strip ${CACTUS_NATIVE_BUILD}),1)
CACTUS_ARCH_FLAGS ?= ${CACTUS_NATIVE_ARCH_FLAGS}
else
CACTUS_ARCH_FLAGS ?= ${CACTUS_PORTABLE_ARCH_FLAGS}
endif
# Both, deliberately. Until now only CFLAGS carried an arch flag, so Red, hal's C++ and
# cactus2hal were built at the plain x86-64 baseline -- confirmed against the shipped
# binaries, where Red's only AVX2 is glibc's runtime-dispatched strcasecmp, never its own
# code. They are the components with the most headroom here, having had none at all.
CFLAGS += ${CACTUS_ARCH_FLAGS}
CXXFLAGS += ${CACTUS_ARCH_FLAGS}
# ...but only for what this makefile compiles itself. CFLAGS and CXXFLAGS are ordinary make
# variables here, not exported, so "cd submodules/x && ${MAKE}" starts a make that re-derives
# them from sonLib's include.mk and sees no arch flag at all. Only the release build ever
# propagated them, by way of the "static:" target putting them in the environment -- so in a
# plain build sonLib, cPecan, pinchesAndCacti, matchingAndOrdering, paffy, lastz, hal and
# cactus2hal were all still at the bare baseline, which is most of the tree.
#
# Prefix a sub-make with ${archEnv} to hand them over. Every submodule we do this for appends
# with +=, so its own -O3 and include paths survive; the arch flags simply land in front.
# Deliberately not "export CFLAGS": that would also push --pedantic, -D__AVX2__ -DUSE_SIMDE
# and our libxml2 include path into every submodule, and abPOA already has to filter
# --pedantic back out. This hands over the baseline and nothing else.
archEnv = CFLAGS="$${CFLAGS} ${CACTUS_ARCH_FLAGS}" CXXFLAGS="$${CXXFLAGS} ${CACTUS_ARCH_FLAGS}"
# ...but CFLAGS specifically must not be handed to a submodule that recursively builds bundled
# third-party C. Doing so makes CFLAGS environment-origin, and make then exports it onward
# from that submodule's own make, carrying sonLib's -Werror --pedantic down into code that has
# never compiled clean under them: sonLib/quicktree, sonLib/cutest, cPecan/lastz,
# pinchesAndCacti/threeEdgeConnected and matchingAndOrdering/matchGraph are all in that
# position, and CGL_DEBUG=ultra then fails on unrelated fscanf and format warnings -- which is
# how CI broke. paffy is in the same position at one remove: it builds its own nested
# sonLib, quicktree and all. Bundled C++ (blossom) is fine, since CXXFLAGS_ultraDbg
# carries no -Werror.
#
# Hand the baseline to those four through CC instead. A command-line override reaches the
# nested makes through MAKEFLAGS just as effectively, but carries nothing but the arch flag.
# Not CXX, which would clobber sonLib's own clang++/g++ selection.
archEnvExt = CXXFLAGS="$${CXXFLAGS} ${CACTUS_ARCH_FLAGS}"
archCC = CC="$${CC:-cc} ${CACTUS_ARCH_FLAGS}"
# flags needed to include simde abpoa in cactus on any architecture
ifdef CACTUS_LEGACY_ARCH
CFLAGS+= -D__SSE2__ -DUSE_SIMDE -DSIMDE_ENABLE_NATIVE_ALIASES
else
CFLAGS+= -D__AVX2__ -DUSE_SIMDE -DSIMDE_ENABLE_NATIVE_ALIASES
endif
dataSetsPath=/Users/benedictpaten/Dropbox/Documents/work/myPapers/genomeCactusPaper/dataSets
inclDirs = hal/inc api/inc setup/inc bar/inc caf/inc paf/inc hal/inc reference/inc pipeline/inc submodules/sonLib/C/inc \
blastLib submodules/sonLib/externalTools/cutest submodules/pinchesAndCacti/inc \
submodules/matchingAndOrdering/inc submodules/cPecan/inc
CPPFLAGS += ${inclDirs:%=-I${rootPath}/%} -I${LIBDIR} -I${rootPath}/include
# libraries can't be added until they are build, so add as to LDLIBS until needed
cactusLibs = ${LIBDIR}/stCaf.a ${LIBDIR}/stReference.a ${LIBDIR}/cactusBarLib.a ${LIBDIR}/cactusLib.a
sonLibLibs = ${sonLibDir}/sonLib.a ${sonLibDir}/cuTest.a
# Add jemalloc if enabled
ifeq ($(jemalloc),on)
jemallocLib = -ljemalloc -lm
jemallocDepends = ${LIBDIR}/libjemalloc.a
endif
# jemalloc flags for submodules that are built by cd'ing into their own tree. jemallocLib
# deliberately carries no -L, because cactus's own link lines pick up -L${LIBDIR} from LDLIBS
# below -- but a submodule that has already cd'd elsewhere cannot resolve a bare -ljemalloc
# against the copy we build into lib/, and ${LIBDIR} is relative to the cactus root so it
# would point at the wrong directory from there. Empty when jemalloc is off.
jemallocSubLibs = $(if ${jemallocLib},-L$(abspath ${LIBDIR}) ${jemallocLib})
# note: the CACTUS_STATIC_LINK_FLAGS below can generally be empty -- it's used by the static builder script only
LDLIBS += ${cactusLibs} ${sonLibLibs} ${LIBS} -L${rootPath}/lib -Wl,-rpath,${rootPath}/lib -labpoa ${jemallocLib} -lz -lbz2 -lpthread -lm -lstdc++ -lm -lxml2 ${CACTUS_STATIC_LINK_FLAGS}
LIBDEPENDS = ${sonLibDir}/sonLib.a ${sonLibDir}/cuTest.a ${jemallocDepends}