File indexing completed on 2026-05-27 07:24:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "container_cuda_kernel.hpp"
0011
0012
0013 #include <vecmem/memory/cuda/device_memory_resource.hpp>
0014 #include <vecmem/memory/cuda/managed_memory_resource.hpp>
0015 #include <vecmem/memory/host_memory_resource.hpp>
0016 #include <vecmem/utils/cuda/copy.hpp>
0017
0018
0019 #include <gtest/gtest.h>
0020
0021
0022 #include <algorithm>
0023 #include <iterator>
0024 #include <numeric>
0025
0026 using namespace detray;
0027
0028 constexpr double tol{1e-6};
0029
0030
0031 TEST(container_cuda, single_store) {
0032
0033 vecmem::host_memory_resource host_mr;
0034 vecmem::cuda::managed_memory_resource mng_mr;
0035 vecmem::cuda::device_memory_resource dev_mr;
0036 vecmem::cuda::copy cpy;
0037
0038
0039 single_store_t store(host_mr);
0040 single_store_t mng_store(mng_mr);
0041
0042
0043 EXPECT_TRUE(store.empty());
0044 EXPECT_EQ(store.size(), 0u);
0045 EXPECT_TRUE(mng_store.empty());
0046 EXPECT_EQ(mng_store.size(), 0u);
0047
0048
0049 geometry_context ctx{};
0050 mng_store.reserve(4, ctx);
0051 mng_store.emplace_back(ctx, 1.);
0052 mng_store.push_back(2., ctx);
0053 mng_store.insert(vecmem::vector<double>{10.5, 7.6}, ctx);
0054 store.append(mng_store, ctx);
0055
0056 EXPECT_FALSE(store.empty());
0057 EXPECT_EQ(store.size(), 4u);
0058 EXPECT_FALSE(mng_store.empty());
0059 EXPECT_EQ(mng_store.size(), 4u);
0060
0061
0062 EXPECT_NEAR(mng_store.at(0, ctx), 1., tol);
0063 EXPECT_NEAR(mng_store.at(2, ctx), 10.5, tol);
0064 EXPECT_NEAR(mng_store.at(1, ctx), 2., tol);
0065 EXPECT_NEAR(mng_store.at(3, ctx), 7.6, tol);
0066
0067
0068 double cpu_sum{std::accumulate(mng_store.begin(), mng_store.end(), 0.)};
0069 EXPECT_NEAR(cpu_sum, 21.1, tol);
0070 EXPECT_NEAR(cpu_sum, std::accumulate(store.begin(), store.end(), 0.), tol);
0071
0072
0073 single_store_t::view_type mng_store_view = detray::get_data(mng_store);
0074
0075 vecmem::vector<double> cuda_sum(&mng_mr);
0076 cuda_sum.push_back(0.);
0077 vecmem::data::vector_view<double> sum_data = vecmem::get_data(cuda_sum);
0078
0079 test_single_store(mng_store_view, sum_data);
0080
0081 EXPECT_NEAR(cpu_sum, cuda_sum[0], tol);
0082
0083
0084 mng_store.clear(ctx);
0085
0086 EXPECT_TRUE(mng_store.empty());
0087 EXPECT_EQ(mng_store.size(), 0u);
0088
0089
0090 cuda_sum[0] = 0.;
0091
0092
0093 single_store_t::buffer_type store_buffer =
0094 detray::get_buffer(store, dev_mr, cpy);
0095 single_store_t::view_type buffer_view = detray::get_data(store_buffer);
0096
0097 EXPECT_NEAR(cuda_sum[0], 0.f, tol);
0098
0099 test_single_store(buffer_view, sum_data);
0100
0101 EXPECT_NEAR(cuda_sum[0], cpu_sum, tol);
0102 }
0103
0104
0105 TEST(container_cuda, tuple_container) {
0106
0107 vecmem::host_memory_resource host_mr;
0108 vecmem::cuda::managed_memory_resource mng_mr;
0109 vecmem::cuda::device_memory_resource dev_mr;
0110 vecmem::cuda::copy cpy;
0111
0112
0113 tuple_cont_t tcont(host_mr);
0114 tuple_cont_t mng_tcont(mng_mr);
0115
0116
0117 EXPECT_EQ(tcont.size(), 2u);
0118 EXPECT_EQ(mng_tcont.size(), 2u);
0119
0120
0121 mng_tcont.get<0>().push_back(3);
0122 mng_tcont.get<1>().push_back(4.);
0123 mng_tcont.get<1>().push_back(5.8);
0124
0125 vecmem::vector<double> new_data{10.5, 7.6, 14.5};
0126 auto& data_coll = detail::get<1>(mng_tcont);
0127 std::ranges::copy(new_data, std::back_inserter(data_coll));
0128 std::ranges::copy(mng_tcont.get<0>(), std::back_inserter(tcont.get<0>()));
0129 std::ranges::copy(mng_tcont.get<1>(), std::back_inserter(tcont.get<1>()));
0130
0131 EXPECT_EQ(mng_tcont.get<0>().size(), 1u);
0132 EXPECT_EQ(mng_tcont.get<1>().size(), 5u);
0133 EXPECT_EQ(tcont.get<0>().size(), 1u);
0134 EXPECT_EQ(tcont.get<1>().size(), 5u);
0135
0136
0137 double cpu_sum{static_cast<double>(mng_tcont.get<0>().at(0))};
0138 cpu_sum = std::accumulate(data_coll.begin(), data_coll.end(), cpu_sum);
0139 EXPECT_NEAR(cpu_sum, 45.4, tol);
0140
0141
0142 tuple_cont_t::view_type mng_store_view = detray::get_data(mng_tcont);
0143
0144 vecmem::vector<double> cuda_sum(&mng_mr);
0145 cuda_sum.push_back(0.);
0146 vecmem::data::vector_view<double> sum_data = vecmem::get_data(cuda_sum);
0147
0148 test_tuple_container(mng_store_view, sum_data);
0149
0150 EXPECT_NEAR(cpu_sum, cuda_sum[0], tol);
0151
0152
0153 cuda_sum[0] = 0.;
0154
0155
0156 tuple_cont_t::buffer_type store_buffer =
0157 detray::get_buffer(tcont, dev_mr, cpy);
0158 tuple_cont_t::view_type buffer_view = detray::get_data(store_buffer);
0159
0160 EXPECT_NEAR(cuda_sum[0], 0.f, tol);
0161
0162 test_tuple_container(buffer_view, sum_data);
0163
0164 EXPECT_NEAR(cuda_sum[0], cpu_sum, tol);
0165 }
0166
0167
0168 TEST(container_cuda, regular_multi_store) {
0169 using enum reg_type_ids;
0170
0171
0172 vecmem::host_memory_resource host_mr;
0173 vecmem::cuda::managed_memory_resource mng_mr;
0174 vecmem::cuda::device_memory_resource dev_mr;
0175 vecmem::cuda::copy cpy;
0176
0177
0178 reg_multi_store_t mng_store(mng_mr);
0179 reg_multi_store_t store(host_mr);
0180
0181
0182 EXPECT_EQ(mng_store.n_collections(), 3u);
0183 EXPECT_EQ(mng_store.empty<e_size>(), true);
0184 EXPECT_EQ(mng_store.empty<e_float>(), true);
0185 EXPECT_EQ(mng_store.empty<e_double>(), true);
0186
0187
0188 empty_context ctx{};
0189 mng_store.emplace_back<e_size>(ctx, 1u);
0190 mng_store.push_back<e_size>(2u, ctx);
0191 mng_store.emplace_back<e_float>(ctx, 3.1f);
0192 mng_store.push_back<e_float>(4.5f, ctx);
0193 mng_store.emplace_back<e_double>(ctx, 5.5);
0194 mng_store.push_back<e_double>(6.0, ctx);
0195
0196 vecmem::vector<std::size_t> int_vec{3u, 4u, 5u};
0197 mng_store.insert(int_vec);
0198
0199 vecmem::vector<float> float_vec{12.1f, 5.6f};
0200 mng_store.insert(float_vec);
0201
0202 mng_store.insert(vecmem::vector<double>{10.5, 7.6});
0203
0204 store.append(mng_store, ctx);
0205
0206 EXPECT_EQ(mng_store.size<e_size>(), 5u);
0207 EXPECT_EQ(mng_store.size<e_float>(), 4u);
0208 EXPECT_EQ(mng_store.size<e_double>(), 4u);
0209 EXPECT_EQ(store.size<e_size>(), 5u);
0210 EXPECT_EQ(store.size<e_float>(), 4u);
0211 EXPECT_EQ(store.size<e_double>(), 4u);
0212
0213
0214 double cpu_sum{std::accumulate(mng_store.get<e_size>().begin(),
0215 mng_store.get<e_size>().end(), 0.)};
0216 cpu_sum = std::accumulate(mng_store.get<e_float>().begin(),
0217 mng_store.get<e_float>().end(), cpu_sum);
0218 cpu_sum = std::accumulate(mng_store.get<e_double>().begin(),
0219 mng_store.get<e_double>().end(), cpu_sum);
0220 EXPECT_NEAR(cpu_sum, 69.9, tol);
0221
0222
0223 typename reg_multi_store_t::view_type store_view = get_data(mng_store);
0224
0225 vecmem::vector<double> cuda_sum(&mng_mr);
0226 cuda_sum.push_back(0.);
0227 auto sum_data = vecmem::get_data(cuda_sum);
0228
0229 test_reg_multi_store(store_view, sum_data);
0230
0231 EXPECT_NEAR(cpu_sum, cuda_sum[0], tol);
0232
0233
0234 cuda_sum[0] = 0.;
0235
0236
0237 reg_multi_store_t::buffer_type store_buffer =
0238 detray::get_buffer(store, dev_mr, cpy);
0239 reg_multi_store_t::view_type buffer_view = detray::get_data(store_buffer);
0240
0241 EXPECT_NEAR(cuda_sum[0], 0.f, tol);
0242
0243 test_reg_multi_store(buffer_view, sum_data);
0244
0245 EXPECT_NEAR(cuda_sum[0], cpu_sum, tol);
0246 }
0247
0248
0249 TEST(container_cuda, multi_store) {
0250 using enum type_ids;
0251
0252
0253 vecmem::host_memory_resource host_mr;
0254 vecmem::cuda::managed_memory_resource mng_mr;
0255 vecmem::cuda::device_memory_resource dev_mr;
0256 vecmem::cuda::copy cpy;
0257
0258
0259 multi_store_t mng_store(mng_mr);
0260 multi_store_t store(host_mr);
0261
0262
0263 EXPECT_EQ(mng_store.n_collections(), 2u);
0264 EXPECT_EQ(mng_store.empty<e_float>(), true);
0265
0266
0267 vecmem::vector<float> float_vec{12.1f, 5.6f};
0268 mng_store.insert(float_vec);
0269
0270 mng_store.get<e_test_class>().first = vecmem::vector<int>{2, 3};
0271 mng_store.get<e_test_class>().second = vecmem::vector<double>{18., 42.6};
0272
0273 std::ranges::copy(mng_store.get<e_float>(),
0274 std::back_inserter(store.get<e_float>()));
0275 store.get<e_test_class>() = mng_store.get<e_test_class>();
0276
0277 EXPECT_EQ(mng_store.size<e_float>(), 2u);
0278 EXPECT_EQ(mng_store.get<e_test_class>().first.size(), 2u);
0279 EXPECT_EQ(mng_store.get<e_test_class>().second.size(), 2u);
0280 EXPECT_EQ(store.size<e_float>(), 2u);
0281 EXPECT_EQ(store.get<e_test_class>().first.size(), 2u);
0282 EXPECT_EQ(store.get<e_test_class>().second.size(), 2u);
0283
0284
0285 double cpu_sum{std::accumulate(mng_store.get<e_float>().begin(),
0286 mng_store.get<e_float>().end(), 0.)};
0287 cpu_sum = std::accumulate(mng_store.get<e_test_class>().first.begin(),
0288 mng_store.get<e_test_class>().first.end(), cpu_sum);
0289 cpu_sum =
0290 std::accumulate(mng_store.get<e_test_class>().second.begin(),
0291 mng_store.get<e_test_class>().second.end(), cpu_sum);
0292 EXPECT_NEAR(cpu_sum, 83.3, tol);
0293
0294
0295 typename multi_store_t::view_type store_view = get_data(mng_store);
0296
0297 vecmem::vector<double> cuda_sum(&mng_mr);
0298 cuda_sum.push_back(0.);
0299 auto sum_data = vecmem::get_data(cuda_sum);
0300
0301 test_multi_store(store_view, sum_data);
0302
0303 EXPECT_NEAR(cpu_sum, cuda_sum[0], tol);
0304
0305
0306 cuda_sum[0] = 0.;
0307
0308
0309 multi_store_t::buffer_type store_buffer =
0310 detray::get_buffer(store, dev_mr, cpy);
0311 multi_store_t::view_type buffer_view = detray::get_data(store_buffer);
0312
0313 EXPECT_NEAR(cuda_sum[0], 0.f, tol);
0314
0315 test_multi_store(buffer_view, sum_data);
0316
0317 EXPECT_NEAR(cuda_sum[0], cpu_sum, tol);
0318 }