Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a91b140
initial solver and cuda header
adhamsi Jul 23, 2025
ed06b6a
cuda implementation
adhamsi Jul 23, 2025
5d1f812
minimal test on cuda passes
adhamsi Jul 24, 2025
19fcfc0
cpu implementation
adhamsi Jul 24, 2025
d461cbc
tell cmake to find cholmod
adhamsi Jul 25, 2025
b667e82
add template hip implementation
adhamsi Jul 25, 2025
67bcfd3
dependencies
adhamsi Jul 28, 2025
2eedfb4
cpu: memory freeing and unused fields
adhamsi Jul 28, 2025
9733f63
Apply pre-commmit fixes
adhamsi Jul 29, 2025
95c7b59
error handling and correct memory in cuda
adhamsi Jul 29, 2025
b37584a
randomized testing: different sparsity patterns
adhamsi Jul 30, 2025
a75fddb
Apply pre-commmit fixes
adhamsi Aug 7, 2025
6701b7b
fix for cuda: resetting workspace
adhamsi Aug 8, 2025
fc5c679
Apply pre-commmit fixes
adhamsi Aug 8, 2025
9210b8a
test reusing sparsity pattern
adhamsi Aug 8, 2025
b5f357d
Apply pre-commmit fixes
adhamsi Aug 8, 2025
243367c
Apply pre-commmit fixes
adhamsi Aug 11, 2025
bb77551
draft: rocsolver
adhamsi Aug 11, 2025
9c471ea
Apply pre-commmit fixes
adhamsi Aug 11, 2025
c36939a
fix build issue
adhamsi Aug 22, 2025
b55b8e6
documentation
adhamsi Aug 25, 2025
486694f
Apply pre-commmit fixes
adhamsi Aug 25, 2025
118ff08
error message when no gpu support
adhamsi Aug 27, 2025
774505e
address minor review comments
adhamsi Aug 27, 2025
662dbee
Apply pre-commmit fixes
adhamsi Aug 27, 2025
ca35833
remove commented code
adhamsi Aug 27, 2025
b22ce10
more detail on documentation
adhamsi Aug 31, 2025
f0b85fc
Apply pre-commmit fixes
adhamsi Aug 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/FindSuiteSparse.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(SUITESPARSE_MODULES
amd
colamd
klu
cholmod
suitesparseconfig)

find_library(SUITESPARSE_LIBRARY
Expand Down
1 change: 0 additions & 1 deletion resolve/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ endif()
if(RESOLVE_USE_KLU)
add_subdirectory(hykkt)
endif()
#list(APPEND ReSolve_Targets_List resolve_hykkt)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing this from the list of targets?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolve_hykkt is the target for only the Permutation class. This is a holdover from your original commit of the Permutation class. The name hasn't been changed and needs to be. The other hykkt modules are named resolve_hykkt_ruiz, etc. But it appears adding it to the list of targets is redundant if the subdirectory is added.


# Set installable targets
install(TARGETS ${ReSolve_Targets_List} EXPORT ReSolveTargets)
Expand Down
133 changes: 66 additions & 67 deletions resolve/MemoryUtils.tpp
Original file line number Diff line number Diff line change
@@ -1,82 +1,81 @@
/**
* @file MemoryUtils.tpp
*
*
* Contains implementation of memory utility functions wrappers.
* All it does it calls vendor specific functions frm an abstract interface.
*
*
* @author Slaven Peles <peless@ornl.gov>
*/

#pragma once


namespace ReSolve
{
template <class Policy>
void MemoryUtils<Policy>::deviceSynchronize()
{
Policy::deviceSynchronize();
}
template <class Policy>
void MemoryUtils<Policy>::deviceSynchronize()
{
Policy::deviceSynchronize();
}

template <class Policy>
int MemoryUtils<Policy>::getLastDeviceError()
{
return Policy::getLastDeviceError();
}

template <class Policy>
int MemoryUtils<Policy>::deleteOnDevice(void* v)
{
return Policy::deleteOnDevice(v);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::allocateArrayOnDevice(T** v, I n)
{
return Policy::template allocateArrayOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::allocateBufferOnDevice(T** v, I n)
{
return Policy::template allocateBufferOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::setZeroArrayOnDevice(T* v, I n)
{
return Policy::template setZeroArrayOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::setArrayToConstOnDevice(T* v, T c, I n)
{
return Policy::template setArrayToConstOnDevice<I, T>(v, c, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayDeviceToHost(T* dst, const T* src, I n)
{
return Policy::template copyArrayDeviceToHost<I, T>(dst, src, n);
}

template <class Policy>
int MemoryUtils<Policy>::getLastDeviceError()
{
return Policy::getLastDeviceError();
}
template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayDeviceToDevice(T* dst, const T* src, I n)
{
return Policy::template copyArrayDeviceToDevice<I, T>(dst, src, n);
}

template <class Policy>
int MemoryUtils<Policy>::deleteOnDevice(void* v)
{
return Policy::deleteOnDevice(v);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::allocateArrayOnDevice(T** v, I n)
{
return Policy::template allocateArrayOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::allocateBufferOnDevice(T** v, I n)
{
return Policy::template allocateBufferOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::setZeroArrayOnDevice(T* v, I n)
{
return Policy::template setZeroArrayOnDevice<I, T>(v, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::setArrayToConstOnDevice(T* v, T c, I n)
{
return Policy::template setArrayToConstOnDevice<I, T>(v, c, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayDeviceToHost(T* dst, const T* src, I n)
{
return Policy::template copyArrayDeviceToHost<I, T>(dst, src, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayDeviceToDevice(T* dst, const T* src, I n)
{
return Policy::template copyArrayDeviceToDevice<I, T>(dst, src, n);
}

template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayHostToDevice(T* dst, const T* src, I n)
{
return Policy::template copyArrayHostToDevice<I, T>(dst, src, n);
}
template <class Policy>
template <typename I, typename T>
int MemoryUtils<Policy>::copyArrayHostToDevice(T* dst, const T* src, I n)
{
return Policy::template copyArrayHostToDevice<I, T>(dst, src, n);
}

} // namespace ReSolve
1 change: 1 addition & 0 deletions resolve/hykkt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(permutation)
add_subdirectory(ruiz)
add_subdirectory(cholesky)
65 changes: 65 additions & 0 deletions resolve/hykkt/cholesky/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#[[

@brief Build ReSolve matrix module

@author Slaven Peles <peless@ornl.gov>

]]

# C++ code
set(HyKKT_CHOL_SRC
CholeskySolver.cpp
CholeskySolverCpu.cpp
)

# C++ code that depends on CUDA SDK libraries
set(HyKKT_CUDASDK_SRC
CholeskySolverCuda.cpp
)

# and on HIP
set(HyKKT_ROCM_SRC
CholeskySolverHip.cpp
)

# Header files to be installed
set(HyKKT_CHOL_HEADER_INSTALL
CholeskySolver.hpp
CholeskySolverImpl.hpp
CholeskySolverCpu.hpp
CholeskySolverCuda.hpp
CholeskySolverHip.hpp
)

add_library(resolve_hykkt_chol SHARED ${HyKKT_CHOL_SRC})

target_link_libraries(resolve_hykkt_chol PUBLIC ${suitesparse_cholmod})
target_include_directories(resolve_hykkt_chol PUBLIC ${SUITESPARSE_INCLUDE_DIR})

# Link to CUDA ReSolve backend if CUDA is support enabled
if (RESOLVE_USE_CUDA)
target_sources(resolve_hykkt_chol PRIVATE ${HyKKT_CUDASDK_SRC})
target_link_libraries(resolve_hykkt_chol PUBLIC resolve_backend_cuda)
endif()

if (RESOLVE_USE_HIP)
target_sources(resolve_hykkt_chol PRIVATE ${HyKKT_ROCM_SRC})
target_link_libraries(resolve_hykkt_chol PUBLIC resolve_backend_hip)
endif()

# Link to dummy device backend if GPU support is not enabled
if (NOT RESOLVE_USE_GPU)
target_link_libraries(resolve_hykkt_chol PUBLIC resolve_backend_cpu)
endif()

target_link_libraries(resolve_hykkt_chol PUBLIC resolve_workspace
resolve_vector
resolve_matrix
resolve_logger)

target_include_directories(resolve_hykkt_chol INTERFACE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)

install(FILES ${HyKKT_CHOL_HEADER_INSTALL} DESTINATION include/resolve/hykkt)
109 changes: 109 additions & 0 deletions resolve/hykkt/cholesky/CholeskySolver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* @file CholeskySolver.cpp
* @author Adham Ibrahim (ibrahimas@ornl.gov)
* @brief Cholesky decomposition solver implementation
*/

#include "CholeskySolver.hpp"

#include "CholeskySolverCpu.hpp"
#ifdef RESOLVE_USE_CUDA
#include "CholeskySolverCuda.hpp"
#elif defined(RESOLVE_USE_HIP)
#include "CholeskySolverHip.hpp"
#endif

namespace ReSolve
{
using real_type = ReSolve::real_type;
using out = ReSolve::io::Logger;

namespace hykkt
{
/**
* @brief Cholesky Solver constructor
* @param[in] memspace - memory space to use for computations
*/
CholeskySolver::CholeskySolver(memory::MemorySpace memspace)
: memspace_(memspace)
{
if (memspace_ == memory::HOST)
{
impl_ = new CholeskySolverCpu();
}
else
{
#ifdef RESOLVE_USE_CUDA
impl_ = new CholeskySolverCuda();
#elif defined(RESOLVE_USE_HIP)
impl_ = new CholeskySolverHip();
#else
out::error() << "Memory space set to DEVICE, though no GPU support enabled. Must enable RESOLVE_USE_CUDA or RESOLVE_USE_HIP.\n";
exit(1);
#endif
}
}

/**
* @brief Cholesky Solver destructor
*/
CholeskySolver::~CholeskySolver()
{
delete impl_;
}

/**
* @brief Loads or reloads matrix pointer to the solver
* @param[in] A - pointer to the matrix in CSR format
*/
void CholeskySolver::addMatrixInfo(matrix::Csr* A)
{
A_ = A;
impl_->addMatrixInfo(A);
}

/**
* @brief Performs symbolic analysis. This need only be called once
* as long as the sparsity pattern does not change.
*/
void CholeskySolver::symbolicAnalysis()
{
impl_->symbolicAnalysis();
}

/**
* @brief Sets the pivot tolerance for the solver.
*
* This is only used in the CUDA implementation. For other backends,
* it is ignored.
*
* @param[in] tol - pivot tolerance value
*/
void CholeskySolver::setPivotTolerance(real_type tol)
{
tol_ = tol;
}

/**
* @brief Performs numerical factorization.
*/
void CholeskySolver::numericalFactorization()
{
impl_->numericalFactorization(tol_);
}

/**
* @brief Solves the linear system Ax = b and stores the result in x.
*
* @pre The vector x is allocated in the given memspace.
*
* @param[out] x - pointer to the solution vector
* @param[in] b - pointer to the right-hand side vector
*/
void CholeskySolver::solve(vector::Vector* x, vector::Vector* b)
{
impl_->solve(x, b);
x->setDataUpdated(memspace_);
}
} // namespace hykkt
} // namespace ReSolve
37 changes: 37 additions & 0 deletions resolve/hykkt/cholesky/CholeskySolver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @file CholeskySolver.hpp
* @author Adham Ibrahim (ibrahimas@ornl.gov)
* @brief Cholesky decomposition solver header
*/

#pragma once
#include "CholeskySolverImpl.hpp"
#include <resolve/MemoryUtils.hpp>
#include <resolve/matrix/Csr.hpp>
#include <resolve/vector/Vector.hpp>

namespace ReSolve
{
namespace hykkt
{
class CholeskySolver
{
public:
CholeskySolver(memory::MemorySpace memspace);
~CholeskySolver();

void addMatrixInfo(matrix::Csr* A);
void symbolicAnalysis();
void setPivotTolerance(real_type tol);
void numericalFactorization();
void solve(vector::Vector* x, vector::Vector* b);

private:
memory::MemorySpace memspace_;

matrix::Csr* A_;
real_type tol_ = 1e-12;
CholeskySolverImpl* impl_;
};
} // namespace hykkt
} // namespace ReSolve
Loading
Loading