1ROOTDIR = $(abspath $(dir $(firstword $(MAKEFILE_LIST))))
2DEPDIR = ../..
3SRCDIR = .
4INCDIR = .
5BLDDIR = obj
6OUTDIR = .
7
8CXXFLAGS = $(NULL)
9CFLAGS = $(NULL)
10DFLAGS = $(NULL)
11
12BLAS = 1
13SYM = 1
14OMP = 0
15
16# explore AVX/ARCH=native
17SSE = 0
18
19# include common Makefile artifacts
20include $(DEPDIR)/Makefile.inc
21
22# necessary include directories
23IFLAGS += -I$(call quote,$(INCDIR))
24IFLAGS += -I$(call quote,$(DEPDIR)/include)
25
26OUTNAME := $(shell basename "$(ROOTDIR)")
27HEADERS := $(wildcard $(INCDIR)/*.h) $(wildcard $(INCDIR)/*.hpp) $(wildcard $(INCDIR)/*.hxx) $(wildcard $(INCDIR)/*.hh) \
28           $(wildcard $(SRCDIR)/*.h) $(wildcard $(SRCDIR)/*.hpp) $(wildcard $(SRCDIR)/*.hxx) $(wildcard $(SRCDIR)/*.hh) \
29           $(DEPDIR)/include/libxsmm_source.h
30CPPSRCS := $(wildcard $(SRCDIR)/*.cpp)
31CXXSRCS := $(wildcard $(SRCDIR)/*.cxx)
32CCXSRCS := $(wildcard $(SRCDIR)/*.cc)
33CSOURCS := $(wildcard $(SRCDIR)/*.c)
34CPPOBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(CPPSRCS:.cpp=-cpp.o)))
35CXXOBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(CXXSRCS:.cxx=-cxx.o)))
36CCXOBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(CCXSRCS:.cc=-cc.o)))
37COBJCTS := $(patsubst %,$(BLDDIR)/%,$(notdir $(CSOURCS:.c=-c.o)))
38ifneq (,$(strip $(FC)))
39FXXSRCS := $(wildcard $(SRCDIR)/*.f)
40F77SRCS := $(wildcard $(SRCDIR)/*.F)
41F90SRCS := $(wildcard $(SRCDIR)/*.f90) $(wildcard $(SRCDIR)/*.F90)
42FXXOBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(FXXSRCS:.f=-f.o)))
43F77OBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(F77SRCS:.F=-f77.o)))
44F90OBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(F90SRCS:.f90=-f90.o)))
45F90OBJS := $(patsubst %,$(BLDDIR)/%,$(notdir $(F90OBJS:.F90=-f90.o)))
46endif
47SOURCES := $(CPPSRCS) $(CXXSRCS) $(CCXSRCS) $(CSOURCS)
48OBJECTS := $(CPPOBJS) $(CXXOBJS) $(CCXOBJS) $(COBJCTS)
49FTNSRCS := $(FXXSRCS) $(F77SRCS) $(F90SRCS)
50MODULES := $(addsuffix .mod,$(basename $(FTNSRCS))) $(addsuffix .modmic,$(basename $(FTNSRCS)))
51FTNOBJS := $(FXXOBJS) $(F77OBJS) $(F90OBJS)
52XFILES := $(OUTDIR)/$(OUTNAME)_xsmm $(OUTDIR)/$(OUTNAME)_batch \
53          $(OUTDIR)/$(OUTNAME)_blas \
54          $(OUTDIR)/$(OUTNAME)_blaze \
55          $(OUTDIR)/$(OUTNAME)_eigen
56
57ifneq (0,$(BLAZE))
58ifeq (,$(strip $(BLAZEROOT)))
59  ifneq (,$(wildcard $(DEPDIR)/../blaze*/blaze/Blaze.h))
60    BLAZEROOT = $(lastword $(sort $(wildcard $(DEPDIR)/../blaze*)))
61  else ifneq (,$(wildcard $(HOME)/blaze*/blaze/Blaze.h))
62    BLAZEROOT = $(lastword $(sort $(wildcard $(HOME)/blaze*)))
63  endif
64endif
65endif
66
67ifneq (,$(BLAZEROOT))
68  DFLAGS += -D__BLAZE
69  IFLAGS += -I$(call quote,$(BLAZEROOT))
70  BLAZE ?= 1
71  DFLAGS += -DBLAZE_USE_SHARED_MEMORY_PARALLELIZATION=$(shell echo "$$(($(BLAZE)-1))")
72else
73  BLAZE := 0
74endif
75
76ifneq (0,$(EIGEN))
77ifeq (,$(strip $(EIGENROOT)))
78  ifneq (,$(wildcard $(DEPDIR)/../eigen*/Eigen/Dense))
79    EIGENROOT = $(lastword $(sort $(wildcard $(DEPDIR)/../eigen*)))
80  else ifneq (,$(wildcard $(HOME)/eigen*/Eigen/Dense))
81    EIGENROOT = $(lastword $(sort $(wildcard $(HOME)/eigen*)))
82  else ifneq (,$(wildcard /usr/include/eigen3/Eigen/Dense))
83    EIGENROOT = /usr/include/eigen3
84  else ifneq (,$(wildcard /usr/local/opt/eigen/include/eigen3/Eigen/Dense))
85    EIGENROOT = /usr/local/opt/eigen/include/eigen3
86  endif
87endif
88endif
89
90ifneq (,$(EIGENROOT))
91  DFLAGS += -D__EIGEN
92  IFLAGS += -I$(call quote,$(EIGENROOT))
93  EIGEN ?= 1
94  #ifneq (0,$(MKL))
95    #DFLAGS += -DEIGEN_USE_MKL_ALL
96  #endif
97  ifneq (0,$(shell echo "$$((1 < $(BLAS) || 1 < $(EIGEN)))"))
98    DFLAGS += -DEIGEN_USE_THREADS
99  else
100    DFLAGS += -DEIGEN_DONT_PARALLELIZE
101  endif
102  ifneq (,$(wildcard $(EIGENROOT)/unsupported/Eigen/CXX11/ThreadPool))
103    DFLAGS += -D__EIGEN_UNSUPPORTED
104  endif
105else
106  EIGEN := 0
107endif
108
109.PHONY: all
110all: $(XFILES)
111
112.PHONY: compile
113compile: $(OBJECTS) $(FTNOBJS)
114
115$(OUTDIR)/$(OUTNAME)_xsmm: $(OUTDIR)/.make $(BLDDIR)/$(OUTNAME)_xsmm-c.o $(LIBDEP) $(EXTDEP) $(NOBLASDEP)
116	$(LD) -o $@ $(BLDDIR)/$(OUTNAME)_xsmm-c.o $(call cleanld,$(MAINLIB) $(NOBLASLIB) $(SLDFLAGS) $(LDFLAGS) $(CLDFLAGS))
117
118$(OUTDIR)/$(OUTNAME)_batch: $(OUTDIR)/.make $(BLDDIR)/$(OUTNAME)_batch-c.o $(LIBDEP) $(EXTDEP) $(NOBLASDEP)
119	$(LD) -o $@ $(BLDDIR)/$(OUTNAME)_batch-c.o $(call cleanld,$(EXTLIB) $(MAINLIB) $(SLDFLAGS) $(LDFLAGS) $(CLDFLAGS))
120
121$(OUTDIR)/$(OUTNAME)_blas: $(OUTDIR)/.make $(BLDDIR)/$(OUTNAME)_blas-c.o $(LIBDEP) $(EXTDEP)
122	$(LD) -o $@ $(BLDDIR)/$(OUTNAME)_blas-c.o $(call cleanld,$(SLDFLAGS) $(LDFLAGS) $(CLDFLAGS))
123
124ifneq (,$(BLAZEROOT))
125$(OUTDIR)/$(OUTNAME)_blaze: $(OUTDIR)/.make $(BLDDIR)/$(OUTNAME)_blaze-cpp.o
126	$(LD) -o $@ $(BLDDIR)/$(OUTNAME)_blaze-cpp.o $(call cleanld,$(SLDFLAGS) $(LDFLAGS) $(CLDFLAGS))
127else
128.PHONY: $(OUTDIR)/$(OUTNAME)_blaze
129endif
130
131ifneq (,$(EIGENROOT))
132$(OUTDIR)/$(OUTNAME)_eigen: $(OUTDIR)/.make $(BLDDIR)/$(OUTNAME)_eigen-cpp.o
133	$(LD) -o $@ $(BLDDIR)/$(OUTNAME)_eigen-cpp.o $(call cleanld,$(SLDFLAGS) $(LDFLAGS) $(CLDFLAGS))
134else
135.PHONY: $(OUTDIR)/$(OUTNAME)_eigen
136endif
137
138$(BLDDIR)/%-cpp.o: $(SRCDIR)/%.cpp .state $(BLDDIR)/.make $(HEADERS) Makefile $(DEPDIR)/Makefile.inc
139	$(CXX) $(DFLAGS) $(IFLAGS) $(CXXFLAGS) $(CTARGET) -c $< -o $@
140
141$(BLDDIR)/%-c.o: $(SRCDIR)/%.c .state $(BLDDIR)/.make $(HEADERS) Makefile $(DEPDIR)/Makefile.inc
142	$(CC) $(DFLAGS) $(IFLAGS) $(CFLAGS) $(CTARGET) -c $< -o $@
143
144$(BLDDIR)/%-f.o: $(SRCDIR)/%.f .state $(BLDDIR)/.make Makefile $(DEPDIR)/Makefile.inc
145	$(FC) $(FCMTFLAGS) $(DFLAGS) $(IFLAGS) $(FCFLAGS) $(FTARGET) -c $< -o $@
146
147$(BLDDIR)/%-f90.o: $(SRCDIR)/%.f90 .state $(BLDDIR)/.make Makefile $(DEPDIR)/Makefile.inc
148	$(FC) $(FCMTFLAGS) $(DFLAGS) $(IFLAGS) $(FCFLAGS) $(FTARGET) -c $< -o $@
149
150$(BLDDIR)/%-f90.o: $(SRCDIR)/%.F90 .state $(BLDDIR)/.make Makefile $(DEPDIR)/Makefile.inc
151	$(FC) $(FCMTFLAGS) $(DFLAGS) $(IFLAGS) $(FCFLAGS) $(FTARGET) -c $< -o $@
152
153$(BLDDIR)/%-f77.o: $(SRCDIR)/%.F .state $(BLDDIR)/.make Makefile $(DEPDIR)/Makefile.inc
154	$(FC) $(FCMTFLAGS) $(DFLAGS) $(IFLAGS) $(FCFLAGS) $(FTARGET) -c $< -o $@
155
156.PHONY: clean
157clean:
158ifneq ($(call qapath,$(BLDDIR)),$(ROOTDIR))
159ifneq ($(call qapath,$(BLDDIR)),$(call qapath,.))
160	@rm -rf $(BLDDIR)
161endif
162endif
163ifneq (,$(wildcard $(BLDDIR))) # still exists
164	@rm -f $(OBJECTS) $(OBJECTX) $(FTNOBJS) $(FTNOBJX) *__genmod.* fit.log *.dat
165	@rm -f $(BLDDIR)/*.gcno $(BLDDIR)/*.gcda $(BLDDIR)/*.gcov
166endif
167	@rm -f .make .state
168
169.PHONY: realclean
170realclean: clean
171ifneq ($(call qapath,$(OUTDIR)),$(ROOTDIR))
172ifneq ($(call qapath,$(OUTDIR)),$(call qapath,.))
173	@rm -rf $(OUTDIR)
174endif
175endif
176ifneq (,$(wildcard $(OUTDIR))) # still exists
177	@rm -f $(OUTDIR)/libxsmm.$(DLIBEXT) $(OUTDIR)/*.stackdump
178	@rm -f $(XFILES) $(MODULES)
179endif
180
181