Skip to content

Commit ff4154c

Browse files
authored
Merge branch 'main' into enh-launch-kernel-extended
2 parents 09d3ecb + 22a6c3f commit ff4154c

3 files changed

Lines changed: 60 additions & 6 deletions

File tree

cpp/include/raft/linalg/detail/strided_reduction.cuh

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ namespace raft {
1717
namespace linalg {
1818
namespace detail {
1919

20+
/**
21+
* Upper bound on the number of blocks covering the reduced dimension, i.e. on @c gridDim.y .
22+
*
23+
* Both kernels below stride over the reduced dimension, so covering it with fewer blocks than
24+
* elements is always correct. The bound must stay at or below the CUDA limit of 65535 on the y
25+
* dimension of the grid, which the reduced dimension can otherwise easily exceed: reducing a
26+
* matrix of 10M rows along the rows is a common case.
27+
*/
28+
constexpr int kMaxBlocksDimY = 8192;
29+
2030
// Kernel to perform summation along the strided dimension
2131
// of the matrix, i.e. reduce along columns for row major or reduce along rows
2232
// for column major layout
@@ -150,10 +160,10 @@ void stridedReduction(OutType* dots,
150160
constexpr dim3 Block(ColsPerBlk, TPB / ColsPerBlk);
151161
constexpr int MinRowsPerThread = 16;
152162
constexpr int MinRowsPerBlk = Block.y * MinRowsPerThread;
153-
constexpr int MaxBlocksDimY = 8192;
154163

155-
const dim3 grid(raft::ceildiv(D, (IdxType)ColsPerBlk),
156-
raft::min((IdxType)MaxBlocksDimY, raft::ceildiv(N, (IdxType)MinRowsPerBlk)));
164+
const dim3 grid(
165+
raft::div_rounding_up_safe(D, (IdxType)ColsPerBlk),
166+
raft::min((IdxType)kMaxBlocksDimY, raft::div_rounding_up_safe(N, (IdxType)MinRowsPerBlk)));
157167
const size_t shmemSize = sizeof(OutType) * Block.x * 2;
158168

159169
raft::launch_kernel({stream, shmemSize},
@@ -169,10 +179,11 @@ void stridedReduction(OutType* dots,
169179
} else {
170180
// Arbitrary numbers for now, probably need to tune
171181
const dim3 thrds(32, 16);
172-
IdxType elemsPerThread = raft::ceildiv(N, (IdxType)thrds.y);
182+
IdxType elemsPerThread = raft::div_rounding_up_safe(N, (IdxType)thrds.y);
173183
elemsPerThread = (elemsPerThread > 8) ? 8 : elemsPerThread;
174-
const dim3 nblks(raft::ceildiv(D, (IdxType)thrds.x),
175-
raft::ceildiv(N, (IdxType)thrds.y * elemsPerThread));
184+
const dim3 nblks(raft::div_rounding_up_safe(D, (IdxType)thrds.x),
185+
raft::min((IdxType)kMaxBlocksDimY,
186+
raft::div_rounding_up_safe(N, (IdxType)thrds.y * elemsPerThread)));
176187
const size_t shmemSize = sizeof(OutType) * thrds.x * thrds.y;
177188

178189
raft::launch_kernel({stream, shmemSize},

cpp/include/raft/sparse/solver/detail/mst_solver_inl.cuh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#pragma once
77

88
#include <raft/core/detail/macros.hpp>
9+
#include <raft/core/resource/cuda_stream.hpp>
910
#include <raft/core/resource/device_properties.hpp>
1011
#include <raft/core/resource/dry_run_flag.hpp>
1112
#include <raft/core/resource/thrust_policy.hpp>
@@ -174,6 +175,7 @@ Graph_COO<vertex_t, edge_t, weight_t> MST_solver<vertex_t, edge_t, weight_t, alt
174175

175176
// copy this iteration's results and store
176177
prev_mst_edge_count.set_value_async(curr_mst_edge_count, stream);
178+
resource::sync_stream(handle, stream);
177179
}
178180

179181
// result packaging

cpp/tests/linalg/strided_reduction.cu

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
#include "../test_utils.cuh"
77
#include "reduce.cuh"
88

9+
#include <raft/core/device_mdarray.hpp>
910
#include <raft/core/operators.hpp>
1011
#include <raft/core/resource/cuda_stream.hpp>
1112
#include <raft/linalg/strided_reduction.cuh>
13+
#include <raft/matrix/init.cuh>
1214
#include <raft/random/rng.cuh>
1315
#include <raft/util/cuda_utils.cuh>
1416
#include <raft/util/cudart_utils.hpp>
@@ -122,5 +124,44 @@ INSTANTIATE_TEST_CASE_P(stridedReductionTests, stridedReductionTestF, ::testing:
122124

123125
INSTANTIATE_TEST_CASE_P(stridedReductionTests, stridedReductionTestD, ::testing::ValuesIn(inputsd));
124126

127+
/*
128+
* The reduced dimension is mapped onto the y dimension of the grid, which CUDA limits to 65535
129+
* blocks. That is far fewer blocks than the number of rows a caller may reduce along, so the grid
130+
* must be bounded and the kernels must stride over the remaining rows.
131+
*/
132+
TEST(stridedReductionTest, LargeReducedDimension)
133+
{
134+
raft::resources handle;
135+
auto stream = resource::get_cuda_stream(handle);
136+
// More rows than the largest grid the kernels are launched with can cover one row per thread.
137+
constexpr int64_t kRows = 8'400'000;
138+
constexpr int64_t kCols = 2;
139+
140+
auto data = raft::make_device_matrix<float, int64_t>(handle, kRows, kCols);
141+
raft::matrix::fill(handle, data.view(), 1.0f);
142+
auto data_view = raft::make_const_mdspan(data.view());
143+
144+
// Summing into the input type takes the compensated-summation path.
145+
auto sums_same_type = raft::make_device_vector<float, int64_t>(handle, kCols);
146+
strided_reduction(handle, data_view, sums_same_type.view(), 0.0f);
147+
148+
// Summing into a wider type takes the generic path, which handles an arbitrary reduce operation.
149+
auto sums_wider_type = raft::make_device_vector<double, int64_t>(handle, kCols);
150+
strided_reduction(handle, data_view, sums_wider_type.view(), 0.0, false, raft::cast_op<double>{});
151+
152+
resource::sync_stream(handle, stream);
153+
154+
ASSERT_TRUE(devArrMatch(static_cast<float>(kRows),
155+
sums_same_type.data_handle(),
156+
kCols,
157+
raft::CompareApprox<float>(1e-6f),
158+
stream));
159+
ASSERT_TRUE(devArrMatch(static_cast<double>(kRows),
160+
sums_wider_type.data_handle(),
161+
kCols,
162+
raft::CompareApprox<double>(1e-12),
163+
stream));
164+
}
165+
125166
} // end namespace linalg
126167
} // end namespace raft

0 commit comments

Comments
 (0)