|
6 | 6 | #include "../test_utils.cuh" |
7 | 7 | #include "reduce.cuh" |
8 | 8 |
|
| 9 | +#include <raft/core/device_mdarray.hpp> |
9 | 10 | #include <raft/core/operators.hpp> |
10 | 11 | #include <raft/core/resource/cuda_stream.hpp> |
11 | 12 | #include <raft/linalg/strided_reduction.cuh> |
| 13 | +#include <raft/matrix/init.cuh> |
12 | 14 | #include <raft/random/rng.cuh> |
13 | 15 | #include <raft/util/cuda_utils.cuh> |
14 | 16 | #include <raft/util/cudart_utils.hpp> |
@@ -122,5 +124,44 @@ INSTANTIATE_TEST_CASE_P(stridedReductionTests, stridedReductionTestF, ::testing: |
122 | 124 |
|
123 | 125 | INSTANTIATE_TEST_CASE_P(stridedReductionTests, stridedReductionTestD, ::testing::ValuesIn(inputsd)); |
124 | 126 |
|
| 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 | + |
125 | 166 | } // end namespace linalg |
126 | 167 | } // end namespace raft |
0 commit comments