From 183768356a982c766c941a0b252c2ab17a8e0b25 Mon Sep 17 00:00:00 2001 From: pelesh Date: Tue, 2 Jun 2026 15:00:42 -0400 Subject: [PATCH 01/22] Add FindReSolve.cmake --- cmake/SundialsSetupTPLs.cmake | 9 ++++ cmake/SundialsTPLOptions.cmake | 22 ++++++++ cmake/tpl/FindReSolve.cmake | 96 +++++++++++++++++++++++++++++++++ cmake/tpl/SundialsReSolve.cmake | 83 ++++++++++++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 cmake/tpl/FindReSolve.cmake create mode 100644 cmake/tpl/SundialsReSolve.cmake diff --git a/cmake/SundialsSetupTPLs.cmake b/cmake/SundialsSetupTPLs.cmake index 44b60d26ee..ab7f7c75e5 100644 --- a/cmake/SundialsSetupTPLs.cmake +++ b/cmake/SundialsSetupTPLs.cmake @@ -170,6 +170,15 @@ if(SUNDIALS_ENABLE_RAJA) list(APPEND SUNDIALS_TPL_LIST "RAJA") endif() +# --------------------------------------------------------------- +# Find (and test) the ReSolve libraries +# --------------------------------------------------------------- + +if(SUNDIALS_ENABLE_RESOLVE) + include(SundialsReSolve) + list(APPEND SUNDIALS_TPL_LIST "RESOLVE") +endif() + # --------------------------------------------------------------- # Find (and test) the SuperLUDIST libraries # --------------------------------------------------------------- diff --git a/cmake/SundialsTPLOptions.cmake b/cmake/SundialsTPLOptions.cmake index f5c5f2360d..9ec0b61f57 100644 --- a/cmake/SundialsTPLOptions.cmake +++ b/cmake/SundialsTPLOptions.cmake @@ -547,6 +547,28 @@ sundials_option( SUNDIALS_ENABLE_KOKKOS_KERNELS BOOL "Enable Kokkos Kernels support" OFF DEPRECATED_NAMES ENABLE_KOKKOS_KERNELS) +# --------------------------------------------------------------- +# Enable ReSolve support? +# --------------------------------------------------------------- + +sundials_option(SUNDIALS_ENABLE_RESOLVE BOOL "Enable ReSolve support" OFF) + +sundials_option(ReSolve_DIR PATH + "Path to the root of a ReSolve installation" "${ReSolve_DIR}") + +sundials_option(ReSolve_INCLUDE_DIR PATH "ReSolve include directory" + "${ReSolve_INCLUDE_DIR}" ADVANCED) + +sundials_option(ReSolve_LIBRARY_DIR PATH "ReSolve library directory" + "${ReSolve_LIBRARY_DIR}" ADVANCED) + +sundials_option( + SUNDIALS_ENABLE_RESOLVE_CHECKS + BOOL + "Enable ReSolve compatibility checks" + ON + ADVANCED) + sundials_option( KokkosKernels_DIR PATH "Path to the root of a Kokkos Kernels installation" "${KokkosKernels_DIR}") diff --git a/cmake/tpl/FindReSolve.cmake b/cmake/tpl/FindReSolve.cmake new file mode 100644 index 0000000000..0cc22533e8 --- /dev/null +++ b/cmake/tpl/FindReSolve.cmake @@ -0,0 +1,96 @@ +# ------------------------------------------------------------------------------ +# Programmer(s): Slaven Peles @ ORNL +# ------------------------------------------------------------------------------ +# SUNDIALS Copyright Start +# Copyright (c) 2025-2026, Lawrence Livermore National Security, +# University of Maryland Baltimore County, and the SUNDIALS contributors. +# Copyright (c) 2013-2025, Lawrence Livermore National Security +# and Southern Methodist University. +# Copyright (c) 2002-2013, Lawrence Livermore National Security. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# ------------------------------------------------------------------------------ +# ReSolve find module that creates an imported target for ReSolve. +# The target is SUNDIALS::ReSolve. +# +# The variable ReSolve_DIR can be used to control where the module +# looks for the library (path to the root of a ReSolve installation or +# to a directory containing ReSolveConfig.cmake). +# +# The variable ReSolve_INCLUDE_DIR can be used to set the include path. +# The variable ReSolve_LIBRARY_DIR can be used to set the library path. +# +# This module also defines variables, but it is best to use the defined +# target to ensure includes and compile/link options are correctly passed +# to consumers. +# +# ReSolve_FOUND - system has the ReSolve library +# ReSolve_LIBRARY - the ReSolve library +# ReSolve_INCLUDE_DIR - the ReSolve include path +# ReSolve_LIBRARIES - all libraries needed for ReSolve +# ------------------------------------------------------------------------------ + +# Prefer the upstream CMake config file if the user did not point to a specific +# include/library directory. +if(NOT (ReSolve_INCLUDE_DIR OR ReSolve_LIBRARY_DIR OR ReSolve_LIBRARY)) + + find_package(ReSolve CONFIG QUIET PATHS "${ReSolve_DIR}" + PATH_SUFFIXES lib/cmake/ReSolve cmake/ReSolve) + + if(ReSolve_FOUND AND TARGET ReSolve::ReSolve) + if(NOT TARGET SUNDIALS::ReSolve) + add_library(SUNDIALS::ReSolve ALIAS ReSolve::ReSolve) + endif() + return() + endif() + +endif() + +# Fall back to manual detection using ReSolve_DIR, ReSolve_INCLUDE_DIR, and +# ReSolve_LIBRARY_DIR. + +# Find the include directory +find_path( + ReSolve_INCLUDE_DIR resolve/SystemSolver.hpp + PATHS "${ReSolve_DIR}" + PATH_SUFFIXES include + DOC "ReSolve include directory") + +if(ReSolve_LIBRARY) + get_filename_component(ReSolve_LIBRARY_DIR "${ReSolve_LIBRARY}" PATH) + set(ReSolve_LIBRARY_DIR + "${ReSolve_LIBRARY_DIR}" + CACHE PATH "" FORCE) +else() + find_library( + ReSolve_LIBRARY resolve + PATHS "${ReSolve_DIR}" "${ReSolve_LIBRARY_DIR}" + PATH_SUFFIXES lib lib64 + DOC "ReSolve library") +endif() +mark_as_advanced(ReSolve_LIBRARY) + +set(ReSolve_LIBRARIES "${ReSolve_LIBRARY}") + +# Set package variables including ReSolve_FOUND +find_package_handle_standard_args( + ReSolve REQUIRED_VARS ReSolve_LIBRARY ReSolve_LIBRARIES ReSolve_INCLUDE_DIR) + +# Create the SUNDIALS::ReSolve imported target +if(ReSolve_FOUND) + + if(NOT TARGET SUNDIALS::ReSolve) + add_library(SUNDIALS::ReSolve UNKNOWN IMPORTED) + endif() + + set_target_properties( + SUNDIALS::ReSolve + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ReSolve_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${ReSolve_LIBRARIES}" + IMPORTED_LOCATION "${ReSolve_LIBRARY}") + +endif() diff --git a/cmake/tpl/SundialsReSolve.cmake b/cmake/tpl/SundialsReSolve.cmake new file mode 100644 index 0000000000..6b152736bb --- /dev/null +++ b/cmake/tpl/SundialsReSolve.cmake @@ -0,0 +1,83 @@ +# ----------------------------------------------------------------------------- +# Programmer(s): Slaven Peles @ ORNL +# ----------------------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2025-2026, Lawrence Livermore National Security, +# University of Maryland Baltimore County, and the SUNDIALS contributors. +# Copyright (c) 2013-2025, Lawrence Livermore National Security +# and Southern Methodist University. +# Copyright (c) 2002-2013, Lawrence Livermore National Security. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# ----------------------------------------------------------------------------- +# Module to find and setup ReSolve. +# ReSolve is a GPU-friendly linear solver library developed at ORNL: +# https://github.com/ORNL/ReSolve +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# Section 1: Include guard +# ----------------------------------------------------------------------------- + +include_guard(GLOBAL) + +# ----------------------------------------------------------------------------- +# Section 2: Check to make sure options are compatible +# ----------------------------------------------------------------------------- + +# ReSolve requires C++14 or newer +if(CMAKE_CXX_STANDARD LESS "14") + message(FATAL_ERROR "CMAKE_CXX_STANDARD must be >= 14 when using ReSolve") +endif() + +# ----------------------------------------------------------------------------- +# Section 3: Find the TPL +# ----------------------------------------------------------------------------- + +find_package(ReSolve REQUIRED) + +message(STATUS "ReSolve_LIBRARIES: ${ReSolve_LIBRARIES}") +message(STATUS "ReSolve_INCLUDE_DIR: ${ReSolve_INCLUDE_DIR}") + +# ----------------------------------------------------------------------------- +# Section 4: Test the TPL +# ----------------------------------------------------------------------------- + +if(SUNDIALS_ENABLE_RESOLVE_CHECKS) + + message(CHECK_START "Testing ReSolve") + + set(TEST_DIR ${PROJECT_BINARY_DIR}/RESOLVE_TEST) + + file( + WRITE ${TEST_DIR}/test.cpp + "\#include \n" + "int main(void) {\n" + "ReSolve::SystemSolver solver;\n" + "return 0;\n" + "}\n") + + try_compile( + COMPILE_OK ${TEST_DIR} + ${TEST_DIR}/test.cpp + LINK_LIBRARIES SUNDIALS::ReSolve + OUTPUT_VARIABLE COMPILE_OUTPUT) + + if(COMPILE_OK) + message(CHECK_PASS "success") + else() + message(CHECK_FAIL "failed") + file(WRITE ${TEST_DIR}/compile.out "${COMPILE_OUTPUT}") + message( + FATAL_ERROR + "Could not compile ReSolve test. Check output in ${TEST_DIR}/compile.out" + ) + endif() + +else() + message(STATUS "Skipped ReSolve checks.") +endif() From 08a245370fdecb9f61a0c39644b2b81edee1d31e Mon Sep 17 00:00:00 2001 From: pelesh Date: Tue, 2 Jun 2026 15:34:16 -0400 Subject: [PATCH 02/22] Fix Re::Solve smoke test --- cmake/SundialsSetupCompilers.cmake | 3 ++- cmake/tpl/SundialsReSolve.cmake | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cmake/SundialsSetupCompilers.cmake b/cmake/SundialsSetupCompilers.cmake index 3a82d9b841..58ffca0d6d 100644 --- a/cmake/SundialsSetupCompilers.cmake +++ b/cmake/SundialsSetupCompilers.cmake @@ -438,7 +438,8 @@ if(SUNDIALS_ENABLE_BENCHMARKS OR SUNDIALS_ENABLE_MAGMA OR SUNDIALS_ENABLE_GINKGO OR SUNDIALS_ENABLE_KOKKOS - OR SUNDIALS_ENABLE_ADIAK) + OR SUNDIALS_ENABLE_ADIAK + OR SUNDIALS_ENABLE_RESOLVE) include(SundialsSetupCXX) endif() diff --git a/cmake/tpl/SundialsReSolve.cmake b/cmake/tpl/SundialsReSolve.cmake index 6b152736bb..9c6f4b8a07 100644 --- a/cmake/tpl/SundialsReSolve.cmake +++ b/cmake/tpl/SundialsReSolve.cmake @@ -29,7 +29,15 @@ include_guard(GLOBAL) # Section 2: Check to make sure options are compatible # ----------------------------------------------------------------------------- -# ReSolve requires C++14 or newer +# ReSolve is a C++ library; CXX must be enabled (SundialsSetupCompilers.cmake +# gates include(SundialsSetupCXX) on SUNDIALS_ENABLE_RESOLVE). +if(NOT CMAKE_CXX_COMPILER_LOADED) + message( + FATAL_ERROR + "ReSolve requires C++ but no C++ compiler was found. " + "Enable a C++ compiler or set CMAKE_CXX_COMPILER.") +endif() + if(CMAKE_CXX_STANDARD LESS "14") message(FATAL_ERROR "CMAKE_CXX_STANDARD must be >= 14 when using ReSolve") endif() @@ -53,12 +61,15 @@ if(SUNDIALS_ENABLE_RESOLVE_CHECKS) set(TEST_DIR ${PROJECT_BINARY_DIR}/RESOLVE_TEST) + # Use the self-contained Common.hpp rather than SystemSolver.hpp; the latter + # has missing internal includes in some ReSolve versions. file( WRITE ${TEST_DIR}/test.cpp - "\#include \n" + "\#include \n" "int main(void) {\n" - "ReSolve::SystemSolver solver;\n" - "return 0;\n" + " ReSolve::real_type x = ReSolve::constants::ONE;\n" + " (void)x;\n" + " return 0;\n" "}\n") try_compile( From 675fae507793e1e769d7b1ee00fc5b44758b92cc Mon Sep 17 00:00:00 2001 From: pelesh Date: Tue, 2 Jun 2026 15:55:56 -0400 Subject: [PATCH 03/22] cmake formatting fixes --- cmake/SundialsTPLOptions.cmake | 12 ++++-------- cmake/tpl/FindReSolve.cmake | 16 +++++++++++++--- cmake/tpl/SundialsReSolve.cmake | 15 +++++---------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/cmake/SundialsTPLOptions.cmake b/cmake/SundialsTPLOptions.cmake index 9ec0b61f57..f84a4f540e 100644 --- a/cmake/SundialsTPLOptions.cmake +++ b/cmake/SundialsTPLOptions.cmake @@ -553,8 +553,8 @@ sundials_option( sundials_option(SUNDIALS_ENABLE_RESOLVE BOOL "Enable ReSolve support" OFF) -sundials_option(ReSolve_DIR PATH - "Path to the root of a ReSolve installation" "${ReSolve_DIR}") +sundials_option(ReSolve_DIR PATH "Path to the root of a ReSolve installation" + "${ReSolve_DIR}") sundials_option(ReSolve_INCLUDE_DIR PATH "ReSolve include directory" "${ReSolve_INCLUDE_DIR}" ADVANCED) @@ -562,12 +562,8 @@ sundials_option(ReSolve_INCLUDE_DIR PATH "ReSolve include directory" sundials_option(ReSolve_LIBRARY_DIR PATH "ReSolve library directory" "${ReSolve_LIBRARY_DIR}" ADVANCED) -sundials_option( - SUNDIALS_ENABLE_RESOLVE_CHECKS - BOOL - "Enable ReSolve compatibility checks" - ON - ADVANCED) +sundials_option(SUNDIALS_ENABLE_RESOLVE_CHECKS BOOL + "Enable ReSolve compatibility checks" ON ADVANCED) sundials_option( KokkosKernels_DIR PATH "Path to the root of a Kokkos Kernels installation" diff --git a/cmake/tpl/FindReSolve.cmake b/cmake/tpl/FindReSolve.cmake index 0cc22533e8..8fd9fc7072 100644 --- a/cmake/tpl/FindReSolve.cmake +++ b/cmake/tpl/FindReSolve.cmake @@ -36,10 +36,20 @@ # Prefer the upstream CMake config file if the user did not point to a specific # include/library directory. -if(NOT (ReSolve_INCLUDE_DIR OR ReSolve_LIBRARY_DIR OR ReSolve_LIBRARY)) +if(NOT + (ReSolve_INCLUDE_DIR + OR ReSolve_LIBRARY_DIR + OR ReSolve_LIBRARY)) - find_package(ReSolve CONFIG QUIET PATHS "${ReSolve_DIR}" - PATH_SUFFIXES lib/cmake/ReSolve cmake/ReSolve) + find_package( + ReSolve + CONFIG + QUIET + PATHS + "${ReSolve_DIR}" + PATH_SUFFIXES + lib/cmake/ReSolve + cmake/ReSolve) if(ReSolve_FOUND AND TARGET ReSolve::ReSolve) if(NOT TARGET SUNDIALS::ReSolve) diff --git a/cmake/tpl/SundialsReSolve.cmake b/cmake/tpl/SundialsReSolve.cmake index 9c6f4b8a07..04c8069ac2 100644 --- a/cmake/tpl/SundialsReSolve.cmake +++ b/cmake/tpl/SundialsReSolve.cmake @@ -32,10 +32,8 @@ include_guard(GLOBAL) # ReSolve is a C++ library; CXX must be enabled (SundialsSetupCompilers.cmake # gates include(SundialsSetupCXX) on SUNDIALS_ENABLE_RESOLVE). if(NOT CMAKE_CXX_COMPILER_LOADED) - message( - FATAL_ERROR - "ReSolve requires C++ but no C++ compiler was found. " - "Enable a C++ compiler or set CMAKE_CXX_COMPILER.") + message(FATAL_ERROR "ReSolve requires C++ but no C++ compiler was found. " + "Enable a C++ compiler or set CMAKE_CXX_COMPILER.") endif() if(CMAKE_CXX_STANDARD LESS "14") @@ -65,12 +63,9 @@ if(SUNDIALS_ENABLE_RESOLVE_CHECKS) # has missing internal includes in some ReSolve versions. file( WRITE ${TEST_DIR}/test.cpp - "\#include \n" - "int main(void) {\n" - " ReSolve::real_type x = ReSolve::constants::ONE;\n" - " (void)x;\n" - " return 0;\n" - "}\n") + "\#include \n" "int main(void) {\n" + " ReSolve::real_type x = ReSolve::constants::ONE;\n" " (void)x;\n" + " return 0;\n" "}\n") try_compile( COMPILE_OK ${TEST_DIR} From 0b67630e44b18c6d3abebf484e9146a12ea0f23f Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Wed, 3 Jun 2026 15:12:51 -0400 Subject: [PATCH 04/22] Modified the try_compile test to link ReSolve::ReSolve instead of the alias. The ReSolve tests now pass. --- cmake/SundialsTPLOptions.cmake | 28 ++++++++++++++-------------- cmake/tpl/SundialsReSolve.cmake | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/cmake/SundialsTPLOptions.cmake b/cmake/SundialsTPLOptions.cmake index f84a4f540e..98fe8ac331 100644 --- a/cmake/SundialsTPLOptions.cmake +++ b/cmake/SundialsTPLOptions.cmake @@ -547,6 +547,20 @@ sundials_option( SUNDIALS_ENABLE_KOKKOS_KERNELS BOOL "Enable Kokkos Kernels support" OFF DEPRECATED_NAMES ENABLE_KOKKOS_KERNELS) +sundials_option( + KokkosKernels_DIR PATH "Path to the root of a Kokkos Kernels installation" + "${KokkosKernels_DIR}") + +sundials_option( + SUNDIALS_ENABLE_KOKKOS_KERNELS_CHECKS + BOOL + "Enable Kokkos Kernels compatibility checks" + ON + ADVANCED + DEPRECATED_NAMES + KOKKOS_KERNELS_WORKS + NEGATE_DEPRECATED) + # --------------------------------------------------------------- # Enable ReSolve support? # --------------------------------------------------------------- @@ -564,17 +578,3 @@ sundials_option(ReSolve_LIBRARY_DIR PATH "ReSolve library directory" sundials_option(SUNDIALS_ENABLE_RESOLVE_CHECKS BOOL "Enable ReSolve compatibility checks" ON ADVANCED) - -sundials_option( - KokkosKernels_DIR PATH "Path to the root of a Kokkos Kernels installation" - "${KokkosKernels_DIR}") - -sundials_option( - SUNDIALS_ENABLE_KOKKOS_KERNELS_CHECKS - BOOL - "Enable Kokkos Kernels compatibility checks" - ON - ADVANCED - DEPRECATED_NAMES - KOKKOS_KERNELS_WORKS - NEGATE_DEPRECATED) diff --git a/cmake/tpl/SundialsReSolve.cmake b/cmake/tpl/SundialsReSolve.cmake index 04c8069ac2..7aded013d3 100644 --- a/cmake/tpl/SundialsReSolve.cmake +++ b/cmake/tpl/SundialsReSolve.cmake @@ -70,7 +70,7 @@ if(SUNDIALS_ENABLE_RESOLVE_CHECKS) try_compile( COMPILE_OK ${TEST_DIR} ${TEST_DIR}/test.cpp - LINK_LIBRARIES SUNDIALS::ReSolve + LINK_LIBRARIES ReSolve::ReSolve OUTPUT_VARIABLE COMPILE_OUTPUT) if(COMPILE_OK) From 3078b644b83aa9a75ef0225e93042129c3930be2 Mon Sep 17 00:00:00 2001 From: pelesh Date: Wed, 3 Jun 2026 16:52:09 -0400 Subject: [PATCH 05/22] Add Re::Solve build to the CI pipeline --- .github/hubcast.yml | 46 ++++++++++--------- .../spack-nightly/int32-double/spack.yaml | 1 + .../spack-nightly/int64-double/spack.yaml | 1 + test/config_cmake.py | 24 ++++++++++ test/env/docker.sh | 12 +++++ 5 files changed, 63 insertions(+), 21 deletions(-) diff --git a/.github/hubcast.yml b/.github/hubcast.yml index bf7f35e28f..8989f9e6e8 100644 --- a/.github/hubcast.yml +++ b/.github/hubcast.yml @@ -1,21 +1,25 @@ -Repo: - # Required: organization or user that owns the repo on CZ GitLab - dest_org: sundials - - # Required: name of the destination repository on CZ GitLab - dest_name: sundials - - # Optional: name of the CI check as reported back to GitHub (default: gitlab-ci) - check_name: llnl-lc-gitlab-ci - - # Optional: granularity of CI statuses reported to GitHub (default: [pipeline]) - # Set to [pipeline] for overall pipeline status only - # Set to [jobs] for individual job statuses only - # Set to [pipeline, jobs] to report both - check_types: [pipeline, jobs] - - # Optional: delete branches from destination when source PR is closed (default: true) - delete_closed: true - - # Optional: sync draft PRs/MRs (default: true) - sync_drafts: true +# Hubcast configuration is disabled; CI runs on GitHub-hosted resources only. +# To re-enable mirroring to LLNL CZ GitLab (and the llnl-lc-gitlab-ci checks +# on LLNL clusters), uncomment the block below. +# +# Repo: +# # Required: organization or user that owns the repo on CZ GitLab +# dest_org: sundials +# +# # Required: name of the destination repository on CZ GitLab +# dest_name: sundials +# +# # Optional: name of the CI check as reported back to GitHub (default: gitlab-ci) +# check_name: llnl-lc-gitlab-ci +# +# # Optional: granularity of CI statuses reported to GitHub (default: [pipeline]) +# # Set to [pipeline] for overall pipeline status only +# # Set to [jobs] for individual job statuses only +# # Set to [pipeline, jobs] to report both +# check_types: [pipeline, jobs] +# +# # Optional: delete branches from destination when source PR is closed (default: true) +# delete_closed: true +# +# # Optional: sync draft PRs/MRs (default: true) +# sync_drafts: true diff --git a/docker/sundials-ci/spack-nightly/int32-double/spack.yaml b/docker/sundials-ci/spack-nightly/int32-double/spack.yaml index 4291a71a27..cbb78c8e50 100644 --- a/docker/sundials-ci/spack-nightly/int32-double/spack.yaml +++ b/docker/sundials-ci/spack-nightly/int32-double/spack.yaml @@ -20,6 +20,7 @@ spack: - superlu-dist~int64 ^parmetis~int64 arch=x86_64 %gcc@9.4.0 - trilinos+tpetra gotype=int arch=x86_64 %gcc@9.4.0 - xbraid arch=x86_64 %gcc@9.4.0 + - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 config: install_tree: /opt/software mirrors: diff --git a/docker/sundials-ci/spack-nightly/int64-double/spack.yaml b/docker/sundials-ci/spack-nightly/int64-double/spack.yaml index 2e0f859aa6..50b380d64b 100644 --- a/docker/sundials-ci/spack-nightly/int64-double/spack.yaml +++ b/docker/sundials-ci/spack-nightly/int64-double/spack.yaml @@ -20,6 +20,7 @@ spack: - superlu-dist+int64 ^parmetis+int64 ^netlib-lapack arch=x86_64 %gcc@9.4.0 - trilinos+tpetra gotype=long_long arch=x86_64 %gcc@9.4.0 - xbraid arch=x86_64 %gcc@9.4.0 + - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 config: install_tree: /opt/software mirrors: diff --git a/test/config_cmake.py b/test/config_cmake.py index a208260299..bb02013388 100644 --- a/test/config_cmake.py +++ b/test/config_cmake.py @@ -1156,6 +1156,30 @@ def main(): dependson="--xbraid", ) + # ReSolve + group = parser.add_argument_group("ReSolve Options") + + add_arg( + group, + "--resolve", + "SUNDIALS_RESOLVE", + "SUNDIALS_ENABLE_RESOLVE", + "OFF", + "BOOL", + "SUNDIALS ReSolve support", + ) + + add_arg( + group, + "--resolve-dir", + "RESOLVE_ROOT", + "ReSolve_DIR", + None, + "PATH", + "ReSolve install directory", + dependson="--resolve", + ) + # -------- # Testing # -------- diff --git a/test/env/docker.sh b/test/env/docker.sh index b26abc1cd1..88080b8a8d 100644 --- a/test/env/docker.sh +++ b/test/env/docker.sh @@ -360,3 +360,15 @@ else export SUNDIALS_XBRAID=OFF unset XBRAID_ROOT fi + +# ------- +# resolve +# ------- + +if [ "$SUNDIALS_PRECISION" == "double" ]; then + export SUNDIALS_RESOLVE=ON + export RESOLVE_ROOT=/opt/view +else + export SUNDIALS_RESOLVE=OFF + unset RESOLVE_ROOT +fi From 0bc7bb02cd70ec99ca6459fc6962368c4bb44a9b Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 9 Jun 2026 21:36:20 -0400 Subject: [PATCH 06/22] Create the SUNMatrix_ReSolve class --- cmake/SundialsBuildOptionsPost.cmake | 7 + include/sundials/sundials_matrix.h | 1 + include/sunmatrix/sunmatrix_resolve.h | 94 +++++++ src/sunmatrix/CMakeLists.txt | 4 + src/sunmatrix/resolve/CMakeLists.txt | 49 ++++ src/sunmatrix/resolve/sunmatrix_resolve.cpp | 276 ++++++++++++++++++++ 6 files changed, 431 insertions(+) create mode 100644 include/sunmatrix/sunmatrix_resolve.h create mode 100644 src/sunmatrix/resolve/CMakeLists.txt create mode 100644 src/sunmatrix/resolve/sunmatrix_resolve.cpp diff --git a/cmake/SundialsBuildOptionsPost.cmake b/cmake/SundialsBuildOptionsPost.cmake index 23df261a95..8ee00f746c 100644 --- a/cmake/SundialsBuildOptionsPost.cmake +++ b/cmake/SundialsBuildOptionsPost.cmake @@ -201,6 +201,13 @@ sundials_option( ADVANCED DEPRECATED_NAMES BUILD_SUNMATRIX_ONEMKLDENSE) list(APPEND SUNDIALS_BUILD_LIST "SUNDIALS_ENABLE_SUNMATRIX_ONEMKLDENSE") +sundials_option( + SUNDIALS_ENABLE_SUNMATRIX_RESOLVE BOOL + "Enable the SUNMATRIX_RESOLVE module (requires Re::Solve)" ON + DEPENDS_ON SUNDIALS_ENABLE_RESOLVE + ADVANCED DEPRECATED_NAMES BUILD_SUNMATRIX_RESOLVE) +list(APPEND SUNDIALS_BUILD_LIST "SUNDIALS_ENABLE_SUNMATRIX_RESOLVE") + sundials_option( SUNDIALS_ENABLE_SUNMATRIX_SLUNRLOC BOOL "Enable the SUNMATRIX_SLUNRLOC module (requires SuperLU_DIST)" ON diff --git a/include/sundials/sundials_matrix.h b/include/sundials/sundials_matrix.h index e89dede7c0..6dedeff29e 100644 --- a/include/sundials/sundials_matrix.h +++ b/include/sundials/sundials_matrix.h @@ -72,6 +72,7 @@ enum SUNMatrix_ID SUNMATRIX_GINKGO, SUNMATRIX_GINKGOBATCH, SUNMATRIX_KOKKOSDENSE, + SUNMATRIX_RESOLVE, SUNMATRIX_CUSTOM }; diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h new file mode 100644 index 0000000000..e7704cafec --- /dev/null +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -0,0 +1,94 @@ +/* + * ----------------------------------------------------------------- + * Programmer(s): Jeffery Zhang + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025-2026, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the header file for the sparse implementation of the + * SUNMATRIX module, SUNMATRIX_RESOLVE. + * ----------------------------------------------------------------- + */ + +#ifndef _SUNMATRIX_RESOLVE_H +#define _SUNMATRIX_RESOLVE_H + +#include +#include +#include +#include +#include + + +// #if defined(SUNDIALS_MAGMA_BACKENDS_CUDA) +// #define HAVE_CUBLAS +// #elif defined(SUNDIALS_MAGMA_BACKENDS_HIP) +// #define HAVE_HIP +// #endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +struct _SUNMatrixContent_ReSolve +{ + sunindextype M; + sunindextype N; + sunindextype NNZ; + sunindextype NP; + ReSolve::matrix::Csr* mat; +}; + +typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; + +/* --------------------------------------- + * Implementation specific functions + * ---------------------------------------*/ + +SUNDIALS_EXPORT SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, sunindextype NNZ, + ReSolve::memory::MemorySpace memspace, + SUNContext sunctx); + +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A); + +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A); + +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); + +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A); + +SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +/* --------------------------------------- + * SUNMatrix API functions + * ---------------------------------------*/ + +static inline SUNMatrix_ID SUNMatGetID_ReSolve(SUNMatrix A) +{ + return SUNMATRIX_RESOLVE; +} + +SUNDIALS_EXPORT void SUNMatDestroy_ReSolve(SUNMatrix A); +SUNDIALS_EXPORT SUNErrCode SUNMatZero_ReSolve(SUNMatrix A); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sunmatrix/CMakeLists.txt b/src/sunmatrix/CMakeLists.txt index e61aed9513..6618c0ff88 100644 --- a/src/sunmatrix/CMakeLists.txt +++ b/src/sunmatrix/CMakeLists.txt @@ -76,6 +76,10 @@ if(SUNDIALS_ENABLE_SUNMATRIX_ONEMKLDENSE) add_subdirectory(onemkldense) endif() +if(SUNDIALS_ENABLE_SUNMATRIX_RESOLVE) + add_subdirectory(resolve) +endif() + if(SUNDIALS_ENABLE_SUNMATRIX_SLUNRLOC) add_subdirectory(slunrloc) endif() diff --git a/src/sunmatrix/resolve/CMakeLists.txt b/src/sunmatrix/resolve/CMakeLists.txt new file mode 100644 index 0000000000..a2562559d5 --- /dev/null +++ b/src/sunmatrix/resolve/CMakeLists.txt @@ -0,0 +1,49 @@ +# --------------------------------------------------------------- +# Programmer(s): Jeffery Zhang +# --------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2025-2026, Lawrence Livermore National Security, +# University of Maryland Baltimore County, and the SUNDIALS contributors. +# Copyright (c) 2013-2025, Lawrence Livermore National Security +# and Southern Methodist University. +# Copyright (c) 2002-2013, Lawrence Livermore National Security. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# --------------------------------------------------------------- + +# TODO Add ReSolve Backends for now hardcode cpu + +install( + CODE "MESSAGE(\"\nInstall SUNMATRIX_RESOLVE with CPU backend(s)\n\")" +) + +# if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") +# set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CUDA) +# set(_libs_needed sundials_nveccuda) +# elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") +# set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CXX) +# set(_libs_needed sundials_nvechip hip::device) +# endif() + +# Add the sunmatrix_resolve library +sundials_add_library( + sundials_sunmatrixresolve + SOURCES sunmatrix_resolve.cpp + HEADERS ${SUNDIALS_SOURCE_DIR}/include/sunmatrix/sunmatrix_resolve.h + INCLUDE_SUBDIR sunmatrix + LINK_LIBRARIES PUBLIC sundials_core + OBJECT_LIBRARIES + INCLUDE_DIRECTORIES PUBLIC ${ReSolve_INCLUDE_DIR} + LINK_LIBRARIES PUBLIC SUNDIALS::ReSolve ${_libs_needed} + OUTPUT_NAME sundials_sunmatrixresolve + VERSION ${sunmatrixlib_VERSION} + SOVERSION ${sunmatrixlib_SOVERSION}) + +message( + STATUS + "Added SUNMATRIX_RESOLVE module with CPU backend(s)" +) diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp new file mode 100644 index 0000000000..db7d560a42 --- /dev/null +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -0,0 +1,276 @@ +/* --------------------------------------------------------------------------- + * Programmer(s): Jeffery Zhang + * --------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025-2026, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * --------------------------------------------------------------------------- + * This is the implementation file for the dense implementation of the + * SUNMATRIX class using the Re::Solve library + * ---------------------------------------------------------------------------*/ + + +#include +#include + +// Re::Solve headers +#include +#include +#include +#include +#include + +// SUNDIALS headers +#include +#include +#include +#include "sundials/sundials_errors.h" +#include "sundials_debug.h" +#include "sundials_macros.h" + +// Check for a valid precision +#if defined(SUNDIALS_EXTENDED_PRECISION) +#error "Re::Solve set precision does not match SUNDIALS precision for floating type" +#endif + +#if defined(SUNDIALS_INT64_T) +#error "Re::Solve set precision does not match SUNDIALS precision for indices" +#endif + +// Constants +#define ZERO SUN_RCONST(0.0) +#define ONE SUN_RCONST(1.0) + +// Content accessor macro +#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT +#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) +#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) +#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) +#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) +#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) + +// TODO add checks for gpu memspace + + +/* -------------------------------------------------------------------------- + * Constructor + * -------------------------------------------------------------------------- */ + +// TODO Add ability to choose format. Currently, constructor assumes CSR format +SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, + ReSolve::memory::MemorySpace memspace, SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + SUNMatrixContent_ReSolve content; + + // Check inputs + if ((m <= 0) || (n <= 0) || (nnz < 0)) + { + SUNDIALS_DEBUG_ERROR("Illegal input\n"); + return NULL; + } + + // Create an empty matrix object + SUNMatrix A = SUNMatNewEmpty(sunctx); + if (!A) + { + SUNDIALS_DEBUG_ERROR("SUNMatNewEmpty returned NULL\n"); + return NULL; + } + + // Attach operations + A->ops->getid = SUNMatGetID_ReSolve; + A->ops->destroy = SUNMatDestroy_ReSolve; + A->ops->zero = SUNMatZero_ReSolve; + + // Create ReSolve matrix + ReSolve::matrix::Csr* mat = new ReSolve::matrix::Csr(m, n, nnz); + mat->allocateMatrixData(memspace); + + /* Create content */ + content = NULL; + content = (SUNMatrixContent_ReSolve)malloc(sizeof *content); + SUNAssertNull(content, SUN_ERR_MALLOC_FAIL); + + /* Attach content */ + A->content = content; + + /* Fill content */ + content->M = m; + content->N = n; + content->NNZ = nnz; + content->NP = m; + content->mat = mat; + + + if (!(A->content)) + { + SUNDIALS_DEBUG_ERROR("Content allocation failed\n"); + SUNMatDestroy(A); + return NULL; + } + + return A; +} + +/* -------------------------------------------------------------------------- + * Implementation specific functions + * -------------------------------------------------------------------------- */ + +sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); + return RESOLVE_M(A); +} + +sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); + return RESOLVE_N(A); +} + +sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); + return RESOLVE_NNZ(A); +} + +sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); + return RESOLVE_NP(A); +} + +/** + Get the pointer to the ReSolve matrix data array + The pointer is always to the array stored on the host + + @param A The SUNMatrix object +*/ +sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + return RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); +} + +/** + Get the pointer to the ReSolve matrix offsets array + The pointer is always to the array stored on the host + + @param A The SUNMatrix object +*/ +sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + return RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); +} + +/** + Get the pointer to the ReSolve matrix indices array + The pointer is always to the array stored on the host + + @param A The SUNMatrix object +*/ +sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + return RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); +} + +/** + Print the Re::Solve matrix +*/ +void SUNMatrix_ReSolve_Print(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + RESOLVE_MAT(A)->print(std::cout, 0); +} + +/* -------------------------------------------------------------------------- + * Implementation of generic SUNMatrix operations. + * -------------------------------------------------------------------------- */ + +void SUNMatDestroy_ReSolve(SUNMatrix A) +{ + if (!A) + { + SUNDIALS_DEBUG_ERROR("Input matrix is NULL\n"); + return; + } + + if (SUNMatGetID(A) != SUNMATRIX_RESOLVE) + { + SUNDIALS_DEBUG_ERROR("Invalid matrix ID\n"); + return; + } + + // Free ReSolve matrix + delete RESOLVE_MAT(A); + + /* free content struct */ + free(A->content); + A->content = NULL; + + /* free ops and matrix */ + if (A->ops) + { + free(A->ops); + A->ops = NULL; + } + + // Free matrix + SUNMatFreeEmpty(A); + A = NULL; + + return; +} + +SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) +{ + if (!A) + { + SUNDIALS_DEBUG_ERROR("Input matrix is NULL\n"); + return SUN_ERR_ARG_INCOMPATIBLE; + } + + if (SUNMatGetID(A) != SUNMATRIX_RESOLVE) + { + SUNDIALS_DEBUG_ERROR("Invalid matrix ID\n"); + return SUN_ERR_ARG_INCOMPATIBLE; + } + + sunindextype i; + // TODO sync between device and data + + // Get pointers to the data, indexvalues and indexpointers arrays in ReSolve + sunrealtype* values = RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); + + sunindextype* index_pointers = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); + + sunindextype* index_values = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); + + // Zero out the values of these arrays + for (i = 0; i < RESOLVE_NNZ(A); i++) + { + values[i] = ZERO; + index_values[i] = 0; + } + + for (i = 0; i < RESOLVE_NP(A); i++) + { + index_pointers[i] = 0; + } + + (index_pointers)[RESOLVE_NP(A)] = 0; + + return SUN_SUCCESS; +} From cc5a82c696b70d0aa514bed9c15f633cbf4552de Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 9 Jun 2026 21:37:02 -0400 Subject: [PATCH 07/22] Simple unit tests --- test/unit_tests/sunmatrix/CMakeLists.txt | 4 + .../sunmatrix/resolve/CMakeLists.txt | 64 +++++++ .../resolve/test_sunmatrix_resolve.cpp | 166 ++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 test/unit_tests/sunmatrix/resolve/CMakeLists.txt create mode 100644 test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp diff --git a/test/unit_tests/sunmatrix/CMakeLists.txt b/test/unit_tests/sunmatrix/CMakeLists.txt index 5a828f6222..27117805ef 100644 --- a/test/unit_tests/sunmatrix/CMakeLists.txt +++ b/test/unit_tests/sunmatrix/CMakeLists.txt @@ -60,6 +60,10 @@ if(SUNDIALS_ENABLE_SUNMATRIX_ONEMKLDENSE) add_subdirectory(onemkldense) endif() +if(SUNDIALS_ENABLE_SUNMATRIX_RESOLVE) + add_subdirectory(resolve) +endif() + if(SUNDIALS_ENABLE_SUNMATRIX_SLUNRLOC) add_subdirectory(slunrloc) endif() diff --git a/test/unit_tests/sunmatrix/resolve/CMakeLists.txt b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt new file mode 100644 index 0000000000..752df8547b --- /dev/null +++ b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt @@ -0,0 +1,64 @@ +# ------------------------------------------------------------------------------ +# Programmer(s): [Your name] +# ------------------------------------------------------------------------------ +# SUNDIALS Copyright Start +# Copyright (c) 2025-2026, Lawrence Livermore National Security, +# University of Maryland Baltimore County, and the SUNDIALS contributors. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# ------------------------------------------------------------------------------ + +set(examples_list + "test_sunmatrix_resolve.cpp\;\;") + +# Add source directory to include directories +include_directories(..) + +foreach(example_tuple ${examples_list}) + # parse the example tuple + list(GET example_tuple 0 example) + list(GET example_tuple 1 example_args) + list(GET example_tuple 2 example_type) + + # extract the file name without extension + get_filename_component(example_target ${example} NAME_WE) + + if(NOT TARGET ${example_target}) + # example source files + sundials_add_executable( + ${example_target} + ${example} + ../test_sunmatrix.c + ../test_sunmatrix.h) + + # folder for IDEs + set_target_properties(${example_target} PROPERTIES FOLDER "Examples") + + # libraries to link against + target_link_libraries( + ${example_target} + PRIVATE sundials_core + sundials_sunmatrixresolve + ReSolve::ReSolve + ${EXE_EXTRA_LINK_LIBS}) + endif() + + # set test name + if("${example_args}" STREQUAL "") + set(test_name ${example_target}) + else() + string(REGEX REPLACE " " "_" test_name ${example_target}_${example_args}) + endif() + + # add to regression tests + sundials_add_test( + ${test_name} ${example_target} + TEST_ARGS ${example_args} + EXAMPLE_TYPE ${example_type} + NODIFF) + +endforeach() \ No newline at end of file diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp new file mode 100644 index 0000000000..40e3409260 --- /dev/null +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -0,0 +1,166 @@ +/* + * ----------------------------------------------------------------- + * Programmer(s): Jeffery Zhang + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025-2026, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the testing routine to check the SUNMatrix ReSolve module + * implementation. + * ----------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include + +#include "test_sunmatrix.h" + +/* ---------------------------------------------------------------------- + * Main SUNMatrix Testing Routine + * --------------------------------------------------------------------*/ +int main(int argc, char* argv[]) +{ + int fails = 0; /* counter for test failures */ +// sunindextype matrows, matcols; /* matrix dims */ + SUNMatrix A; + sunindextype i, j, k, kstart, kend, N, uband, lband; + int print_timing, square; + SUNContext sunctx; + + if (SUNContext_Create(SUN_COMM_NULL, &sunctx)) + { + printf("ERROR: SUNContext_Create failed\n"); + return (-1); + } + +// /* check input and set vector length */ +// if (argc < 5) +// { +// printf("ERROR: FOUR (4) Input required: matrix rows, matrix cols, matrix " +// "type (0/1), print timing \n"); +// return (-1); +// } + +// matrows = (sunindextype)atol(argv[1]); +// if (matrows < 1) +// { +// printf("ERROR: number of rows must be a positive integer\n"); +// return (-1); +// } + +// matcols = (sunindextype)atol(argv[2]); +// if (matcols < 1) +// { +// printf("ERROR: number of cols must be a positive integer\n"); +// return (-1); +// } + + // Initialize a ReSolve HOST memory space. + ReSolve::memory::MemorySpace memspace = ReSolve::memory::HOST; + // Create a SUNMatrix_ReSolve object + A = NULL; + A = SUNMatrix_ReSolve(5, 5, 13, memspace, sunctx); + + // Get pointers to content arrays + sunrealtype* data = SUNMatrix_ReSolve_Data(A, memspace); + sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, memspace); + sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, memspace); + + // Fill the matrix as a 5x5 second difference matrix + for (i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) + { + if (i % 3 == 0) + { + data[i] = 2; + } + else + { + data[i] = -1; + } + } + + // Row pointers — how many non-zeros before each row + index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) + index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) + index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) + index_pointers[3] = 8; // row 3 starts at 8 (3 non-zeros) + index_pointers[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) + index_pointers[5] = 13; // total non-zeros + + // Column indices + index_values[0] = 0; index_values[1] = 1; // row 0: cols 0, 1 + index_values[2] = 0; index_values[3] = 1; index_values[4] = 2; // row 1: cols 0, 1, 2 + index_values[5] = 1; index_values[6] = 2; index_values[7] = 3; // row 2: cols 1, 2, 3 + index_values[8] = 2; index_values[9] = 3; index_values[10] = 4; // row 3: cols 2, 3, 4 + index_values[11] = 3; index_values[12] = 4; // row 4: cols 3, 4 + + // Print the second difference matrix + SUNMatrix_ReSolve_Print(A, memspace); + + // Set the matrix to zero + SUNMatZero_ReSolve(A); + + // Print empty matrix + SUNMatrix_ReSolve_Print(A, memspace); + + // Destroy the SUNMatrix_ReSolve object + SUNMatDestroy_ReSolve(A); + + return 0; +} + +/* ---------------------------------------------------------------------- + * Check matrix + * --------------------------------------------------------------------*/ + +// Currently stubs +int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) +{ + int failure = 0; + sunrealtype *Adata, *Bdata; + sunindextype *Aindexptrs, *Bindexptrs; + sunindextype *Aindexvals, *Bindexvals; + sunindextype i, ANP, BNP, Annz, Bnnz; + + return (0); +} + +int check_matrix_entry(SUNMatrix A, sunrealtype val, sunrealtype tol) +{ + return (0); +} + +int check_vector(N_Vector x, N_Vector y, sunrealtype tol) +{ + return 0; +} + +sunbooleantype has_data(SUNMatrix A) +{ + return SUNTRUE; +} + +sunbooleantype is_square(SUNMatrix A) +{ + if (SUNMatrix_ReSolve_Rows(A) == SUNMatrix_ReSolve_Columns(A)) { return SUNTRUE; } + else { return SUNFALSE; } +} + +void sync_device(SUNMatrix A) +{ + /* not running on GPU, just return */ + return; +} \ No newline at end of file From 6e2ff038c1904ef7360df30be73a8b36766ef9f2 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 16 Jun 2026 23:05:27 -0400 Subject: [PATCH 08/22] Add GPU support for the SUNMatrix_ReSolve class and implemented functions to use sunmatrix generic tests --- cmake/SundialsSetupConfig.cmake | 5 + cmake/SundialsTPLOptions.cmake | 7 + cmake/tpl/FindReSolve.cmake | 17 ++ cmake/tpl/SundialsReSolve.cmake | 1 + include/sundials/sundials_config.in | 5 + include/sunmatrix/sunmatrix_resolve.h | 10 +- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 129 +++++++++--- .../sunmatrix/resolve/CMakeLists.txt | 12 +- .../resolve/test_sunmatrix_resolve.cpp | 190 ++++++++++++++---- 9 files changed, 309 insertions(+), 67 deletions(-) diff --git a/cmake/SundialsSetupConfig.cmake b/cmake/SundialsSetupConfig.cmake index 1bf49bee9d..21316890d8 100644 --- a/cmake/SundialsSetupConfig.cmake +++ b/cmake/SundialsSetupConfig.cmake @@ -87,6 +87,11 @@ foreach(backend ${SUNDIALS_MAGMA_BACKENDS}) set(SUNDIALS_MAGMA_BACKENDS_${backend} TRUE) endforeach() +# prepare substitution variable(s) SUNDIALS_RESOLVE_BACKENDS_* +foreach(backend ${SUNDIALS_RESOLVE_BACKENDS}) + set(SUNDIALS_RESOLVE_BACKENDS_${backend} TRUE) +endforeach() + # prepare substitution variable SUNDIALS_HAVE_POSIX_TIMERS for sundials_config.h if(SUNDIALS_POSIX_TIMERS) # set in SundialsPOSIXTimers.cmake set(SUNDIALS_HAVE_POSIX_TIMERS TRUE) diff --git a/cmake/SundialsTPLOptions.cmake b/cmake/SundialsTPLOptions.cmake index 98fe8ac331..d730494b80 100644 --- a/cmake/SundialsTPLOptions.cmake +++ b/cmake/SundialsTPLOptions.cmake @@ -567,6 +567,13 @@ sundials_option( sundials_option(SUNDIALS_ENABLE_RESOLVE BOOL "Enable ReSolve support" OFF) +sundials_option( + SUNDIALS_RESOLVE_BACKENDS STRING + "Which ReSolve backend to use under the SUNDIALS ReSolve interfaces (CPU, CUDA, HIP)" + "CPU" + OPTIONS "CPU;CUDA;HIP" + DEPENDS_ON SUNDIALS_ENABLE_RESOLVE) + sundials_option(ReSolve_DIR PATH "Path to the root of a ReSolve installation" "${ReSolve_DIR}") diff --git a/cmake/tpl/FindReSolve.cmake b/cmake/tpl/FindReSolve.cmake index 8fd9fc7072..560fb631da 100644 --- a/cmake/tpl/FindReSolve.cmake +++ b/cmake/tpl/FindReSolve.cmake @@ -36,6 +36,7 @@ # Prefer the upstream CMake config file if the user did not point to a specific # include/library directory. + if(NOT (ReSolve_INCLUDE_DIR OR ReSolve_LIBRARY_DIR @@ -55,6 +56,22 @@ if(NOT if(NOT TARGET SUNDIALS::ReSolve) add_library(SUNDIALS::ReSolve ALIAS ReSolve::ReSolve) endif() + + # Check for CUDA backend + if(TARGET ReSolve::CUDA) + set(RESOLVE_CUDA_FOUND TRUE CACHE BOOL "ReSolve CUDA backend found") + if(NOT TARGET SUNDIALS::ReSolve_CUDA) + add_library(SUNDIALS::ReSolve_CUDA ALIAS ReSolve::resolve_backend_cuda) + endif() + endif() + + # Check for HIP backend + if(TARGET ReSolve::HIP) + set(RESOLVE_HIP_FOUND TRUE CACHE BOOL "ReSolve HIP backend found") + if(NOT TARGET SUNDIALS::ReSolve_HIP) + add_library(SUNDIALS::ReSolve_HIP ALIAS ReSolve::resolve_backend_hip) + endif() + endif() return() endif() diff --git a/cmake/tpl/SundialsReSolve.cmake b/cmake/tpl/SundialsReSolve.cmake index 7aded013d3..0e553df60d 100644 --- a/cmake/tpl/SundialsReSolve.cmake +++ b/cmake/tpl/SundialsReSolve.cmake @@ -48,6 +48,7 @@ find_package(ReSolve REQUIRED) message(STATUS "ReSolve_LIBRARIES: ${ReSolve_LIBRARIES}") message(STATUS "ReSolve_INCLUDE_DIR: ${ReSolve_INCLUDE_DIR}") +message(STATUS "SUNDIALS_RESOLVE_BACKENDS: ${SUNDIALS_RESOLVE_BACKENDS}") # ----------------------------------------------------------------------------- # Section 4: Test the TPL diff --git a/include/sundials/sundials_config.in b/include/sundials/sundials_config.in index 662807c61d..75adbbedca 100644 --- a/include/sundials/sundials_config.in +++ b/include/sundials/sundials_config.in @@ -236,6 +236,11 @@ #cmakedefine SUNDIALS_MAGMA_BACKENDS_CUDA #cmakedefine SUNDIALS_MAGMA_BACKENDS_HIP +/* ReSolve backends */ +#cmakedefine SUNDIALS_RESOLVE_BACKENDS_CPU +#cmakedefine SUNDIALS_RESOLVE_BACKENDS_CUDA +#cmakedefine SUNDIALS_RESOLVE_BACKENDS_HIP + /* Set if SUNDIALS is built with MPI support, then * #define SUNDIALS_MPI_ENABLED 1 * otherwise diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index e7704cafec..02b94539c7 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -46,6 +46,7 @@ struct _SUNMatrixContent_ReSolve sunindextype N; sunindextype NNZ; sunindextype NP; + ReSolve::memory::MemorySpace memspace; ReSolve::matrix::Csr* mat; }; @@ -73,7 +74,13 @@ SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); + +SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A); + +//SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print_Array(SUNMatrix A); /* --------------------------------------- * SUNMatrix API functions @@ -86,6 +93,7 @@ static inline SUNMatrix_ID SUNMatGetID_ReSolve(SUNMatrix A) SUNDIALS_EXPORT void SUNMatDestroy_ReSolve(SUNMatrix A); SUNDIALS_EXPORT SUNErrCode SUNMatZero_ReSolve(SUNMatrix A); +SUNDIALS_EXPORT SUNMatrix SUNMatClone_ReSolve(SUNMatrix A); #ifdef __cplusplus } diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index db7d560a42..00a1eca52f 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -51,15 +51,13 @@ #define ONE SUN_RCONST(1.0) // Content accessor macro -#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT -#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) -#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) -#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) -#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) -#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) - -// TODO add checks for gpu memspace - +#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT +#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) +#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) +#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) +#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) +#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) +#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) /* -------------------------------------------------------------------------- * Constructor @@ -91,10 +89,16 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, A->ops->getid = SUNMatGetID_ReSolve; A->ops->destroy = SUNMatDestroy_ReSolve; A->ops->zero = SUNMatZero_ReSolve; + A->ops->clone = SUNMatClone_ReSolve; // Create ReSolve matrix ReSolve::matrix::Csr* mat = new ReSolve::matrix::Csr(m, n, nnz); - mat->allocateMatrixData(memspace); + mat->allocateMatrixData(ReSolve::memory::HOST); + // Allocate matrix on device if necessary + if (memspace == ReSolve::memory::DEVICE) + { + mat->allocateMatrixData(memspace); + } /* Create content */ content = NULL; @@ -110,6 +114,7 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, content->NNZ = nnz; content->NP = m; content->mat = mat; + content->memspace = memspace; if (!(A->content)) @@ -156,45 +161,106 @@ sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A) /** Get the pointer to the ReSolve matrix data array - The pointer is always to the array stored on the host - @param A The SUNMatrix object + @param[in] A The SUNMatrix object */ sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { - return RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); + return RESOLVE_MAT(A)->getValues(memspace); } /** Get the pointer to the ReSolve matrix offsets array - The pointer is always to the array stored on the host - @param A The SUNMatrix object + @param[in] A The SUNMatrix object */ sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { - return RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); + return RESOLVE_MAT(A)->getRowData(memspace); } /** Get the pointer to the ReSolve matrix indices array - The pointer is always to the array stored on the host - @param A The SUNMatrix object + @param[in] A The SUNMatrix object */ sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { - return RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); + return RESOLVE_MAT(A)->getColData(memspace); +} + +/** + * @brief Tags `memspace` as updated. + * + * @param[in] memspace - memory space (HOST or DEVICE) to set to "updated" + * + * @return 0 if successful, -1 if not. + * + * The method sets the boolean flag indicating that the `memspace` is updated. + * It automatically sets the other data mirror to non-updated. You would + * use this function if you update matrix data by accessing its raw pointers. + * In such case, the matrix has no way of knowing which data is most recent, so + * you have to tell it. + * + * @warning This is an expert-level function. Use only if you know what you are + * doing. + * + * @note If you want to set both DEVICE and HOST memory to the same value + * use syncData function. +*/ +SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + RESOLVE_MAT(A)->setUpdated(memspace); + return SUN_SUCCESS; +} + +/** + * @brief Sync data in memspace with the updated memory space. + * + * @param A - The SUNMatrix_ReSolve object + * @param memspace - memory space to be synced up (HOST or DEVICE) + * + * @pre The memory space other than `memspace` must be up-to-date. Otherwise, + * this function will return an error. + * + * @see Sparse::setUpdated in the Re::Solve library +*/ +SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +{ + RESOLVE_MAT(A)->syncData(memspace); + return SUN_SUCCESS; } /** Print the Re::Solve matrix */ -void SUNMatrix_ReSolve_Print(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +void SUNMatrix_ReSolve_Print(SUNMatrix A) { RESOLVE_MAT(A)->print(std::cout, 0); } +/** + Utility function to print an array on the device for debugging +*/ +// void SUNMatrix_ReSolve_Print_Array(SUNMatrix A) +// { +// if (RESOLVE_MEMSPACE(A) == ReSolve::memory::HOST) {return;} + +// ReSolve::memory::MemorySpace memspace = RESOLVE_MEMSPACE(A); +// sunrealtype* d_data = SUNMatrix_ReSolve_Data(A, memspace); +// sunrealtype* h_data = new sunrealtype[SUNMatrix_ReSolve_NNZ(A)]; + +// cudaMemcpy(h_data, d_data, +// SUNMatrix_ReSolve_NNZ(A) * sizeof(sunrealtype), +// cudaMemcpyDeviceToHost); + +// for (int i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) +// { +// printf("data[%d] = %f\n", i, h_data[i]); +// } +// delete[] h_data; +// } + /* -------------------------------------------------------------------------- * Implementation of generic SUNMatrix operations. * -------------------------------------------------------------------------- */ @@ -234,6 +300,7 @@ void SUNMatDestroy_ReSolve(SUNMatrix A) return; } +// This function automatically syncs data between host and device SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) { if (!A) @@ -249,9 +316,8 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) } sunindextype i; - // TODO sync between device and data - // Get pointers to the data, indexvalues and indexpointers arrays in ReSolve + // Get pointers to the data, indexvalues and indexpointers arrays on host in ReSolve sunrealtype* values = RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); sunindextype* index_pointers = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); @@ -267,10 +333,27 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) for (i = 0; i < RESOLVE_NP(A); i++) { - index_pointers[i] = 0; + index_pointers[i] = ZERO; } (index_pointers)[RESOLVE_NP(A)] = 0; + SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); + + // Sync to device if necessary + if (RESOLVE_MEMSPACE(A) != ReSolve::memory::HOST) + { + SUNMatrix_ReSolve_SyncData(A, RESOLVE_MEMSPACE(A)); + } + return SUN_SUCCESS; } + +SUNMatrix SUNMatClone_ReSolve(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), + RESOLVE_MEMSPACE(A), A->sunctx); + SUNCheckLastErrNull(); + return (B); +} diff --git a/test/unit_tests/sunmatrix/resolve/CMakeLists.txt b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt index 752df8547b..2619920e8b 100644 --- a/test/unit_tests/sunmatrix/resolve/CMakeLists.txt +++ b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt @@ -1,5 +1,5 @@ # ------------------------------------------------------------------------------ -# Programmer(s): [Your name] +# Programmer(s): Jeffery Zhang # ------------------------------------------------------------------------------ # SUNDIALS Copyright Start # Copyright (c) 2025-2026, Lawrence Livermore National Security, @@ -43,8 +43,16 @@ foreach(example_tuple ${examples_list}) ${example_target} PRIVATE sundials_core sundials_sunmatrixresolve - ReSolve::ReSolve + SUNDIALS::ReSolve ${EXE_EXTRA_LINK_LIBS}) + + # Target GPU backends if necessary + if(SUNDIALS_RESOLVE_BACKENDS MATCHES "CUDA") + target_link_libraries(${example_target} PRIVATE SUNDIALS::ReSolve_CUDA) + elseif(SUNDIALS_RESOLVE_BACKENDS MATCHES "HIP") + target_link_libraries(${example_target} PRIVATE SUNDIALS::ReSolve_HIP) + endif() + endif() # set test name diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index 40e3409260..39f2f64cfb 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -39,6 +39,7 @@ int main(int argc, char* argv[]) sunindextype i, j, k, kstart, kend, N, uband, lband; int print_timing, square; SUNContext sunctx; + std::string hwbackend = "CPU"; if (SUNContext_Create(SUN_COMM_NULL, &sunctx)) { @@ -46,38 +47,25 @@ int main(int argc, char* argv[]) return (-1); } -// /* check input and set vector length */ -// if (argc < 5) -// { -// printf("ERROR: FOUR (4) Input required: matrix rows, matrix cols, matrix " -// "type (0/1), print timing \n"); -// return (-1); -// } - -// matrows = (sunindextype)atol(argv[1]); -// if (matrows < 1) -// { -// printf("ERROR: number of rows must be a positive integer\n"); -// return (-1); -// } - -// matcols = (sunindextype)atol(argv[2]); -// if (matcols < 1) -// { -// printf("ERROR: number of cols must be a positive integer\n"); -// return (-1); -// } - // Initialize a ReSolve HOST memory space. ReSolve::memory::MemorySpace memspace = ReSolve::memory::HOST; + // Check if a GPU backend is enabled + #ifdef SUNDIALS_RESOLVE_BACKENDS_CUDA + hwbackend = "CUDA"; + memspace = ReSolve::memory::DEVICE; + #elif defined(SUNDIALS_RESOLVE_BACKENDS_HIP) + hwbackend = "HIP"; + memspace = ReSolve::memory::DEVICE; + #endif + // Create a SUNMatrix_ReSolve object A = NULL; A = SUNMatrix_ReSolve(5, 5, 13, memspace, sunctx); // Get pointers to content arrays - sunrealtype* data = SUNMatrix_ReSolve_Data(A, memspace); - sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, memspace); - sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, memspace); + sunrealtype* data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); + sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); // Fill the matrix as a 5x5 second difference matrix for (i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) @@ -107,14 +95,34 @@ int main(int argc, char* argv[]) index_values[8] = 2; index_values[9] = 3; index_values[10] = 4; // row 3: cols 2, 3, 4 index_values[11] = 3; index_values[12] = 4; // row 4: cols 3, 4 - // Print the second difference matrix - SUNMatrix_ReSolve_Print(A, memspace); + + SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); + // Sync host to device if necessary + if (memspace != ReSolve::memory::HOST) + { + SUNMatrix_ReSolve_SyncData(A, memspace); + // SUNMatrix_ReSolve_Print_Array(A); + } + + // Print the matrix + SUNMatrix_ReSolve_Print(A); + + /* SUNMatrix Tests */ + fails += Test_SUNMatGetID(A, SUNMATRIX_RESOLVE, 0); + fails += Test_SUNMatZero(A, 0); - // Set the matrix to zero - SUNMatZero_ReSolve(A); + if (fails) + { + printf("FAIL: SUNMatrix module failed %i tests \n \n", fails); + printf("\nA =\n"); + SUNMatrix_ReSolve_Print(A); + } + else { printf("SUCCESS: SUNMatrix module passed all tests \n \n"); } - // Print empty matrix - SUNMatrix_ReSolve_Print(A, memspace); + // Print the backend + std::cout << "\n Hardware backend: " + << hwbackend + << "\n"; // Destroy the SUNMatrix_ReSolve object SUNMatDestroy_ReSolve(A); @@ -126,31 +134,131 @@ int main(int argc, char* argv[]) * Check matrix * --------------------------------------------------------------------*/ -// Currently stubs +// Assumes already synced int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) { int failure = 0; - sunrealtype *Adata, *Bdata; - sunindextype *Aindexptrs, *Bindexptrs; - sunindextype *Aindexvals, *Bindexvals; - sunindextype i, ANP, BNP, Annz, Bnnz; + sunindextype i, A_NP, B_NP, A_nnz, B_nnz; + sunrealtype *A_data, *B_data; + sunindextype *A_index_values, *A_index_pointers, *B_index_values, *B_index_pointers; + + // Get pointers to the data, pointer and value arrays + A_data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + A_index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); + A_index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + + B_data = SUNMatrix_ReSolve_Data(B, ReSolve::memory::HOST); + B_index_values = SUNMatrix_ReSolve_IndexValues(B, ReSolve::memory::HOST); + B_index_pointers = SUNMatrix_ReSolve_IndexPointers(B, ReSolve::memory::HOST); + + // Get nnz and np + A_nnz = SUNMatrix_ReSolve_NNZ(A); + A_NP = SUNMatrix_ReSolve_NP(A); + + B_nnz = SUNMatrix_ReSolve_NNZ(B); + B_NP = SUNMatrix_ReSolve_NP(B); + + // Check same storage type + if (SUNMatGetID(A) != SUNMatGetID(B)) + { + printf(">>> ERROR: check_matrix: Different storage types (%d vs %d)\n", + SUNMatGetID(A), SUNMatGetID(B)); + return (1); + } + + // Check shape + if (SUNMatrix_ReSolve_Rows(A) != SUNMatrix_ReSolve_Rows(B)) + { + printf(">>> ERROR: check_matrix: Different numbers of rows (%ld vs %ld)\n", + (long int)SUNMatrix_ReSolve_Rows(A), (long int)SUNMatrix_ReSolve_Rows(B)); + return (1); + } + if (SUNMatrix_ReSolve_Columns(A) != SUNMatrix_ReSolve_Columns(B)) + { + printf(">>> ERROR: check_matrix: Different numbers of columns (%ld vs " + "%ld)\n", + (long int)SUNMatrix_ReSolve_Columns(A), + (long int)SUNMatrix_ReSolve_Columns(B)); + return (1); + } + + // Check non zeros + if (A_nnz != B_nnz) + { + printf(">>> ERROR: check_matrix: Different numbers of nonzeros (%ld vs " + "%ld)\n", + (long int)A_nnz, (long int)B_nnz); + return (1); + } + + /* compare sparsity patterns */ + for (i = 0; i < A_NP; i++) + { + failure += (A_index_pointers[i] != B_index_pointers[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different indexptrs \n"); + return (1); + } + + for (i = 0; i < A_nnz; i++) + { + failure += (A_index_values[i] != B_index_values[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different indexvals \n"); + return (1); + } + + /* compare matrix values */ + for (i = 0; i < A_nnz; i++) + { + failure += SUNRCompareTol(A_data[i], B_data[i], tol); + } + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different entries \n"); + return (1); + } return (0); } int check_matrix_entry(SUNMatrix A, sunrealtype val, sunrealtype tol) { - return (0); + int failure = 0; + sunrealtype* Adata; + sunindextype* indexptrs; + sunindextype i, NP; + + /* get data pointer */ + Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + + /* compare data */ + indexptrs = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + NP = SUNMatrix_ReSolve_NP(A); + for (i = 0; i < indexptrs[NP]; i++) + { + failure += SUNRCompareTol(Adata[i], val, tol); + } + + if (failure > ZERO) { return (1); } + else { return (0); } } -int check_vector(N_Vector x, N_Vector y, sunrealtype tol) +int check_vector(N_Vector actual, N_Vector expected, sunrealtype tol) { return 0; } - sunbooleantype has_data(SUNMatrix A) { - return SUNTRUE; + sunrealtype* Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + if (Adata == NULL) { return SUNFALSE; } + else { return SUNTRUE; } } sunbooleantype is_square(SUNMatrix A) @@ -161,6 +269,6 @@ sunbooleantype is_square(SUNMatrix A) void sync_device(SUNMatrix A) { - /* not running on GPU, just return */ + /* sync is performed by functions for now */ return; } \ No newline at end of file From d55cf1eee6510b61689456357d562c90a37325e1 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Thu, 18 Jun 2026 23:04:31 -0400 Subject: [PATCH 09/22] Adds support for csc and coo Re::Solve matrices. (Not fully tested) --- include/sunmatrix/sunmatrix_resolve.h | 37 +-- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 126 ++++++--- .../resolve/test_sunmatrix_resolve.cpp | 245 ++++++++++++------ 3 files changed, 285 insertions(+), 123 deletions(-) diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index 02b94539c7..a16662d00a 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -26,28 +26,32 @@ #include #include #include -#include +#include +#include +#include #include -// #if defined(SUNDIALS_MAGMA_BACKENDS_CUDA) -// #define HAVE_CUBLAS -// #elif defined(SUNDIALS_MAGMA_BACKENDS_HIP) -// #define HAVE_HIP -// #endif - #ifdef __cplusplus /* wrapper to enable C++ usage */ extern "C" { #endif +typedef enum +{ + SUN_RESOLVE_COO, + SUN_RESOLVE_CSC, + SUN_RESOLVE_CSR +} SUNMatrix_ReSolve_StorageType; + struct _SUNMatrixContent_ReSolve { sunindextype M; sunindextype N; sunindextype NNZ; sunindextype NP; + SUNMatrix_ReSolve_StorageType storageType; ReSolve::memory::MemorySpace memspace; - ReSolve::matrix::Csr* mat; + ReSolve::matrix::Sparse* mat; }; typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; @@ -57,22 +61,25 @@ typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; * ---------------------------------------*/ SUNDIALS_EXPORT SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, sunindextype NNZ, + SUNMatrix_ReSolve_StorageType storageType, ReSolve::memory::MemorySpace memspace, SUNContext sunctx); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetRows(SUNMatrix A); + +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetColumns(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetNNZ(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetNP(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A); +SUNDIALS_EXPORT SUNMatrix_ReSolve_StorageType SUNMatrix_ReSolve_GetStorageType(SUNMatrix A); -SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_GetData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_GetRowData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_GetColData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace); diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index 00a1eca52f..bb3b907f13 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -51,24 +51,27 @@ #define ONE SUN_RCONST(1.0) // Content accessor macro -#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT -#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) -#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) -#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) -#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) -#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) -#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) +#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) +#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) +#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) +#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) +#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) +#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) +#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) +#define RESOLVE_STORAGETYPE(A) (RESOLVE_CONTENT(A)->storageType) /* -------------------------------------------------------------------------- * Constructor * -------------------------------------------------------------------------- */ // TODO Add ability to choose format. Currently, constructor assumes CSR format -SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, +SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, + SUNMatrix_ReSolve_StorageType storageType, ReSolve::memory::MemorySpace memspace, SUNContext sunctx) { SUNFunctionBegin(sunctx); SUNMatrixContent_ReSolve content; + sunindextype np = 0; // Check inputs if ((m <= 0) || (n <= 0) || (nnz < 0)) @@ -92,7 +95,26 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, A->ops->clone = SUNMatClone_ReSolve; // Create ReSolve matrix - ReSolve::matrix::Csr* mat = new ReSolve::matrix::Csr(m, n, nnz); + ReSolve::matrix::Sparse* mat; + switch (storageType) + { + case SUN_RESOLVE_COO: + mat = new ReSolve::matrix::Coo(m, n, nnz); + break; + case SUN_RESOLVE_CSC: + mat = new ReSolve::matrix::Csc(m, n, nnz); + np = n; + break; + case SUN_RESOLVE_CSR: + mat = new ReSolve::matrix::Csr(m, n, nnz); + np = m; + break; + default: + SUNDIALS_DEBUG_ERROR("Unsupported storage type\n"); + return NULL; + } + + // Allocate data for matrix mat->allocateMatrixData(ReSolve::memory::HOST); // Allocate matrix on device if necessary if (memspace == ReSolve::memory::DEVICE) @@ -112,7 +134,7 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, content->M = m; content->N = n; content->NNZ = nnz; - content->NP = m; + content->NP = np; content->mat = mat; content->memspace = memspace; @@ -131,60 +153,67 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, * Implementation specific functions * -------------------------------------------------------------------------- */ -sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_GetRows(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_M(A); } -sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_GetColumns(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_N(A); } -sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_GetNNZ(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_NNZ(A); } -sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_GetNP(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_NP(A); } +SUNMatrix_ReSolve_StorageType SUNMatrix_ReSolve_GetStorageType(SUNMatrix A) +{ + SUNFunctionBegin(A->sunctx); + SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); + return RESOLVE_STORAGETYPE(A); +} + /** Get the pointer to the ReSolve matrix data array @param[in] A The SUNMatrix object */ -sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunrealtype* SUNMatrix_ReSolve_GetData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getValues(memspace); } /** - Get the pointer to the ReSolve matrix offsets array + Get the pointer to the ReSolve matrix row data @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_GetRowData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getRowData(memspace); } /** - Get the pointer to the ReSolve matrix indices array + Get the pointer to the ReSolve matrix column data @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_GetColData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getColData(memspace); } @@ -317,26 +346,55 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) sunindextype i; - // Get pointers to the data, indexvalues and indexpointers arrays on host in ReSolve + // Get pointers to the data, row data and column data arrays on host in ReSolve sunrealtype* values = RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); - sunindextype* index_pointers = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); + sunindextype* row_data = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); - sunindextype* index_values = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); + sunindextype* col_data = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); - // Zero out the values of these arrays - for (i = 0; i < RESOLVE_NNZ(A); i++) + // Zero out the values of these arrays depending on storage type + switch (RESOLVE_STORAGETYPE(A)) { - values[i] = ZERO; - index_values[i] = 0; - } - - for (i = 0; i < RESOLVE_NP(A); i++) - { - index_pointers[i] = ZERO; + case SUN_RESOLVE_COO: + for (i = 0; i < RESOLVE_NNZ(A); i++) + { + values[i] = ZERO; + row_data[i] = 0; + col_data[i] = 0; + } + break; + case SUN_RESOLVE_CSC: + for (i = 0; i < RESOLVE_NNZ(A); i++) + { + values[i] = ZERO; + row_data[i] = 0; + } + + for (i = 0; i < RESOLVE_NP(A); i++) + { + col_data[i] = ZERO; + } + + (col_data)[RESOLVE_NP(A)] = 0; + break; + case SUN_RESOLVE_CSR: + for (i = 0; i < RESOLVE_NNZ(A); i++) + { + values[i] = ZERO; + col_data[i] = 0; + } + + for (i = 0; i < RESOLVE_NP(A); i++) + { + row_data[i] = ZERO; + } + + (row_data)[RESOLVE_NP(A)] = 0; + default: + SUNDIALS_DEBUG_ERROR("Unsupported storage type\n"); + return SUN_ERR_ARG_INCOMPATIBLE; } - - (index_pointers)[RESOLVE_NP(A)] = 0; SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); @@ -352,7 +410,7 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) SUNMatrix SUNMatClone_ReSolve(SUNMatrix A) { SUNFunctionBegin(A->sunctx); - SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), + SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), RESOLVE_STORAGETYPE(A), RESOLVE_MEMSPACE(A), A->sunctx); SUNCheckLastErrNull(); return (B); diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index 39f2f64cfb..bc3dc4074b 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -22,9 +22,16 @@ #include #include +#include + +// SUNDIALS headers +#include +#include #include #include -#include +#include "sundials/sundials_errors.h" +#include "sundials_debug.h" +#include "sundials_macros.h" #include "test_sunmatrix.h" @@ -58,17 +65,19 @@ int main(int argc, char* argv[]) memspace = ReSolve::memory::DEVICE; #endif - // Create a SUNMatrix_ReSolve object + // Create a SUNMatrix_ReSolve CSR matrix A = NULL; - A = SUNMatrix_ReSolve(5, 5, 13, memspace, sunctx); + // Set the storage type + SUNMatrix_ReSolve_StorageType storageType = SUN_RESOLVE_CSR; + A = SUNMatrix_ReSolve(5, 5, 13, storageType, memspace, sunctx); // Get pointers to content arrays - sunrealtype* data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); - sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); - sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + sunrealtype* data = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); + sunindextype* row_data = SUNMatrix_ReSolve_GetRowData(A, ReSolve::memory::HOST); + sunindextype* col_data = SUNMatrix_ReSolve_GetColData(A, ReSolve::memory::HOST); // Fill the matrix as a 5x5 second difference matrix - for (i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) + for (i = 0; i < SUNMatrix_ReSolve_GetNNZ(A); i++) { if (i % 3 == 0) { @@ -81,19 +90,19 @@ int main(int argc, char* argv[]) } // Row pointers — how many non-zeros before each row - index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) - index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) - index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) - index_pointers[3] = 8; // row 3 starts at 8 (3 non-zeros) - index_pointers[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) - index_pointers[5] = 13; // total non-zeros + row_data[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) + row_data[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) + row_data[2] = 5; // row 2 starts at 5 (3 non-zeros) + row_data[3] = 8; // row 3 starts at 8 (3 non-zeros) + row_data[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) + row_data[5] = 13; // total non-zeros // Column indices - index_values[0] = 0; index_values[1] = 1; // row 0: cols 0, 1 - index_values[2] = 0; index_values[3] = 1; index_values[4] = 2; // row 1: cols 0, 1, 2 - index_values[5] = 1; index_values[6] = 2; index_values[7] = 3; // row 2: cols 1, 2, 3 - index_values[8] = 2; index_values[9] = 3; index_values[10] = 4; // row 3: cols 2, 3, 4 - index_values[11] = 3; index_values[12] = 4; // row 4: cols 3, 4 + col_data[0] = 0; col_data[1] = 1; // row 0: cols 0, 1 + col_data[2] = 0; col_data[3] = 1; col_data[4] = 2; // row 1: cols 0, 1, 2 + col_data[5] = 1; col_data[6] = 2; col_data[7] = 3; // row 2: cols 1, 2, 3 + col_data[8] = 2; col_data[9] = 3; col_data[10] = 4; // row 3: cols 2, 3, 4 + col_data[11] = 3; col_data[12] = 4; // row 4: cols 3, 4 SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); @@ -140,45 +149,53 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) int failure = 0; sunindextype i, A_NP, B_NP, A_nnz, B_nnz; sunrealtype *A_data, *B_data; - sunindextype *A_index_values, *A_index_pointers, *B_index_values, *B_index_pointers; + sunindextype *A_row_data, *A_col_data, *B_row_data, *B_col_data; // Get pointers to the data, pointer and value arrays - A_data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); - A_index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); - A_index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + A_data = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); + A_row_data = SUNMatrix_ReSolve_GetRowData(A, ReSolve::memory::HOST); + A_col_data = SUNMatrix_ReSolve_GetColData(A, ReSolve::memory::HOST); - B_data = SUNMatrix_ReSolve_Data(B, ReSolve::memory::HOST); - B_index_values = SUNMatrix_ReSolve_IndexValues(B, ReSolve::memory::HOST); - B_index_pointers = SUNMatrix_ReSolve_IndexPointers(B, ReSolve::memory::HOST); + B_data = SUNMatrix_ReSolve_GetData(B, ReSolve::memory::HOST); + B_row_data = SUNMatrix_ReSolve_GetRowData(B, ReSolve::memory::HOST); + B_col_data = SUNMatrix_ReSolve_GetColData(B, ReSolve::memory::HOST); // Get nnz and np - A_nnz = SUNMatrix_ReSolve_NNZ(A); - A_NP = SUNMatrix_ReSolve_NP(A); + A_nnz = SUNMatrix_ReSolve_GetNNZ(A); + A_NP = SUNMatrix_ReSolve_GetNP(A); - B_nnz = SUNMatrix_ReSolve_NNZ(B); - B_NP = SUNMatrix_ReSolve_NP(B); + B_nnz = SUNMatrix_ReSolve_GetNNZ(B); + B_NP = SUNMatrix_ReSolve_GetNP(B); - // Check same storage type + // Check same storage SUNMatrix Type if (SUNMatGetID(A) != SUNMatGetID(B)) { - printf(">>> ERROR: check_matrix: Different storage types (%d vs %d)\n", + printf(">>> ERROR: check_matrix: Different SUNMatrix Type (%d vs %d)\n", SUNMatGetID(A), SUNMatGetID(B)); return (1); } + // Check same storage type + if (SUNMatrix_ReSolve_GetStorageType(A) != SUNMatrix_ReSolve_GetStorageType(B)) + { + printf(">>> ERROR: check_matrix: Different Sparse Storage type (%d vs %d)\n", + SUNMatrix_ReSolve_GetStorageType(A), SUNMatrix_ReSolve_GetStorageType(B)); + return (1); + } + // Check shape - if (SUNMatrix_ReSolve_Rows(A) != SUNMatrix_ReSolve_Rows(B)) + if (SUNMatrix_ReSolve_GetRows(A) != SUNMatrix_ReSolve_GetRows(B)) { printf(">>> ERROR: check_matrix: Different numbers of rows (%ld vs %ld)\n", - (long int)SUNMatrix_ReSolve_Rows(A), (long int)SUNMatrix_ReSolve_Rows(B)); + (long int)SUNMatrix_ReSolve_GetRows(A), (long int)SUNMatrix_ReSolve_GetRows(B)); return (1); } - if (SUNMatrix_ReSolve_Columns(A) != SUNMatrix_ReSolve_Columns(B)) + if (SUNMatrix_ReSolve_GetColumns(A) != SUNMatrix_ReSolve_GetColumns(B)) { printf(">>> ERROR: check_matrix: Different numbers of columns (%ld vs " "%ld)\n", - (long int)SUNMatrix_ReSolve_Columns(A), - (long int)SUNMatrix_ReSolve_Columns(B)); + (long int)SUNMatrix_ReSolve_GetColumns(A), + (long int)SUNMatrix_ReSolve_GetColumns(B)); return (1); } @@ -192,37 +209,119 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) } /* compare sparsity patterns */ - for (i = 0; i < A_NP; i++) - { - failure += (A_index_pointers[i] != B_index_pointers[i]); - } - - if (failure > ZERO) + switch (SUNMatrix_ReSolve_GetStorageType(A)) { - printf(">>> ERROR: check_matrix: Different indexptrs \n"); - return (1); - } - - for (i = 0; i < A_nnz; i++) - { - failure += (A_index_values[i] != B_index_values[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different indexvals \n"); - return (1); - } - - /* compare matrix values */ - for (i = 0; i < A_nnz; i++) - { - failure += SUNRCompareTol(A_data[i], B_data[i], tol); - } - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different entries \n"); - return (1); + case SUN_RESOLVE_COO: + for (i = 0; i < A_nnz; i++) + { + failure += (A_col_data[i] != B_col_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different column data \n"); + return (1); + } + + for (i = 0; i < A_nnz; i++) + { + failure += (A_row_data[i] != B_row_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different row data \n"); + return (1); + } + + /* compare matrix values */ + for (i = 0; i < A_nnz; i++) + { + failure += SUNRCompareTol(A_data[i], B_data[i], tol); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different entries \n"); + return (1); + } + break; + + case SUN_RESOLVE_CSC: + for (i = 0; i < A_NP; i++) + { + failure += (A_col_data[i] != B_col_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different column data \n"); + return (1); + } + + for (i = 0; i < A_nnz; i++) + { + failure += (A_row_data[i] != B_row_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different row data \n"); + return (1); + } + + /* compare matrix values */ + for (i = 0; i < A_nnz; i++) + { + failure += SUNRCompareTol(A_data[i], B_data[i], tol); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different entries \n"); + return (1); + } + break; + + case SUN_RESOLVE_CSR: + for (i = 0; i < A_NP; i++) + { + failure += (A_row_data[i] != B_row_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different indexptrs \n"); + return (1); + } + + for (i = 0; i < A_nnz; i++) + { + failure += (A_col_data[i] != B_col_data[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different indexvals \n"); + return (1); + } + + /* compare matrix values */ + for (i = 0; i < A_nnz; i++) + { + failure += SUNRCompareTol(A_data[i], B_data[i], tol); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different entries \n"); + return (1); + } + break; + + default: + printf(">>> ERROR: Unsupported Storage Type \n"); + return (1); } return (0); @@ -232,16 +331,14 @@ int check_matrix_entry(SUNMatrix A, sunrealtype val, sunrealtype tol) { int failure = 0; sunrealtype* Adata; - sunindextype* indexptrs; - sunindextype i, NP; + sunindextype i, nnz; /* get data pointer */ - Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + Adata = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); /* compare data */ - indexptrs = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); - NP = SUNMatrix_ReSolve_NP(A); - for (i = 0; i < indexptrs[NP]; i++) + nnz = SUNMatrix_ReSolve_GetNNZ(A); + for (i = 0; i < nnz; i++) { failure += SUNRCompareTol(Adata[i], val, tol); } @@ -256,14 +353,14 @@ int check_vector(N_Vector actual, N_Vector expected, sunrealtype tol) } sunbooleantype has_data(SUNMatrix A) { - sunrealtype* Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + sunrealtype* Adata = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); if (Adata == NULL) { return SUNFALSE; } else { return SUNTRUE; } } sunbooleantype is_square(SUNMatrix A) { - if (SUNMatrix_ReSolve_Rows(A) == SUNMatrix_ReSolve_Columns(A)) { return SUNTRUE; } + if (SUNMatrix_ReSolve_GetRows(A) == SUNMatrix_ReSolve_GetColumns(A)) { return SUNTRUE; } else { return SUNFALSE; } } From 0e048fcf15fa3c858df21ecadac3594566649dc3 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Fri, 19 Jun 2026 12:09:27 -0400 Subject: [PATCH 10/22] Revert "Adds support for csc and coo Re::Solve matrices. (Not fully tested)" This reverts commit d55cf1eee6510b61689456357d562c90a37325e1. --- include/sunmatrix/sunmatrix_resolve.h | 37 ++- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 126 +++------ .../resolve/test_sunmatrix_resolve.cpp | 245 ++++++------------ 3 files changed, 123 insertions(+), 285 deletions(-) diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index a16662d00a..02b94539c7 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -26,32 +26,28 @@ #include #include #include -#include -#include -#include +#include #include +// #if defined(SUNDIALS_MAGMA_BACKENDS_CUDA) +// #define HAVE_CUBLAS +// #elif defined(SUNDIALS_MAGMA_BACKENDS_HIP) +// #define HAVE_HIP +// #endif + #ifdef __cplusplus /* wrapper to enable C++ usage */ extern "C" { #endif -typedef enum -{ - SUN_RESOLVE_COO, - SUN_RESOLVE_CSC, - SUN_RESOLVE_CSR -} SUNMatrix_ReSolve_StorageType; - struct _SUNMatrixContent_ReSolve { sunindextype M; sunindextype N; sunindextype NNZ; sunindextype NP; - SUNMatrix_ReSolve_StorageType storageType; ReSolve::memory::MemorySpace memspace; - ReSolve::matrix::Sparse* mat; + ReSolve::matrix::Csr* mat; }; typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; @@ -61,25 +57,22 @@ typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; * ---------------------------------------*/ SUNDIALS_EXPORT SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, sunindextype NNZ, - SUNMatrix_ReSolve_StorageType storageType, ReSolve::memory::MemorySpace memspace, SUNContext sunctx); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetRows(SUNMatrix A); - -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetColumns(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetNNZ(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_GetNP(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); -SUNDIALS_EXPORT SUNMatrix_ReSolve_StorageType SUNMatrix_ReSolve_GetStorageType(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A); -SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_GetData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_GetRowData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_GetColData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace); SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace); diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index bb3b907f13..00a1eca52f 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -51,27 +51,24 @@ #define ONE SUN_RCONST(1.0) // Content accessor macro -#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) -#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) -#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) -#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) -#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) -#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) -#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) -#define RESOLVE_STORAGETYPE(A) (RESOLVE_CONTENT(A)->storageType) +#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT +#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) +#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) +#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) +#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) +#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) +#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) /* -------------------------------------------------------------------------- * Constructor * -------------------------------------------------------------------------- */ // TODO Add ability to choose format. Currently, constructor assumes CSR format -SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, - SUNMatrix_ReSolve_StorageType storageType, +SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, ReSolve::memory::MemorySpace memspace, SUNContext sunctx) { SUNFunctionBegin(sunctx); SUNMatrixContent_ReSolve content; - sunindextype np = 0; // Check inputs if ((m <= 0) || (n <= 0) || (nnz < 0)) @@ -95,26 +92,7 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, A->ops->clone = SUNMatClone_ReSolve; // Create ReSolve matrix - ReSolve::matrix::Sparse* mat; - switch (storageType) - { - case SUN_RESOLVE_COO: - mat = new ReSolve::matrix::Coo(m, n, nnz); - break; - case SUN_RESOLVE_CSC: - mat = new ReSolve::matrix::Csc(m, n, nnz); - np = n; - break; - case SUN_RESOLVE_CSR: - mat = new ReSolve::matrix::Csr(m, n, nnz); - np = m; - break; - default: - SUNDIALS_DEBUG_ERROR("Unsupported storage type\n"); - return NULL; - } - - // Allocate data for matrix + ReSolve::matrix::Csr* mat = new ReSolve::matrix::Csr(m, n, nnz); mat->allocateMatrixData(ReSolve::memory::HOST); // Allocate matrix on device if necessary if (memspace == ReSolve::memory::DEVICE) @@ -134,7 +112,7 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, content->M = m; content->N = n; content->NNZ = nnz; - content->NP = np; + content->NP = m; content->mat = mat; content->memspace = memspace; @@ -153,67 +131,60 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, * Implementation specific functions * -------------------------------------------------------------------------- */ -sunindextype SUNMatrix_ReSolve_GetRows(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_M(A); } -sunindextype SUNMatrix_ReSolve_GetColumns(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_N(A); } -sunindextype SUNMatrix_ReSolve_GetNNZ(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_NNZ(A); } -sunindextype SUNMatrix_ReSolve_GetNP(SUNMatrix A) +sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); return RESOLVE_NP(A); } -SUNMatrix_ReSolve_StorageType SUNMatrix_ReSolve_GetStorageType(SUNMatrix A) -{ - SUNFunctionBegin(A->sunctx); - SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); - return RESOLVE_STORAGETYPE(A); -} - /** Get the pointer to the ReSolve matrix data array @param[in] A The SUNMatrix object */ -sunrealtype* SUNMatrix_ReSolve_GetData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getValues(memspace); } /** - Get the pointer to the ReSolve matrix row data + Get the pointer to the ReSolve matrix offsets array @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_GetRowData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getRowData(memspace); } /** - Get the pointer to the ReSolve matrix column data + Get the pointer to the ReSolve matrix indices array @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_GetColData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getColData(memspace); } @@ -346,55 +317,26 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) sunindextype i; - // Get pointers to the data, row data and column data arrays on host in ReSolve + // Get pointers to the data, indexvalues and indexpointers arrays on host in ReSolve sunrealtype* values = RESOLVE_MAT(A)->getValues(ReSolve::memory::HOST); - sunindextype* row_data = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); + sunindextype* index_pointers = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); - sunindextype* col_data = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); + sunindextype* index_values = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); - // Zero out the values of these arrays depending on storage type - switch (RESOLVE_STORAGETYPE(A)) + // Zero out the values of these arrays + for (i = 0; i < RESOLVE_NNZ(A); i++) { - case SUN_RESOLVE_COO: - for (i = 0; i < RESOLVE_NNZ(A); i++) - { - values[i] = ZERO; - row_data[i] = 0; - col_data[i] = 0; - } - break; - case SUN_RESOLVE_CSC: - for (i = 0; i < RESOLVE_NNZ(A); i++) - { - values[i] = ZERO; - row_data[i] = 0; - } - - for (i = 0; i < RESOLVE_NP(A); i++) - { - col_data[i] = ZERO; - } - - (col_data)[RESOLVE_NP(A)] = 0; - break; - case SUN_RESOLVE_CSR: - for (i = 0; i < RESOLVE_NNZ(A); i++) - { - values[i] = ZERO; - col_data[i] = 0; - } - - for (i = 0; i < RESOLVE_NP(A); i++) - { - row_data[i] = ZERO; - } - - (row_data)[RESOLVE_NP(A)] = 0; - default: - SUNDIALS_DEBUG_ERROR("Unsupported storage type\n"); - return SUN_ERR_ARG_INCOMPATIBLE; + values[i] = ZERO; + index_values[i] = 0; + } + + for (i = 0; i < RESOLVE_NP(A); i++) + { + index_pointers[i] = ZERO; } + + (index_pointers)[RESOLVE_NP(A)] = 0; SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); @@ -410,7 +352,7 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) SUNMatrix SUNMatClone_ReSolve(SUNMatrix A) { SUNFunctionBegin(A->sunctx); - SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), RESOLVE_STORAGETYPE(A), + SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), RESOLVE_MEMSPACE(A), A->sunctx); SUNCheckLastErrNull(); return (B); diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index bc3dc4074b..39f2f64cfb 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -22,16 +22,9 @@ #include #include -#include - -// SUNDIALS headers -#include -#include #include #include -#include "sundials/sundials_errors.h" -#include "sundials_debug.h" -#include "sundials_macros.h" +#include #include "test_sunmatrix.h" @@ -65,19 +58,17 @@ int main(int argc, char* argv[]) memspace = ReSolve::memory::DEVICE; #endif - // Create a SUNMatrix_ReSolve CSR matrix + // Create a SUNMatrix_ReSolve object A = NULL; - // Set the storage type - SUNMatrix_ReSolve_StorageType storageType = SUN_RESOLVE_CSR; - A = SUNMatrix_ReSolve(5, 5, 13, storageType, memspace, sunctx); + A = SUNMatrix_ReSolve(5, 5, 13, memspace, sunctx); // Get pointers to content arrays - sunrealtype* data = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); - sunindextype* row_data = SUNMatrix_ReSolve_GetRowData(A, ReSolve::memory::HOST); - sunindextype* col_data = SUNMatrix_ReSolve_GetColData(A, ReSolve::memory::HOST); + sunrealtype* data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); + sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); // Fill the matrix as a 5x5 second difference matrix - for (i = 0; i < SUNMatrix_ReSolve_GetNNZ(A); i++) + for (i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) { if (i % 3 == 0) { @@ -90,19 +81,19 @@ int main(int argc, char* argv[]) } // Row pointers — how many non-zeros before each row - row_data[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) - row_data[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) - row_data[2] = 5; // row 2 starts at 5 (3 non-zeros) - row_data[3] = 8; // row 3 starts at 8 (3 non-zeros) - row_data[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) - row_data[5] = 13; // total non-zeros + index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) + index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) + index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) + index_pointers[3] = 8; // row 3 starts at 8 (3 non-zeros) + index_pointers[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) + index_pointers[5] = 13; // total non-zeros // Column indices - col_data[0] = 0; col_data[1] = 1; // row 0: cols 0, 1 - col_data[2] = 0; col_data[3] = 1; col_data[4] = 2; // row 1: cols 0, 1, 2 - col_data[5] = 1; col_data[6] = 2; col_data[7] = 3; // row 2: cols 1, 2, 3 - col_data[8] = 2; col_data[9] = 3; col_data[10] = 4; // row 3: cols 2, 3, 4 - col_data[11] = 3; col_data[12] = 4; // row 4: cols 3, 4 + index_values[0] = 0; index_values[1] = 1; // row 0: cols 0, 1 + index_values[2] = 0; index_values[3] = 1; index_values[4] = 2; // row 1: cols 0, 1, 2 + index_values[5] = 1; index_values[6] = 2; index_values[7] = 3; // row 2: cols 1, 2, 3 + index_values[8] = 2; index_values[9] = 3; index_values[10] = 4; // row 3: cols 2, 3, 4 + index_values[11] = 3; index_values[12] = 4; // row 4: cols 3, 4 SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); @@ -149,53 +140,45 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) int failure = 0; sunindextype i, A_NP, B_NP, A_nnz, B_nnz; sunrealtype *A_data, *B_data; - sunindextype *A_row_data, *A_col_data, *B_row_data, *B_col_data; + sunindextype *A_index_values, *A_index_pointers, *B_index_values, *B_index_pointers; // Get pointers to the data, pointer and value arrays - A_data = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); - A_row_data = SUNMatrix_ReSolve_GetRowData(A, ReSolve::memory::HOST); - A_col_data = SUNMatrix_ReSolve_GetColData(A, ReSolve::memory::HOST); + A_data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); + A_index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); + A_index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); - B_data = SUNMatrix_ReSolve_GetData(B, ReSolve::memory::HOST); - B_row_data = SUNMatrix_ReSolve_GetRowData(B, ReSolve::memory::HOST); - B_col_data = SUNMatrix_ReSolve_GetColData(B, ReSolve::memory::HOST); + B_data = SUNMatrix_ReSolve_Data(B, ReSolve::memory::HOST); + B_index_values = SUNMatrix_ReSolve_IndexValues(B, ReSolve::memory::HOST); + B_index_pointers = SUNMatrix_ReSolve_IndexPointers(B, ReSolve::memory::HOST); // Get nnz and np - A_nnz = SUNMatrix_ReSolve_GetNNZ(A); - A_NP = SUNMatrix_ReSolve_GetNP(A); + A_nnz = SUNMatrix_ReSolve_NNZ(A); + A_NP = SUNMatrix_ReSolve_NP(A); - B_nnz = SUNMatrix_ReSolve_GetNNZ(B); - B_NP = SUNMatrix_ReSolve_GetNP(B); + B_nnz = SUNMatrix_ReSolve_NNZ(B); + B_NP = SUNMatrix_ReSolve_NP(B); - // Check same storage SUNMatrix Type + // Check same storage type if (SUNMatGetID(A) != SUNMatGetID(B)) { - printf(">>> ERROR: check_matrix: Different SUNMatrix Type (%d vs %d)\n", + printf(">>> ERROR: check_matrix: Different storage types (%d vs %d)\n", SUNMatGetID(A), SUNMatGetID(B)); return (1); } - // Check same storage type - if (SUNMatrix_ReSolve_GetStorageType(A) != SUNMatrix_ReSolve_GetStorageType(B)) - { - printf(">>> ERROR: check_matrix: Different Sparse Storage type (%d vs %d)\n", - SUNMatrix_ReSolve_GetStorageType(A), SUNMatrix_ReSolve_GetStorageType(B)); - return (1); - } - // Check shape - if (SUNMatrix_ReSolve_GetRows(A) != SUNMatrix_ReSolve_GetRows(B)) + if (SUNMatrix_ReSolve_Rows(A) != SUNMatrix_ReSolve_Rows(B)) { printf(">>> ERROR: check_matrix: Different numbers of rows (%ld vs %ld)\n", - (long int)SUNMatrix_ReSolve_GetRows(A), (long int)SUNMatrix_ReSolve_GetRows(B)); + (long int)SUNMatrix_ReSolve_Rows(A), (long int)SUNMatrix_ReSolve_Rows(B)); return (1); } - if (SUNMatrix_ReSolve_GetColumns(A) != SUNMatrix_ReSolve_GetColumns(B)) + if (SUNMatrix_ReSolve_Columns(A) != SUNMatrix_ReSolve_Columns(B)) { printf(">>> ERROR: check_matrix: Different numbers of columns (%ld vs " "%ld)\n", - (long int)SUNMatrix_ReSolve_GetColumns(A), - (long int)SUNMatrix_ReSolve_GetColumns(B)); + (long int)SUNMatrix_ReSolve_Columns(A), + (long int)SUNMatrix_ReSolve_Columns(B)); return (1); } @@ -209,119 +192,37 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) } /* compare sparsity patterns */ - switch (SUNMatrix_ReSolve_GetStorageType(A)) + for (i = 0; i < A_NP; i++) + { + failure += (A_index_pointers[i] != B_index_pointers[i]); + } + + if (failure > ZERO) { - case SUN_RESOLVE_COO: - for (i = 0; i < A_nnz; i++) - { - failure += (A_col_data[i] != B_col_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different column data \n"); - return (1); - } - - for (i = 0; i < A_nnz; i++) - { - failure += (A_row_data[i] != B_row_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different row data \n"); - return (1); - } - - /* compare matrix values */ - for (i = 0; i < A_nnz; i++) - { - failure += SUNRCompareTol(A_data[i], B_data[i], tol); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different entries \n"); - return (1); - } - break; - - case SUN_RESOLVE_CSC: - for (i = 0; i < A_NP; i++) - { - failure += (A_col_data[i] != B_col_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different column data \n"); - return (1); - } - - for (i = 0; i < A_nnz; i++) - { - failure += (A_row_data[i] != B_row_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different row data \n"); - return (1); - } - - /* compare matrix values */ - for (i = 0; i < A_nnz; i++) - { - failure += SUNRCompareTol(A_data[i], B_data[i], tol); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different entries \n"); - return (1); - } - break; - - case SUN_RESOLVE_CSR: - for (i = 0; i < A_NP; i++) - { - failure += (A_row_data[i] != B_row_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different indexptrs \n"); - return (1); - } - - for (i = 0; i < A_nnz; i++) - { - failure += (A_col_data[i] != B_col_data[i]); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different indexvals \n"); - return (1); - } - - /* compare matrix values */ - for (i = 0; i < A_nnz; i++) - { - failure += SUNRCompareTol(A_data[i], B_data[i], tol); - } - - if (failure > ZERO) - { - printf(">>> ERROR: check_matrix: Different entries \n"); - return (1); - } - break; - - default: - printf(">>> ERROR: Unsupported Storage Type \n"); - return (1); + printf(">>> ERROR: check_matrix: Different indexptrs \n"); + return (1); + } + + for (i = 0; i < A_nnz; i++) + { + failure += (A_index_values[i] != B_index_values[i]); + } + + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different indexvals \n"); + return (1); + } + + /* compare matrix values */ + for (i = 0; i < A_nnz; i++) + { + failure += SUNRCompareTol(A_data[i], B_data[i], tol); + } + if (failure > ZERO) + { + printf(">>> ERROR: check_matrix: Different entries \n"); + return (1); } return (0); @@ -331,14 +232,16 @@ int check_matrix_entry(SUNMatrix A, sunrealtype val, sunrealtype tol) { int failure = 0; sunrealtype* Adata; - sunindextype i, nnz; + sunindextype* indexptrs; + sunindextype i, NP; /* get data pointer */ - Adata = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); + Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); /* compare data */ - nnz = SUNMatrix_ReSolve_GetNNZ(A); - for (i = 0; i < nnz; i++) + indexptrs = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + NP = SUNMatrix_ReSolve_NP(A); + for (i = 0; i < indexptrs[NP]; i++) { failure += SUNRCompareTol(Adata[i], val, tol); } @@ -353,14 +256,14 @@ int check_vector(N_Vector actual, N_Vector expected, sunrealtype tol) } sunbooleantype has_data(SUNMatrix A) { - sunrealtype* Adata = SUNMatrix_ReSolve_GetData(A, ReSolve::memory::HOST); + sunrealtype* Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); if (Adata == NULL) { return SUNFALSE; } else { return SUNTRUE; } } sunbooleantype is_square(SUNMatrix A) { - if (SUNMatrix_ReSolve_GetRows(A) == SUNMatrix_ReSolve_GetColumns(A)) { return SUNTRUE; } + if (SUNMatrix_ReSolve_Rows(A) == SUNMatrix_ReSolve_Columns(A)) { return SUNTRUE; } else { return SUNFALSE; } } From d80de11ad91fa9c7ebc3c4009e2bafb367131261 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Fri, 19 Jun 2026 12:17:02 -0400 Subject: [PATCH 11/22] Cleaned up some comments --- include/sunmatrix/sunmatrix_resolve.h | 7 ------- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 3 --- .../sunmatrix/resolve/test_sunmatrix_resolve.cpp | 6 +++--- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index 02b94539c7..91aaf40afa 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -29,13 +29,6 @@ #include #include - -// #if defined(SUNDIALS_MAGMA_BACKENDS_CUDA) -// #define HAVE_CUBLAS -// #elif defined(SUNDIALS_MAGMA_BACKENDS_HIP) -// #define HAVE_HIP -// #endif - #ifdef __cplusplus /* wrapper to enable C++ usage */ extern "C" { #endif diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index 00a1eca52f..08222a41a3 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -23,8 +23,6 @@ #include // Re::Solve headers -#include -#include #include #include #include @@ -63,7 +61,6 @@ * Constructor * -------------------------------------------------------------------------- */ -// TODO Add ability to choose format. Currently, constructor assumes CSR format SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, ReSolve::memory::MemorySpace memspace, SUNContext sunctx) { diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index 39f2f64cfb..b747182127 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -34,11 +34,12 @@ int main(int argc, char* argv[]) { int fails = 0; /* counter for test failures */ -// sunindextype matrows, matcols; /* matrix dims */ SUNMatrix A; sunindextype i, j, k, kstart, kend, N, uband, lband; int print_timing, square; SUNContext sunctx; + + // Default backend std::string hwbackend = "CPU"; if (SUNContext_Create(SUN_COMM_NULL, &sunctx)) @@ -80,7 +81,7 @@ int main(int argc, char* argv[]) } } - // Row pointers — how many non-zeros before each row + // Row pointers index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) @@ -101,7 +102,6 @@ int main(int argc, char* argv[]) if (memspace != ReSolve::memory::HOST) { SUNMatrix_ReSolve_SyncData(A, memspace); - // SUNMatrix_ReSolve_Print_Array(A); } // Print the matrix From af8b5e31c4dd632c177ea1731f4206c87d183d37 Mon Sep 17 00:00:00 2001 From: jefferyz2024S Date: Mon, 22 Jun 2026 20:42:09 -0400 Subject: [PATCH 12/22] Create documentation for the ReSolve interface --- doc/shared/sundials/Install.rst | 79 ++++++++ doc/shared/sunmatrix/SUNMatrix_ReSolve.rst | 178 ++++++++++++++++++ .../source/sunmatrix/SUNMatrix_links.rst | 1 + 3 files changed, 258 insertions(+) create mode 100644 doc/shared/sunmatrix/SUNMatrix_ReSolve.rst diff --git a/doc/shared/sundials/Install.rst b/doc/shared/sundials/Install.rst index b08d2627ba..ab88983f39 100644 --- a/doc/shared/sundials/Install.rst +++ b/doc/shared/sundials/Install.rst @@ -2127,6 +2127,66 @@ the CUDA backend (targeting Ampere GPUs): Default: ``CUDA`` +.. _Installation.Options.ReSolve: + +Building with Re\:\:Solve +^^^^^^^^^^^^^^^^^^^ + +The `Re\:\:Solve library `__ is a library of +GPU-resident linear solvers. It contains iterative and direct solvers designed to run +on NVIDIA and AMD GPUs, as well as on CPU devices. The library is +developed by Oak Ridge National Laboratory and is available from the `Re::Solve GitHub +repository `__. + +When Re::Solve support is enabled, :ref:`Re::Solve sparse SUNMatrix +` will be built (see section +:numref:`Installation.LibrariesAndHeaders.Matrix.ReSolve` for the corresponding +header files and libraries). + +To enable Re::Solve support, set :cmakeop:`SUNDIALS_ENABLE_RESOLVE` to ``ON``, +:cmakeop:`ReSolve_DIR` to the root path of a Re::Solve installation, and +:cmakeop:`SUNDIALS_RESOLVE_BACKENDS` to the desired Re::Solve backend to use. For +example, the following command will configure SUNDIALS with Re::Solve support with +the CUDA backend (targeting Pascal GPUs): + +.. code-block:: bash + + cmake \ + -S SOLVER_DIR \ + -B BUILD_DIR \ + -D CMAKE_INSTALL_PREFIX=INSTALL_DIR \ + -D SUNDIALS_ENABLE_RESOLVE=ON \ + -D ReSolve_DIR=/path/to/resolve/installation \ + -D SUNDIALS_RESOLVE_BACKENDS=CUDA \ + -D SUNDIALS_ENABLE_CUDA=ON \ + -D CMAKE_CUDA_ARCHITECTURES="60" + +.. cmakeoption:: SUNDIALS_ENABLE_RESOLVE + + Enable Re\:\:Solve support + + Default: ``OFF`` + +.. cmakeoption:: ReSolve_DIR + + Path to the Re\:\:Solve installation + + Default: None + +.. cmakeoption:: SUNDIALS_RESOLVE_BACKENDS + + Which Re\:\:Solve backend to use under the SUNDIALS Re\:\:Solve interface: ``CPU`` ``CUDA`` or + ``HIP`` + + Default: ``CPU`` + +.. cmakeoption:: SUNDIALS_ENABLE_RESOLVE_CHECKS + + Perform Re::Solve compatibility checks + + Default: ``ON`` + + .. _Installation.Options.SuperLU_DIST: Building with SuperLU_DIST @@ -3681,6 +3741,25 @@ header file and link to the library given below. | CMake target | ``SUNDIALS::sunmatrixonemkldense`` | +--------------+----------------------------------------------+ +.. _Installation.LibrariesAndHeaders.Matrix.ReSolve: + +Re::Solve +"""""""""""" + +To use the :ref:`Re\:\:Solve sparse SUNMatrix `, include the +header file and link to the library given below. + +.. table:: The sparse Re::Solve SUNMatrix library, header file, and CMake target + :align: center + + +--------------+----------------------------------------------+ + | Libraries | ``libsundials_sunmatrixresolve.LIB`` | + +--------------+----------------------------------------------+ + | Headers | ``sunmatrix/sunmatrix_resolve.h`` | + +--------------+----------------------------------------------+ + | CMake target | ``SUNDIALS::sunmatrixresolve`` | + +--------------+----------------------------------------------+ + .. _Installation.LibrariesAndHeaders.Matrix.Sparse: Sparse diff --git a/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst b/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst new file mode 100644 index 0000000000..cfe77ef1a3 --- /dev/null +++ b/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst @@ -0,0 +1,178 @@ +.. + Programmer(s): Jeffery Zhang + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2025-2026, Lawrence Livermore National Security, + University of Maryland Baltimore County, and the SUNDIALS contributors. + Copyright (c) 2013-2025, Lawrence Livermore National Security + and Southern Methodist University. + Copyright (c) 2002-2013, Lawrence Livermore National Security. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _SUNMatrix.ReSolve: + +The SUNMATRIX_RESOLVE Module +====================================== + +The SUNMATRIX_RESOLVE module interfaces to the +`Re::Solve `_ library of GPU-resident linear +solvers designed to run on NVIDIA and AMD GPUs as well as on CPU devices. The module stores +matrices in the *compressed-sparse-row* (CSR) sparse matrix format. + +More general information about sparse matrices can be found in the SUNMatrix_Sparse documentation +described in :numref:`SUNMatrix.Sparse`. + + +The header file to include when using this module is ``sunmatrix/sunmatrix_resolve.h``. +The installed library to link to is ``libsundials_sunmatrixresolve.lib`` where ``lib`` is +typically ``.so`` for shared libraries and ``.a`` for static libraries. + + +.. _SUNMatrix.ReSolve.functions: + +SUNMATRIX_RESOLVE Functions +----------------------------------- + + +The SUNMATRIX_RESOLVE module currently defines the following implementations +of matrix operations listed in :numref:`SUNMatrix.Ops`. + +* ``SUNMatGetID_ReSolve`` -- returns ``SUNMATRIX_RESOLVE`` +* ``SUNMatClone_ReSolve`` +* ``SUNMatDestroy_ReSolve`` +* ``SUNMatZero_ReSolve`` + +In addition, the SUNMATRIX_RESOLVE module defines the following +implementation specific functions: + +.. cpp:function:: SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, sunindextype NNZ, ReSolve::memory::MemorySpace memspace, SUNContext sunctx) + + This constructor function creates and allocates memory for an + :math:`M \times N` SUNMATRIX_RESOLVE ``SUNMatrix``. + + **Arguments:** + * *M* -- the number of matrix rows. + * *N* -- the number of matrix columns. + * *NNZ* -- the number of non-zeros. + * *memspace* -- A Re::Solve variable used to choose between performing an operation on + either the HOST and DEVICE. Choose ``ReSolve::memory::HOST`` to use CPU devices or + ``ReSolve::memory::DEVICE`` to use NVIDIA or AMD GPUs. + * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) + + **Return value:** + If successful, a ``SUNMatrix`` object otherwise ``NULL``. + +.. cpp:function:: sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A) + + This function returns the number of rows in the ``SUNMatrix`` object. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + + **Return value:** + The number of rows in the ``SUNMatrix`` object. + + +.. cpp:function:: sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A) + + This function returns the number of columns in the ``SUNMatrix`` object. + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + + **Return value:** + The number of columns in the ``SUNMatrix`` object. + + +.. cpp:function:: sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) + + This function returns the number of nonzeros in a ``SUNMatrix`` + object. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + + **Return value:** + The number of nonzeros in the ``SUNMatrix`` object. + + +.. cpp:function:: sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) + + This function returns a pointer to the nonzero entries of the ``SUNMatrix`` + object on either the HOST or the DEVICE. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` + + **Return value:** + A pointer to the array of the nonzero entries of the ``SUNMatrix`` object on either + the HOST or DEVICE. + +.. cpp:function:: sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) + + This function returns a pointer to the array of column indices of the ``SUNMatrix`` + object on either the HOST or the DEVICE. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` + + **Return value:** + A pointer to the array of column indices of the ``SUNMatrix`` object on either + the HOST or DEVICE. + +.. cpp:function:: sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) + + This function returns a pointer to the array of row pointers of the ``SUNMatrix`` + object on either the HOST or the DEVICE. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` + + **Return value:** + A pointer to the array of row pointers of the ``SUNMatrix`` object on either + the HOST or DEVICE. + +.. cpp:function:: SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace) + + This function is used to set a Re::Solve memory space to "updated". The other data + mirror is also automatically set as non-updated. + This function should be used if matrix data is updated through access of the raw pointers + as the matrix has no way of knowing which data is most recent otherwise. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` + + **Return value:** + ``SUN_SUCCESS`` if the update is successful. + +.. cpp:function:: SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) + + This function is used to sync data in the given memory space with the updated memory space. + + The memory space other than the the given memory space must be up-to-date. Otherwise, + the function will return an error. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` + + **Return value:** + * ``SUN_SUCCESS`` if the sync is successful. + * ``SUN_ERR_ARG_INCOMPATIBLE`` if the given memory space is not updated. + +.. cpp:function:: void SUNMatrix_ReSolve_Print(SUNMatrix A) + + This function can be used to print the ``SUNMatrix`` object. + + **Arguments:** + * *A* -- a ``SUNMatrix`` object. + * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` \ No newline at end of file diff --git a/doc/superbuild/source/sunmatrix/SUNMatrix_links.rst b/doc/superbuild/source/sunmatrix/SUNMatrix_links.rst index 187ed6b53d..68de41c22f 100644 --- a/doc/superbuild/source/sunmatrix/SUNMatrix_links.rst +++ b/doc/superbuild/source/sunmatrix/SUNMatrix_links.rst @@ -23,4 +23,5 @@ .. include:: ../../../shared/sunmatrix/SUNMatrix_Ginkgo.rst .. include:: ../../../shared/sunmatrix/SUNMatrix_GinkgoBatch.rst .. include:: ../../../shared/sunmatrix/SUNMatrix_KokkosDense.rst +.. include:: ../../../shared/sunmatrix/SUNMatrix_ReSolve.rst .. include:: ../../../shared/sunmatrix/SUNMatrix_Examples.rst From c653dbdc62f7299802d54ec74b73c29f48d09dff Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Mon, 22 Jun 2026 21:06:12 -0400 Subject: [PATCH 13/22] Update SUNMatrix_ReSolve class to remove the NP variable and add ability to choose output and indexing base for the print() function --- doc/shared/sunmatrix/SUNMatrix_ReSolve.rst | 5 +++-- include/sunmatrix/sunmatrix_resolve.h | 7 ++---- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 17 ++++---------- .../resolve/test_sunmatrix_resolve.cpp | 22 +++++++++---------- 4 files changed, 19 insertions(+), 32 deletions(-) diff --git a/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst b/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst index cfe77ef1a3..901d0b9cb2 100644 --- a/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst +++ b/doc/shared/sunmatrix/SUNMatrix_ReSolve.rst @@ -169,10 +169,11 @@ implementation specific functions: * ``SUN_SUCCESS`` if the sync is successful. * ``SUN_ERR_ARG_INCOMPATIBLE`` if the given memory space is not updated. -.. cpp:function:: void SUNMatrix_ReSolve_Print(SUNMatrix A) +.. cpp:function:: void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexing_base) This function can be used to print the ``SUNMatrix`` object. **Arguments:** * *A* -- a ``SUNMatrix`` object. - * *memspace* -- Either ``ReSolve::memory::HOST`` or ``ReSolve::memory::DEVICE`` \ No newline at end of file + * *out* -- reference specifying where output should be written + * *indexing_base* -- value specifying the indexing base \ No newline at end of file diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index 91aaf40afa..8789fb1f46 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -38,7 +38,6 @@ struct _SUNMatrixContent_ReSolve sunindextype M; sunindextype N; sunindextype NNZ; - sunindextype NP; ReSolve::memory::MemorySpace memspace; ReSolve::matrix::Csr* mat; }; @@ -57,9 +56,7 @@ SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A); SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); - -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace); @@ -71,7 +68,7 @@ SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::me SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A); +SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexing_base); //SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print_Array(SUNMatrix A); diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index 08222a41a3..5b89054496 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -53,7 +53,6 @@ #define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) #define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) #define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) -#define RESOLVE_NP(A) (RESOLVE_CONTENT(A)->NP) #define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) #define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) @@ -109,7 +108,6 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, content->M = m; content->N = n; content->NNZ = nnz; - content->NP = m; content->mat = mat; content->memspace = memspace; @@ -149,13 +147,6 @@ sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) return RESOLVE_NNZ(A); } -sunindextype SUNMatrix_ReSolve_NP(SUNMatrix A) -{ - SUNFunctionBegin(A->sunctx); - SUNAssertNoRet(SUNMatGetID(A) == SUNMATRIX_RESOLVE, SUN_ERR_ARG_WRONGTYPE); - return RESOLVE_NP(A); -} - /** Get the pointer to the ReSolve matrix data array @@ -231,9 +222,9 @@ SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace /** Print the Re::Solve matrix */ -void SUNMatrix_ReSolve_Print(SUNMatrix A) +void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexing_base) { - RESOLVE_MAT(A)->print(std::cout, 0); + RESOLVE_MAT(A)->print(out, indexing_base); } /** @@ -328,12 +319,12 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) index_values[i] = 0; } - for (i = 0; i < RESOLVE_NP(A); i++) + for (i = 0; i < RESOLVE_M(A); i++) { index_pointers[i] = ZERO; } - (index_pointers)[RESOLVE_NP(A)] = 0; + (index_pointers)[RESOLVE_M(A)] = 0; SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index b747182127..f1c6f9f9dd 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -105,24 +105,22 @@ int main(int argc, char* argv[]) } // Print the matrix - SUNMatrix_ReSolve_Print(A); + printf("\n The SUNMatrix object\n"); + SUNMatrix_ReSolve_Print(A, std::cout, 0); + printf("\n"); + std::cout << "Running SUNMatrix generic unit tests\n"; /* SUNMatrix Tests */ fails += Test_SUNMatGetID(A, SUNMATRIX_RESOLVE, 0); fails += Test_SUNMatZero(A, 0); if (fails) { - printf("FAIL: SUNMatrix module failed %i tests \n \n", fails); + std::cout << "FAIL: SUNMatrix module failed " << fails << " tests on the " < Date: Mon, 22 Jun 2026 21:19:31 -0400 Subject: [PATCH 14/22] Updated the SUNMatrix_ReSolve_SyncData() function to check if syncData fails --- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index 5b89054496..fad0dd5078 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -215,8 +215,13 @@ SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpac */ SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) { - RESOLVE_MAT(A)->syncData(memspace); - return SUN_SUCCESS; + int result = RESOLVE_MAT(A)->syncData(memspace); + if (result == 0) { + return SUN_SUCCESS; + } + else { + return SUN_ERR_ARG_INCOMPATIBLE; + } } /** From 09ca11ed43e93132505ac3282b6c5a1e2d36ff88 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 23 Jun 2026 13:50:21 -0400 Subject: [PATCH 15/22] update CHANGELOG.md and RecentChanges.rst --- CHANGELOG.md | 3 +++ doc/shared/RecentChanges.rst | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ed1a1fde8..25f2e720a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ ### New Features and Enhancements +Added a interface for the Re::Solve library (https://github.com/ORNL/ReSolve) and the +SUNMatrix_ReSolve class to use ReSolve matrices. + Added the function `SUNLogger_SetQueueAndFlushMsgFns` to allow for user-defined functions to queue and flush log messages. diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 39bc58019a..c4b3b580c0 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -5,6 +5,9 @@ **New Features and Enhancements** +Added a interface for the Re::Solve library (https://github.com/ORNL/ReSolve) +and the SUNMatrix_ReSolve class to use ReSolve matrices. + Added the function :c:func:`SUNLogger_SetQueueAndFlushMsgFns` to allow for user-defined functions to queue and flush log messages. From 34b4bf6cc21a6eda46aac7840ab5960ddc9c9140 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 23 Jun 2026 20:39:23 -0400 Subject: [PATCH 16/22] Remove the debugging print function --- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 22 --------------------- 1 file changed, 22 deletions(-) diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index fad0dd5078..493126f058 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -232,28 +232,6 @@ void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexi RESOLVE_MAT(A)->print(out, indexing_base); } -/** - Utility function to print an array on the device for debugging -*/ -// void SUNMatrix_ReSolve_Print_Array(SUNMatrix A) -// { -// if (RESOLVE_MEMSPACE(A) == ReSolve::memory::HOST) {return;} - -// ReSolve::memory::MemorySpace memspace = RESOLVE_MEMSPACE(A); -// sunrealtype* d_data = SUNMatrix_ReSolve_Data(A, memspace); -// sunrealtype* h_data = new sunrealtype[SUNMatrix_ReSolve_NNZ(A)]; - -// cudaMemcpy(h_data, d_data, -// SUNMatrix_ReSolve_NNZ(A) * sizeof(sunrealtype), -// cudaMemcpyDeviceToHost); - -// for (int i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) -// { -// printf("data[%d] = %f\n", i, h_data[i]); -// } -// delete[] h_data; -// } - /* -------------------------------------------------------------------------- * Implementation of generic SUNMatrix operations. * -------------------------------------------------------------------------- */ From cdc7e96ea67329238db377ca304267aa301de5fb Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 23 Jun 2026 20:40:18 -0400 Subject: [PATCH 17/22] Update the Install.rst docs to use more modern cuda architecture as an example --- doc/shared/sundials/Install.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/shared/sundials/Install.rst b/doc/shared/sundials/Install.rst index ab88983f39..e4022ae6a1 100644 --- a/doc/shared/sundials/Install.rst +++ b/doc/shared/sundials/Install.rst @@ -2145,9 +2145,7 @@ header files and libraries). To enable Re::Solve support, set :cmakeop:`SUNDIALS_ENABLE_RESOLVE` to ``ON``, :cmakeop:`ReSolve_DIR` to the root path of a Re::Solve installation, and -:cmakeop:`SUNDIALS_RESOLVE_BACKENDS` to the desired Re::Solve backend to use. For -example, the following command will configure SUNDIALS with Re::Solve support with -the CUDA backend (targeting Pascal GPUs): +:cmakeop:`SUNDIALS_RESOLVE_BACKENDS` to the desired Re::Solve backend to use. .. code-block:: bash @@ -2158,8 +2156,9 @@ the CUDA backend (targeting Pascal GPUs): -D SUNDIALS_ENABLE_RESOLVE=ON \ -D ReSolve_DIR=/path/to/resolve/installation \ -D SUNDIALS_RESOLVE_BACKENDS=CUDA \ - -D SUNDIALS_ENABLE_CUDA=ON \ - -D CMAKE_CUDA_ARCHITECTURES="60" + -D SUNDIALS_ENABLE_CUDA=ON + +Optionally, a specific CUDA architecture can be set using `-D CMAKE_CUDA_ARCHITECTURES="80"`. .. cmakeoption:: SUNDIALS_ENABLE_RESOLVE @@ -2184,7 +2183,7 @@ the CUDA backend (targeting Pascal GPUs): Perform Re::Solve compatibility checks - Default: ``ON`` + Default: ``OFF`` .. _Installation.Options.SuperLU_DIST: From 6167e0483eb85b8bb0297c0f1525b2227495837a Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Tue, 23 Jun 2026 20:40:44 -0400 Subject: [PATCH 18/22] Update the sunmatrix CMake file to check for the backend used and remove the commented code --- src/sunmatrix/resolve/CMakeLists.txt | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/sunmatrix/resolve/CMakeLists.txt b/src/sunmatrix/resolve/CMakeLists.txt index a2562559d5..61def5b1e1 100644 --- a/src/sunmatrix/resolve/CMakeLists.txt +++ b/src/sunmatrix/resolve/CMakeLists.txt @@ -15,20 +15,10 @@ # SUNDIALS Copyright End # --------------------------------------------------------------- -# TODO Add ReSolve Backends for now hardcode cpu - install( - CODE "MESSAGE(\"\nInstall SUNMATRIX_RESOLVE with CPU backend(s)\n\")" + CODE "MESSAGE(\"\nInstall SUNMATRIX_RESOLVE with ${SUNDIALS_RESOLVE_BACKENDS} backend(s)\n\")" ) -# if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") -# set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CUDA) -# set(_libs_needed sundials_nveccuda) -# elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") -# set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CXX) -# set(_libs_needed sundials_nvechip hip::device) -# endif() - # Add the sunmatrix_resolve library sundials_add_library( sundials_sunmatrixresolve @@ -45,5 +35,5 @@ sundials_add_library( message( STATUS - "Added SUNMATRIX_RESOLVE module with CPU backend(s)" + "Added SUNMATRIX_RESOLVE module with ${SUNDIALS_RESOLVE_BACKENDS} backend(s)" ) From 91c5b8f64456e668f76a5b2e1e2d456cfa4322ce Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Thu, 25 Jun 2026 16:35:38 -0400 Subject: [PATCH 19/22] Update formatting --- cmake/SundialsTPLOptions.cmake | 3 +- cmake/tpl/FindReSolve.cmake | 20 +-- include/sunmatrix/sunmatrix_resolve.h | 28 +++-- src/sunmatrix/resolve/sunmatrix_resolve.cpp | 91 +++++++------- .../sunmatrix/resolve/CMakeLists.txt | 21 ++-- .../resolve/test_sunmatrix_resolve.cpp | 114 ++++++++++-------- 6 files changed, 144 insertions(+), 133 deletions(-) diff --git a/cmake/SundialsTPLOptions.cmake b/cmake/SundialsTPLOptions.cmake index d730494b80..f92bbef89d 100644 --- a/cmake/SundialsTPLOptions.cmake +++ b/cmake/SundialsTPLOptions.cmake @@ -568,7 +568,8 @@ sundials_option( sundials_option(SUNDIALS_ENABLE_RESOLVE BOOL "Enable ReSolve support" OFF) sundials_option( - SUNDIALS_RESOLVE_BACKENDS STRING + SUNDIALS_RESOLVE_BACKENDS + STRING "Which ReSolve backend to use under the SUNDIALS ReSolve interfaces (CPU, CUDA, HIP)" "CPU" OPTIONS "CPU;CUDA;HIP" diff --git a/cmake/tpl/FindReSolve.cmake b/cmake/tpl/FindReSolve.cmake index 560fb631da..7d3ffc738d 100644 --- a/cmake/tpl/FindReSolve.cmake +++ b/cmake/tpl/FindReSolve.cmake @@ -59,18 +59,22 @@ if(NOT # Check for CUDA backend if(TARGET ReSolve::CUDA) - set(RESOLVE_CUDA_FOUND TRUE CACHE BOOL "ReSolve CUDA backend found") - if(NOT TARGET SUNDIALS::ReSolve_CUDA) - add_library(SUNDIALS::ReSolve_CUDA ALIAS ReSolve::resolve_backend_cuda) - endif() + set(RESOLVE_CUDA_FOUND + TRUE + CACHE BOOL "ReSolve CUDA backend found") + if(NOT TARGET SUNDIALS::ReSolve_CUDA) + add_library(SUNDIALS::ReSolve_CUDA ALIAS ReSolve::resolve_backend_cuda) + endif() endif() # Check for HIP backend if(TARGET ReSolve::HIP) - set(RESOLVE_HIP_FOUND TRUE CACHE BOOL "ReSolve HIP backend found") - if(NOT TARGET SUNDIALS::ReSolve_HIP) - add_library(SUNDIALS::ReSolve_HIP ALIAS ReSolve::resolve_backend_hip) - endif() + set(RESOLVE_HIP_FOUND + TRUE + CACHE BOOL "ReSolve HIP backend found") + if(NOT TARGET SUNDIALS::ReSolve_HIP) + add_library(SUNDIALS::ReSolve_HIP ALIAS ReSolve::resolve_backend_hip) + endif() endif() return() endif() diff --git a/include/sunmatrix/sunmatrix_resolve.h b/include/sunmatrix/sunmatrix_resolve.h index 8789fb1f46..931d9d98f3 100644 --- a/include/sunmatrix/sunmatrix_resolve.h +++ b/include/sunmatrix/sunmatrix_resolve.h @@ -23,11 +23,10 @@ #ifndef _SUNMATRIX_RESOLVE_H #define _SUNMATRIX_RESOLVE_H +#include #include #include #include -#include -#include #ifdef __cplusplus /* wrapper to enable C++ usage */ extern "C" { @@ -48,7 +47,8 @@ typedef struct _SUNMatrixContent_ReSolve* SUNMatrixContent_ReSolve; * Implementation specific functions * ---------------------------------------*/ -SUNDIALS_EXPORT SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, sunindextype NNZ, +SUNDIALS_EXPORT SUNMatrix SUNMatrix_ReSolve(sunindextype M, sunindextype N, + sunindextype NNZ, ReSolve::memory::MemorySpace memspace, SUNContext sunctx); @@ -56,21 +56,25 @@ SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Rows(SUNMatrix A); SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_Columns(SUNMatrix A); -SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); +SUNDIALS_EXPORT sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A); -SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunrealtype* SUNMatrix_ReSolve_Data( + SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexValues( + SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT sunindextype* SUNMatrix_ReSolve_IndexPointers( + SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT SUNErrCode +SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); +SUNDIALS_EXPORT SUNErrCode +SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace); -SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexing_base); - -//SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print_Array(SUNMatrix A); +SUNDIALS_EXPORT void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, + sunindextype indexing_base); /* --------------------------------------- * SUNMatrix API functions diff --git a/src/sunmatrix/resolve/sunmatrix_resolve.cpp b/src/sunmatrix/resolve/sunmatrix_resolve.cpp index 493126f058..e25f5ebd63 100644 --- a/src/sunmatrix/resolve/sunmatrix_resolve.cpp +++ b/src/sunmatrix/resolve/sunmatrix_resolve.cpp @@ -18,26 +18,21 @@ * SUNMATRIX class using the Re::Solve library * ---------------------------------------------------------------------------*/ - #include #include -// Re::Solve headers -#include -#include -#include - // SUNDIALS headers -#include #include #include +#include #include "sundials/sundials_errors.h" #include "sundials_debug.h" #include "sundials_macros.h" // Check for a valid precision #if defined(SUNDIALS_EXTENDED_PRECISION) -#error "Re::Solve set precision does not match SUNDIALS precision for floating type" +#error \ + "Re::Solve set precision does not match SUNDIALS precision for floating type" #endif #if defined(SUNDIALS_INT64_T) @@ -49,19 +44,21 @@ #define ONE SUN_RCONST(1.0) // Content accessor macro -#define RESOLVE_CONTENT(A) ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT -#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) -#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) -#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) -#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) -#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) +#define RESOLVE_CONTENT(A) \ + ((SUNMatrixContent_ReSolve)(A)->content) // ASSUMES CSR FORMAT DEFAULT +#define RESOLVE_MAT(A) (RESOLVE_CONTENT(A)->mat) +#define RESOLVE_M(A) (RESOLVE_CONTENT(A)->M) +#define RESOLVE_N(A) (RESOLVE_CONTENT(A)->N) +#define RESOLVE_NNZ(A) (RESOLVE_CONTENT(A)->NNZ) +#define RESOLVE_MEMSPACE(A) (RESOLVE_CONTENT(A)->memspace) /* -------------------------------------------------------------------------- * Constructor * -------------------------------------------------------------------------- */ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, - ReSolve::memory::MemorySpace memspace, SUNContext sunctx) + ReSolve::memory::MemorySpace memspace, + SUNContext sunctx) { SUNFunctionBegin(sunctx); SUNMatrixContent_ReSolve content; @@ -82,10 +79,10 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, } // Attach operations - A->ops->getid = SUNMatGetID_ReSolve; - A->ops->destroy = SUNMatDestroy_ReSolve; - A->ops->zero = SUNMatZero_ReSolve; - A->ops->clone = SUNMatClone_ReSolve; + A->ops->getid = SUNMatGetID_ReSolve; + A->ops->destroy = SUNMatDestroy_ReSolve; + A->ops->zero = SUNMatZero_ReSolve; + A->ops->clone = SUNMatClone_ReSolve; // Create ReSolve matrix ReSolve::matrix::Csr* mat = new ReSolve::matrix::Csr(m, n, nnz); @@ -105,12 +102,11 @@ SUNMatrix SUNMatrix_ReSolve(sunindextype m, sunindextype n, sunindextype nnz, A->content = content; /* Fill content */ - content->M = m; - content->N = n; - content->NNZ = nnz; - content->mat = mat; - content->memspace = memspace; - + content->M = m; + content->N = n; + content->NNZ = nnz; + content->mat = mat; + content->memspace = memspace; if (!(A->content)) { @@ -152,7 +148,8 @@ sunindextype SUNMatrix_ReSolve_NNZ(SUNMatrix A) @param[in] A The SUNMatrix object */ -sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, + ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getValues(memspace); } @@ -162,7 +159,8 @@ sunrealtype* SUNMatrix_ReSolve_Data(SUNMatrix A, ReSolve::memory::MemorySpace me @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, + ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getRowData(memspace); } @@ -172,7 +170,8 @@ sunindextype* SUNMatrix_ReSolve_IndexPointers(SUNMatrix A, ReSolve::memory::Memo @param[in] A The SUNMatrix object */ -sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, + ReSolve::memory::MemorySpace memspace) { return RESOLVE_MAT(A)->getColData(memspace); } @@ -196,7 +195,8 @@ sunindextype* SUNMatrix_ReSolve_IndexValues(SUNMatrix A, ReSolve::memory::Memory * @note If you want to set both DEVICE and HOST memory to the same value * use syncData function. */ -SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, + ReSolve::memory::MemorySpace memspace) { RESOLVE_MAT(A)->setUpdated(memspace); return SUN_SUCCESS; @@ -213,21 +213,19 @@ SUNErrCode SUNMatrix_ReSolve_SetUpdated(SUNMatrix A, ReSolve::memory::MemorySpac * * @see Sparse::setUpdated in the Re::Solve library */ -SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, ReSolve::memory::MemorySpace memspace) +SUNErrCode SUNMatrix_ReSolve_SyncData(SUNMatrix A, + ReSolve::memory::MemorySpace memspace) { int result = RESOLVE_MAT(A)->syncData(memspace); - if (result == 0) { - return SUN_SUCCESS; - } - else { - return SUN_ERR_ARG_INCOMPATIBLE; - } + if (result == 0) { return SUN_SUCCESS; } + else { return SUN_ERR_ARG_INCOMPATIBLE; } } /** Print the Re::Solve matrix */ -void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, sunindextype indexing_base) +void SUNMatrix_ReSolve_Print(SUNMatrix A, std::ostream& out, + sunindextype indexing_base) { RESOLVE_MAT(A)->print(out, indexing_base); } @@ -294,26 +292,23 @@ SUNErrCode SUNMatZero_ReSolve(SUNMatrix A) sunindextype* index_pointers = RESOLVE_MAT(A)->getRowData(ReSolve::memory::HOST); sunindextype* index_values = RESOLVE_MAT(A)->getColData(ReSolve::memory::HOST); - + // Zero out the values of these arrays for (i = 0; i < RESOLVE_NNZ(A); i++) { - values[i] = ZERO; - index_values[i] = 0; + values[i] = ZERO; + index_values[i] = 0; } - for (i = 0; i < RESOLVE_M(A); i++) - { - index_pointers[i] = ZERO; - } - + for (i = 0; i < RESOLVE_M(A); i++) { index_pointers[i] = ZERO; } + (index_pointers)[RESOLVE_M(A)] = 0; SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); // Sync to device if necessary - if (RESOLVE_MEMSPACE(A) != ReSolve::memory::HOST) - { + if (RESOLVE_MEMSPACE(A) != ReSolve::memory::HOST) + { SUNMatrix_ReSolve_SyncData(A, RESOLVE_MEMSPACE(A)); } @@ -324,7 +319,7 @@ SUNMatrix SUNMatClone_ReSolve(SUNMatrix A) { SUNFunctionBegin(A->sunctx); SUNMatrix B = SUNMatrix_ReSolve(RESOLVE_M(A), RESOLVE_N(A), RESOLVE_NNZ(A), - RESOLVE_MEMSPACE(A), A->sunctx); + RESOLVE_MEMSPACE(A), A->sunctx); SUNCheckLastErrNull(); return (B); } diff --git a/test/unit_tests/sunmatrix/resolve/CMakeLists.txt b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt index 2619920e8b..4dc5a40172 100644 --- a/test/unit_tests/sunmatrix/resolve/CMakeLists.txt +++ b/test/unit_tests/sunmatrix/resolve/CMakeLists.txt @@ -12,8 +12,7 @@ # SUNDIALS Copyright End # ------------------------------------------------------------------------------ -set(examples_list - "test_sunmatrix_resolve.cpp\;\;") +set(examples_list "test_sunmatrix_resolve.cpp\;\;") # Add source directory to include directories include_directories(..) @@ -29,23 +28,17 @@ foreach(example_tuple ${examples_list}) if(NOT TARGET ${example_target}) # example source files - sundials_add_executable( - ${example_target} - ${example} - ../test_sunmatrix.c - ../test_sunmatrix.h) + sundials_add_executable(${example_target} ${example} ../test_sunmatrix.c + ../test_sunmatrix.h) # folder for IDEs set_target_properties(${example_target} PROPERTIES FOLDER "Examples") # libraries to link against target_link_libraries( - ${example_target} - PRIVATE sundials_core - sundials_sunmatrixresolve - SUNDIALS::ReSolve - ${EXE_EXTRA_LINK_LIBS}) - + ${example_target} PRIVATE sundials_core sundials_sunmatrixresolve + SUNDIALS::ReSolve ${EXE_EXTRA_LINK_LIBS}) + # Target GPU backends if necessary if(SUNDIALS_RESOLVE_BACKENDS MATCHES "CUDA") target_link_libraries(${example_target} PRIVATE SUNDIALS::ReSolve_CUDA) @@ -69,4 +62,4 @@ foreach(example_tuple ${examples_list}) EXAMPLE_TYPE ${example_type} NODIFF) -endforeach() \ No newline at end of file +endforeach() diff --git a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp index f1c6f9f9dd..e03e115c90 100644 --- a/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp +++ b/test/unit_tests/sunmatrix/resolve/test_sunmatrix_resolve.cpp @@ -33,7 +33,7 @@ * --------------------------------------------------------------------*/ int main(int argc, char* argv[]) { - int fails = 0; /* counter for test failures */ + int fails = 0; /* counter for test failures */ SUNMatrix A; sunindextype i, j, k, kstart, kend, N, uband, lband; int print_timing, square; @@ -50,14 +50,14 @@ int main(int argc, char* argv[]) // Initialize a ReSolve HOST memory space. ReSolve::memory::MemorySpace memspace = ReSolve::memory::HOST; - // Check if a GPU backend is enabled - #ifdef SUNDIALS_RESOLVE_BACKENDS_CUDA - hwbackend = "CUDA"; - memspace = ReSolve::memory::DEVICE; - #elif defined(SUNDIALS_RESOLVE_BACKENDS_HIP) - hwbackend = "HIP"; - memspace = ReSolve::memory::DEVICE; - #endif +// Check if a GPU backend is enabled +#ifdef SUNDIALS_RESOLVE_BACKENDS_CUDA + hwbackend = "CUDA"; + memspace = ReSolve::memory::DEVICE; +#elif defined(SUNDIALS_RESOLVE_BACKENDS_HIP) + hwbackend = "HIP"; + memspace = ReSolve::memory::DEVICE; +#endif // Create a SUNMatrix_ReSolve object A = NULL; @@ -65,42 +65,45 @@ int main(int argc, char* argv[]) // Get pointers to content arrays sunrealtype* data = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); - sunindextype* index_values = SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); - sunindextype* index_pointers = SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); + sunindextype* index_values = + SUNMatrix_ReSolve_IndexValues(A, ReSolve::memory::HOST); + sunindextype* index_pointers = + SUNMatrix_ReSolve_IndexPointers(A, ReSolve::memory::HOST); // Fill the matrix as a 5x5 second difference matrix for (i = 0; i < SUNMatrix_ReSolve_NNZ(A); i++) { - if (i % 3 == 0) - { - data[i] = 2; - } - else - { - data[i] = -1; - } + if (i % 3 == 0) { data[i] = 2; } + else { data[i] = -1; } } // Row pointers - index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) - index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) - index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) - index_pointers[3] = 8; // row 3 starts at 8 (3 non-zeros) - index_pointers[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) - index_pointers[5] = 13; // total non-zeros + index_pointers[0] = 0; // row 0 starts at 0 (2 non-zeros: diag + right) + index_pointers[1] = 2; // row 1 starts at 2 (3 non-zeros: left + diag + right) + index_pointers[2] = 5; // row 2 starts at 5 (3 non-zeros) + index_pointers[3] = 8; // row 3 starts at 8 (3 non-zeros) + index_pointers[4] = 11; // row 4 starts at 11 (2 non-zeros: left + diag) + index_pointers[5] = 13; // total non-zeros // Column indices - index_values[0] = 0; index_values[1] = 1; // row 0: cols 0, 1 - index_values[2] = 0; index_values[3] = 1; index_values[4] = 2; // row 1: cols 0, 1, 2 - index_values[5] = 1; index_values[6] = 2; index_values[7] = 3; // row 2: cols 1, 2, 3 - index_values[8] = 2; index_values[9] = 3; index_values[10] = 4; // row 3: cols 2, 3, 4 - index_values[11] = 3; index_values[12] = 4; // row 4: cols 3, 4 + index_values[0] = 0; + index_values[1] = 1; // row 0: cols 0, 1 + index_values[2] = 0; + index_values[3] = 1; + index_values[4] = 2; // row 1: cols 0, 1, 2 + index_values[5] = 1; + index_values[6] = 2; + index_values[7] = 3; // row 2: cols 1, 2, 3 + index_values[8] = 2; + index_values[9] = 3; + index_values[10] = 4; // row 3: cols 2, 3, 4 + index_values[11] = 3; + index_values[12] = 4; // row 4: cols 3, 4 - SUNMatrix_ReSolve_SetUpdated(A, ReSolve::memory::HOST); // Sync host to device if necessary - if (memspace != ReSolve::memory::HOST) - { + if (memspace != ReSolve::memory::HOST) + { SUNMatrix_ReSolve_SyncData(A, memspace); } @@ -116,11 +119,16 @@ int main(int argc, char* argv[]) if (fails) { - std::cout << "FAIL: SUNMatrix module failed " << fails << " tests on the " <>> ERROR: check_matrix: Different numbers of rows (%ld vs %ld)\n", - (long int)SUNMatrix_ReSolve_Rows(A), (long int)SUNMatrix_ReSolve_Rows(B)); + (long int)SUNMatrix_ReSolve_Rows(A), + (long int)SUNMatrix_ReSolve_Rows(B)); return (1); } if (SUNMatrix_ReSolve_Columns(A) != SUNMatrix_ReSolve_Columns(B)) @@ -190,9 +200,9 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) } /* compare sparsity patterns */ - for (i = 0; i < A_NP; i++) - { - failure += (A_index_pointers[i] != B_index_pointers[i]); + for (i = 0; i < A_NP; i++) + { + failure += (A_index_pointers[i] != B_index_pointers[i]); } if (failure > ZERO) @@ -201,9 +211,9 @@ int check_matrix(SUNMatrix A, SUNMatrix B, sunrealtype tol) return (1); } - for (i = 0; i < A_nnz; i++) - { - failure += (A_index_values[i] != B_index_values[i]); + for (i = 0; i < A_nnz; i++) + { + failure += (A_index_values[i] != B_index_values[i]); } if (failure > ZERO) @@ -252,6 +262,7 @@ int check_vector(N_Vector actual, N_Vector expected, sunrealtype tol) { return 0; } + sunbooleantype has_data(SUNMatrix A) { sunrealtype* Adata = SUNMatrix_ReSolve_Data(A, ReSolve::memory::HOST); @@ -261,7 +272,10 @@ sunbooleantype has_data(SUNMatrix A) sunbooleantype is_square(SUNMatrix A) { - if (SUNMatrix_ReSolve_Rows(A) == SUNMatrix_ReSolve_Columns(A)) { return SUNTRUE; } + if (SUNMatrix_ReSolve_Rows(A) == SUNMatrix_ReSolve_Columns(A)) + { + return SUNTRUE; + } else { return SUNFALSE; } } From 98247e14abe5d89ffc32ad8cdd61003fc3cf2485 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Thu, 25 Jun 2026 20:20:28 -0400 Subject: [PATCH 20/22] Apply swig and litgen patches --- bindings/sundials4py/sundials/sundials_matrix_generated.hpp | 1 + src/sundials/fmod_int32/fsundials_core_mod.f90 | 3 ++- src/sundials/fmod_int64/fsundials_core_mod.f90 | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_matrix_generated.hpp b/bindings/sundials4py/sundials/sundials_matrix_generated.hpp index 672fac632d..2eb2347aae 100644 --- a/bindings/sundials4py/sundials/sundials_matrix_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_matrix_generated.hpp @@ -16,6 +16,7 @@ auto pyEnumSUNMatrix_ID = .value("SUNMATRIX_GINKGO", SUNMATRIX_GINKGO, "") .value("SUNMATRIX_GINKGOBATCH", SUNMATRIX_GINKGOBATCH, "") .value("SUNMATRIX_KOKKOSDENSE", SUNMATRIX_KOKKOSDENSE, "") + .value("SUNMATRIX_RESOLVE", SUNMATRIX_RESOLVE, "") .value("SUNMATRIX_CUSTOM", SUNMATRIX_CUSTOM, "") .export_values(); // #ifndef SWIG diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 9f392ded5e..d010e7c605 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -340,11 +340,12 @@ module fsundials_core_mod enumerator :: SUNMATRIX_GINKGO enumerator :: SUNMATRIX_GINKGOBATCH enumerator :: SUNMATRIX_KOKKOSDENSE + enumerator :: SUNMATRIX_RESOLVE enumerator :: SUNMATRIX_CUSTOM end enum integer, parameter, public :: SUNMatrix_ID = kind(SUNMATRIX_DENSE) public :: SUNMATRIX_DENSE, SUNMATRIX_MAGMADENSE, SUNMATRIX_ONEMKLDENSE, SUNMATRIX_BAND, SUNMATRIX_SPARSE, SUNMATRIX_SLUNRLOC, & - SUNMATRIX_CUSPARSE, SUNMATRIX_GINKGO, SUNMATRIX_GINKGOBATCH, SUNMATRIX_KOKKOSDENSE, SUNMATRIX_CUSTOM + SUNMATRIX_CUSPARSE, SUNMATRIX_GINKGO, SUNMATRIX_GINKGOBATCH, SUNMATRIX_KOKKOSDENSE, SUNMATRIX_RESOLVE, SUNMATRIX_CUSTOM ! struct struct _generic_SUNMatrix_Ops type, bind(C), public :: SUNMatrix_Ops type(C_FUNPTR), public :: getid diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index b3037e6dd5..778e391c0f 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -340,11 +340,12 @@ module fsundials_core_mod enumerator :: SUNMATRIX_GINKGO enumerator :: SUNMATRIX_GINKGOBATCH enumerator :: SUNMATRIX_KOKKOSDENSE + enumerator :: SUNMATRIX_RESOLVE enumerator :: SUNMATRIX_CUSTOM end enum integer, parameter, public :: SUNMatrix_ID = kind(SUNMATRIX_DENSE) public :: SUNMATRIX_DENSE, SUNMATRIX_MAGMADENSE, SUNMATRIX_ONEMKLDENSE, SUNMATRIX_BAND, SUNMATRIX_SPARSE, SUNMATRIX_SLUNRLOC, & - SUNMATRIX_CUSPARSE, SUNMATRIX_GINKGO, SUNMATRIX_GINKGOBATCH, SUNMATRIX_KOKKOSDENSE, SUNMATRIX_CUSTOM + SUNMATRIX_CUSPARSE, SUNMATRIX_GINKGO, SUNMATRIX_GINKGOBATCH, SUNMATRIX_KOKKOSDENSE, SUNMATRIX_RESOLVE, SUNMATRIX_CUSTOM ! struct struct _generic_SUNMatrix_Ops type, bind(C), public :: SUNMatrix_Ops type(C_FUNPTR), public :: getid From d63c6ef950504286238d8bba79f270a8209db4e6 Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Thu, 25 Jun 2026 20:50:11 -0400 Subject: [PATCH 21/22] Test disabling resolve in the sundials-ci spack.yaml files --- docker/sundials-ci/spack-nightly/int32-double/spack.yaml | 2 +- docker/sundials-ci/spack-nightly/int64-double/spack.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/sundials-ci/spack-nightly/int32-double/spack.yaml b/docker/sundials-ci/spack-nightly/int32-double/spack.yaml index cbb78c8e50..388484cf52 100644 --- a/docker/sundials-ci/spack-nightly/int32-double/spack.yaml +++ b/docker/sundials-ci/spack-nightly/int32-double/spack.yaml @@ -20,7 +20,7 @@ spack: - superlu-dist~int64 ^parmetis~int64 arch=x86_64 %gcc@9.4.0 - trilinos+tpetra gotype=int arch=x86_64 %gcc@9.4.0 - xbraid arch=x86_64 %gcc@9.4.0 - - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 + # - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 config: install_tree: /opt/software mirrors: diff --git a/docker/sundials-ci/spack-nightly/int64-double/spack.yaml b/docker/sundials-ci/spack-nightly/int64-double/spack.yaml index 50b380d64b..d434efec89 100644 --- a/docker/sundials-ci/spack-nightly/int64-double/spack.yaml +++ b/docker/sundials-ci/spack-nightly/int64-double/spack.yaml @@ -20,7 +20,7 @@ spack: - superlu-dist+int64 ^parmetis+int64 ^netlib-lapack arch=x86_64 %gcc@9.4.0 - trilinos+tpetra gotype=long_long arch=x86_64 %gcc@9.4.0 - xbraid arch=x86_64 %gcc@9.4.0 - - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 + # - resolve~cuda~rocm arch=x86_64 %gcc@9.4.0 config: install_tree: /opt/software mirrors: From 7e84d18e087dadc303963c855a79714a70654ced Mon Sep 17 00:00:00 2001 From: JeffZ594 Date: Thu, 25 Jun 2026 21:02:45 -0400 Subject: [PATCH 22/22] Try disabling resolve in ci tests for now --- test/env/docker.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/env/docker.sh b/test/env/docker.sh index 88080b8a8d..465f3f850a 100644 --- a/test/env/docker.sh +++ b/test/env/docker.sh @@ -365,10 +365,10 @@ fi # resolve # ------- -if [ "$SUNDIALS_PRECISION" == "double" ]; then - export SUNDIALS_RESOLVE=ON - export RESOLVE_ROOT=/opt/view -else - export SUNDIALS_RESOLVE=OFF - unset RESOLVE_ROOT -fi +# if [ "$SUNDIALS_PRECISION" == "double" ] && [ "$SUNDIALS_INDEX_SIZE" == "32" ]; then +# export SUNDIALS_RESOLVE=ON +# export RESOLVE_ROOT=/opt/view +# else +# export SUNDIALS_RESOLVE=OFF +# unset RESOLVE_ROOT +# fi