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