1CONFIG ?= config.mk 2-include $(CONFIG) 3COMMON ?= common.mk 4-include $(COMMON) 5 6pkgconf-path = $(if $(wildcard $(1)/$(2).pc),$(1)/$(2).pc,$(2)) 7 8# Library dependencies 9# Note: PETSC_ARCH can be undefined or empty for installations which do not use 10# PETSC_ARCH - for example when using PETSc installed through Spack. 11ifneq ($(wildcard ../petsc/lib/libpetsc.*),) 12 PETSC_DIR ?= ../petsc 13endif 14petsc.pc := $(call pkgconf-path,$(PETSC_DIR)/$(PETSC_ARCH)/lib/pkgconfig,petsc) 15 16CEED_DIR ?= $(if $(wildcard $(PETSC_DIR)/$(PETSC_ARCH)/lib/pkgconfig/ceed.pc),$(PETSC_DIR)/$(PETSC_ARCH),../libCEED) 17ceed.pc := $(call pkgconf-path,$(CEED_DIR)/lib/pkgconfig,ceed) 18 19pkgconf = $(shell pkg-config $(if $(STATIC),--static) $1 | $(SED) -e 's/^"//g' -e 's/"$$//g') 20 21# Error checking flags 22PEDANTIC ?= 23PEDANTICFLAGS ?= -Werror -pedantic 24 25CC = $(call pkgconf, --variable=ccompiler $(petsc.pc) $(ceed.pc)) 26CFLAGS = -std=c99 \ 27 $(call pkgconf, --variable=cflags_extra $(petsc.pc)) \ 28 $(call pkgconf, --cflags-only-other $(petsc.pc)) \ 29 $(OPT) 30CPPFLAGS = $(call pkgconf, --cflags-only-I $(petsc.pc) $(ceed.pc)) \ 31 $(call pkgconf, --variable=cflags_dep $(petsc.pc)) 32CXX = $(call pkgconf, --variable=cxxcompiler $(petsc.pc) $(ceed.pc)) 33CXXFLAGS = -std=c++17 -Wno-deprecated -Wno-tautological-compare 34LDFLAGS = $(call pkgconf, --libs-only-L --libs-only-other $(petsc.pc) $(ceed.pc)) 35LDFLAGS += $(patsubst -L%, $(call pkgconf, --variable=ldflag_rpath $(petsc.pc))%, $(call pkgconf, --libs-only-L $(petsc.pc) $(ceed.pc))) 36LDLIBS = $(call pkgconf, --libs-only-l $(petsc.pc) $(ceed.pc)) -lm -lstdc++ 37 38# ASAN must be left empty if you don't want to use it 39ASAN ?= 40 41AFLAGS ?= -fsanitize=address 42CFLAGS += $(if $(ASAN),$(AFLAGS)) 43FFLAGS += $(if $(ASAN),$(AFLAGS)) 44LDFLAGS += $(if $(ASAN),$(AFLAGS)) 45 46CPPFLAGS += -I./include 47 48# External tools 49PYTHON ?= python3 50SED ?= sed 51 52# LibTorch 53USE_TORCH ?= 54ifeq ($(USE_TORCH),1) 55 libtorch.pc := $(shell $(PYTHON) ./pytorch_pkgconfig.py) 56 CPPFLAGS += $(call pkgconf, --cflags-only-I $(libtorch.pc)) 57 CXXFLAGS += $(call pkgconf, --cflags-only-other $(libtorch.pc)) 58 LDFLAGS += $(call pkgconf, --libs-only-L --libs-only-other $(libtorch.pc)) 59 LDFLAGS += $(patsubst -L%, $(call pkgconf, --variable=ldflag_rpath $(petsc.pc))%, $(call pkgconf, --libs-only-L $(libtorch.pc))) 60 LDLIBS += $(call pkgconf, --libs-only-l $(libtorch.pc)) 61 62 src.cpp += $(sort $(wildcard $(PROBLEMDIR)/torch/*.cpp)) 63 src.c += $(sort $(wildcard $(PROBLEMDIR)/torch/*.c)) 64 65 # Intel Pytorch EXtension (IPEX) 66 IPEX_DIR ?= 67 ifdef IPEX_DIR 68 LDFLAGS += -L$(IPEX_DIR)/lib/ 69 LDFLAGS += -Wl,-rpath,$(IPEX_DIR)/lib/ 70 LDLIBS += -lintel-ext-pt-gpu 71 endif 72endif 73 74# Source Files 75OBJDIR := build 76SRCDIR := src 77PROBLEMDIR := problems 78 79src.c := examples/navierstokes.c $(sort $(wildcard $(PROBLEMDIR)/*.c)) $(sort $(wildcard $(SRCDIR)/*.c)) 80src.o = $(src.c:%.c=$(OBJDIR)/%.o) $(src.cpp:%.cpp=$(OBJDIR)/%.o) 81 82# Path to install directory for SmartRedis. Example: /software/smartredis/install 83SMARTREDIS_DIR ?= 84ifdef SMARTREDIS_DIR 85 CPPFLAGS += -I$(SMARTREDIS_DIR)/include 86 LDFLAGS += -L$(SMARTREDIS_DIR)/lib $(call pkgconf, --variable=ldflag_rpath $(petsc.pc))$(SMARTREDIS_DIR)/lib 87 LDLIBS += -lsmartredis 88 src.c += $(sort $(wildcard $(SRCDIR)/smartsim/*.c)) 89endif 90 91all: navierstokes 92 93# Diagnostic information 94info-basic: 95 $(info -----------------------------------------) 96 $(info | __ ______ _ ______________ |) 97 $(info | / / / / __ \/ | / / ____/ ____/ |) 98 $(info | / /_/ / / / / |/ / __/ / __/ |) 99 $(info | / __ / /_/ / /| / /___/ /___ |) 100 $(info | /_/ /_/\____/_/ |_/_____/_____/ |) 101 $(info -----------------------------------------) 102 $(info ) 103 $(info -----------------------------------------) 104 $(info ) 105 $(info Dependencies:) 106 $(info CEED_DIR = $(CEED_DIR)) 107 $(info PETSC_DIR = $(PETSC_DIR)) 108 $(info PETSC_ARCH = $(PETSC_ARCH)) 109 $(info ) 110 $(info Optional Dependencies:) 111 $(info SMARTREDIS_DIR = $(or $(SMARTREDIS_DIR),(not found))) 112 $(info USE_TORCH = $(USE_TORCH)) 113 $(info ) 114 $(info -----------------------------------------) 115 $(info ) 116 @true 117 118info: 119 $(info -----------------------------------------) 120 $(info | __ ______ _ ______________ |) 121 $(info | / / / / __ \/ | / / ____/ ____/ |) 122 $(info | / /_/ / / / / |/ / __/ / __/ |) 123 $(info | / __ / /_/ / /| / /___/ /___ |) 124 $(info | /_/ /_/\____/_/ |_/_____/_____/ |) 125 $(info -----------------------------------------) 126 $(info ) 127 $(info -----------------------------------------) 128 $(info ) 129 $(info Dependencies:) 130 $(info CEED_DIR = $(CEED_DIR)) 131 $(info PETSC_DIR = $(PETSC_DIR)) 132 $(info PETSC_ARCH = $(PETSC_ARCH)) 133 $(info ) 134 $(info Optional Dependencies:) 135 $(info SMARTREDIS_DIR = $(or $(SMARTREDIS_DIR),(not found))) 136 $(info USE_TORCH = $(USE_TORCH)) 137 $(info ) 138 $(info -----------------------------------------) 139 $(info ) 140 $(info Build Options:) 141 $(info CC = $(CC)) 142 $(info CFLAGS = $(CFLAGS)) 143 $(info CPPFLAGS = $(CPPFLAGS)) 144 $(info LDFLAGS = $(LDFLAGS)) 145 $(info LDLIBS = $(LDLIBS)) 146 $(info AR = $(AR)) 147 $(info ARFLAGS = $(ARFLAGS)) 148 $(info OPT = $(OPT)) 149 $(info AFLAGS = $(AFLAGS)) 150 $(info ASAN = $(or $(ASAN),(empty))) 151 $(info VERBOSE = $(or $(V),(empty)) [verbose=$(if $(V),on,off)]) 152 $(info ) 153 $(info -----------------------------------------) 154 $(info ) 155 $(info Format and Style Options:) 156 $(info CLANG_FORMAT = $(CLANG_FORMAT)) 157 $(info FORMAT_OPTS = $(FORMAT_OPTS)) 158 $(info CLANG_TIDY = $(CLANG_TIDY)) 159 $(info TIDY_OPTS = $(TIDY_OPTS)) 160 $(info TIDY_FILE_OPTS = $(TIDY_FILE_OPTS)) 161 $(info ) 162 $(info -----------------------------------------) 163 $(info ) 164 @true 165 166# Get number of processors of the machine 167NPROCS := $(shell getconf _NPROCESSORS_ONLN) 168# prepare make options to run in parallel 169MFLAGS := -j $(NPROCS) --warn-undefined-variables \ 170 --no-print-directory --no-keep-going 171 172$(OBJDIR)/navierstokes: $(src.o) | navierstokes 173navierstokes: $(src.o) | $(petsc.pc) $(ceed.pc) 174 $(call quiet,LINK.o) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $(OBJDIR)/$@ 175 176.SECONDEXPANSION: # to expand $$(@D)/.DIR 177%/.DIR : 178 @mkdir -p $(@D) 179 @touch $@ 180 181# Quiet, color output 182quiet ?= $($(1)) 183 184$(OBJDIR)/%.o : %.c | $$(@D)/.DIR 185 $(call quiet,CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(abspath $<) 186 187$(OBJDIR)/%.o : %.cpp | $$(@D)/.DIR 188 $(call quiet,CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(abspath $<) 189 190print: $(petsc.pc) $(ceed.pc) 191 $(info CC : $(CC)) 192 $(info CFLAGS : $(CFLAGS)) 193 $(info CPPFLAGS: $(CPPFLAGS)) 194 $(info LDFLAGS : $(LDFLAGS)) 195 $(info LDLIBS : $(LDLIBS)) 196 $(info OPT : $(OPT)) 197 @true 198 199print-% : 200 $(info [ variable name]: $*) 201 $(info [ origin]: $(origin $*)) 202 $(info [ flavor]: $(flavor $*)) 203 $(info [ value]: $(value $*)) 204 $(info [expanded value]: $($*)) 205 $(info ) 206 @true 207 208clean: 209 $(RM) -r $(OBJDIR) navierstokes *.vtu *.bin* *.csv *.png 210 211$(petsc.pc): 212 $(if $(wildcard $@),,$(error \ 213 PETSc config not found. Please set PETSC_DIR and PETSC_ARCH)) 214 215.PHONY: all print clean 216 217# Define test files 218examples.c := $(sort $(wildcard examples/*.c)) 219examples := $(examples.c:examples/%.c=$(OBJDIR)/%) 220tests.smartsim := test-smartsim 221tests += $(tests.smartsim:%=$(OBJDIR)/%) 222 223$(tests.smartsim:%=$(OBJDIR)/%): $(OBJDIR)/navierstokes 224 225# Documentation 226DOXYGEN ?= doxygen 227DOXYGENOPTS ?= -q 228doxygen : 229 $(DOXYGEN) $(DOXYGENOPTS) Doxyfile 230 231SPHINXOPTS = 232SPHINXBUILD = sphinx-build 233SPHINXAUTOBUILD = sphinx-autobuild 234SPHINXPROJ = HONEE 235SPHINXBUILDDIR = doc/build 236 237doc-html doc-dirhtml doc-latexpdf doc-epub doc-help : doc-% : doxygen 238 @$(SPHINXBUILD) -M $* . "$(SPHINXBUILDDIR)" $(SPHINXOPTS) 239 240doc-livehtml : doxygen 241 @$(SPHINXAUTOBUILD) . "$(SPHINXBUILDDIR)" $(SPHINXOPTS) 242 243doc : doc-html 244 245doc-clean: 246 $(RM) -r doc/html doc/build 247 248# Tidy 249CLANG_TIDY ?= clang-tidy 250TIDY_OPTS ?= --quiet 251TIDY_FILE_OPTS += $(CPPFLAGS) --std=c99 252 253%.c.tidy : %.c 254 $(call quiet,CLANG_TIDY) $(TIDY_OPTS) $^ -- $(TIDY_FILE_OPTS) 255 256tidy-c : $(src.c:%=%.tidy) 257 258tidy : tidy-c 259 260# Style 261CLANG_FORMAT ?= clang-format 262FORMAT_OPTS += -style=file -i 263AUTOPEP8 ?= autopep8 264AUTOPEP8_OPTS += --in-place --aggressive --max-line-length 120 265SED_FMT_OPTS += -r 's/\s+$$//' -i 266 267%.format : % 268 $(call quiet,CLANG_FORMAT) $(FORMAT_OPTS) $^ 269 270format.ch := $(shell git ls-files '*.[ch]pp' '*.[ch]') 271format.py := $(filter-out tests/junit-xml/junit_xml/__init__.py, $(shell git ls-files '*.py')) 272format.ot := $(shell git ls-files '*.md') 273 274format-c : 275 $(call quiet,CLANG_FORMAT) $(FORMAT_OPTS) $(format.ch) 276 277format-py : 278 $(call quiet,AUTOPEP8) $(AUTOPEP8_OPTS) $(format.py) 279 280format-ot : 281 $(call quiet,SED) $(SED_FMT_OPTS) $(format.ot) 282 283format : format-c format-py format-ot 284 285# Testing 286ifeq ($(COVERAGE), 1) 287 CFLAGS += --coverage 288 LDFLAGS += --coverage 289endif 290 291PROVE ?= prove 292PROVE_OPTS ?= -j $(NPROCS) 293 294# Set libCEED backends for testing 295CEED_BACKENDS ?= /cpu/self 296export CEED_BACKENDS 297 298# Set number processes for testing 299NPROC_TEST ?= 1 300export NPROC_TEST 301 302# Set pool size for testing 303NPROC_POOL ?= 1 304export NPROC_POOL 305 306JUNIT_BATCH ?= '' 307 308run-% : $(OBJDIR)/% 309 @$(PYTHON) tests/junit.py --ceed-backends $(CEED_BACKENDS) --mode tap $(if $(SMARTREDIS_DIR),--smartredis_dir $(SMARTREDIS_DIR) ) $(if $(USE_TORCH),--has_torch $(USE_TORCH) )--nproc $(NPROC_TEST) --pool-size $(NPROC_POOL) $(<:$(OBJDIR)/%=%) 310 311# The test and prove targets can be controlled via pattern searches. The default 312# is to run all tests and examples. Examples of finer grained control: 313# 314# make prove search='t3' # t3xx series tests 315# make junit search='t ex' # core tests and examples 316search ?= navierstokes 317realsearch = $(search:%=%%) 318matched = $(foreach pattern,$(realsearch),$(filter $(OBJDIR)/$(pattern),$(tests) $(examples))) 319 320# Test 321test : $(matched:$(OBJDIR)/%=run-%) 322 323tst : ;@$(MAKE) $(MFLAGS) V=$(V) test 324 325# Test with TAP output 326prove : $(matched) 327 $(info Running unit tests) 328 $(info - Testing with libCEED backends: $(CEED_BACKENDS)) 329 $(info - Testing on $(NPROC_TEST) processes) 330 $(PROVE) $(PROVE_OPTS) --exec '$(PYTHON) tests/junit.py --ceed-backends $(CEED_BACKENDS) --mode tap $(if $(SMARTREDIS_DIR),--smartredis_dir $(SMARTREDIS_DIR) ) $(if $(USE_TORCH),--has_torch $(USE_TORCH) )--nproc $(NPROC_TEST) --pool-size $(NPROC_POOL)' $(matched:$(OBJDIR)/%=%) 331 332prv : ;@$(MAKE) $(MFLAGS) V=$(V) prove 333 334prove-all : 335 +$(MAKE) prove realsearch=% 336 337# Test with JUNIT output 338junit-% : $(OBJDIR)/% 339 @printf " %10s %s\n" TEST $(<:$(OBJDIR)/%=%); $(PYTHON) tests/junit.py --junit-batch $(JUNIT_BATCH) --ceed-backends $(CEED_BACKENDS) $(if $(SMARTREDIS_DIR),--smartredis_dir $(SMARTREDIS_DIR) ) $(if $(USE_TORCH),--has_torch $(USE_TORCH) )--nproc $(NPROC_TEST) --pool-size $(NPROC_POOL) $(<:$(OBJDIR)/%=%) 340 341junit : $(matched:$(OBJDIR)/%=junit-%) 342 343 344# Configure 345# "make configure" detects any variables passed on the command line or 346# previously set in config.mk, caching them in config.mk as simple 347# (:=) variables. Variables set in config.mk or on the command line 348# take precedence over the defaults provided in the file. Typical 349# usage: 350# 351# make configure CC=/path/to/my/cc CUDA_DIR=/opt/cuda 352# make 353# make prove 354# 355# The values in the file can be updated by passing them on the command 356# line, e.g., 357# 358# make configure CC=/path/to/other/clang 359 360# All variables to consider for caching 361CONFIG_VARS = CEED_DIR PETSC_DIR PETSC_ARCH OPT CFLAGS CPPFLAGS AR ARFLAGS LDFLAGS LDLIBS SED USE_TORCH SMARTREDIS_DIR 362 363# $(call needs_save,CFLAGS) returns true (a nonempty string) if CFLAGS 364# was set on the command line or in config.mk (where it will appear as 365# a simple variable). 366needs_save = $(or $(filter command line,$(origin $(1))),$(filter simple,$(flavor $(1)))) 367 368configure : 369 $(file > $(CONFIG)) 370 $(foreach v,$(CONFIG_VARS),$(if $(call needs_save,$(v)),$(file >> $(CONFIG),$(v) := $($(v))))) 371 @echo "Configuration cached in $(CONFIG):" 372 @cat $(CONFIG) 373 374-include $(src.o:%.o=%.d) 375