Skip to content

Commit a8b74c8

Browse files
committed
Add option for LAPACK/cuSOLVER bindings for [he,sy]gvd
1 parent c3e1b80 commit a8b74c8

30 files changed

+1305
-12
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ option(
144144
)
145145
option(BUILD_SHARED_LIBS "Build shared (.so, .dylib, .dll) libraries" ON)
146146
option(GINKGO_BUILD_HWLOC "Build Ginkgo with HWLOC. Default is OFF." OFF)
147+
option(GINKGO_BUILD_LAPACK "Build Ginkgo with LAPACK. Default is OFF." OFF)
147148
option(
148149
GINKGO_BUILD_PAPI_SDE
149150
"Build Ginkgo with PAPI SDE. Enabled if a system installation is found."
@@ -359,6 +360,12 @@ if(GINKGO_BUILD_HWLOC AND (MSVC OR WIN32 OR CYGWIN OR APPLE))
359360
)
360361
endif()
361362

363+
set(GINKGO_HAVE_LAPACK 0)
364+
if(GINKGO_BUILD_LAPACK)
365+
find_package(LAPACK REQUIRED)
366+
set(GINKGO_HAVE_LAPACK 1)
367+
endif()
368+
362369
set(GINKGO_HAVE_GPU_AWARE_MPI OFF)
363370
set(GINKGO_HAVE_OPENMPI_PRE_4_1_X OFF)
364371
if(GINKGO_BUILD_MPI)

cmake/get_info.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ foreach(log_type ${log_types})
160160
)
161161
ginkgo_print_module_footer(${${log_type}} " Enabled features:")
162162
ginkgo_print_foreach_variable(${${log_type}}
163-
"GINKGO_MIXED_PRECISION;GINKGO_HAVE_GPU_AWARE_MPI;GINKGO_ENABLE_HALF"
163+
"GINKGO_MIXED_PRECISION;GINKGO_HAVE_GPU_AWARE_MPI;GINKGO_ENABLE_HALF;GINKGO_HAVE_LAPACK"
164164
)
165165
ginkgo_print_module_footer(${${log_type}} " Tests, benchmarks and examples:")
166166
ginkgo_print_foreach_variable(${${log_type}}

common/cuda_hip/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ set(CUDA_HIP_SOURCES
4444
reorder/rcm_kernels.cpp
4545
solver/cb_gmres_kernels.cpp
4646
solver/idr_kernels.cpp
47+
solver/lobpcg_kernels.cpp
4748
solver/multigrid_kernels.cpp
4849
stop/criterion_kernels.cpp
4950
stop/residual_norm_kernels.cpp
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#ifndef GKO_COMMON_CUDA_HIP_BASE_DEV_LAPACK_BINDINGS_HPP_
6+
#define GKO_COMMON_CUDA_HIP_BASE_DEV_LAPACK_BINDINGS_HPP_
7+
8+
9+
#if defined(GKO_COMPILING_CUDA)
10+
#include "cuda/base/cusolver_bindings.hpp"
11+
#elif defined(GKO_COMPILING_HIP)
12+
#include "hip/base/hipsolver_bindings.hip.hpp"
13+
#else
14+
#error "Executor definition missing"
15+
#endif
16+
17+
18+
#endif // GKO_COMMON_CUDA_HIP_BASE_DEV_LAPACK_BINDINGS_HPP_
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#include "core/solver/lobpcg_kernels.hpp"
6+
7+
#include <ginkgo/core/base/types.hpp>
8+
9+
#include "common/cuda_hip/base/dev_lapack_bindings.hpp"
10+
11+
#if GKO_HAVE_LAPACK
12+
13+
14+
namespace gko {
15+
namespace kernels {
16+
namespace GKO_DEVICE_NAMESPACE {
17+
namespace lobpcg {
18+
19+
20+
using gko::kernels::lobpcg::workspace_mode;
21+
22+
template <typename ValueType>
23+
void symm_generalized_eig(std::shared_ptr<const DefaultExecutor> exec,
24+
const workspace_mode alloc,
25+
matrix::Dense<ValueType>* a,
26+
matrix::Dense<ValueType>* b,
27+
array<remove_complex<ValueType>>* e_vals,
28+
array<char>* workspace)
29+
{
30+
const auto id = exec->get_device_id();
31+
auto handle = exec->get_dev_lapack_handle();
32+
33+
int n = static_cast<int>(a->get_size()[1]); // column-major
34+
int lda = static_cast<int>(a->get_stride());
35+
int ldb = static_cast<int>(b->get_stride());
36+
int fp_buffer_num_elems;
37+
if (alloc == workspace_mode::allocate) {
38+
dev_lapack::sygvd_buffersize(handle, LAPACK_EIG_TYPE_1,
39+
LAPACK_EIG_VECTOR, LAPACK_FILL_LOWER, n,
40+
a->get_values(), lda, b->get_values(), ldb,
41+
e_vals->get_data(), &fp_buffer_num_elems);
42+
size_type total_bytes = sizeof(ValueType) * fp_buffer_num_elems;
43+
workspace->resize_and_reset(total_bytes);
44+
} else {
45+
fp_buffer_num_elems = workspace->get_size() / sizeof(ValueType);
46+
}
47+
array<int> dev_info(exec, 1);
48+
dev_lapack::sygvd(handle, LAPACK_EIG_TYPE_1, LAPACK_EIG_VECTOR,
49+
LAPACK_FILL_LOWER, n, a->get_values(), lda,
50+
b->get_values(), ldb, e_vals->get_data(),
51+
(ValueType*)workspace->get_data(), fp_buffer_num_elems,
52+
dev_info.get_data());
53+
}
54+
55+
GKO_INSTANTIATE_FOR_EACH_VALUE_TYPE(
56+
GKO_DECLARE_LOBPCG_SYMM_GENERALIZED_EIG_KERNEL);
57+
58+
59+
} // namespace lobpcg
60+
} // namespace GKO_DEVICE_NAMESPACE
61+
} // namespace kernels
62+
} // namespace gko
63+
64+
#endif // GKO_HAVE_LAPACK

core/device_hooks/common_kernels.inc.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "core/solver/gmres_kernels.hpp"
7070
#include "core/solver/idr_kernels.hpp"
7171
#include "core/solver/ir_kernels.hpp"
72+
#include "core/solver/lobpcg_kernels.hpp"
7273
#include "core/solver/lower_trs_kernels.hpp"
7374
#include "core/solver/minres_kernels.hpp"
7475
#include "core/solver/multigrid_kernels.hpp"
@@ -708,6 +709,17 @@ GKO_STUB_VALUE_TYPE(GKO_DECLARE_MINRES_STEP_2_KERNEL);
708709
} // namespace minres
709710

710711

712+
#if GKO_HAVE_LAPACK
713+
namespace lobpcg {
714+
715+
716+
GKO_STUB_VALUE_TYPE(GKO_DECLARE_LOBPCG_SYMM_GENERALIZED_EIG_KERNEL);
717+
718+
719+
} // namespace lobpcg
720+
#endif
721+
722+
711723
namespace sparsity_csr {
712724

713725

core/device_hooks/cuda_hooks.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
22
//
33
// SPDX-License-Identifier: BSD-3-Clause
44

@@ -175,6 +175,12 @@ std::string CusparseError::get_error(int64)
175175
}
176176

177177

178+
std::string CusolverError::get_error(int64)
179+
{
180+
return "ginkgo CUDA module is not compiled";
181+
}
182+
183+
178184
std::string CufftError::get_error(int64)
179185
{
180186
return "ginkgo CUDA module is not compiled";

core/solver/lobpcg_kernels.hpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#ifndef GKO_CORE_SOLVER_LOBPCG_KERNELS_HPP_
6+
#define GKO_CORE_SOLVER_LOBPCG_KERNELS_HPP_
7+
8+
9+
#include <ginkgo/core/base/array.hpp>
10+
#include <ginkgo/core/base/math.hpp>
11+
#include <ginkgo/core/base/types.hpp>
12+
#include <ginkgo/core/matrix/dense.hpp>
13+
14+
#include "core/base/kernel_declaration.hpp"
15+
16+
17+
namespace gko {
18+
namespace kernels {
19+
namespace lobpcg {
20+
21+
/**
22+
* Set the workspace mode for LAPACK/cuSOLVER/rocSOLVER/MKL calls
23+
*/
24+
enum class workspace_mode {
25+
/**
26+
* Query workspace size and allocate required memory
27+
*/
28+
allocate,
29+
/**
30+
* Use workspace that has already been allocated
31+
*/
32+
use_preallocated
33+
};
34+
35+
36+
#define GKO_DECLARE_LOBPCG_SYMM_GENERALIZED_EIG_KERNEL(_type) \
37+
void symm_generalized_eig( \
38+
std::shared_ptr<const DefaultExecutor> exec, \
39+
const gko::kernels::lobpcg::workspace_mode alloc, \
40+
matrix::Dense<_type>* a, matrix::Dense<_type>* b, \
41+
array<remove_complex<_type>>* e_vals, array<char>* workspace)
42+
43+
44+
#define GKO_DECLARE_ALL_AS_TEMPLATES \
45+
template <typename ValueType> \
46+
GKO_DECLARE_LOBPCG_SYMM_GENERALIZED_EIG_KERNEL(ValueType)
47+
48+
49+
} // namespace lobpcg
50+
51+
52+
GKO_DECLARE_FOR_ALL_EXECUTOR_NAMESPACES(lobpcg, GKO_DECLARE_ALL_AS_TEMPLATES);
53+
54+
55+
#undef GKO_DECLARE_ALL_AS_TEMPLATES
56+
57+
58+
} // namespace kernels
59+
} // namespace gko
60+
61+
62+
#endif // GKO_CORE_SOLVER_LOBPCG_KERNELS_HPP_

core/test/base/exception.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
22
//
33
// SPDX-License-Identifier: BSD-3-Clause
44

@@ -44,7 +44,6 @@ TEST(ExceptionClasses, NotSupportedReturnsCorrectWhatMessage)
4444
error.what());
4545
}
4646

47-
4847
TEST(ExceptionClasses, CudaErrorReturnsCorrectWhatMessage)
4948
{
5049
gko::CudaError error("test_file.cpp", 123, "test_func", 1);
@@ -77,6 +76,16 @@ TEST(ExceptionClasses, CusparseErrorReturnsCorrectWhatMessage)
7776
}
7877

7978

79+
#if GKO_HAVE_LAPACK
80+
TEST(ExceptionClasses, CusolverErrorReturnsCorrectWhatMessage)
81+
{
82+
gko::CusolverError error("test_file.cpp", 123, "test_func", 1);
83+
std::string expected = "test_file.cpp:123: test_func: ";
84+
ASSERT_EQ(expected, std::string(error.what()).substr(0, expected.size()));
85+
}
86+
#endif
87+
88+
8089
TEST(ExceptionClasses, CufftErrorReturnsCorrectWhatMessage)
8190
{
8291
gko::CufftError error("test_file.cpp", 123, "test_func", 1);
@@ -125,6 +134,16 @@ TEST(ExceptionClasses, HipfftErrorReturnsCorrectWhatMessage)
125134
}
126135

127136

137+
#if GKO_HAVE_LAPACK
138+
TEST(ExceptionClasses, LapackErrorReturnsCorrectWhatMessage)
139+
{
140+
gko::LapackError error("test_file.cpp", 123, "test_func", 1);
141+
std::string expected = "test_file.cpp:123: test_func: ";
142+
ASSERT_EQ(expected, std::string(error.what()).substr(0, expected.size()));
143+
}
144+
#endif
145+
146+
128147
TEST(ExceptionClasses, DimensionMismatchReturnsCorrectWhatMessage)
129148
{
130149
gko::DimensionMismatch error("test_file.cpp", 243, "test_func", "a", 3, 4,

core/test/base/exception_helpers.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
22
//
33
// SPDX-License-Identifier: BSD-3-Clause
44

@@ -103,6 +103,16 @@ TEST(CudaError, ReturnsCusparseError)
103103
}
104104

105105

106+
#if GKO_HAVE_LAPACK
107+
void throws_cusolver_error() { throw GKO_CUSOLVER_ERROR(0); }
108+
109+
TEST(CudaError, ReturnsCusolverError)
110+
{
111+
ASSERT_THROW(throws_cusolver_error(), gko::CusolverError);
112+
}
113+
#endif
114+
115+
106116
void throws_cufft_error() { throw GKO_CUFFT_ERROR(0); }
107117

108118
TEST(CudaError, ReturnsCufftError)
@@ -150,6 +160,15 @@ TEST(HipError, ReturnsHipfftError)
150160
ASSERT_THROW(throws_hipfft_error(), gko::HipfftError);
151161
}
152162

163+
#if GKO_HAVE_LAPACK
164+
void throws_lapack_error() { throw GKO_LAPACK_ERROR(0); }
165+
166+
TEST(LapackError, ReturnsLapackError)
167+
{
168+
ASSERT_THROW(throws_lapack_error(), gko::LapackError);
169+
}
170+
#endif
171+
153172

154173
TEST(AssertIsSquareMatrix, DoesNotThrowWhenIsSquareMatrix)
155174
{

cuda/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ target_link_libraries(
131131
CUDA::cufft
132132
nvtx::nvtx
133133
)
134+
if(GINKGO_BUILD_LAPACK)
135+
target_link_libraries(ginkgo_cuda PRIVATE CUDA::cusolver)
136+
endif()
134137
# NVTX3 is header-only and requires dlopen/dlclose in static builds
135138
target_link_libraries(ginkgo_cuda PUBLIC ginkgo_device ${CMAKE_DL_LIBS})
136139

0 commit comments

Comments
 (0)