diff --git a/.github/workflows/continuousIntegration.yml b/.github/workflows/continuousIntegration.yml index 93608fe..7720371 100644 --- a/.github/workflows/continuousIntegration.yml +++ b/.github/workflows/continuousIntegration.yml @@ -13,18 +13,18 @@ concurrency: jobs: get_docker_image_tag_hash: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: DOCKER_IMAGE_TAG_HASH: ${{ steps.extract_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} steps: - name: Extract docker image tag hash id: extract_docker_image_tag_hash run: | - echo "DOCKER_IMAGE_TAG_HASH=b838c3153fadcfd4cd37e4859a4b172581e08417" >> "$GITHUB_OUTPUT" + echo "DOCKER_IMAGE_TAG_HASH=8222ff90b7e0083101204ce7f2c476ec23785a03" >> "$GITHUB_OUTPUT" # code_style: # needs: [check_pull_request_is_not_a_draft] - # runs-on: ubuntu-22.04 + # runs-on: ubuntu-24.04 # steps: # - name: Checkout Repository # uses: actions/checkout@v4.1.6 @@ -39,7 +39,7 @@ jobs: # run: ./scripts/ci_build_and_test.sh doxygen_check: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: - get_docker_image_tag_hash steps: @@ -50,7 +50,7 @@ jobs: lfs: false - name: Check doxygen env: - DOCKER_REPOSITORY: geosx/ubuntu:22.04-${{ needs.get_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang-${{ needs.get_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} HOST_CONFIG: hostconfigs/environment.cmake CMAKE_CXX_COMPILER: /usr/bin/clang++ CMAKE_C_COMPILER: /usr/bin/clang @@ -60,7 +60,7 @@ jobs: code_checks: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: - get_docker_image_tag_hash steps: @@ -71,7 +71,7 @@ jobs: lfs: false - name: code_checks env: - DOCKER_REPOSITORY: geosx/ubuntu:22.04-${{ needs.get_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang-${{ needs.get_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} HOST_CONFIG: hostconfigs/environment.cmake CMAKE_CXX_COMPILER: /usr/bin/clang++ CMAKE_C_COMPILER: /usr/bin/clang @@ -89,127 +89,105 @@ jobs: fail-fast: false matrix: include: - # - name: RHEL8.10-clang17-dbg (ubi8.10, clang-17.0.6, Debug) - # DOCKER_REPOSITORY: geosx/ubi:8.10 - # RUNS_ON: ubuntu-22.04 - # CMAKE_CXX_COMPILER: clang++ - # CMAKE_C_COMPILER: clang - # CMAKE_BUILD_TYPE: Debug + - name: rocky-gcc-dbg (rockylinux8, gcc 14, Release) + DOCKER_REPOSITORY: geosx/rockylinux:8-gcc + RUNS_ON: ubuntu-24.04 + CMAKE_CXX_COMPILER: /opt/rh/gcc-toolset-13/root/usr/bin/g++ + CMAKE_C_COMPILER: /opt/rh/gcc-toolset-13/root/usr/bin/gcc + CMAKE_BUILD_TYPE: Debug - # - name: RHEL8.10-clang17-rel (ubi8.10, clang-17.0.6, Release) - # DOCKER_REPOSITORY: geosx/ubi:8.10 - # RUNS_ON: ubuntu-22.04 - # CMAKE_CXX_COMPILER: clang++ - # CMAKE_C_COMPILER: clang - # CMAKE_BUILD_TYPE: Release + - name: rocky-gcc-rel (rockylinux8, gcc 14, Release) + DOCKER_REPOSITORY: geosx/rockylinux:8-gcc + RUNS_ON: ubuntu-24.04 + CMAKE_CXX_COMPILER: /opt/rh/gcc-toolset-13/root/usr/bin/g++ + CMAKE_C_COMPILER: /opt/rh/gcc-toolset-13/root/usr/bin/gcc + CMAKE_BUILD_TYPE: Release - # - name: RHEL8.10-gcc13-dbg (ubi8.10, gcc 13.2.1, Debug) - # DOCKER_REPOSITORY: geosx/ubi:8.10 - # RUNS_ON: ubuntu-22.04 - # CMAKE_CXX_COMPILER: /opt/rh/gcc-toolset-13/root/bin/g++ - # CMAKE_C_COMPILER: /opt/rh/gcc-toolset-13/root/bin/gcc - # CMAKE_BUILD_TYPE: Debug + - name: rocky-clang-dbg (rockylinux8, clang-15, Debug) + DOCKER_REPOSITORY: geosx/rockylinux:8-clang + RUNS_ON: ubuntu-24.04 + CMAKE_CXX_COMPILER: /usr/bin/clang++ + CMAKE_C_COMPILER: /usr/bin/clang + CMAKE_BUILD_TYPE: Debug - # - name: RHEL8.10-gcc13-rel (ubi8.10, gcc 13.2.1, Release) - # DOCKER_REPOSITORY: geosx/ubi:8.10 - # RUNS_ON: ubuntu-22.04 - # CMAKE_CXX_COMPILER: /opt/rh/gcc-toolset-13/root/bin/g++ - # CMAKE_C_COMPILER: /opt/rh/gcc-toolset-13/root/bin/gcc - # CMAKE_BUILD_TYPE: Release + - name: rocky-clang-rel (rockylinux8, clang-15, Release) + DOCKER_REPOSITORY: geosx/rockylinux:8-clang + RUNS_ON: ubuntu-24.04 + CMAKE_CXX_COMPILER: /usr/bin/clang++ + CMAKE_C_COMPILER: /usr/bin/clang + CMAKE_BUILD_TYPE: Release - - name: ubuntu22-gcc11-dbg (ubuntu-22, gcc 11.4.0, Release) - DOCKER_REPOSITORY: geosx/ubuntu:22.04 - RUNS_ON: ubuntu-22.04 + - name: ubuntu24-gcc11-dbg (ubuntu-24, gcc 11.4.0, Release) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-gcc + RUNS_ON: ubuntu-24.04 CMAKE_CXX_COMPILER: /usr/bin/g++ CMAKE_C_COMPILER: /usr/bin/gcc CMAKE_BUILD_TYPE: Debug - - name: ubuntu22-gcc11-rel (ubuntu-22, gcc 11.4.0, Release) - DOCKER_REPOSITORY: geosx/ubuntu:22.04 - RUNS_ON: ubuntu-22.04 + - name: ubuntu24-gcc11-rel (ubuntu-24, gcc 11.4.0, Release) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-gcc + RUNS_ON: ubuntu-24.04 CMAKE_CXX_COMPILER: /usr/bin/g++ CMAKE_C_COMPILER: /usr/bin/gcc CMAKE_BUILD_TYPE: Release - - name: ubuntu22-clang14-dbg (ubuntu-22, clang-14.0.0, Debug) - DOCKER_REPOSITORY: geosx/ubuntu:22.04 - RUNS_ON: ubuntu-22.04 + - name: ubuntu24-clang18-dbg (ubuntu-24, clang-18.0.0, Debug) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang + RUNS_ON: ubuntu-24.04 CMAKE_CXX_COMPILER: /usr/bin/clang++ CMAKE_C_COMPILER: /usr/bin/clang CMAKE_BUILD_TYPE: Debug - - name: ubuntu22-clang14-rel (ubuntu-22, clang-14.0.0, Release) - DOCKER_REPOSITORY: geosx/ubuntu:22.04 - RUNS_ON: ubuntu-22.04 + - name: ubuntu24-clang18-rel (ubuntu-24, clang-18.0.0, Release) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang + RUNS_ON: ubuntu-24.04 CMAKE_CXX_COMPILER: /usr/bin/clang++ CMAKE_C_COMPILER: /usr/bin/clang CMAKE_BUILD_TYPE: Release - # - name: ubuntu22-gcc11-cuda11-rel (ubuntu-22, gcc 11.4.0, cuda-11.8.0, Release) - # DOCKER_REPOSITORY: geosx/ubuntu:22.04-cuda11.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: /usr/bin/g++ - # CMAKE_C_COMPILER: /usr/bin/gcc - # CMAKE_BUILD_TYPE: Release - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" - - # - name: ubuntu22-gcc11-cuda11-dbg (ubuntu-22, gcc 11.4.0, cuda-11.8.0, Debug) - # DOCKER_REPOSITORY: geosx/ubuntu:22.04-cuda11.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: /usr/bin/g++ - # CMAKE_C_COMPILER: /usr/bin/gcc - # CMAKE_BUILD_TYPE: Debug - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" - - # - name: ubuntu22-clang14-cuda11-rel (ubuntu-22, clang-14.0.0, cuda-11.8.0, Release) - # DOCKER_REPOSITORY: geosx/ubuntu:22.04-cuda11.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: /usr/bin/clang++ - # CMAKE_C_COMPILER: /usr/bin/clang - # CMAKE_BUILD_TYPE: Release - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" + - name: ubuntu24-gcc11-cuda12-rel (ubuntu-24, gcc 11.4.0, cuda-12.9.1, Release) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-gcc-cuda12.9 + RUNS_ON: streak2 + CMAKE_CXX_COMPILER: /usr/bin/g++ + CMAKE_C_COMPILER: /usr/bin/gcc + CMAKE_BUILD_TYPE: Release + ENABLE_CUDA: ON + CMAKE_CUDA_ARCHITECTURES: "86" + NPROC: 4 + DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" - # - name: ubuntu22-clang14-cuda11-dbg (ubuntu-22, clang-14.0.0, cuda-11.8.0, Debug) - # DOCKER_REPOSITORY: geosx/ubuntu:22.04-cuda11.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: /usr/bin/clang++ - # CMAKE_C_COMPILER: /usr/bin/clang - # CMAKE_BUILD_TYPE: Debug - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" + - name: ubuntu24-gcc11-cuda12-dbg (ubuntu-24, gcc 11.4.0, cuda-12.9.1, Debug) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-gcc-cuda12.9 + RUNS_ON: streak2 + CMAKE_CXX_COMPILER: /usr/bin/g++ + CMAKE_C_COMPILER: /usr/bin/gcc + CMAKE_BUILD_TYPE: Debug + ENABLE_CUDA: ON + CMAKE_CUDA_ARCHITECTURES: "86" + NPROC: 4 + DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" - # - name: RHEL8.10-clang17-cuda12-rel (ubi8.10, clang-17.0.6, cuda-12.4.1, Release) - # DOCKER_REPOSITORY: geosx/ubi:8.10-cuda12.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: clang++ - # CMAKE_C_COMPILER: clang - # CMAKE_BUILD_TYPE: Release - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" + - name: ubuntu24-clang14-cuda12-rel (ubuntu-24, clang-14.0.0, cuda-12.9.1, Release) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang-cuda12.9 + RUNS_ON: streak2 + CMAKE_CXX_COMPILER: /usr/bin/clang++ + CMAKE_C_COMPILER: /usr/bin/clang + CMAKE_BUILD_TYPE: Release + ENABLE_CUDA: ON + CMAKE_CUDA_ARCHITECTURES: "86" + NPROC: 4 + DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" - # - name: RHEL8.10-gcc13-cuda12-rel (ubi8.10, gcc 13.2.1, cuda-12.4.1, Release) - # DOCKER_REPOSITORY: geosx/ubi:8.10-cuda12.8 - # RUNS_ON: streak2 - # CMAKE_CXX_COMPILER: /opt/rh/gcc-toolset-13/root/bin/g++ - # CMAKE_C_COMPILER: /opt/rh/gcc-toolset-13/root/bin/gcc - # CMAKE_BUILD_TYPE: Release - # ENABLE_CUDA: ON - # CMAKE_CUDA_ARCHITECTURES: "86" - # NPROC: 4 - # DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" + - name: ubuntu24-clang14-cuda12-dbg (ubuntu-24, clang-14.0.0, cuda-12.9.1, Debug) + DOCKER_REPOSITORY: geosx/ubuntu:24.04-clang-cuda12.9 + RUNS_ON: streak2 + CMAKE_CXX_COMPILER: /usr/bin/clang++ + CMAKE_C_COMPILER: /usr/bin/clang + CMAKE_BUILD_TYPE: Debug + ENABLE_CUDA: ON + CMAKE_CUDA_ARCHITECTURES: "86" + NPROC: 4 + DOCKER_RUN_ARGS: "--cpus=4 --memory=64g --runtime=nvidia --gpus all" steps: - name: Checkout Repository @@ -247,7 +225,7 @@ jobs: lfs: false - name: run code coverage env: - DOCKER_REPOSITORY: geosx/ubuntu:22.04-${{ needs.get_docker_image_tag_hash.outputs.DOCKER_IMAGE_TAG_HASH }} + DOCKER_REPOSITORY: geosx/ubuntu:22.04-b838c3153fadcfd4cd37e4859a4b172581e08417 HOST_CONFIG: hostconfigs/environment.cmake CMAKE_CXX_COMPILER: /usr/bin/g++ CMAKE_C_COMPILER: /usr/bin/gcc @@ -264,7 +242,7 @@ jobs: check_that_all_jobs_succeeded: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: - get_docker_image_tag_hash - linux_builds diff --git a/CMakeLists.txt b/CMakeLists.txt index 21042db..06a59d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,9 @@ if( NOT is_submodule ) set( BLT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/cmake/blt CACHE PATH "" ) set( BLT_CXX_STD "c++17" CACHE STRING "Version of C++ standard" FORCE ) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CUDA_STANDARD_REQUIRED ON) + set( ENABLE_WARNINGS_AS_ERRORS "ON" CACHE PATH "" ) option( HPCREACT_ENABLE_UNIT_TESTS "Builds tests" ON ) diff --git a/cmake/CMakeBasics.cmake b/cmake/CMakeBasics.cmake index 8ddca0a..4faf2a2 100644 --- a/cmake/CMakeBasics.cmake +++ b/cmake/CMakeBasics.cmake @@ -26,4 +26,10 @@ blt_append_custom_compiler_flag( FLAGS_VAR CMAKE_CXX_FLAGS_DEBUG CLANG "-fstandalone-debug" ) +if( ENABLE_COVERAGE ) + blt_append_custom_compiler_flag( FLAGS_VAR CMAKE_CXX_FLAGS_DEBUG + GNU "-O0 -fno-inline -fno-inline-functions -fno-inline-functions-called-once" + ) +endif() + set( CAMP_ENABLE_TESTS OFF CACHE BOOL "") diff --git a/cmake/blt b/cmake/blt index 5468efd..fe075e5 160000 --- a/cmake/blt +++ b/cmake/blt @@ -1 +1 @@ -Subproject commit 5468efd7d8c00e6ce4a18af187f66e6669ff1aae +Subproject commit fe075e596c5fde30acbe4e05f40baaf0a258ff54 diff --git a/hostconfigs/LLNL/dane-toss_4_x86_64_ib-clang@19.1.3.cmake b/hostconfigs/LLNL/dane-toss_4_x86_64_ib-clang@19.1.3.cmake new file mode 100644 index 0000000..b18f9a8 --- /dev/null +++ b/hostconfigs/LLNL/dane-toss_4_x86_64_ib-clang@19.1.3.cmake @@ -0,0 +1,57 @@ +################################################################################# +# Generated host-config - Edit at own risk! +################################################################################# +#-------------------------------------------------------------------------------- +# SYS_TYPE: toss_4_x86_64_ib +# Compiler Spec: clang@=19.1.3 +# CMake executable path: /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-10.3.1/cmake-3.26.3-nz532rvfpaf5lf74zxmplgiobuhol7lu/bin/cmake +#-------------------------------------------------------------------------------- + +#-------------------------------------------------------------------------------- +# Compilers +#-------------------------------------------------------------------------------- + +set(CMAKE_C_COMPILER "/usr/tce/packages/clang/clang-19.1.3-magic/bin/clang" CACHE PATH "") + +set(CMAKE_CXX_COMPILER "/usr/tce/packages/clang/clang-19.1.3-magic/bin/clang++" CACHE PATH "") + +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native -mtune=native" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE STRING "") + +#-------------------------------------------------------------------------------- +# CMake Standard +#-------------------------------------------------------------------------------- + +set(BLT_CXX_STD "c++17" CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# OpenMP +#-------------------------------------------------------------------------------- + +set(ENABLE_OPENMP ON CACHE BOOL "") + +#-------------------------------------------------------------------------------- +# Cuda +#-------------------------------------------------------------------------------- + +set(ENABLE_CUDA OFF CACHE BOOL "") + +#-------------------------------------------------------------------------------- +# System Math Libraries +#-------------------------------------------------------------------------------- + +set(ENABLE_MKL ON CACHE BOOL "") + +set(MKL_INCLUDE_DIRS "/usr/tce/packages/mkl/mkl-2022.1.0/include" CACHE PATH "") + +set(MKL_LIBRARIES /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_intel_lp64.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_gnu_thread.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_core.so + /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-13.3.1/llvm-19.1.3-gy2lu5xbi4csr2k47emlajzfs5mlsd4g/bin/../lib/x86_64-unknown-linux-gnu/libomp.so + /lib64/libpthread.so + /lib64/libm.so + /lib64/libdl.so CACHE STRING "") \ No newline at end of file diff --git a/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-clang@19.1.7-cuda@12.9.1.cmake b/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-clang@19.1.7-cuda@12.9.1.cmake new file mode 100644 index 0000000..5351390 --- /dev/null +++ b/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-clang@19.1.7-cuda@12.9.1.cmake @@ -0,0 +1,83 @@ +################################################################################# +# Generated host-config - Edit at own risk! +################################################################################# +#-------------------------------------------------------------------------------- +# SYS_TYPE: toss_4_x86_64_ib +# Compiler Spec: gcc@=13.3.1 +# CMake executable path: /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-10.3.1/cmake-3.26.3-nz532rvfpaf5lf74zxmplgiobuhol7lu/bin/cmake +#-------------------------------------------------------------------------------- + +#-------------------------------------------------------------------------------- +# Compilers +#-------------------------------------------------------------------------------- + +set(CMAKE_C_COMPILER "/usr/tce/packages/clang-tce/clang-19.1.3/bin/clang" CACHE PATH "") + +set(CMAKE_CXX_COMPILER "/usr/tce/packages/clang-tce/clang-19.1.3/bin/clang++" CACHE PATH "") + +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE STRING "") + +#-------------------------------------------------------------------------------- +# CMake Standard +#-------------------------------------------------------------------------------- + +set(BLT_CXX_STD "c++17" CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# Cuda +#-------------------------------------------------------------------------------- + +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CMAKE_CUDA_STANDARD "17" CACHE PATH "") + +set(CUDA_TOOLKIT_ROOT_DIR "/usr/tce/packages/cuda/cuda-12.9.1" CACHE PATH "") + +set(CMAKE_CUDA_COMPILER "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" CACHE PATH "") + +set(CMAKE_CUDA_ARCHITECTURES "90" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS "-restrict --expt-extended-lambda -Werror cross-execution-space-call,reorder,deprecated-declarations -arch sm_90" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS_RELWITHDEBINFO "-g -lineinfo ${CMAKE_CUDA_FLAGS_RELEASE}" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS_DEBUG "-g -G -O0 -Xcompiler -O0" CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# System Math Libraries +#-------------------------------------------------------------------------------- + +set(ENABLE_MKL ON CACHE BOOL "") + +set(MKL_INCLUDE_DIRS "/usr/tce/packages/mkl/mkl-2022.1.0/include" CACHE PATH "") + +set(MKL_LIBRARIES /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_intel_lp64.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_gnu_thread.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_core.so + /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-13.3.1/llvm-19.1.3-gy2lu5xbi4csr2k47emlajzfs5mlsd4g/bin/../lib/x86_64-unknown-linux-gnu/libomp.so + /lib64/libpthread.so + /lib64/libm.so + /lib64/libdl.so CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# Documentation +#-------------------------------------------------------------------------------- + +set(ENABLE_DOCS OFF CACHE BOOL "") + +set(ENABLE_DOXYGEN OFF CACHE BOOL "") + +set(ENABLE_SPHINX OFF CACHE BOOL "") + +#-------------------------------------------------------------------------------- +# Development tools +#-------------------------------------------------------------------------------- + +set(ENABLE_UNCRUSTIFY OFF CACHE BOOL "") diff --git a/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-gcc@13.3.1-cuda@12.9.1.cmake b/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-gcc@13.3.1-cuda@12.9.1.cmake new file mode 100644 index 0000000..8d24a73 --- /dev/null +++ b/hostconfigs/LLNL/matrix-toss_4_x86_64_ib-gcc@13.3.1-cuda@12.9.1.cmake @@ -0,0 +1,83 @@ +################################################################################# +# Generated host-config - Edit at own risk! +################################################################################# +#-------------------------------------------------------------------------------- +# SYS_TYPE: toss_4_x86_64_ib +# Compiler Spec: gcc@=13.3.1 +# CMake executable path: /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-10.3.1/cmake-3.26.3-nz532rvfpaf5lf74zxmplgiobuhol7lu/bin/cmake +#-------------------------------------------------------------------------------- + +#-------------------------------------------------------------------------------- +# Compilers +#-------------------------------------------------------------------------------- + +set(CMAKE_C_COMPILER "/usr/tce/packages/gcc/gcc-13.3.1-magic/bin/gcc" CACHE PATH "") + +set(CMAKE_CXX_COMPILER "/usr/tce/packages/gcc/gcc-13.3.1-magic/bin/g++" CACHE PATH "") + +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG" CACHE STRING "") + +set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE STRING "") + +#-------------------------------------------------------------------------------- +# CMake Standard +#-------------------------------------------------------------------------------- + +set(BLT_CXX_STD "c++17" CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# Cuda +#-------------------------------------------------------------------------------- + +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CMAKE_CUDA_STANDARD "17" CACHE PATH "") + +set(CUDA_TOOLKIT_ROOT_DIR "/usr/tce/packages/cuda/cuda-12.9.1" CACHE PATH "") + +set(CMAKE_CUDA_COMPILER "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" CACHE PATH "") + +set(CMAKE_CUDA_ARCHITECTURES "90" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS "-restrict --expt-extended-lambda -Werror cross-execution-space-call,reorder,deprecated-declarations -arch sm_90" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS_RELWITHDEBINFO "-g -lineinfo ${CMAKE_CUDA_FLAGS_RELEASE}" CACHE STRING "") + +set(CMAKE_CUDA_FLAGS_DEBUG "-g -G -O0 -Xcompiler -O0" CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# System Math Libraries +#-------------------------------------------------------------------------------- + +set(ENABLE_MKL ON CACHE BOOL "") + +set(MKL_INCLUDE_DIRS "/usr/tce/packages/mkl/mkl-2022.1.0/include" CACHE PATH "") + +set(MKL_LIBRARIES /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_intel_lp64.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_gnu_thread.so + /usr/tce/packages/mkl/mkl-2022.1.0/mkl/2022.1.0/lib/intel64/libmkl_core.so + /usr/tce/backend/installations/linux-rhel8-x86_64/gcc-13.3.1/llvm-19.1.3-gy2lu5xbi4csr2k47emlajzfs5mlsd4g/bin/../lib/x86_64-unknown-linux-gnu/libomp.so + /lib64/libpthread.so + /lib64/libm.so + /lib64/libdl.so CACHE STRING "") + + +#-------------------------------------------------------------------------------- +# Documentation +#-------------------------------------------------------------------------------- + +set(ENABLE_DOCS OFF CACHE BOOL "") + +set(ENABLE_DOXYGEN OFF CACHE BOOL "") + +set(ENABLE_SPHINX OFF CACHE BOOL "") + +#-------------------------------------------------------------------------------- +# Development tools +#-------------------------------------------------------------------------------- + +set(ENABLE_UNCRUSTIFY OFF CACHE BOOL "") diff --git a/scripts/ci_build_and_test.sh b/scripts/ci_build_and_test.sh index 20481ca..985cbdc 100755 --- a/scripts/ci_build_and_test.sh +++ b/scripts/ci_build_and_test.sh @@ -14,6 +14,11 @@ fi # but that would not have solved the problem for the TPLs (we would require extra action to copy them to the mount point). CONTAINER_NAME=hpcReact_build +set -x +cat /etc/docker/daemon.json || echo "no mirror configured" +docker info | grep -A2 Registry +docker pull registry-1.docker.io/${DOCKER_REPOSITORY} + docker run \ --rm \ --volume=${BUILD_DIR}:${BUILD_DIR_MOUNT_POINT} \ diff --git a/scripts/ci_build_and_test_in_container.sh b/scripts/ci_build_and_test_in_container.sh index aebc48c..c46e367 100755 --- a/scripts/ci_build_and_test_in_container.sh +++ b/scripts/ci_build_and_test_in_container.sh @@ -3,28 +3,47 @@ env if [ -f /etc/os-release ]; then - . /etc/os-release - if [[ "$ID" == "ubuntu" || "$ID_LIKE" == "debian" ]]; then - PACKAGE_MANAGER="apt" - elif [[ "$ID" == "rhel" || "$ID_LIKE" == "rhel fedora rocky centos" ]]; then - PACKAGE_MANAGER="yum" - else - echo "Unsupported OS: $ID" - exit 1 - fi + . /etc/os-release + if [[ "$ID" == "ubuntu" ]]; then + PACKAGE_MANAGER="apt" + elif [[ "$ID" == "rocky" ]]; then + PACKAGE_MANAGER="yum" + else + echo "Unsupported OS: $ID" + exit 1 + fi else - echo "/etc/os-release not found. Unable to determine OS." - exit 1 + echo "/etc/os-release not found. Unable to determine OS." + exit 1 fi -echo "Using package manager: $PACKAGE_MANAGER" -if [ "$PACKAGE_MANAGER" == "apt" ]; then - apt update && apt-get install -y libblas-dev liblapack-dev texlive-full -elif [ "$PACKAGE_MANAGER" == "yum" ]; then - yum update && yum install -y blas lapack +if [ -f /usr/lib64/libblas.so.3 ]; then + BLAS_LIB=/usr/lib64/libblas.so.3 + LAPACK_LIB=/usr/lib64/liblapack.so.3 +elif [ -f /usr/lib/x86_64-linux-gnu/libblas.so ]; then + BLAS_LIB=/usr/lib/x86_64-linux-gnu/libblas.so + LAPACK_LIB=/usr/lib/x86_64-linux-gnu/liblapack.so +else + echo "BLAS/LAPACK not found"; + + echo "Using package manager: $PACKAGE_MANAGER" + + if [ "$PACKAGE_MANAGER" == "apt" ]; then + apt update && apt-get install -y libblas-dev liblapack-dev + elif [ "$PACKAGE_MANAGER" == "yum" ]; then + yum update && yum install -y blas lapack + fi + fi + + + + + + + # The or_die function run the passed command line and # exits the program in case of non zero error code function or_die () { @@ -62,7 +81,9 @@ or_die python3 scripts/config-build.py \ -hc ${HOST_CONFIG} \ -bt ${CMAKE_BUILD_TYPE} \ -bp ${HPCREACT_BUILD_DIR} \ - -ip ${HPCREACT_INSTALL_DIR}\ + -ip ${HPCREACT_INSTALL_DIR} \ + -DBLAS_LIBRARIES=${BLAS_LIB} \ + -DLAPACK_LIBRARIES=${LAPACK_LIB} \ -DENABLE_COVERAGE:BOOL=${ENABLE_COVERAGE} or_die cd ${HPCREACT_BUILD_DIR} @@ -75,6 +96,13 @@ fi # Documentation check if [[ "$*" == *--test-doxygen* ]]; then + + if [ "$PACKAGE_MANAGER" == "apt" ]; then + apt update && apt-get install -y texlive-full + elif [ "$PACKAGE_MANAGER" == "yum" ]; then + yum update && yum install -y texlive + fi + or_die ctest --output-on-failure -R "testDoxygenCheck" exit 0 fi @@ -89,13 +117,13 @@ fi if [[ "$*" == *--code-coverage* ]]; then or_die make -j ${NPROC} VERBOSE=1 - or_die make hpcReact_coverage + or_die make hpcReact_coverage VERBOSE=1 cp -r ${HPCREACT_BUILD_DIR}/hpcReact_coverage.info.cleaned /tmp/hpcReact/hpcReact_coverage.info.cleaned fi if [[ "$*" == *--build-exe* ]]; then - or_die make -j ${NPROC} + or_die make -j ${NPROC} VERBOSE=1 if [[ "$*" != *--disable-unit-tests* ]]; then or_die ctest --output-on-failure -E "testUncrustifyCheck|testDoxygenCheck|testCppCheck|testClangTidy" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00821d0..096ba7c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,15 +26,16 @@ set( hpcReact_sources) find_package(LAPACK REQUIRED) find_package(BLAS REQUIRED) - - -#target_link_libraries(MyExecutable PRIVATE LAPACK::LAPACK) -set( hpcReack_dependencies +set( hpcReact_dependencies LAPACK::LAPACK BLAS::BLAS ) +if( ENABLE_CUDA ) + list( APPEND hpcReact_dependencies cuda ) +endif() + blt_add_library( NAME hpcReact # SOURCES ${hpcReact_sources} HEADERS ${hpcReact_headers} diff --git a/src/common/CArrayWrapper.hpp b/src/common/CArrayWrapper.hpp index f33c51b..5fd6674 100644 --- a/src/common/CArrayWrapper.hpp +++ b/src/common/CArrayWrapper.hpp @@ -53,6 +53,7 @@ struct CArrayWrapper< T, DIM0 > * * @note No runtime bounds checking is performed on the initializer size. */ + HPCREACT_HOST_DEVICE constexpr CArrayWrapper( std::initializer_list< T > init ) { // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20 @@ -66,6 +67,7 @@ struct CArrayWrapper< T, DIM0 > * @brief Copy constructor. * @param src The source CArrayWrapper to copy from. */ + HPCREACT_HOST_DEVICE constexpr CArrayWrapper( CArrayWrapper const & src ) { for( std::size_t i = 0; i < DIM0; i++ ) @@ -79,6 +81,7 @@ struct CArrayWrapper< T, DIM0 > * @param dim The index (must be in range [0, DIM0)). * @return Reference to the element at the specified index. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T & operator()( int const dim ) { return data[dim]; } /** @@ -86,6 +89,7 @@ struct CArrayWrapper< T, DIM0 > * @param dim The index (must be in range [0, DIM0)). * @return Const reference to the element at the specified index. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const & operator()( int const dim ) const { return data[dim]; } /** @@ -93,6 +97,7 @@ struct CArrayWrapper< T, DIM0 > * @param dim The index (must be in range [0, DIM0)). * @return Reference to the element at the specified index. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T & operator[]( int const dim ) { return data[dim]; } /** @@ -100,6 +105,7 @@ struct CArrayWrapper< T, DIM0 > * @param dim The index (must be in range [0, DIM0)). * @return Const reference to the element at the specified index. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const & operator[]( int const dim ) const { return data[dim]; } /// The underlying 1D C-style array. @@ -126,6 +132,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * @brief Copy constructor. * @param src The source CArrayWrapper to copy from. */ + HPCREACT_HOST_DEVICE constexpr CArrayWrapper( CArrayWrapper const & src ) { for( std::size_t i = 0; i < DIM0; i++ ) @@ -150,6 +157,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * * @note No runtime bounds checking is performed on the initializer dimensions. */ + HPCREACT_HOST_DEVICE constexpr CArrayWrapper( std::initializer_list< std::initializer_list< T > > init ) { // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20 @@ -172,6 +180,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * @param dim1 Index in the second dimension (range [0, DIM1)). * @return Reference to the element at the specified 2D location. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T & operator()( int const dim0, int const dim1 ) { return data[dim0][dim1]; @@ -183,6 +192,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * @param dim1 Index in the second dimension (range [0, DIM1)). * @return Const reference to the element at the specified 2D location. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const & operator()( int const dim0, int const dim1 ) const { return data[dim0][dim1]; @@ -195,6 +205,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * * This allows usage like `obj[dim0][dim1]`. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T ( & operator[]( int const dim0 ))[DIM1] { return data[dim0]; @@ -205,6 +216,7 @@ struct CArrayWrapper< T, DIM0, DIM1 > * @param dim0 The row index (range [0, DIM0)). * @return Const reference to an array of type T[DIM1]. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const (&operator[]( int const dim0 ) const)[DIM1] { return data[dim0]; @@ -254,6 +266,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 > * @note This constructor does not perform size validation. Incorrect initializer sizes * may lead to undefined behavior. */ + HPCREACT_HOST_DEVICE constexpr CArrayWrapper( std::initializer_list< std::initializer_list< std::initializer_list< T > > > init ) { // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20 @@ -286,6 +299,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 > * @note Currently, this function incorrectly indexes data[dim0][dim1], missing dim2. * It should be `data[dim0][dim1][dim2]`. Please correct if intended. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T & operator()( int const dim0, int const dim1, int const dim2 ) { // NOTE: This looks like a bug in your original code. Should be data[dim0][dim1][dim2]. @@ -299,6 +313,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 > * @param dim2 Index in the third dimension (range [0, DIM2)). * @return Const reference to the element at the specified 3D location. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const & operator()( int const dim0, int const dim1, int const dim2 ) const { // NOTE: Same potential bug as above. Should be data[dim0][dim1][dim2]. @@ -312,6 +327,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 > * * This allows usage like `obj[dim0][dim1][dim2]`. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T ( & operator[]( int const dim0 ))[DIM1][DIM2] { return data[dim0]; @@ -322,6 +338,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 > * @param dim0 The slice index (range [0, DIM0)). * @return Const reference to an array of type T[DIM1][DIM2]. */ + HPCREACT_HOST_DEVICE constexpr HPCREACT_HOST_DEVICE inline T const (&operator[]( int const dim0 ) const)[DIM1][DIM2] { return data[dim0]; diff --git a/src/common/DirectSystemSolve.hpp b/src/common/DirectSystemSolve.hpp index b1c8d4b..3329829 100644 --- a/src/common/DirectSystemSolve.hpp +++ b/src/common/DirectSystemSolve.hpp @@ -13,12 +13,14 @@ #include "macros.hpp" #include "symmetricMatrix.hpp" -#include + +#include namespace hpcReact { template< typename REAL_TYPE, int N > +HPCREACT_HOST_DEVICE bool isPositiveDefinite( REAL_TYPE const (&A)[N][N] ) { REAL_TYPE temp[N][N]; @@ -52,6 +54,7 @@ bool isPositiveDefinite( REAL_TYPE const (&A)[N][N] ) template< typename REAL_TYPE, int N > +HPCREACT_HOST_DEVICE void solveNxN_Cholesky( REAL_TYPE const (&A)[N][N], REAL_TYPE const (&b)[N], REAL_TYPE (& x)[N] ) { REAL_TYPE L[N][N] = {{0}}; @@ -96,6 +99,7 @@ void solveNxN_Cholesky( REAL_TYPE const (&A)[N][N], REAL_TYPE const (&b)[N], REA template< typename REAL_TYPE, int N > +HPCREACT_HOST_DEVICE void solveNxN_Cholesky( symmetricMatrix< REAL_TYPE, int, N > const & A, REAL_TYPE const (&b)[N], REAL_TYPE (& x)[N] ) diff --git a/src/common/macros.hpp b/src/common/macros.hpp index 683789a..83a2dad 100644 --- a/src/common/macros.hpp +++ b/src/common/macros.hpp @@ -13,18 +13,23 @@ -#if defined( __CUDACC__ ) || defined( __HIPCC__ ) +#if defined( __CUDACC__ ) #define HPCREACT_USE_DEVICE -#define HPCREACT_HOST_DEVICE __host__ __device__ -#else -#define HPCREACT_HOST_DEVICE +#define HPCREACT_USE_CUDA +#elif defined( __HIPCC__ ) +#define HPCREACT_USE_DEVICE +#define HPCREACT_USE_HIP #endif #if defined( HPCREACT_USE_DEVICE ) #define HPCREACT_GLOBAL __global__ +#define HPCREACT_DEVICE __device__ +#define HPCREACT_HOST_DEVICE __host__ __device__ #else #define HPCREACT_GLOBAL +#define HPCREACT_DEVICE +#define HPCREACT_HOST_DEVICE #endif /// This macro is used to ignore warnings that that a variable is diff --git a/src/common/nonlinearSolvers.hpp b/src/common/nonlinearSolvers.hpp index 3429b30..2888abb 100644 --- a/src/common/nonlinearSolvers.hpp +++ b/src/common/nonlinearSolvers.hpp @@ -13,7 +13,7 @@ #include "macros.hpp" #include "DirectSystemSolve.hpp" -#include +#include namespace hpcReact { diff --git a/src/common/pmpl.hpp b/src/common/pmpl.hpp index 6fc382f..ce622cd 100644 --- a/src/common/pmpl.hpp +++ b/src/common/pmpl.hpp @@ -13,24 +13,26 @@ #include "common/macros.hpp" +#include #include +#include namespace hpcReact { #if defined(HPCREACT_USE_DEVICE) #if defined(HPCREACT_USE_CUDA) -#define deviceMalloc( PTR, BYTES ) cudaMalloc( PTR, BYTES ); -#define deviceMallocManaged( PTR, BYTES ) cudaMallocManaged( PTR, BYTES ); -#define deviceDeviceSynchronize() cudaDeviceSynchronize(); -#define deviceMemCpy( DST, SRC, BYTES, KIND ) cudaMemcpy( DST, SRC, BYTES, KIND ); -#define deviceFree( PTR ) cudaFree( PTR ); + #define deviceMalloc( PTR, BYTES ) cudaMalloc( PTR, BYTES ); + #define deviceMallocManaged( PTR, BYTES ) cudaMallocManaged( PTR, BYTES ); + #define deviceDeviceSynchronize() cudaDeviceSynchronize(); + #define deviceMemCpy( DST, SRC, BYTES, KIND ) cudaMemcpy( DST, SRC, BYTES, KIND ); + #define deviceFree( PTR ) cudaFree( PTR ); #elif defined(HPCREACT_USE_HIP) -#define deviceMalloc( PTR, BYTES ) hipMalloc( PTR, BYTES ); -#define deviceMallocManaged( PTR, BYTES ) hipMallocManaged( PTR, BYTES ); -#define deviceDeviceSynchronize() hipDeviceSynchronize(); -#define deviceMemCpy( DST, SRC, BYTES, KIND ) hipMemcpy( DST, SRC, BYTES, KIND ); -#define deviceFree( PTR ) hipFree( PTR ); + #define deviceMalloc( PTR, BYTES ) hipMalloc( PTR, BYTES ); + #define deviceMallocManaged( PTR, BYTES ) hipMallocManaged( PTR, BYTES ); + #define deviceDeviceSynchronize() hipDeviceSynchronize(); + #define deviceMemCpy( DST, SRC, BYTES, KIND ) hipMemcpy( DST, SRC, BYTES, KIND ); + #define deviceFree( PTR ) hipFree( PTR ); #endif #endif @@ -121,13 +123,20 @@ HPCREACT_GLOBAL void genericKernel( LAMBDA func, DATA_TYPE * const data ) template< typename DATA_TYPE, typename LAMBDA > void genericKernelWrapper( int const N, DATA_TYPE * const hostData, LAMBDA && func ) { - #if defined(HPCREACT_USE_DEVICE) DATA_TYPE * deviceData; deviceMalloc( &deviceData, N * sizeof(DATA_TYPE) ); deviceMemCpy( deviceData, hostData, N * sizeof(DATA_TYPE), cudaMemcpyHostToDevice ); genericKernel <<< 1, 1 >>> ( std::forward< LAMBDA >( func ), deviceData ); + + cudaError_t e = cudaGetLastError(); + if (e != cudaSuccess) { fprintf(stderr, "launch error: %s\n", cudaGetErrorString(e)); abort(); } + deviceDeviceSynchronize(); + + e = cudaGetLastError(); + if (e != cudaSuccess) { fprintf(stderr, "post-sync error: %s\n", cudaGetErrorString(e)); abort(); } + deviceMemCpy( hostData, deviceData, N * sizeof(DATA_TYPE), cudaMemcpyDeviceToHost ); deviceFree( deviceData ); #else diff --git a/src/common/unitTests/CMakeLists.txt b/src/common/unitTests/CMakeLists.txt index 298d8e7..9a72c85 100644 --- a/src/common/unitTests/CMakeLists.txt +++ b/src/common/unitTests/CMakeLists.txt @@ -2,8 +2,13 @@ set( testSourceFiles testDirectSystemSolve.cpp ) + set( dependencyList hpcReact gtest ) +if( ENABLE_CUDA ) + list( APPEND dependencyList cuda ) +endif() + # Add gtest C++ based tests foreach(test ${testSourceFiles}) get_filename_component( test_name ${test} NAME_WE ) diff --git a/src/common/unitTests/testDirectSystemSolve.cpp b/src/common/unitTests/testDirectSystemSolve.cpp index a01fbc8..f9c5bef 100644 --- a/src/common/unitTests/testDirectSystemSolve.cpp +++ b/src/common/unitTests/testDirectSystemSolve.cpp @@ -16,43 +16,6 @@ #include using namespace hpcReact; -// TEST( testDirectSystemSolve, test3x3 ) -// { -// // **Define a Sample NxN Linear System** -// double A_host[9] = -// { -// 1.0, 2.0, 3.0, -// 2.0, -1.0, 1.0, -// 3.0, 4.0, 5.0 -// }; -// double b_host[3] = { 14.0, 3.0, 24.0 }; // Right-hand side -// double x_host[3]; // Solution - -// // **Allocate Memory on the GPU** -// double *d_A, *d_b, *d_x; -// cudaMalloc(&d_A, sizeof(A_host)); -// cudaMalloc(&d_b, sizeof(b_host)); -// cudaMalloc(&d_x, sizeof(x_host)); - -// // **Copy Data to the GPU** -// cudaMemcpy(d_A, A_host, sizeof(A_host), cudaMemcpyHostToDevice); -// cudaMemcpy(d_b, b_host, sizeof(b_host), cudaMemcpyHostToDevice); - -// // **Launch Kernel (1 block, 1 thread per system)** -// kernel_solveNxN_pivoted<<<1, 1>>>(d_A, d_b, d_x, 1); - -// // **Copy Result Back to Host** -// cudaMemcpy(x_host, d_x, sizeof(x_host), cudaMemcpyDeviceToHost); - -// // **Print the Solution** -// std::cout << "Solution: x = [" << x_host[0] << ", " << x_host[1] << ", " << x_host[2] << "]" << std::endl; - -// // **Free GPU Memory** -// cudaFree(d_A); -// cudaFree(d_b); -// cudaFree(d_x); - -// } template< typename REAL_TYPE, int N > struct LinearSystem @@ -62,7 +25,8 @@ struct LinearSystem REAL_TYPE x[N]; }; -TEST( testDirectSystemSolve, test3x3 ) + +void test3x3_helper() { // **Define a Sample NxN Linear System** @@ -76,7 +40,7 @@ TEST( testDirectSystemSolve, test3x3 ) { 0.0, 0.0, 0.0 } // Solution }; - pmpl::genericKernelWrapper( 1, &linearSystem, [&]( auto * copyOfLinearSystem ) + pmpl::genericKernelWrapper( 1, &linearSystem, [] HPCREACT_DEVICE ( auto * const copyOfLinearSystem ) { solveNxN_pivoted< double, 3 >( copyOfLinearSystem->A, copyOfLinearSystem->b, copyOfLinearSystem->x ); } ); @@ -84,50 +48,13 @@ TEST( testDirectSystemSolve, test3x3 ) EXPECT_NEAR( linearSystem.x[0], 0.0, std::numeric_limits< double >::epsilon()*100 ); EXPECT_NEAR( linearSystem.x[1], 1.0, std::numeric_limits< double >::epsilon()*100 ); EXPECT_NEAR( linearSystem.x[2], 4.0, std::numeric_limits< double >::epsilon()*100 ); -// std::cout << "Solution: x = [" << linearSystem.x[0] << ", " << linearSystem.x[1] << ", " << linearSystem.x[2] << "]" << std::endl; } - -#if 0 -TEST( testDirectSystemSolve, test3x3_CUDA ) +TEST( testDirectSystemSolve, test3x3 ) { - // **Define a Sample NxN Linear System** - double A_host[9] = - { - 1.0, 2.0, 3.0, - 2.0, -1.0, 1.0, - 3.0, 4.0, 5.0 - }; - double b_host[3] = { 14.0, 3.0, 24.0 }; // Right-hand side - double x_host[3]; // Solution - - // **Allocate Memory on the GPU** - double *d_A, *d_b, *d_x; - cudaMalloc( &d_A, sizeof(A_host)); - cudaMalloc( &d_b, sizeof(b_host)); - cudaMalloc( &d_x, sizeof(x_host)); - - // **Copy Data to the GPU** - cudaMemcpy( d_A, A_host, sizeof(A_host), cudaMemcpyHostToDevice ); - cudaMemcpy( d_b, b_host, sizeof(b_host), cudaMemcpyHostToDevice ); - - // **Launch Kernel (1 block, 1 thread per system)** - kernel_solveNxN_pivoted< double, 3 ><<<1, 1>>>(d_A, d_b, d_x, 1); - - // **Copy Result Back to Host** - cudaMemcpy( x_host, d_x, sizeof(x_host), cudaMemcpyDeviceToHost ); - - // **Print the Solution** - std::cout << "Solution: x = [" << x_host[0] << ", " << x_host[1] << ", " << x_host[2] << "]" << std::endl; - - // **Free GPU Memory** - cudaFree( d_A ); - cudaFree( d_b ); - cudaFree( d_x ); - + test3x3_helper(); } -#endif int main( int argc, char * * argv ) diff --git a/src/reactions/exampleSystems/unitTests/CMakeLists.txt b/src/reactions/exampleSystems/unitTests/CMakeLists.txt index 710de67..bbc8bab 100644 --- a/src/reactions/exampleSystems/unitTests/CMakeLists.txt +++ b/src/reactions/exampleSystems/unitTests/CMakeLists.txt @@ -7,6 +7,9 @@ set( testSourceFiles ) set( dependencyList hpcReact gtest ) +if( ENABLE_CUDA ) + list( APPEND dependencyList cuda ) +endif() # Add gtest C++ based tests foreach(test ${testSourceFiles}) diff --git a/src/reactions/exampleSystems/unitTests/testEquilibriumReactions.cpp b/src/reactions/exampleSystems/unitTests/testEquilibriumReactions.cpp index f580f42..d263fc1 100644 --- a/src/reactions/exampleSystems/unitTests/testEquilibriumReactions.cpp +++ b/src/reactions/exampleSystems/unitTests/testEquilibriumReactions.cpp @@ -13,6 +13,7 @@ #include "reactions/unitTestUtilities/equilibriumReactionsTestUtilities.hpp" #include "../BulkGeneric.hpp" + #include using namespace hpcReact; @@ -30,6 +31,7 @@ TEST( testEquilibriumReactions, computeResidualAndJacobianTest ) double const expectedJacobian[2][2] = { { 1.0e16, -2.0 }, { -2.0, 4.0e16 } }; + computeResidualAndJacobianTest< double, 2 >( bulkGeneric::simpleTestRateParams, initialSpeciesConcentration, expectedResiduals, diff --git a/src/reactions/exampleSystems/unitTests/testMomasEasyCase.cpp b/src/reactions/exampleSystems/unitTests/testMomasEasyCase.cpp index 3fe3eb6..33b4669 100644 --- a/src/reactions/exampleSystems/unitTests/testMomasEasyCase.cpp +++ b/src/reactions/exampleSystems/unitTests/testMomasEasyCase.cpp @@ -19,48 +19,53 @@ using namespace hpcReact::unitTest_utilities; //****************************************************************************** -TEST( testEquilibriumReactions, testMoMasAllEquilibrium ) -{ + +void testMoMasAllEquilibriumHelper() +{ using EquilibriumReactionsType = reactionsSystems::EquilibriumReactions< double, int, int >; - constexpr int numPrimarySpecies = hpcReact::MoMasBenchmark::easyCaseParams.numPrimarySpecies(); + static constexpr int numPrimarySpecies = hpcReact::MoMasBenchmark::easyCaseParams.numPrimarySpecies(); - double const targetAggregatePrimarySpeciesConcentration[numPrimarySpecies] = - { - 1.0e-20, // X1 - -2.0, // X2 - 1.0e-20, // X3 - 2.0, // X4 - 1.0 // S - }; - - double const initialPrimarySpeciesConcentration[numPrimarySpecies] = - { - 1.0e-20, // X1 - 0.02, // X2 - 1.0e-20, // X3 - 1.0, // X4 - 1.00 // S - }; + double logPrimarySpeciesConcentration[numPrimarySpecies]; - double const logInitialPrimarySpeciesConcentration[numPrimarySpecies] = + pmpl::genericKernelWrapper( numPrimarySpecies, logPrimarySpeciesConcentration, [] HPCREACT_DEVICE ( auto * const logPrimarySpeciesConcentrationCopy ) { - log( initialPrimarySpeciesConcentration[0] ), - log( initialPrimarySpeciesConcentration[1] ), - log( initialPrimarySpeciesConcentration[2] ), - log( initialPrimarySpeciesConcentration[3] ), - log( initialPrimarySpeciesConcentration[4] ) - }; - - double logPrimarySpeciesConcentration[numPrimarySpecies]; - EquilibriumReactionsType::enforceEquilibrium_Aggregate( 0, - hpcReact::MoMasBenchmark::easyCaseParams.equilibriumReactionsParameters(), - targetAggregatePrimarySpeciesConcentration, - logInitialPrimarySpeciesConcentration, - logPrimarySpeciesConcentration ); + double const targetAggregatePrimarySpeciesConcentration[numPrimarySpecies] = + { + 1.0e-20, // X1 + -2.0, // X2 + 1.0e-20, // X3 + 2.0, // X4 + 1.0 // S + }; + + double const initialPrimarySpeciesConcentration[numPrimarySpecies] = + { + 1.0e-20, // X1 + 0.02, // X2 + 1.0e-20, // X3 + 1.0, // X4 + 1.00 // S + }; + + double const logInitialPrimarySpeciesConcentration[numPrimarySpecies] = + { + log( initialPrimarySpeciesConcentration[0] ), + log( initialPrimarySpeciesConcentration[1] ), + log( initialPrimarySpeciesConcentration[2] ), + log( initialPrimarySpeciesConcentration[3] ), + log( initialPrimarySpeciesConcentration[4] ) + }; + + EquilibriumReactionsType::enforceEquilibrium_Aggregate( 0, + hpcReact::MoMasBenchmark::easyCaseParams.equilibriumReactionsParameters(), + targetAggregatePrimarySpeciesConcentration, + logInitialPrimarySpeciesConcentration, + logPrimarySpeciesConcentrationCopy ); + }); double const expectedPrimarySpeciesConcentrations[numPrimarySpecies] = { @@ -76,7 +81,10 @@ TEST( testEquilibriumReactions, testMoMasAllEquilibrium ) EXPECT_NEAR( exp( logPrimarySpeciesConcentration[r] ), expectedPrimarySpeciesConcentrations[r], 1.0e-8 * expectedPrimarySpeciesConcentrations[r] ); } - +} +TEST( testEquilibriumReactions, testMoMasAllEquilibrium ) +{ + testMoMasAllEquilibriumHelper(); } int main( int argc, char * * argv ) diff --git a/src/reactions/exampleSystems/unitTests/testMomasMediumCase.cpp b/src/reactions/exampleSystems/unitTests/testMomasMediumCase.cpp index dffb5da..534cd03 100644 --- a/src/reactions/exampleSystems/unitTests/testMomasMediumCase.cpp +++ b/src/reactions/exampleSystems/unitTests/testMomasMediumCase.cpp @@ -19,47 +19,54 @@ using namespace hpcReact::unitTest_utilities; //****************************************************************************** -TEST( testEquilibriumReactions, testMoMasMediumEquilibrium ) + +void testMoMasMediumEquilibriumHelper() { using EquilibriumReactionsType = reactionsSystems::EquilibriumReactions< double, int, int >; - constexpr int numPrimarySpecies = hpcReact::MoMasBenchmark::mediumCaseParams.numPrimarySpecies(); + static constexpr int numPrimarySpecies = hpcReact::MoMasBenchmark::mediumCaseParams.numPrimarySpecies(); - double const targetAggregatePrimarySpeciesConcentration[numPrimarySpecies] = - { - 1.0e-20, // X1 - -3.0, // X2 - 1.0e-20, // X3 - 1.0, // X4 - 1.0 // S - }; - double const initialPrimarySpeciesConcentration[numPrimarySpecies] = - { - 1.0e-20, // X1 - 0.02, // X2 - 1.0e-20, // X3 - 1.0, // X4 - 1.0 // S - }; - double const logInitialPrimarySpeciesConcentration[numPrimarySpecies] = + double logPrimarySpeciesConcentration[numPrimarySpecies]; + + pmpl::genericKernelWrapper( numPrimarySpecies, logPrimarySpeciesConcentration, [] HPCREACT_DEVICE ( auto * const logPrimarySpeciesConcentrationCopy ) { - log( initialPrimarySpeciesConcentration[0] ), - log( initialPrimarySpeciesConcentration[1] ), - log( initialPrimarySpeciesConcentration[2] ), - log( initialPrimarySpeciesConcentration[3] ), - log( initialPrimarySpeciesConcentration[4] ) - }; + double const targetAggregatePrimarySpeciesConcentration[numPrimarySpecies] = + { + 1.0e-20, // X1 + -3.0, // X2 + 1.0e-20, // X3 + 1.0, // X4 + 1.0 // S + }; - double logPrimarySpeciesConcentration[numPrimarySpecies]; - EquilibriumReactionsType::enforceEquilibrium_Aggregate( 0, - hpcReact::MoMasBenchmark::mediumCaseParams.equilibriumReactionsParameters(), - targetAggregatePrimarySpeciesConcentration, - logInitialPrimarySpeciesConcentration, - logPrimarySpeciesConcentration ); + double const initialPrimarySpeciesConcentration[numPrimarySpecies] = + { + 1.0e-20, // X1 + 0.02, // X2 + 1.0e-20, // X3 + 1.0, // X4 + 1.0 // S + }; + + double const logInitialPrimarySpeciesConcentration[numPrimarySpecies] = + { + log( initialPrimarySpeciesConcentration[0] ), + log( initialPrimarySpeciesConcentration[1] ), + log( initialPrimarySpeciesConcentration[2] ), + log( initialPrimarySpeciesConcentration[3] ), + log( initialPrimarySpeciesConcentration[4] ) + }; + + EquilibriumReactionsType::enforceEquilibrium_Aggregate( 0, + hpcReact::MoMasBenchmark::mediumCaseParams.equilibriumReactionsParameters(), + targetAggregatePrimarySpeciesConcentration, + logInitialPrimarySpeciesConcentration, + logPrimarySpeciesConcentrationCopy ); + }); double const expectedPrimarySpeciesConcentrations[numPrimarySpecies] = { @@ -78,6 +85,11 @@ TEST( testEquilibriumReactions, testMoMasMediumEquilibrium ) } +TEST( testEquilibriumReactions, testMoMasMediumEquilibrium ) +{ + testMoMasMediumEquilibriumHelper(); +} + int main( int argc, char * * argv ) { ::testing::InitGoogleTest( &argc, argv ); diff --git a/src/reactions/geochemistry/unitTests/CMakeLists.txt b/src/reactions/geochemistry/unitTests/CMakeLists.txt index a75b366..69e5522 100644 --- a/src/reactions/geochemistry/unitTests/CMakeLists.txt +++ b/src/reactions/geochemistry/unitTests/CMakeLists.txt @@ -6,6 +6,9 @@ set( testSourceFiles ) set( dependencyList hpcReact gtest ) +if( ENABLE_CUDA ) + list( APPEND dependencyList cuda ) +endif() # Add gtest C++ based tests foreach(test ${testSourceFiles}) diff --git a/src/reactions/geochemistry/unitTests/testGeochemicalEquilibriumReactions.cpp b/src/reactions/geochemistry/unitTests/testGeochemicalEquilibriumReactions.cpp index 1cdd149..ee38825 100644 --- a/src/reactions/geochemistry/unitTests/testGeochemicalEquilibriumReactions.cpp +++ b/src/reactions/geochemistry/unitTests/testGeochemicalEquilibriumReactions.cpp @@ -105,7 +105,7 @@ TEST( testEquilibriumReactions, testcarbonateSystemAllEquilibrium2 ) int, int >; - constexpr int numPrimarySpecies = hpcReact::geochemistry::carbonateSystemAllEquilibrium.numPrimarySpecies(); + static constexpr int numPrimarySpecies = hpcReact::geochemistry::carbonateSystemAllEquilibrium.numPrimarySpecies(); double const initialPrimarySpeciesConcentration[numPrimarySpecies] = { diff --git a/src/reactions/geochemistry/unitTests/testGeochemicalKineticReactions.cpp b/src/reactions/geochemistry/unitTests/testGeochemicalKineticReactions.cpp index b84f1bd..6df4950 100644 --- a/src/reactions/geochemistry/unitTests/testGeochemicalKineticReactions.cpp +++ b/src/reactions/geochemistry/unitTests/testGeochemicalKineticReactions.cpp @@ -164,8 +164,8 @@ TEST( testKineticReactions, testTimeStep_carbonateSystemAllKinetic ) }; timeStepTest< double, false >( carbonateSystemAllKinetic.kineticReactionsParameters(), - 2.0, - 100000, + 10.0, + 10000, initialSpeciesConcentration, expectedSpeciesConcentrations ); diff --git a/src/reactions/geochemistry/unitTests/testGeochemicalMixedReactions.cpp b/src/reactions/geochemistry/unitTests/testGeochemicalMixedReactions.cpp index 9392b75..ce3b244 100644 --- a/src/reactions/geochemistry/unitTests/testGeochemicalMixedReactions.cpp +++ b/src/reactions/geochemistry/unitTests/testGeochemicalMixedReactions.cpp @@ -21,7 +21,7 @@ TEST( testMixedReactions, testTimeStep_carbonateSystem ) { using namespace hpcReact::geochemistry; - constexpr int numPrimarySpecies = carbonateSystemType::numPrimarySpecies(); + static constexpr int numPrimarySpecies = carbonateSystemType::numPrimarySpecies(); double const surfaceArea[carbonateSystemType::numKineticReactions()] = { diff --git a/src/reactions/massActions/MassActions.hpp b/src/reactions/massActions/MassActions.hpp index f8d6b96..d579809 100644 --- a/src/reactions/massActions/MassActions.hpp +++ b/src/reactions/massActions/MassActions.hpp @@ -38,8 +38,8 @@ void calculateLogSecondarySpeciesConcentration( PARAMS_DATA const & params, ARRAY_1D & logSecondarySpeciesConcentrations, FUNC && derivativeFunc ) { - constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); - constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); + static constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); + static constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); for( INDEX_TYPE i = 0; i < numSecondarySpecies; ++i ) { @@ -120,8 +120,8 @@ void calculateAggregatePrimaryConcentrationsWrtLogC( PARAMS_DATA const & params, ARRAY_1D_PRIMARY & aggregatePrimarySpeciesConcentrations, ARRAY_2D & dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations ) { - constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); - constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); + static constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); + static constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); calculateLogSecondarySpeciesConcentration< REAL_TYPE, @@ -171,7 +171,7 @@ void calculateAggregatePrimaryConcentrationsWrtLogC( PARAMS_DATA const & params, ARRAY_1D & aggregatePrimarySpeciesConcentrations, ARRAY_2D & dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations ) { - constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); + static constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); REAL_TYPE logSecondarySpeciesConcentrations[numSecondarySpecies] = {0}; @@ -203,8 +203,8 @@ void calculateTotalAndMobileAggregatePrimaryConcentrationsWrtLogC( PARAMS_DATA c ARRAY_2D & dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations, ARRAY_2D & dMobileAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations ) { - constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); - constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); + static constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); + static constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); calculateLogSecondarySpeciesConcentration< REAL_TYPE, INT_TYPE, diff --git a/src/reactions/massActions/unitTests/CMakeLists.txt b/src/reactions/massActions/unitTests/CMakeLists.txt index 1614eb0..1a7c090 100644 --- a/src/reactions/massActions/unitTests/CMakeLists.txt +++ b/src/reactions/massActions/unitTests/CMakeLists.txt @@ -4,6 +4,9 @@ set( testSourceFiles ) set( dependencyList hpcReact gtest ) +if( ENABLE_CUDA ) + list( APPEND dependencyList cuda ) +endif() # Add gtest C++ based tests foreach(test ${testSourceFiles}) diff --git a/src/reactions/massActions/unitTests/testMassActions.cpp b/src/reactions/massActions/unitTests/testMassActions.cpp index 28f411a..42d9a16 100644 --- a/src/reactions/massActions/unitTests/testMassActions.cpp +++ b/src/reactions/massActions/unitTests/testMassActions.cpp @@ -11,8 +11,10 @@ #include "../MassActions.hpp" #include "reactions/geochemistry/GeochemicalSystems.hpp" +#include "common/pmpl.hpp" #include "common/printers.hpp" + #include using namespace hpcReact; @@ -20,12 +22,11 @@ using namespace hpcReact::massActions; using namespace hpcReact::geochemistry; - -TEST( testUtilities, test_calculateLogSecondarySpeciesConcentration ) +template< int numPrimarySpecies, int numSecondarySpecies > +struct CalculateLogSecondarySpeciesConcentrationData { - constexpr int numPrimarySpecies = carbonateSystemAllEquilibrium.numPrimarySpecies(); - constexpr int numSecondarySpecies = carbonateSystemAllEquilibrium.numSecondarySpecies(); - + double logSecondarySpeciesConcentrations[numSecondarySpecies] = {0}; + double dLogSecondarySpeciesConcentrations_dLogPrimarySpeciesConcentrations[numSecondarySpecies][numPrimarySpecies] = {{0}}; double const logPrimarySpeciesSolution[numPrimarySpecies] = { log( 0.00043969547214915125 ), @@ -36,14 +37,36 @@ TEST( testUtilities, test_calculateLogSecondarySpeciesConcentration ) log( 0.009881874292035079 ), log( 1.0723078278653704 ) }; +}; + + +void test_calculateLogSecondarySpeciesConcentration_helper() +{ + static constexpr int numPrimarySpecies = carbonateSystemAllEquilibrium.numPrimarySpecies(); + static constexpr int numSecondarySpecies = carbonateSystemAllEquilibrium.numSecondarySpecies(); + + CalculateLogSecondarySpeciesConcentrationData data; + + pmpl::genericKernelWrapper( 1, &data, [] HPCREACT_DEVICE ( auto * const dataCopy ) + { + calculateLogSecondarySpeciesConcentration< double, + int, + int >( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), + dataCopy->logPrimarySpeciesSolution, + dataCopy->logSecondarySpeciesConcentrations ); + + + + calculateLogSecondarySpeciesConcentrationWrtLogC< double, + int, + int >( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), + dataCopy->logPrimarySpeciesSolution, + dataCopy->logSecondarySpeciesConcentrations, + dataCopy->dLogSecondarySpeciesConcentrations_dLogPrimarySpeciesConcentrations ); + }); + - double logSecondarySpeciesConcentrations[numSecondarySpecies] = {0}; - calculateLogSecondarySpeciesConcentration< double, - int, - int >( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), - logPrimarySpeciesSolution, - logSecondarySpeciesConcentrations ); double expectedSecondarySpeciesConcentrations[numSecondarySpecies] = { @@ -61,23 +84,11 @@ TEST( testUtilities, test_calculateLogSecondarySpeciesConcentration ) for( int j=0; j( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), - logPrimarySpeciesSolution, - logSecondarySpeciesConcentrations, - dLogSecondarySpeciesConcentrations_dLogPrimarySpeciesConcentrations ); - - - double expected_dLogSdLogC[numSecondarySpecies][numPrimarySpecies] = { { -1, 0, 0, 0, 0, 0, 0 }, @@ -97,52 +108,51 @@ TEST( testUtilities, test_calculateLogSecondarySpeciesConcentration ) { for( int j=0; j +struct CalculateAggregatePrimaryConcentrationsWrtLogCHelperData +{ + double const primarySpeciesSolution[numPrimarySpecies] = { - 0.00043969547214915125, - 0.00037230096984514874, - 0.014716565308128551, - 0.0024913722747387217, - 1.8586090945989489, - 0.009881874292035079, - 1.0723078278653704 + log(0.00043969547214915125), + log(0.00037230096984514874), + log(0.014716565308128551), + log(0.0024913722747387217), + log(1.8586090945989489), + log(0.009881874292035079), + log(1.0723078278653704) }; - for( int i=0; i dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations; +}; - double aggregatePrimarySpeciesConcentration[numPrimarySpecies] = {0}; +void testcalculateAggregatePrimaryConcentrationsWrtLogCHelper() +{ + static constexpr int numPrimarySpecies = carbonateSystemAllEquilibrium.numPrimarySpecies(); + CalculateAggregatePrimaryConcentrationsWrtLogCHelperData data; - CArrayWrapper< double, numPrimarySpecies, numPrimarySpecies > dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations; - for( int i = 0; i < numPrimarySpecies; ++i ) + pmpl::genericKernelWrapper( 1, &data, [] HPCREACT_DEVICE ( auto * const dataCopy ) { - for( int k=0; k( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), - primarySpeciesSolution, - aggregatePrimarySpeciesConcentration, - dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations ); + calculateAggregatePrimaryConcentrationsWrtLogC< double, int, int >( carbonateSystemAllEquilibrium.equilibriumReactionsParameters(), + dataCopy->primarySpeciesSolution, + dataCopy->aggregatePrimarySpeciesConcentration, + dataCopy->dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations ); + }); double const expectedAggregatePrimarySpeciesConcentration[numPrimarySpecies] = { @@ -157,7 +167,7 @@ TEST( testUtilities, testcalculateAggregatePrimaryConcentrationsWrtLogC ) for( int i=0; i +#include #include #include @@ -368,15 +368,15 @@ KineticReactions< REAL_TYPE, ARRAY_1D & speciesRates, ARRAY_2D & speciesRatesDerivatives ) { -// constexpr int numReactions = PARAMS_DATA::numReactions(); - constexpr int numSpecies = PARAMS_DATA::numSpecies(); +// static constexpr int numReactions = PARAMS_DATA::numReactions(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); REAL_TYPE residualNorm = 0.0; - for( int k=0; k<10; ++k ) // newton loop + for( int k=0; k<20; ++k ) // newton loop { - // printf( "iteration %2d: \n", k ); +// printf( "iteration %2d: \n", k ); computeSpeciesRates( temperature, params, diff --git a/src/reactions/reactionsSystems/Parameters.hpp b/src/reactions/reactionsSystems/Parameters.hpp index d2ca7ba..0b6c1bf 100644 --- a/src/reactions/reactionsSystems/Parameters.hpp +++ b/src/reactions/reactionsSystems/Parameters.hpp @@ -39,19 +39,19 @@ struct EquilibriumReactionsParameters using IntType = INT_TYPE; using IndexType = INDEX_TYPE; - static constexpr IndexType numSpecies() { return NUM_SPECIES; } + HPCREACT_HOST_DEVICE static constexpr IndexType numSpecies() { return NUM_SPECIES; } - static constexpr IndexType numReactions() { return NUM_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numReactions() { return NUM_REACTIONS; } - static constexpr IndexType numSurfaceReactions() { return NUM_SURFACE_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numSurfaceReactions() { return NUM_SURFACE_REACTIONS; } - static constexpr IndexType numAqueousReactions() { return numReactions() - numSurfaceReactions(); } + HPCREACT_HOST_DEVICE static constexpr IndexType numAqueousReactions() { return numReactions() - numSurfaceReactions(); } - static constexpr IndexType numPrimarySpecies() { return numSpecies() - numReactions(); } - - static constexpr IndexType numSecondarySpecies() { return numSpecies() - numPrimarySpecies(); } + HPCREACT_HOST_DEVICE static constexpr IndexType numPrimarySpecies() { return numSpecies() - numReactions(); } + HPCREACT_HOST_DEVICE static constexpr IndexType numSecondarySpecies() { return numSpecies() - numPrimarySpecies(); } + HPCREACT_HOST_DEVICE constexpr EquilibriumReactionsParameters( CArrayWrapper< RealType, NUM_REACTIONS, NUM_SPECIES > const & stoichiometricMatrix, CArrayWrapper< RealType, NUM_REACTIONS > equilibriumConstant, @@ -62,9 +62,9 @@ struct EquilibriumReactionsParameters {} - RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } - RealType equilibriumConstant( IndexType const r ) const { return m_equilibriumConstant[r]; } - IntType mobileSecondarySpeciesFlag( IndexType const r ) const { return m_mobileSecondarySpeciesFlag[r]; } + HPCREACT_HOST_DEVICE RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } + HPCREACT_HOST_DEVICE RealType equilibriumConstant( IndexType const r ) const { return m_equilibriumConstant[r]; } + HPCREACT_HOST_DEVICE IntType mobileSecondarySpeciesFlag( IndexType const r ) const { return m_mobileSecondarySpeciesFlag[r]; } CArrayWrapper< RealType, NUM_REACTIONS, NUM_SPECIES > m_stoichiometricMatrix; CArrayWrapper< RealType, NUM_REACTIONS > m_equilibriumConstant; @@ -82,10 +82,11 @@ struct KineticReactionsParameters using IntType = INT_TYPE; using IndexType = INDEX_TYPE; - static constexpr IndexType numSpecies() { return NUM_SPECIES; } + HPCREACT_HOST_DEVICE static constexpr IndexType numSpecies() { return NUM_SPECIES; } - static constexpr IndexType numReactions() { return NUM_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numReactions() { return NUM_REACTIONS; } + HPCREACT_HOST_DEVICE constexpr KineticReactionsParameters( CArrayWrapper< RealType, NUM_REACTIONS, NUM_SPECIES > const & stoichiometricMatrix, CArrayWrapper< RealType, NUM_REACTIONS > const & rateConstantForward, CArrayWrapper< RealType, NUM_REACTIONS > const & rateConstantReverse, @@ -97,10 +98,10 @@ struct KineticReactionsParameters {} - RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } - RealType rateConstantForward( IndexType const r ) const { return m_rateConstantForward[r]; } - RealType rateConstantReverse( IndexType const r ) const { return m_rateConstantReverse[r]; } - RealType equilibriumConstant( IndexType const r ) const { return m_rateConstantForward[r] / m_rateConstantReverse[r]; } + HPCREACT_HOST_DEVICE RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } + HPCREACT_HOST_DEVICE RealType rateConstantForward( IndexType const r ) const { return m_rateConstantForward[r]; } + HPCREACT_HOST_DEVICE RealType rateConstantReverse( IndexType const r ) const { return m_rateConstantReverse[r]; } + HPCREACT_HOST_DEVICE RealType equilibriumConstant( IndexType const r ) const { return m_rateConstantForward[r] / m_rateConstantReverse[r]; } CArrayWrapper< RealType, NUM_REACTIONS, NUM_SPECIES > m_stoichiometricMatrix; @@ -137,18 +138,19 @@ struct MixedReactionsParameters m_mobileSecondarySpeciesFlag( mobileSecondarySpeciesFlag ) {} - static constexpr IndexType numReactions() { return NUM_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numReactions() { return NUM_REACTIONS; } - static constexpr IndexType numKineticReactions() { return NUM_REACTIONS - NUM_EQ_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numKineticReactions() { return NUM_REACTIONS - NUM_EQ_REACTIONS; } - static constexpr IndexType numEquilibriumReactions() { return NUM_EQ_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numEquilibriumReactions() { return NUM_EQ_REACTIONS; } - static constexpr IndexType numSpecies() { return NUM_SPECIES; } + HPCREACT_HOST_DEVICE static constexpr IndexType numSpecies() { return NUM_SPECIES; } - static constexpr IndexType numPrimarySpecies() { return NUM_SPECIES - NUM_EQ_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numPrimarySpecies() { return NUM_SPECIES - NUM_EQ_REACTIONS; } - static constexpr IndexType numSecondarySpecies() { return NUM_EQ_REACTIONS; } + HPCREACT_HOST_DEVICE static constexpr IndexType numSecondarySpecies() { return NUM_EQ_REACTIONS; } + HPCREACT_HOST_DEVICE constexpr EquilibriumReactionsParameters< RealType, IntType, IndexType, numSpecies(), numEquilibriumReactions() > equilibriumReactionsParameters() const @@ -170,6 +172,7 @@ struct MixedReactionsParameters return { eqMatrix, eqConstants, mobileSpeciesFlags }; } + HPCREACT_HOST_DEVICE constexpr KineticReactionsParameters< RealType, IntType, IndexType, numSpecies(), numKineticReactions() > kineticReactionsParameters() const @@ -193,6 +196,7 @@ struct MixedReactionsParameters return { kineticMatrix, rateConstantForward, rateConstantReverse, equilibriumConstant }; } + HPCREACT_HOST_DEVICE void verifyParameterConsistency() { static constexpr int num_digits = 12; @@ -228,10 +232,10 @@ struct MixedReactionsParameters } } - RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } - RealType equilibriumConstant( IndexType const r ) const { return m_equilibriumConstant[r]; } - RealType rateConstantForward( IndexType const r ) const { return m_rateConstantForward[r]; } - RealType rateConstantReverse( IndexType const r ) const { return m_rateConstantReverse[r]; } + HPCREACT_HOST_DEVICE RealType stoichiometricMatrix( IndexType const r, int const i ) const { return m_stoichiometricMatrix[r][i]; } + HPCREACT_HOST_DEVICE RealType equilibriumConstant( IndexType const r ) const { return m_equilibriumConstant[r]; } + HPCREACT_HOST_DEVICE RealType rateConstantForward( IndexType const r ) const { return m_rateConstantForward[r]; } + HPCREACT_HOST_DEVICE RealType rateConstantReverse( IndexType const r ) const { return m_rateConstantReverse[r]; } CArrayWrapper< RealType, NUM_REACTIONS, NUM_SPECIES > m_stoichiometricMatrix; CArrayWrapper< RealType, NUM_REACTIONS > m_equilibriumConstant; diff --git a/src/reactions/unitTestUtilities/equilibriumReactionsTestUtilities.hpp b/src/reactions/unitTestUtilities/equilibriumReactionsTestUtilities.hpp index d67079a..58b0bdb 100644 --- a/src/reactions/unitTestUtilities/equilibriumReactionsTestUtilities.hpp +++ b/src/reactions/unitTestUtilities/equilibriumReactionsTestUtilities.hpp @@ -12,6 +12,7 @@ #include "reactions/reactionsSystems/EquilibriumReactions.hpp" #include "common/macros.hpp" +#include "common/pmpl.hpp" #include @@ -28,6 +29,23 @@ REAL_TYPE tolerance( REAL_TYPE const a, REAL_TYPE const b ) return std::numeric_limits< double >::epsilon() * std::max( fabs( a ), fabs( b ) ) * 10; } +/** + * POD struct for transferring data between host and device for computeResidualAndJacobianTest. + * @tparam numReactions Number of reactions. + * @tparam numSpecies Number of species. + */ +template< int numReactions, int numSpecies > +struct ComputeResidualAndJacobianTestData +{ + /// The reaction residuals + double residual[numReactions] = { 0.0 }; + + /// The residual derivatives wrt reactions + CArrayWrapper< double, numReactions, numReactions > jacobian; + + /// the species concentrations + double speciesConcentration[numSpecies]; +}; //****************************************************************************** template< typename REAL_TYPE, @@ -42,34 +60,33 @@ void computeResidualAndJacobianTest( PARAMS_DATA const & params, int, int >; - constexpr int numSpecies = PARAMS_DATA::numSpecies(); - constexpr int numReactions = PARAMS_DATA::numReactions(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); + static constexpr int numReactions = PARAMS_DATA::numReactions(); double const temperature = 298.15; - double speciesConcentration[numSpecies]; + ComputeResidualAndJacobianTestData data; for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration[i] = initialSpeciesConcentration[i]; - } - - double residual[numReactions] = { 0.0 }; - double xi[numReactions] = { 0.0 }; - - CArrayWrapper< double, numReactions, numReactions > jacobian; + data.speciesConcentration[i] = initialSpeciesConcentration[i]; + } + pmpl::genericKernelWrapper( 1, &data, [params, temperature] HPCREACT_DEVICE ( auto * const dataCopy ) + { + double xi[numReactions] = { 0.0 }; - EquilibriumReactionsType::computeResidualAndJacobianReactionExtents( temperature, - params, - speciesConcentration, - xi, - residual, - jacobian ); + EquilibriumReactionsType::computeResidualAndJacobianReactionExtents( temperature, + params, + dataCopy->speciesConcentration, + xi, + dataCopy->residual, + dataCopy->jacobian ); + }); // printf( "R = { %8.4g, %8.4g }\n", residual[0], residual[1] ); for( int r=0; r +struct TestEnforceEquilibriumData +{ + /// The initial species concentrations + double speciesConcentration0[numSpecies]; + + /// The final species concentrations + double speciesConcentration[numSpecies]; +}; + template< typename REAL_TYPE, int RESIDUAL_FORM, typename PARAMS_DATA > @@ -98,27 +130,28 @@ void testEnforceEquilibrium( PARAMS_DATA const & params, int, int >; - constexpr int numSpecies = PARAMS_DATA::numSpecies(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); double const temperature = 298.15; - double speciesConcentration0[numSpecies]; - double speciesConcentration[numSpecies]; - + TestEnforceEquilibriumData data; for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration0[i] = initialSpeciesConcentration[i]; + data.speciesConcentration0[i] = initialSpeciesConcentration[i]; } - EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, - params, - speciesConcentration0, - speciesConcentration ); + pmpl::genericKernelWrapper( 1, &data, [params, temperature] HPCREACT_DEVICE ( auto * const dataCopy ) + { + EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, + params, + dataCopy->speciesConcentration0, + dataCopy->speciesConcentration ); + }); for( int r=0; r +struct ComputeReactionRatesTestData +{ + /// The species concentration + double speciesConcentration[numSpecies]; + + /// The reaction rates + double reactionRates[numReactions] = { 0.0 }; + + /// The reaction rates derivatives + CArrayWrapper< double, numReactions, numSpecies > reactionRatesDerivatives; +}; + template< typename REAL_TYPE, bool LOGE_CONCENTRATION, typename PARAMS_DATA > @@ -44,11 +64,11 @@ void computeReactionRatesTest( PARAMS_DATA const & params, int, LOGE_CONCENTRATION >; - constexpr int numSpecies = PARAMS_DATA::numSpecies(); - constexpr int numReactions = PARAMS_DATA::numReactions(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); + static constexpr int numReactions = PARAMS_DATA::numReactions(); double const temperature = 298.15; - double speciesConcentration[numSpecies]; + ComputeReactionRatesTestData< numReactions, numSpecies > data; REAL_TYPE magScale = 0; for( int r=0; r reactionRatesDerivatives; - - - KineticReactionsType::computeReactionRates( temperature, - params, - speciesConcentration, - reactionRates, - reactionRatesDerivatives ); - + pmpl::genericKernelWrapper( 1, &data, [params, temperature] HPCREACT_DEVICE ( auto * const dataCopy ) + { + KineticReactionsType::computeReactionRates( temperature, + params, + dataCopy->speciesConcentration, + dataCopy->reactionRates, + dataCopy->reactionRatesDerivatives ); + }); for( int r=0; r +struct ComputeSpeciesRatesTestData +{ + /// The species concentrations + double speciesConcentration[numSpecies]; + + /// The species rates + double speciesRates[numSpecies] = { 0.0 }; + + /// The species rates derivatives + CArrayWrapper< double, numSpecies, numSpecies > speciesRatesDerivatives; +}; + template< typename REAL_TYPE, bool LOGE_CONCENTRATION, typename PARAMS_DATA > @@ -120,38 +156,39 @@ void computeSpeciesRatesTest( PARAMS_DATA const & params, int, LOGE_CONCENTRATION >; - constexpr int numSpecies = PARAMS_DATA::numSpecies(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); double const temperature = 298.15; - double speciesConcentration[numSpecies]; - double speciesRates[numSpecies] = { 0.0 }; - CArrayWrapper< double, numSpecies, numSpecies > speciesRatesDerivatives; + ComputeSpeciesRatesTestData< numSpecies > data; if constexpr( LOGE_CONCENTRATION ) { for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration[i] = log( initialSpeciesConcentration[i] ); + data.speciesConcentration[i] = log( initialSpeciesConcentration[i] ); } } else { for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration[i] = initialSpeciesConcentration[i]; + data.speciesConcentration[i] = initialSpeciesConcentration[i]; } } - KineticReactionsType::computeSpeciesRates( temperature, - params, - speciesConcentration, - speciesRates, - speciesRatesDerivatives ); + pmpl::genericKernelWrapper( 1, &data, [params, temperature] HPCREACT_DEVICE ( auto * const dataCopy ) + { + KineticReactionsType::computeSpeciesRates( temperature, + params, + dataCopy->speciesConcentration, + dataCopy->speciesRates, + dataCopy->speciesRatesDerivatives ); + }); for( int r=0; r +struct TimeStepTestData +{ + /// The species concentrations + double speciesConcentration[numSpecies]; + + /// The current time + double time = 0.0; +}; + template< typename REAL_TYPE, bool LOGE_CONCENTRATION, typename PARAMS_DATA > @@ -182,58 +234,62 @@ void timeStepTest( PARAMS_DATA const & params, int, LOGE_CONCENTRATION >; - constexpr int numSpecies = PARAMS_DATA::numSpecies(); + static constexpr int numSpecies = PARAMS_DATA::numSpecies(); double const temperature = 298.15; + TimeStepTestData< numSpecies > data; - double speciesConcentration[numSpecies]; if constexpr( LOGE_CONCENTRATION ) { for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration[i] = log( initialSpeciesConcentration[i] ); + data.speciesConcentration[i] = log( initialSpeciesConcentration[i] ); } } else { for( int i = 0; i < numSpecies; ++i ) { - speciesConcentration[i] = initialSpeciesConcentration[i]; + data.speciesConcentration[i] = initialSpeciesConcentration[i]; } } - double time = 0.0; - for( int t = 0; t < numSteps; ++t ) + data.time = 0.0; + + pmpl::genericKernelWrapper( 1, &data, [params, temperature, dt, numSteps] HPCREACT_DEVICE ( auto * const dataCopy ) { double speciesConcentration_n[numSpecies]; - for( int i=0; i speciesRatesDerivatives; - KineticReactionsType::timeStep( dt, - temperature, - params, - speciesConcentration_n, - speciesConcentration, - speciesRates, - speciesRatesDerivatives ); + for( int t = 0; t < numSteps; ++t ) + { + printf("Time step %d \n ", t); + for( int i=0; ispeciesConcentration[i]; + } + KineticReactionsType::timeStep( dt, + temperature, + params, + speciesConcentration_n, + dataCopy->speciesConcentration, + speciesRates, + speciesRatesDerivatives ); + dataCopy->time += dt; + } + }); - time += dt; - } - EXPECT_NEAR( time, dt*numSteps, 1.0e-8 ); + EXPECT_NEAR( data.time, dt*numSteps, 1.0e-8 ); for( int i = 0; i < numSpecies; ++i ) { if constexpr( LOGE_CONCENTRATION ) { - speciesConcentration[i] = exp( speciesConcentration[i] ); + data.speciesConcentration[i] = exp( data.speciesConcentration[i] ); } - EXPECT_NEAR( speciesConcentration[i], expectedSpeciesConcentrations[i], 1.0e-4 ); + EXPECT_NEAR( data.speciesConcentration[i], expectedSpeciesConcentrations[i], 1.0e-4 ); } } diff --git a/src/reactions/unitTestUtilities/mixedReactionsTestUtilities.hpp b/src/reactions/unitTestUtilities/mixedReactionsTestUtilities.hpp index c9575ba..7426c03 100644 --- a/src/reactions/unitTestUtilities/mixedReactionsTestUtilities.hpp +++ b/src/reactions/unitTestUtilities/mixedReactionsTestUtilities.hpp @@ -48,7 +48,7 @@ void timeStepTest( PARAMS_DATA const & params, pmpl::genericKernelWrapper( PARAMS_DATA::numPrimarySpecies(), primarySpeciesConcentration.data, - [=] HPCREACT_HOST_DEVICE ( auto * speciesConcentration ) + [=] HPCREACT_HOST_DEVICE ( decltype(primarySpeciesConcentration.data) speciesConcentration ) { using MixedReactionsType = reactionsSystems::MixedEquilibriumKineticReactions< REAL_TYPE, int, @@ -59,9 +59,9 @@ void timeStepTest( PARAMS_DATA const & params, int >; // constexpr int numSpecies = PARAMS_DATA::numSpecies(); - constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); - constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); - constexpr int numKineticReactions = PARAMS_DATA::numKineticReactions(); + static constexpr int numPrimarySpecies = PARAMS_DATA::numPrimarySpecies(); + static constexpr int numSecondarySpecies = PARAMS_DATA::numSecondarySpecies(); + static constexpr int numKineticReactions = PARAMS_DATA::numKineticReactions(); // define variables double const temperature = 298.15; @@ -81,7 +81,7 @@ void timeStepTest( PARAMS_DATA const & params, // Initialize species concentrations for( int i = 0; i < numPrimarySpecies; ++i ) { - logPrimarySpeciesConcentration[i] = ::log( speciesConcentration[i] ); + logPrimarySpeciesConcentration[i] = log( speciesConcentration[i] ); aggregatePrimarySpeciesConcentration[i] = speciesConcentration[i]; } @@ -101,7 +101,7 @@ void timeStepTest( PARAMS_DATA const & params, aggregatePrimarySpeciesConcentration_n[i] = aggregatePrimarySpeciesConcentration[i]; } - auto computeResidualAndJacobian = [&] HPCREACT_HOST_DEVICE ( REAL_TYPE const (&X)[numPrimarySpecies], + auto computeResidualAndJacobian = [&] ( REAL_TYPE const (&X)[numPrimarySpecies], REAL_TYPE ( &r )[numPrimarySpecies], REAL_TYPE ( &J )[numPrimarySpecies][numPrimarySpecies] ) {