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# LibTorch 49USE_TORCH ?= 50ifeq ($(USE_TORCH),1) 51 libtorch.pc := $(shell python ./pytorch_pkgconfig.py) 52 CPPFLAGS += $(call pkgconf, --cflags-only-I $(libtorch.pc)) 53 CXXFLAGS += $(call pkgconf, --cflags-only-other $(libtorch.pc)) 54 LDFLAGS += $(call pkgconf, --libs-only-L --libs-only-other $(libtorch.pc)) 55 LDFLAGS += $(patsubst -L%, $(call pkgconf, --variable=ldflag_rpath $(petsc.pc))%, $(call pkgconf, --libs-only-L $(libtorch.pc))) 56 LDLIBS += $(call pkgconf, --libs-only-l $(libtorch.pc)) 57 58 src.cpp += $(sort $(wildcard $(PROBLEMDIR)/torch/*.cpp)) 59 src.c += $(sort $(wildcard $(PROBLEMDIR)/torch/*.c)) 60 61 # Intel Pytorch EXtension (IPEX) 62 IPEX_DIR ?= 63 ifdef IPEX_DIR 64 LDFLAGS += -L$(IPEX_DIR)/lib/ 65 LDFLAGS += -Wl,-rpath,$(IPEX_DIR)/lib/ 66 LDLIBS += -lintel-ext-pt-gpu 67 endif 68endif 69 70# Source Files 71OBJDIR := build 72SRCDIR := src 73PROBLEMDIR := problems 74 75src.c := navierstokes.c $(sort $(wildcard $(PROBLEMDIR)/*.c)) $(sort $(wildcard $(SRCDIR)/*.c)) 76src.o = $(src.c:%.c=$(OBJDIR)/%.o) $(src.cpp:%.cpp=$(OBJDIR)/%.o) 77 78# Path to install directory for SmartRedis. Example: /software/smartredis/install 79SMARTREDIS_DIR ?= 80ifdef SMARTREDIS_DIR 81 hiredis.pc := $(SMARTREDIS_DIR)/lib/pkgconfig/hiredis.pc 82 lsmartredis:= -lsmartredis 83 redis++.pc = $(wildcard $(SMARTREDIS_DIR)/lib/pkgconfig/redis++.pc $(SMARTREDIS_DIR)/lib64/pkgconfig/redis++.pc) 84 85 CPPFLAGS += $(call pkgconf, --cflags-only-I $(hiredis.pc) $(redis++.pc)) 86 LDFLAGS += $(call pkgconf, --libs-only-L --libs-only-other $(hiredis.pc) $(redis++.pc)) 87 LDFLAGS += $(patsubst -L%, $(call pkgconf, --variable=ldflag_rpath $(petsc.pc))%, $(call pkgconf, --libs-only-L $(hiredis.pc) $(redis++.pc))) 88 LDLIBS += $(call pkgconf, --libs-only-l $(hiredis.pc) $(redis++.pc)) $(lsmartredis) 89 src.c += $(sort $(wildcard $(SRCDIR)/smartsim/*.c)) 90endif 91 92all: navierstokes 93 94$(OBJDIR)/navierstokes: $(src.o) | navierstokes 95navierstokes: $(src.o) | $(petsc.pc) $(ceed.pc) 96 $(call quiet,LINK.o) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $(OBJDIR)/$@ 97 98.SECONDEXPANSION: # to expand $$(@D)/.DIR 99%/.DIR : 100 @mkdir -p $(@D) 101 @touch $@ 102 103# Quiet, color output 104quiet ?= $($(1)) 105 106$(OBJDIR)/%.o : %.c Makefile | $$(@D)/.DIR 107 $(call quiet,CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(abspath $<) 108 109$(OBJDIR)/%.o : %.cpp Makefile | $$(@D)/.DIR 110 $(call quiet,CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(abspath $<) 111 112print: $(petsc.pc) $(ceed.pc) 113 $(info CC : $(CC)) 114 $(info CFLAGS : $(CFLAGS)) 115 $(info CPPFLAGS: $(CPPFLAGS)) 116 $(info LDFLAGS : $(LDFLAGS)) 117 $(info LDLIBS : $(LDLIBS)) 118 $(info OPT : $(OPT)) 119 @true 120 121print-% : 122 $(info [ variable name]: $*) 123 $(info [ origin]: $(origin $*)) 124 $(info [ flavor]: $(flavor $*)) 125 $(info [ value]: $(value $*)) 126 $(info [expanded value]: $($*)) 127 $(info ) 128 @true 129 130clean: 131 $(RM) -r $(OBJDIR) navierstokes *.vtu *.bin* *.csv *.png 132 133$(petsc.pc): 134 $(if $(wildcard $@),,$(error \ 135 PETSc config not found. Please set PETSC_DIR and PETSC_ARCH)) 136 137.PHONY: all print clean 138 139# Fluid Dynamics Examples 140fluidsexamples.c := $(sort $(wildcard *.c)) 141fluidsexamples.py := smartsim_regression_framework.py 142fluidsexamples := $(fluidsexamples.c:%.c=$(OBJDIR)/%) 143fluidsexamples += $(fluidsexamples.py:%.py=$(OBJDIR)/%) 144 145$(OBJDIR)/$(fluidsexamples.py): $(OBJDIR)/navierstokes 146 147examples := $(fluidsexamples) 148 149$(examples) : $(libceed) 150$(tests) : $(libceed) 151 152# Testing 153ifeq ($(COVERAGE), 1) 154 CFLAGS += --coverage 155 LDFLAGS += --coverage 156endif 157 158PROVE ?= prove 159PROVE_OPTS ?= -j $(NPROCS) 160 161# Set libCEED backends for testing 162CEED_BACKENDS ?= /cpu/self 163export CEED_BACKENDS 164 165# Set number processes for testing 166NPROC_TEST ?= 1 167export NPROC_TEST 168 169# Set pool size for testing 170NPROC_POOL ?= 1 171export NPROC_POOL 172 173JUNIT_BATCH ?= '' 174 175run-% : $(OBJDIR)/% 176 @$(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)/%=%) 177 178# The test and prove targets can be controlled via pattern searches. The default 179# is to run all tests and examples. Examples of finer grained control: 180# 181# make prove search='t3' # t3xx series tests 182# make junit search='t ex' # core tests and examples 183search ?= navierstokes 184realsearch = $(search:%=%%) 185matched = $(foreach pattern,$(realsearch),$(filter $(OBJDIR)/$(pattern),$(tests) $(examples))) 186 187# Test 188test : $(matched:$(OBJDIR)/%=run-%) 189 190tst : ;@$(MAKE) $(MFLAGS) V=$(V) test 191 192# Test with TAP output 193prove : $(matched) 194 $(info Running unit tests) 195 $(info - Testing with libCEED backends: $(CEED_BACKENDS)) 196 $(info - Testing on $(NPROC_TEST) processes) 197 $(PROVE) $(PROVE_OPTS) --exec '$(PYTHON) tests/junit.py --petsc-arch $(or $(PETSC_ARCH),$(PETSC_DIR)) --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)/%=%) 198 199prv : ;@$(MAKE) $(MFLAGS) V=$(V) prove 200 201prove-all : 202 +$(MAKE) prove realsearch=% 203 204# Test with JUNIT output 205junit-% : $(OBJDIR)/% 206 @printf " %10s %s\n" TEST $(<:$(OBJDIR)/%=%); $(PYTHON) tests/junit.py --junit-batch $(JUNIT_BATCH) --petsc-arch $(or $(PETSC_ARCH),$(PETSC_DIR)) --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)/%=%) 207 208junit : $(matched:$(OBJDIR)/%=junit-%) 209 210 211# Configure 212# "make configure" detects any variables passed on the command line or 213# previously set in config.mk, caching them in config.mk as simple 214# (:=) variables. Variables set in config.mk or on the command line 215# take precedence over the defaults provided in the file. Typical 216# usage: 217# 218# make configure CC=/path/to/my/cc CUDA_DIR=/opt/cuda 219# make 220# make prove 221# 222# The values in the file can be updated by passing them on the command 223# line, e.g., 224# 225# make configure CC=/path/to/other/clang 226 227# All variables to consider for caching 228CONFIG_VARS = CEED_DIR PETSC_DIR PETSC_ARCH CCOPT CFLAGS CPPFLAGS AR ARFLAGS LDFLAGS LDLIBS SED USE_TORCH SMARTREDIS_DIR 229 230# $(call needs_save,CFLAGS) returns true (a nonempty string) if CFLAGS 231# was set on the command line or in config.mk (where it will appear as 232# a simple variable). 233needs_save = $(or $(filter command line,$(origin $(1))),$(filter simple,$(flavor $(1)))) 234 235configure : 236 $(file > $(CONFIG)) 237 $(foreach v,$(CONFIG_VARS),$(if $(call needs_save,$(v)),$(file >> $(CONFIG),$(v) := $($(v))))) 238 @echo "Configuration cached in $(CONFIG):" 239 @cat $(CONFIG) 240 241-include $(src.o:%.o=%.d) 242