From f2f7a0ee284e35839d46b8bd02ce393eaf29073c Mon Sep 17 00:00:00 2001 From: SKlapproth Date: Fri, 10 Jul 2026 11:43:05 +0200 Subject: [PATCH 1/5] restructure section overview and folders --- _quarto.yml | 81 ++++-- index.qmd | 6 +- .../analysis-performance/in-situ/index.qmd | 12 + .../analysis-performance/profiling/index.qmd | 118 +++++++++ sections/{ => appendix}/literature/index.qmd | 0 sections/{ => appendix}/playground/index.qmd | 0 sections/demos/alpine-pif/index.qmd | 7 + .../alpine/index.qmd} | 6 +- sections/demos/collisions/index.qmd | 7 + sections/demos/cosmology/index.qmd | 3 + sections/demos/fel/index.qmd | 7 + .../maxwell-solvers/index.qmd | 0 .../poisson-solvers/index.qmd | 0 .../api-reference/index.qmd | 0 .../developer-guide/index.qmd | 0 .../performance-portability/index.qmd | 0 sections/for-developers/unit-tests/index.qmd | 155 +++++++++++ sections/for-developers/workflow/index.qmd | 58 ++++ .../{ => hello-ippl}/index.qmd | 3 +- .../getting-started/installation/index.qmd | 250 ++++++++++++++++++ sections/getting-started/slurm/index.qmd | 77 ++++++ .../{ => introduction}/overview/index.qmd | 0 sections/{ => introduction}/theory/index.qmd | 2 +- .../{ => ippl-core}/communication/index.qmd | 0 .../{ => ippl-core}/core-concepts/index.qmd | 0 sections/{ => ippl-core}/fields/index.qmd | 0 sections/{ => ippl-core}/particles/index.qmd | 0 sections/methods-operators/cg/index.qmd | 100 +++++++ .../{ => methods-operators}/fem/index.qmd | 0 .../{ => methods-operators}/fft/index.qmd | 0 sections/methods-operators/nufft/index.qmd | 7 + .../particle-mesh-interpolation}/index.qmd | 3 +- sections/{examples => tests}/index.qmd | 0 33 files changed, 879 insertions(+), 23 deletions(-) create mode 100644 sections/analysis-performance/in-situ/index.qmd create mode 100644 sections/analysis-performance/profiling/index.qmd rename sections/{ => appendix}/literature/index.qmd (100%) rename sections/{ => appendix}/playground/index.qmd (100%) create mode 100644 sections/demos/alpine-pif/index.qmd rename sections/{examples/alpine-manager-hierarchy.qmd => demos/alpine/index.qmd} (99%) create mode 100644 sections/demos/collisions/index.qmd create mode 100644 sections/demos/cosmology/index.qmd create mode 100644 sections/demos/fel/index.qmd rename sections/{ => field-solvers}/maxwell-solvers/index.qmd (100%) rename sections/{ => field-solvers}/poisson-solvers/index.qmd (100%) rename sections/{ => for-developers}/api-reference/index.qmd (100%) rename sections/{ => for-developers}/developer-guide/index.qmd (100%) rename sections/{ => for-developers}/performance-portability/index.qmd (100%) create mode 100644 sections/for-developers/unit-tests/index.qmd create mode 100644 sections/for-developers/workflow/index.qmd rename sections/getting-started/{ => hello-ippl}/index.qmd (97%) create mode 100644 sections/getting-started/installation/index.qmd create mode 100644 sections/getting-started/slurm/index.qmd rename sections/{ => introduction}/overview/index.qmd (100%) rename sections/{ => introduction}/theory/index.qmd (93%) rename sections/{ => ippl-core}/communication/index.qmd (100%) rename sections/{ => ippl-core}/core-concepts/index.qmd (100%) rename sections/{ => ippl-core}/fields/index.qmd (100%) rename sections/{ => ippl-core}/particles/index.qmd (100%) create mode 100644 sections/methods-operators/cg/index.qmd rename sections/{ => methods-operators}/fem/index.qmd (100%) rename sections/{ => methods-operators}/fft/index.qmd (100%) create mode 100644 sections/methods-operators/nufft/index.qmd rename sections/{particle-mesh => methods-operators/particle-mesh-interpolation}/index.qmd (97%) rename sections/{examples => tests}/index.qmd (100%) diff --git a/_quarto.yml b/_quarto.yml index 060f154..f86dcc1 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -13,24 +13,68 @@ book: favicon: figures/ippl-logo.png chapters: - index.qmd - - sections/overview/index.qmd - - sections/theory/index.qmd - - sections/getting-started/index.qmd - - sections/examples/alpine-manager-hierarchy.qmd - - sections/core-concepts/index.qmd - - sections/fields/index.qmd - - sections/particles/index.qmd - - sections/particle-mesh/index.qmd - - sections/fft/index.qmd - - sections/poisson-solvers/index.qmd - - sections/maxwell-solvers/index.qmd - - sections/fem/index.qmd - - sections/communication/index.qmd - - sections/performance-portability/index.qmd - - sections/examples/index.qmd - - sections/developer-guide/index.qmd - - sections/api-reference/index.qmd - - sections/literature/index.qmd + + - part: "Introduction" + chapters: + - sections/introduction/theory/index.qmd + - sections/introduction/overview/index.qmd + + - part: "Getting Started" + chapters: + - sections/getting-started/installation/index.qmd + - sections/getting-started/hello-ippl/index.qmd + - sections/getting-started/slurm/index.qmd + + - part: "IPPL Core" + chapters: + - sections/ippl-core/core-concepts/index.qmd + - sections/ippl-core/fields/index.qmd + - sections/ippl-core/particles/index.qmd + - sections/ippl-core/communication/index.qmd + + - part: "Methods & Operators" + chapters: + - sections/methods-operators/particle-mesh-interpolation/index.qmd + - sections/methods-operators/cg/index.qmd + - sections/methods-operators/fft/index.qmd + - file: sections/methods-operators/nufft/index.qmd + text: "NUFFT" + - sections/methods-operators/fem/index.qmd + + - part: "Field Solvers" + chapters: + - sections/field-solvers/poisson-solvers/index.qmd + - sections/field-solvers/maxwell-solvers/index.qmd + + - part: "Analysis & Performance" + chapters: + - sections/analysis-performance/profiling/index.qmd + - sections/analysis-performance/in-situ/index.qmd + + - part: "Demos" + chapters: + - sections/demos/alpine/index.qmd + - sections/demos/alpine-pif/index.qmd + - sections/demos/cosmology/index.qmd + - sections/demos/collisions/index.qmd + - sections/demos/fel/index.qmd + + - part: "Tests" + chapters: + - sections/tests/index.qmd + + - part: "For Developers" + chapters: + - sections/for-developers/developer-guide/index.qmd + - sections/for-developers/workflow/index.qmd + - sections/for-developers/unit-tests/index.qmd + - sections/for-developers/performance-portability/index.qmd + - sections/for-developers/api-reference/index.qmd + + - part: "Appendix" + chapters: + - sections/appendix/literature/index.qmd + - sections/appendix/playground/index.qmd number-sections: true number-depth: 3 @@ -39,6 +83,7 @@ format: html: toc: true toc-depth: 3 + # toc-location: right number-sections: true html-math-method: mathjax code-fold: false diff --git a/index.qmd b/index.qmd index be013a6..3b0abb9 100644 --- a/index.qmd +++ b/index.qmd @@ -1,8 +1,9 @@ --- -title: "IPPL Manual" +unnumbered: true number-sections: false --- +# Welcome {.unnumbered} ::: {.hero} ::: {} IPPL, the Independent Parallel Particle Layer, is a C++20 library for performance-portable particle, field, and particle-mesh simulations. It provides dimension-independent building blocks for Eulerian, Lagrangian, and hybrid methods on CPUs and GPUs. @@ -21,9 +22,12 @@ For users: 1. Start with @sec-overview and @sec-getting-started. 2. Read @sec-core-concepts, then the data model chapters on fields and particles. + 3. Move to FFT, Poisson, Maxwell, or FEM depending on the application. 4. Use @sec-examples as executable documentation. + + For developers: 1. Read the user path first. diff --git a/sections/analysis-performance/in-situ/index.qmd b/sections/analysis-performance/in-situ/index.qmd new file mode 100644 index 0000000..21790e9 --- /dev/null +++ b/sections/analysis-performance/in-situ/index.qmd @@ -0,0 +1,12 @@ +--- +subtitle: "in Situ Analysis and Visulization with ParaView Catalyst" +--- + +# In Situ + +coming soon! + +## Visualization + + +## Steering \ No newline at end of file diff --git a/sections/analysis-performance/profiling/index.qmd b/sections/analysis-performance/profiling/index.qmd new file mode 100644 index 0000000..4840442 --- /dev/null +++ b/sections/analysis-performance/profiling/index.qmd @@ -0,0 +1,118 @@ + + +# Profiling + +## MPI Calls +You can use the mpiP tool (https://github.com/LLNL/mpiP) to get statistics about the MPI calls in IPPL. + +To use it, download it from [Github](https://github.com/LLNL/mpiP) and follow the instructions to install it. You may run into some issues while installing, here is a list of common issues and the solution: +- On Cray systems "MPI_Init not defined": This I fixed by passing the correct Cray wrappers for the compilers to the configure: `./configure CC=cc FC=ftn F77=ftn` +- If you have an issue with it not recognizing a function symbol in Fortran 77, you need to substitute the line `echo "main(){ FF(); return 0; }" > flink.c` (line 706) in the file `configure.ac` by the following line `echo "extern void FF(); int main() { FF(); return 0; }" > flink.c` +- During the `make all`, if you run into an issue of some Testing file not recognizing mpi.h, then you need to add the following line `CXX = CC` in the file `Testing/Makefile`. + +If the installation was successful, you should have the library `libmpip.so` in the mpiP directory. + +To instument your application with the mpiP library, add the following line to your jobscript (or run it in your command line if you are running locally/on an interactive node): +`export LD_PRELOAD=$[path to mpip directory]/libmpiP.so` +To pass any options to mpiP, you can export the variable MPIP with the options you want. For example, if you would like to get a histogram of the data sent by MPI calls (option `-y`), you would need to add the following line to your jobscript: +`export MPIP="-y"` + +If you application has been correctly instrumented, you will see that mpiP has been found and its version is printed at the top of the standard output. At the end of the standard output, you will get the name of the file containing the MPI statistics: +`Storing mpiP output in ...` + +To get a total amount of bytes moved around by your application, you can use the python script mpiP.py (found in the top level IPPL directory) in the following form: +`python3 mpiP.py [path/to/directory]` +where path/to/directory refers to the place where the .mpiP output can be found. This python script will then print out the total amount of Bytes moved by MPI in your application. + +## Profiling on LUMI + +### rocprof + +Analysis with: https://ui.perfetto.dev/ + +``` +#!/bin/bash -l +# +#SBATCH --job-name=opalx1 +#SBATCH --error=opalx-%j.error +#SBATCH --output=opalx-2-%j.out +#SBATCH --time=00:05:00 +#SBATCH --partition=standard-g +#SBATCH --nodes 1 +#SBATCH --ntasks-per-core=1 +#SBATCH -c 56 --threads-per-core=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=8 +#SBATCH --account=project_465001705 +#SBATCH --hint=nomultithread +#SBATCH --hint=exclusive +CPU_BIND="map_cpu:49,57,17,25,1,9,33,41" +export MPICH_GPU_SUPPORT_ENABLED=1 + +ulimit -s unlimited +export EXE_DIR=/users/adelmann/sandbox/opalx/build/src/ +module load cray-python/3.11.7 +module use /appl/local/containers/test-modules +module load LUMI/24.03 partition/G cpeAMD rocm/6.1.3 buildtools/24.03 + +cat << EOF > select_gpu +#!/bin/bash +export HIP_VISIBLE_DEVICES=\$SLURM_LOCALID +exec \$* +EOF +chmod +x ./select_gpu +srun ./select_gpu rocprof --hip-trace ${EXE_DIR}/opalx input.in --info 5 +rm -rf ./select_gpu + +``` + + +### omniperf (do not use omnitrace) + +doc url: https://rocm.docs.amd.com/projects/rocprofiler-compute/en/docs-6.2.4/how-to/profile/mode.html + +``` +#!/bin/bash -l +# +#SBATCH --job-name=opalx1 +#SBATCH --error=opalx-%j.error +#SBATCH --output=opalx-2-%j.out +#SBATCH --time=00:05:00 +#SBATCH --partition=standard-g +#SBATCH --nodes 1 +#SBATCH --ntasks-per-core=1 +#SBATCH -c 56 --threads-per-core=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=8 +#SBATCH --account=project_465001705 +#SBATCH --hint=nomultithread +#SBATCH --hint=exclusive +CPU_BIND="map_cpu:49,57,17,25,1,9,33,41" +export MPICH_GPU_SUPPORT_ENABLED=1 + +ulimit -s unlimited +export EXE_DIR=/users/adelmann/sandbox/opalx/build/src/ +module load cray-python/3.11.7 +module use /appl/local/containers/test-modules +module load LUMI/24.03 partition/G cpeAMD rocm/6.1.3 buildtools/24.03 +module load omniperf +cat << EOF > select_gpu +#!/bin/bash +#export ROCR_VISIBLE_DEVICES=\$SLURM_LOCALID +export HIP_VISIBLE_DEVICES=\$SLURM_LOCALID +exec \$* +EOF +chmod +x ./select_gpu +srun ./select_gpu omniperf profile --name opalx --roof-only --kernel-names -- ${EXE_DIR}/opalx input.in --info 5 +rm -rf ./select_gpu +``` + + + + + + + + + +Happy profiling! diff --git a/sections/literature/index.qmd b/sections/appendix/literature/index.qmd similarity index 100% rename from sections/literature/index.qmd rename to sections/appendix/literature/index.qmd diff --git a/sections/playground/index.qmd b/sections/appendix/playground/index.qmd similarity index 100% rename from sections/playground/index.qmd rename to sections/appendix/playground/index.qmd diff --git a/sections/demos/alpine-pif/index.qmd b/sections/demos/alpine-pif/index.qmd new file mode 100644 index 0000000..cd8e019 --- /dev/null +++ b/sections/demos/alpine-pif/index.qmd @@ -0,0 +1,7 @@ +--- +subtitle: "Demonstration of the Particle in Fourier Method" +--- + +# ALPINE-PIF + +coming soon! \ No newline at end of file diff --git a/sections/examples/alpine-manager-hierarchy.qmd b/sections/demos/alpine/index.qmd similarity index 99% rename from sections/examples/alpine-manager-hierarchy.qmd rename to sections/demos/alpine/index.qmd index f83bb21..96f3f93 100644 --- a/sections/examples/alpine-manager-hierarchy.qmd +++ b/sections/demos/alpine/index.qmd @@ -1,4 +1,8 @@ -# ALPINE Manager Hierarchy {#sec-alpine-manager-hierarchy} +--- +subtitle: "Demonstration of an IPPL Application Layer using the PIC Manager" +--- + +# ALPINE {#sec-alpine-manager-hierarchy} ALPINE is IPPL's application layer: a collection of plasma-physics **mini-apps** in the `alpine/` directory that run full particle-in-cell (PIC) simulations end to end. They are not isolated library demos. Each mini-app wires together particles, fields, interpolation, Poisson solvers, MPI load balancing, and diagnostics the way a real simulation code would. diff --git a/sections/demos/collisions/index.qmd b/sections/demos/collisions/index.qmd new file mode 100644 index 0000000..cdcacfa --- /dev/null +++ b/sections/demos/collisions/index.qmd @@ -0,0 +1,7 @@ +--- +subtitle: "Possible approaches to integrate coulomb collisions into PIC" +--- + +# Collisions + +TODO: \ No newline at end of file diff --git a/sections/demos/cosmology/index.qmd b/sections/demos/cosmology/index.qmd new file mode 100644 index 0000000..e77ca00 --- /dev/null +++ b/sections/demos/cosmology/index.qmd @@ -0,0 +1,3 @@ +# Cosmology + +TODO: \ No newline at end of file diff --git a/sections/demos/fel/index.qmd b/sections/demos/fel/index.qmd new file mode 100644 index 0000000..d0c1765 --- /dev/null +++ b/sections/demos/fel/index.qmd @@ -0,0 +1,7 @@ +--- +subtitle: "Simulation of a Free-Electron-Laser Undulator with IPPL" +--- + +# FEL + +Coming soon! \ No newline at end of file diff --git a/sections/maxwell-solvers/index.qmd b/sections/field-solvers/maxwell-solvers/index.qmd similarity index 100% rename from sections/maxwell-solvers/index.qmd rename to sections/field-solvers/maxwell-solvers/index.qmd diff --git a/sections/poisson-solvers/index.qmd b/sections/field-solvers/poisson-solvers/index.qmd similarity index 100% rename from sections/poisson-solvers/index.qmd rename to sections/field-solvers/poisson-solvers/index.qmd diff --git a/sections/api-reference/index.qmd b/sections/for-developers/api-reference/index.qmd similarity index 100% rename from sections/api-reference/index.qmd rename to sections/for-developers/api-reference/index.qmd diff --git a/sections/developer-guide/index.qmd b/sections/for-developers/developer-guide/index.qmd similarity index 100% rename from sections/developer-guide/index.qmd rename to sections/for-developers/developer-guide/index.qmd diff --git a/sections/performance-portability/index.qmd b/sections/for-developers/performance-portability/index.qmd similarity index 100% rename from sections/performance-portability/index.qmd rename to sections/for-developers/performance-portability/index.qmd diff --git a/sections/for-developers/unit-tests/index.qmd b/sections/for-developers/unit-tests/index.qmd new file mode 100644 index 0000000..2afc241 --- /dev/null +++ b/sections/for-developers/unit-tests/index.qmd @@ -0,0 +1,155 @@ +# Unit Tests Overview + +IPPL allows the user to customize the behavior of its data types using template parameters. The unit tests verify that everything is working under all relevant and available configurations of the parameters. In particular, the tests verify behavior under +- mixed precision, i.e. components using single or double precision (`float`, `double`) +- varying dimensionality, i.e. components in 1D, 2D, 3D, etc. up to 6D (the maximum supported by Kokkos) +- mixed execution spaces, i.e. components using different accelerators (e.g. OpenMP, CUDA) in different memory spaces (host, device) + - The unit tests are instantiated for all available execution spaces. These are determined based on the compilation settings for Kokkos, which exposes compiler macros to indicate which execution spaces are available. + +As an example, we look at the unit tests for `BareField`. Consider the following Kokkos configuration: +```sh +cmake \ + -DCMAKE_INSTALL_PREFIX=${KOKKOS_PREFIX} \ + -DCMAKE_CXX_COMPILER="${compiler}" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_STANDARD=20 \ + -DCMAKE_CXX_EXTENSIONS=OFF \ + -DKokkos_ENABLE_SERIAL=OFF \ + -DKokkos_ARCH_AMPERE80=ON \ + -DKokkos_ENABLE_OPENMP=ON \ + -DKokkos_ENABLE_CUDA=ON \ + -DKokkos_ENABLE_CUDA_LAMBDA=ON \ + -DKokkos_ENABLE_CUDA_UVM=OFF \ + kokkos +``` + +This compiles Kokkos to include support for OpenMP and CUDA as accelerators. All Kokkos kernels can thus use either of these execution spaces. In this case, each individual unit test is compiled 24 times: once for each possible combination of precision, rank, and execution space. This is visible in the first few lines of output: +``` +[==========] Running 192 tests from 24 test suites. +[----------] Global test environment set-up. +[----------] 8 tests from BareFieldTest/0, where TypeParam = Parameters > +[ RUN ] BareFieldTest/0.DeepCopy +[ OK ] BareFieldTest/0.DeepCopy (0 ms) +[ RUN ] BareFieldTest/0.Sum +[ OK ] BareFieldTest/0.Sum (0 ms) +[ RUN ] BareFieldTest/0.Min +[ OK ] BareFieldTest/0.Min (0 ms) +[ RUN ] BareFieldTest/0.Max +[ OK ] BareFieldTest/0.Max (0 ms) +[ RUN ] BareFieldTest/0.Prod +[ OK ] BareFieldTest/0.Prod (0 ms) +[ RUN ] BareFieldTest/0.ScalarMultiplication +[ OK ] BareFieldTest/0.ScalarMultiplication (0 ms) +[ RUN ] BareFieldTest/0.DotProduct +[ OK ] BareFieldTest/0.DotProduct (0 ms) +[ RUN ] BareFieldTest/0.AllFuncs +[ OK ] BareFieldTest/0.AllFuncs (3 ms) +[----------] 8 tests from BareFieldTest/0 (6 ms total) +``` + +Here, we see that the first configuration for the unit tests is for a 1D field in double precision using OpenMP. In particular, the field data is stored in host memory. Among the other tests, we also have the following configurations: +``` +[----------] 8 tests from BareFieldTest/9, where TypeParam = Parameters > +[----------] 8 tests from BareFieldTest/10, where TypeParam = Parameters > +[----------] 8 tests from BareFieldTest/15, where TypeParam = Parameters > +``` + +The configurations using `Kokkos::Cuda` as the execution space store the field data on GPUs, as one would expect. + +Not all sets of unit tests have the same level of configuration. Data structures that do not involve parallel execution don't have an associated execution space; instantiations of these unit tests are thus independent of the number of Kokkos backends. On the other hand, some data structures can use multiple execution spaces. One example is particle bunches, which can store attributes in different execution spaces. Here, we have the following setup: +```cpp +template +class ParticleBaseTest>> : public ::testing::Test +``` + +Unit tests are instantiated for a particle bunch with the following properties: +- Particles have an attribute of type `T` (which will be `double` or `float`) +- The particle positions have type `T` (controls the precision of the position data) +- The particle positions use the execution space `PositionSpace` +- The particles are identified by IDs, which use the execution space `IDSpace` +- The particle positions are `Dim`-vectors (controls the dimensionality of the particle layout) + +By instantiating unit tests for all possible combinations of execution spaces of multiple components, we can verify not only the correctness of the computations, but also that data is being copied where needed and that data in all execution spaces is being handled correctly. These are some of the test configurations generated for particle bunches using the same Kokkos configuration as the previous example: +``` +... TypeParam = Parameters > +... TypeParam = Parameters > +... TypeParam = Parameters > +... TypeParam = Parameters > +... TypeParam = Parameters > +``` + +# Implementation + +The generation of test configurations is implemented in `unit_tests/TestUtils.h`. It is controlled using the following struct: + +```cpp +template +struct Parameters { ... }; + +struct TestParams { + using Spaces = ippl::detail::TypeForAllSpaces::exec_spaces_type; + using Precisions = std::tuple; + using Combos = CreateCombinations::type; + + template + using Ranks = std::tuple...>; + + template + using CombosWithRanks = typename CreateCombinations>::type; + + template + using tests = typename TestForTypes< + std::conditional_t>>::type; +... +}; +``` + +First, we generate a tuple containing all the available execution spacs (see `Utility/TypeUtils.h`). We then create tuples with the other parameters we want to test. The `CreateCombinations` struct recursively generates all combinations of the chosen parameters at compile time and instantiates the `Parameter` type to hold these combinations. We then use GoogleTest's `testing::Types<...>` to instantiate all the unit tests for each combination. Example: + +```cpp +template +class FieldTest; + +template +class FieldTest>> : public ::testing::Test { ... }; + +using Tests = TestParams::tests<1, 2, 3, 4, 5, 6>; +TYPED_TEST_CASE(FieldTest, Tests); + +TYPED_TEST(FieldTest, DeepCopy) { ... } +``` + +If we want to generate combinations beyond just ranks/precision/execution space like above, we can use the tuple generation with other types. For example, the particle bunch tests use two execution spaces: + +```cpp +template +class ParticleBaseTest; + +template +class ParticleBaseTest>> : public ::testing::Test { ... }; + +using Precisions = TestParams::Precisions; +using Spaces = TestParams::Spaces; +using Ranks = TestParams::Ranks<1, 2, 3, 4, 5, 6>; +using Combos = CreateCombinations::type; +using Tests = TestForTypes::type; +TYPED_TEST_CASE(ParticleBaseTest, Tests); + +TYPED_TEST(ParticleBaseTest, CreateAndDestroy) { ... } +``` + +# Run all Unit tests + +```bash +#!/bin/bash + +for file in `find $1/unit_tests -type f` +do + if [[ -x "$file" ]] + then + $file + fi +done +``` + +The first argument needs to point to the directory were you build ippl. diff --git a/sections/for-developers/workflow/index.qmd b/sections/for-developers/workflow/index.qmd new file mode 100644 index 0000000..5f010ad --- /dev/null +++ b/sections/for-developers/workflow/index.qmd @@ -0,0 +1,58 @@ +# Naming Conventions + +- Variables should use camel casing +- Compile time constants should use capital casing +- Member variables should be suffixed with `_m` + +# Math + +Mathematical constants should be obtained from `Kokkos::numbers` (moved out of `experimental` in Kokkos 4). Any instance of a mathematical function in host-only code should use symbols from the standard library, e.g. `std::sqrt`. Any instances occurring in device-code or code that might be run on a device (such as those marked with `KOKKOS_INLINE_FUNCTION`) should use the symbols from Kokkos, e.g. `Kokkos::sqrt`, to ensure performance and portability on GPUs. + +# Other Formatting Conventions + +IPPL uses `clang-format` for automatic formatting. For explanations of the available settings, refer to the [clang documentation](https://clang.llvm.org/docs/ClangFormatStyleOptions.html). +IPPL's settings are available in the repository root. For more information about the formatting, refer to the workflow below. + +# Automatic Code Formatting + +IPPL uses `clang-format` to automatically format the codebase to maintain a consistent code style. When modifying IPPL, the changes can be reformatted automatically by +using a *git hook*. A git hook is a script that is executed by `git` before completing certain actions. The `hooks/` top-level directory includes a `pre-commit` script and a +shell script for setting up the git hook. Git hooks are stored in `.git/hooks`; the shell script creates a symbolic link in `.git/hooks` pointing to the `pre-commit` script, +effectively creating a pre-commit hook for the local repository. A pre-commit hook is run automatically before every commit. + +The provided script automatically runs `clang-format` on all files with *staged* changes, i.e. files that have been added to the commit, then re-stages these files to include +the reformatted changes in the commit. The result is that, even if the code is not properly formatted when you run `git commit`, the code is automatically reformatted before the +commit is created, so all committed code will always have the proper formatting. + +## Caveats + +- `clang-format` must be available to use the automatic formatting; Beware of the order in which modules are loaded, as the presence of `clang` can affect project configuration. + If you newly configure a project and `clang` has higher priority in your `$PATH` than `gcc` (or another desired compiler), the project may become configured to compile with clang + instead of your desired compiler. In general, it is advisable to only load the clang module once the project is configured, or to load clang before your desired compiler such + that it has lower priority in your `$PATH`. +- To avoid misconfigurations due to the Clang module, a simple workaround is to create a symbolic link to `clang-format` in a folder that is always in your `$PATH`. + To locate `clang-format`, run `which clang-format` while the module is loaded. Create a symbolic link with `ln -s "$(which clang-format)" /path/to/link`, where `/path/to` is + included in your `$PATH`. Conventional paths include `~/.local/bin` (this folder may need to be created). If this is not already in your `$PATH`, you can modify + your `~/.bash_profile` to add this to your path: `PATH=$PATH:~/.local/bin`. +- The pre-commit script always reformats and re-stages *entire* files. If you used `git add -i` to only stage a subset of the changes in a file, the pre-commit script will + render the interactive staging moot by staging the entire file. To prevent this, use the `--no-verify` flag when committing; this makes `git` skip the pre-commit script. Note that + this means that your changes will not be reformatted before committing. If you would like to commit only a subset of the changes made to a file but still want to run the formatter, + you can stash the changes you don't want to commit by stashing in patch mode (`git stash save -p`) and shelving the other changes. After committing, run `git stash pop` to restore + the uncommitted changes. +- The pre-commit script only reformats *staged* files. It does not affect unstaged or unmodified files. To reformat unchanged files, you will have to run the formatter manually. + This is also true if you stage a subset of modified files; the staged files will be reformatted, but unstaged files will not be reformatted even if they have modifications. + +Refer to our git introduction if the git-related terms on this page are unclear. + +# Git brief introduction + +For those in need of a refresher or an introduction, here is a glossary of Git terms relevant to the workflow caveats, as well as some useful commands and flags: + +- A file is *tracked* if it is under version control. A file that has never been committed is *untracked* and will show up under "untracked files" when running `git status`. +- Files whose names match patterns in a `.gitignore` file will be ignored by git and do not show up as untracked. To start tracking an ignored file, use the `-f` flag when staging it. +- The *working tree* is the current state of the repository, excluding untracked files. Changes to the working tree are shown by `git diff`. +- Before committing, changes have to be *staged*. This is done by running `git add` to stage the changes that need to be committed. You can view the staged changes using `git diff --staged`. This represents the changes that will be recorded by running `git commit`. +- You can stage any subset of the changes to the working tree. You can also stage only a subset of changes to a file by using *interactive staging* with `git add -i` and choosing "patch" at the interactive prompt. +- A *commit* is a set of changes that constitute a fixed point in the repository history. Running `git commit` creates a new commit out of the staged changes. Unstaged changes are untouched. + + diff --git a/sections/getting-started/index.qmd b/sections/getting-started/hello-ippl/index.qmd similarity index 97% rename from sections/getting-started/index.qmd rename to sections/getting-started/hello-ippl/index.qmd index 86ed2ee..a48fc9a 100644 --- a/sections/getting-started/index.qmd +++ b/sections/getting-started/hello-ippl/index.qmd @@ -1,4 +1,5 @@ -# Getting Started {#sec-getting-started} +# Hello IPPL {#sec-getting-started} + IPPL is configured with CMake. A minimal build needs a C++20 compiler, MPI, and Kokkos. FFT and solver chapters require builds with `IPPL_ENABLE_FFT=ON` and usually `IPPL_ENABLE_SOLVERS=ON`, but the first program does not need that stack. diff --git a/sections/getting-started/installation/index.qmd b/sections/getting-started/installation/index.qmd new file mode 100644 index 0000000..ffa05e0 --- /dev/null +++ b/sections/getting-started/installation/index.qmd @@ -0,0 +1,250 @@ +# Installation {#sec-installation} +All the new developments of IPPL are merged into the `master` branch which can make it potentially unstable from time to time. So if you want a stable and more tested version +please checkout the tagged branch corresponding to the latest release (e.g. `git checkout tags/IPPL-x.x.x`). Otherwise if you want the latest developments go with the master with the above caveat in mind. + +## Requirements + +* [CMake](https://cmake.org/download/) +* A C++ compilation toolchain (GPU-capable for GPU builds, e.g. [nvcc](https://developer.nvidia.com/cuda-downloads), [clang]() or [rocmcc](https://rocm.docs.amd.com/en/docs-5.0.2/reference/rocmcc/rocmcc.html)) +* MPI (GPU-aware if building for GPUs) + +### Optional requirements +* FFTW +* CuFFT + +## Compilation +IPPL is a CMake Project and can be configured by passing options in CMake syntax: +``` +cmake -D