Building with GNU Make
In this build approach, you write your own make files defining a number of
variables and rules. Then you invoke make
to start the building process.
This will result in an executable upon successful completion. The temporary
files generated in the building process are stored in a temporary directory
named tmp_build_dir
.
Dissecting a Simple Make File
An example of building with GNU Make can be found in
amrex-tutorials/ExampleCodes/Basic/HelloWorld_C
. Table 1 below shows a
list of important variables.
Variable |
Value |
Default |
---|---|---|
AMREX_HOME |
Path to amrex |
environment |
COMP |
gnu, cray, ibm, intel, intel-llvm, intel-classic, llvm, or pgi |
none |
CXXSTD |
C++ standard ( |
compiler default,
at least |
DEBUG |
TRUE or FALSE |
FALSE |
DIM |
1 or 2 or 3 |
3 |
PRECISION |
DOUBLE or FLOAT |
DOUBLE |
TEST |
TRUE or FALSE |
FALSE |
USE_ASSERTION |
TRUE or FALSE |
FALSE |
USE_MPI |
TRUE or FALSE |
FALSE |
USE_OMP |
TRUE or FALSE |
FALSE |
USE_CUDA |
TRUE or FALSE |
FALSE |
USE_HIP |
TRUE or FALSE |
FALSE |
USE_SYCL |
TRUE or FALSE |
FALSE |
USE_RPATH |
TRUE or FALSE |
FALSE |
WARN_ALL |
TRUE or FALSE |
TRUE for DEBUG FALSE otherwise |
|
CUDA arch such as 70 |
70 if not set or detected |
|
AMD GPU arch such as gfx908 |
none if the machine is unknown |
USE_GPU_RDC |
TRUE or FALSE |
TRUE |
At the beginning of amrex-tutorials/ExampleCodes/Basic/HelloWorld_C/GNUmakefile
,
AMREX_HOME
is set to the path to the top directory of AMReX. Note that in
the example ?=
is a conditional variable assignment operator that only
has an effect if AMREX_HOME
has not been defined (including in the
environment). One can also set AMREX_HOME
as an environment variable. For
example in bash, one can set
export AMREX_HOME=/path/to/amrex
alternatively, in tcsh one can set
setenv AMREX_HOME /path/to/amrex
Note: when setting AMREX_HOME
in the GNUmakefile
, be aware that ~
does
not expand, so AMREX_HOME=~/amrex/
will yield an error.
One must set the COMP
variable to choose a compiler. Currently the list of
supported compilers includes gnu, cray, ibm, intel, llvm, and pgi.
One could set the DIM
variable to either 1, 2, or 3, depending on
the dimensionality of the problem. The default dimensionality is 3.
AMReX uses double precision by default. One can change to single
precision by setting PRECISION=FLOAT
.
(Particles have an equivalent flag USE_SINGLE_PRECISION_PARTICLES=TRUE/FALSE
.)
Variables DEBUG
, TEST
, USE_MPI
and USE_OMP
are optional with
default set to FALSE. The meaning of these variables should
be obvious. When DEBUG=TRUE
, aggressive compiler optimization flags are
turned off and assertions in source code are turned on. For production runs,
DEBUG
should be set to FALSE. TEST
and USE_ASSERTION
are set by
default in CI and add slight debugging, e.g., initializing default values in FABs.
An advanced variable, MPI_THREAD_MULTIPLE
, can be set to TRUE to initialize
MPI with support for concurrent MPI calls from multiple threads.
Variables USE_CUDA
, USE_HIP
and USE_SYCL
are used for
targeting Nvidia, AMD and Intel GPUs, respectively. At most one of
the three can be TRUE.
For HIP and SYCL builds, we do only test against C++17 builds at the moment.
The variable USE_RPATH
controls the link mechanism to dependent libraries.
If enabled, the library path at link time will be saved as a
rpath hint in created binaries.
When disabled, dynamic library paths could be provided via export LD_LIBRARY_PATH
hints at runtime.
For GCC and Clang, the variable WARN_ALL
controls the compiler’s warning options. There is
also a make variable WARN_ERROR
(with default of FALSE
) to turn warnings into errors.
When USE_CUDA
is TRUE
, the make system will try to detect what CUDA
arch should be used by running
$(CUDA_HOME)/extras/demo_suite/deviceQuery
if your computer is unknown.
If it fails to detect the CUDA arch, the default value of 70 will be used.
The user could override it by make USE_CUDA=TRUE CUDA_ARCH=80
or make
USE_CUDA=TRUE AMREX_CUDA_ARCH=80
.
After defining these make variables, a number of files, Make.defs,
Make.package
and Make.rules
, are included in the GNUmakefile. AMReX-based
applications do not need to include all directories in AMReX; an application
which does not use particles, for example, does not need to include files from
the Particle directory in its build. In this simple example, we only need to
include $(AMREX_HOME)/Src/Base/Make.package
. An application code also has
its own Make.package file (e.g., ./Make.package
in this example) to append
source files to the build system using operator +=
. Variables for various
source files are shown below.
- CEXE_sources
C++ source files. Note that C++ source files are assumed to have a .cpp extension.
- CEXE_headers
C++ headers with .h, .hpp, or .H extension.
- cEXE_sources
C source files with .c extension.
- cEXE_headers
C headers with .h extension.
- f90EXE_sources
Free format Fortran source with .f90 extension.
- F90EXE_sources
Free format Fortran source with .F90 extension. Note that these Fortran files will go through preprocessing.
In this simple example, the extra source file, main.cpp
is in the current
directory that is already in the build system’s search path. If this example
has files in a subdirectory (e.g., mysrcdir
), you will then need to add the
following to Make.package
.
VPATH_LOCATIONS += mysrcdir
INCLUDE_LOCATIONS += mysrcdir
Here VPATH_LOCATIONS
and INCLUDE_LOCATIONS
are the search path for
source and header files, respectively.
Tweaking the Make System
The GNU Make build system is located at amrex/Tools/GNUMake
. You can read
README.md
and the make files there for more information. Here we will give
a brief overview.
Besides building executable, other common make commands include:
make cleanconfig
This removes the executable, .o files, and the temporarily generated files for the given build. Note that one can add additional targets to this rule using the double colon (::)
make clean
andmake realclean
These remove all files generated by make for all builds.
make help
This shows the rules for compilation.
make print-xxx
This shows the value of variable xxx. This is very useful for debugging and tweaking the make system.
Compiler flags are set in amrex/Tools/GNUMake/comps/
. Note that variables
like CXX
and CXXFLAGS
are reset in that directory and their values in
environment variables are disregarded. However, one could override them
with make command line arguments (e.g., make CXX=/path/to/my/mpicxx
).
Site-specific setups (e.g., the MPI
installation) are in amrex/Tools/GNUMake/sites/
, which includes a generic
setup in Make.unknown
. You can override the setup by having your own
sites/Make.$(host_name)
file, where variable host_name
is your host
name in the make system and can be found via make print-host_name
. You can
also have an amrex/Tools/GNUMake/Make.local
file to override various
variables. See amrex/Tools/GNUMake/Make.local.template
for more examples of
how to customize the build process.
If you need to pass macro definitions to the preprocessor, you can add them to your make file as follows,
DEFINES += -Dmyname1 -Dmyname2=mydefinition
To link to an additional library say foo
with headers located at
foopath/include
and library at foopath/lib
, you can add the
following to your make file before the line that includes AMReX’s
Make.defs
,
INCLUDE_LOCATIONS += foopath/include
LIBRARY_LOCATIONS += foopath/lib
LIBRARIES += -lfoo
Specifying your own compiler
The amrex/Tools/GNUMake/Make.local
file can also specify your own compile
commands by setting the variables CXX
, CC
, FC
, and F90
. This
might be necessary if your systems contains non-standard names for compiler
commands.
For example, the following amrex/Tools/GNUMake/Make.local
builds AMReX
using a specific compiler (in this case gcc-8
) without MPI. Whenever
USE_MPI
is true, this configuration defaults to the appropriate
mpixxx
command:
ifeq ($(USE_MPI),TRUE)
CXX = mpicxx
CC = mpicc
FC = mpif90
F90 = mpif90
else
CXX = g++-8
CC = gcc-8
FC = gfortran-8
F90 = gfortran-8
endif
For building with MPI, we assume mpicxx
, mpif90
, etc. provide access to
the correct underlying compilers.
GCC on macOS
The example configuration above should also run on the latest macOS. On macOS
the default cxx compiler is clang, whereas the default Fortran compiler is
gfortran. Sometimes it is good to avoid mixing compilers, in that case we can
use the Make.local
to force using GCC. However, macOS’ Xcode ships with its
own (woefully outdated) version of GCC (4.2.1). It is therefore recommended to
install GCC using the homebrew package manager. Running
brew install gcc
installs gcc with names reflecting the version number. If
GCC 8.2 is installed, homebrew installs it as gcc-8
. AMReX can be built
using gcc-8
(with and without MPI) by using the following
amrex/Tools/GNUMake/Make.local
:
CXX = g++-8
CC = gcc-8
FC = gfortran-8
F90 = gfortran-8
INCLUDE_LOCATIONS += /usr/local/include
The additional INCLUDE_LOCATIONS
are installed using homebrew also. Note
that if you are building AMReX using homebrew’s gcc, it is recommended that you
use homebrew’s mpich. Normally it is fine to simply install its binaries:
brew install mpich
. But if you are experiencing problems, we suggest
building mpich using homebrew’s gcc: brew install mpich --cc=gcc-8
.
Fortran
If your code does not use Fortran, you can add BL_NO_FORT=TRUE
to
your makefile to disable Fortran.
ccache
If you use ccache, you can add USE_CCACHE=TRUE
to your makefile.
Building libamrex
If an application code already has its own elaborated build system and wants to
use AMReX, an external AMReX library can be created instead. In this approach, one
runs ./configure
, followed by make
and make install
.
Other make options include make distclean
and make uninstall
. In the top
AMReX directory, one can run ./configure -h
to show the various options for
the configure script. In particular, one can specify the installation path for the AMReX library using:
./configure --prefix=[AMReX library path]
This approach is built on the AMReX GNU Make system. Thus
the section on Building with GNU Make is recommended if any fine tuning is
needed. The result of ./configure
is GNUmakefile
in the AMReX
top directory. One can modify the make file for fine tuning.
To compile an application code against the external AMReX library, it
is necessary to set appropriate compiler flags and set the library
paths for linking. To assist with this, when the AMReX library is
built, a configuration file is created in [AMReX library path]/lib/pkgconfig/amrex.pc
.
This file contains the Fortran and
C++ flags used to compile the AMReX library as well as the appropriate
library and include entries.
The following sample GNU Makefile will compile a main.cpp
source
file against an external AMReX library, using the C++ flags and
library paths used to build AMReX:
AMREX_LIBRARY_HOME ?= [AMReX library path]
LIBDIR := $(AMREX_LIBRARY_HOME)/lib
INCDIR := $(AMREX_LIBRARY_HOME)/include
COMPILE_CPP_FLAGS ?= $(shell awk '/Cflags:/ {$$1=$$2=""; print $$0}' $(LIBDIR)/pkgconfig/amrex.pc)
COMPILE_LIB_FLAGS ?= $(shell awk '/Libs:/ {$$1=$$2=""; print $$0}' $(LIBDIR)/pkgconfig/amrex.pc)
CFLAGS := -I$(INCDIR) $(COMPILE_CPP_FLAGS)
LFLAGS := -L$(LIBDIR) $(COMPILE_LIB_FLAGS)
all:
g++ -o main.exe main.cpp $(CFLAGS) $(LFLAGS)
Building with CMake
An alternative to the approach described in the section on Building libamrex
is to install AMReX as an external library by using the CMake build system. A
CMake build is a two-step process. First cmake
is invoked to create
configuration files and makefiles in a chosen directory (builddir
). This
is roughly equivalent to running ./configure
(see the section on
Building libamrex). Next, the actual build and installation are performed by
invoking make install
from within builddir
. This installs the library files
in a chosen installation directory (installdir
). If no installation path
is provided by the user, AMReX will be installed in /path/to/amrex/installdir
.
The CMake build process is summarized as follows:
mkdir /path/to/builddir
cd /path/to/builddir
cmake [options] -DCMAKE_BUILD_TYPE=[Debug|Release|RelWithDebInfo|MinSizeRel] -DCMAKE_INSTALL_PREFIX=/path/to/installdir /path/to/amrex
make install
make test_install # optional step to test if the installation is working
In the above snippet, [options]
indicates one or more options for the
customization of the build, as described in the subsection on
Customization options. If the option CMAKE_BUILD_TYPE
is omitted,
CMAKE_BUILD_TYPE=Release
is assumed. Although the AMReX source could be used as
build directory, we advise against doing so. After the installation is
complete, builddir
can be removed.
Customization options
AMReX build can be customized by setting the value of suitable configuration variables
on the command line via the -D <var>=<value>
syntax, where <var>
is the
variable to set and <value>
its desired value.
For example, one can enable OpenMP support as follows:
cmake -DAMReX_OMP=YES -DCMAKE_INSTALL_PREFIX=/path/to/installdir /path/to/amrex
In the example above <var>=AMReX_OMP
and <value>=YES
.
Configuration variables requiring a boolean value are evaluated to true if they
are assigned a value of 1
, ON
, YES
, TRUE
, Y
. Conversely they are evaluated to false
if they are assigned a value of 0
, OFF
, NO
, FALSE
, N
.
Boolean configuration variables are case-insensitive.
The list of available options is reported in the table below.
The option CMAKE_BUILD_TYPE=Debug
implies AMReX_ASSERTIONS=YES
. In order to turn off
assertions in debug mode, AMReX_ASSERTIONS=NO
must be set explicitly while
invoking CMake.
The CMAKE_C_COMPILER
, CMAKE_CXX_COMPILER
, and CMAKE_Fortran_COMPILER
options
are used to tell CMake which compiler to use for the compilation of C, C++, and Fortran sources
respectively. If those options are not set by the user, CMake will use the system default compilers.
The options CMAKE_Fortran_FLAGS
and CMAKE_CXX_FLAGS
allow the user to
set their own compilation flags for Fortran and C++ source files respectively.
If CMAKE_Fortran_FLAGS
/ CMAKE_CXX_FLAGS
are not set by the user,
they will be initialized with the value of the environmental variables FFLAGS
/
CXXFLAGS
. If neither FFLAGS
/ CXXFLAGS
nor CMAKE_Fortran_FLAGS
/ CMAKE_CXX_FLAGS
are defined, AMReX default flags are used.
For a detailed explanation of GPU support in AMReX CMake, refer to section Building GPU Support.
CMake and macOS
While not strictly necessary when using homebrew on macOS, it is highly
recommended that the user specifies -DCMAKE_C_COMPILER=$(which gcc-X) -DCMAKE_CXX_COMPILER=$(which
g++-X)
(where X is the GCC version installed by homebrew) when using
gfortran. This is because homebrew’s CMake defaults to the Clang C/C++
compiler. Normally Clang plays well with gfortran, but if there are some issues,
we recommend telling CMake to use gcc for C/C++ also.
Importing AMReX into your CMake project
In order to import AMReX into your CMake project, you need to include the following line in the appropriate CMakeLists.txt file:
find_package(AMReX)
Calls to find_package(AMReX)
will find a valid installation of AMReX, if present,
and import its settings and targets into your CMake project.
Imported AMReX targets can be linked to any of your targets, after they have been made available
following a successful call to find_package(AMReX)
, by including
the following line in the appropriate CMakeLists.txt file:
target_link_libraries( <your-target-name> PUBLIC AMReX::<amrex-target-name> )
In the above snippet, <amrex-target-name>
is any of the targets listed in the table below.
Target name |
Description |
---|---|
amrex_1d |
AMReX library in 1D |
amrex_2d |
AMReX library in 2D |
amrex_3d |
AMReX library in 3D |
amrex |
AMReX library (alias, points to last dim) |
Flags_CXX |
C++ flags preset (interface) |
Flags_Fortran |
Fortran flags preset (interface) |
Flags_FPE |
Floating Point Exception flags (interface) |
The options used to configure the AMReX build may result in certain parts, or components
, of the AMReX source code
to be excluded from compilation. For example, setting -DAMReX_LINEAR_SOLVERS=no
at configure time
prevents the compilation of AMReX linear solvers code.
Your CMake project can check which component is included in the AMReX library via find_package:
find_package(AMReX REQUIRED <components-list>)
The keyword REQUIRED
in the snippet above will cause a fatal error if AMReX is not found, or
if it is found but the components listed in <components-list>
are not include in the installation.
A list of AMReX component names and related configure options are shown in the table below.
Option |
Component |
---|---|
AMReX_SPACEDIM |
1D, 2D, 3D |
AMReX_PRECISION |
DOUBLE, SINGLE |
AMReX_FORTRAN |
FORTRAN |
AMReX_PIC |
PIC |
AMReX_MPI |
MPI |
AMReX_OMP |
OMP |
AMReX_GPU_BACKEND |
CUDA, HIP, SYCL |
AMReX_FORTRAN_INTERFACES |
FINTERFACES |
AMReX_LINEAR_SOLVERS |
LSOLVERS |
AMReX_LINEAR_SOLVERS_INCFLO |
LSOLVERS_INCFLO |
AMReX_LINEAR_SOLVERS_EM |
LSOLVERS_EM |
AMReX_AMRDATA |
AMRDATA |
AMReX_AMRLEVEL |
AMRLEVEL |
AMReX_EB |
EB |
AMReX_FFT |
FFT |
AMReX_PARTICLES |
PARTICLES |
AMReX_PARTICLES_PRECISION |
PDOUBLE, PSINGLE |
AMReX_BASE_PROFILE |
BASEP |
AMReX_TINY_PROFILE |
TINYP |
AMReX_TRACE_PROFILE |
TRACEP |
AMReX_COMM_PROFILE |
COMMP |
AMReX_MEM_PROFILE |
MEMP |
AMReX_PROFPARSER |
PROFPARSER |
AMReX_FPE |
FPE |
AMReX_ASSERTIONS |
ASSERTIONS |
AMReX_SENSEI |
SENSEI |
AMReX_CONDUIT |
CONDUIT |
AMReX_ASCENT |
ASCENT |
AMReX_HYPRE |
HYPRE |
AMReX_PLOTFILE_TOOLS |
PFTOOLS |
As an example, consider the following CMake code:
find_package(AMReX REQUIRED 3D EB)
target_link_libraries(Foo PUBLIC AMReX::amrex_3d)
The code in the snippet above checks whether an AMReX installation with 3D and Embedded Boundary support
is available on the system. If so, AMReX is linked to target Foo
and AMReX flags preset is used
to compile Foo
’s C++ sources. If no AMReX installation is found or if the available one was built without
3D or Embedded Boundary support, a fatal error is issued.
You can tell CMake to look for the AMReX library in non-standard paths by setting the environmental variable
AMReX_ROOT
to point to the AMReX installation directory or by adding
-DAMReX_ROOT=<path/to/amrex/installation/directory>
to the cmake
invocation.
More details on find_package
can be found
here.
AMReX on Windows
The AMReX team does development on Linux machines, from laptops to supercomputers. Many people also use AMReX on Macs without issues.
We do not officially support AMReX on Windows, and many of us do not have access to any Windows machines. However, we believe there are no fundamental issues for it to work on Windows.
(1) AMReX mostly uses standard C++17. We run continuous integration tests on Windows with MSVC and Clang compilers.
(2) We use POSIX signal handling when floating point exceptions, segmentation faults, etc. happen. This capability is not supported on Windows.
(3) Memory profiling is an optional feature in AMReX that is not enabled by default. It reads memory system information from the OS to give us a summary of our memory usage. This is not supported on Windows.
Spack
AMReX can be installed using the scientific software package manager Spack. Spack supports multiple versions and configurations of AMReX across a wide variety of platforms and environments. To learn more about Spack visit http://www.spack.io. For system requirements and installation instructions please see https://spack.readthedocs.io/.
Once Spack has been downloaded and the Spack environment enabled, AMReX can be installed with the command,
spack install amrex
This will install the latest release of AMReX and required dependencies if needed.
AMReX can be built in several combinations of versions and configurations. Available options can be viewed by typing,
spack info amrex
For example, suppose we want to install the development version of AMReX for a two dimensional
simulation with Cuda support for Cuda Architecture sm_60
. Then we would
use the install commands,
spack install amrex@develop dimensions=2 +cuda cuda_arch=60