Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:24

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // Detray test include(s)
0010 #include "detector_cuda_kernel.hpp"
0011 #include "detray/core/detail/alignment.hpp"
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/test/common/build_toy_detector.hpp"
0014 #include "detray/test/framework/assert.hpp"
0015 #include "detray/test/framework/types.hpp"
0016 
0017 // Vecmem include(s)
0018 #include <vecmem/memory/cuda/device_memory_resource.hpp>
0019 #include <vecmem/memory/cuda/managed_memory_resource.hpp>
0020 #include <vecmem/memory/host_memory_resource.hpp>
0021 #include <vecmem/utils/cuda/async_copy.hpp>
0022 #include <vecmem/utils/cuda/copy.hpp>
0023 
0024 // Google Test include(s)
0025 #include <gtest/gtest.h>
0026 
0027 // System include(s)
0028 #include <limits>
0029 
0030 using namespace detray;
0031 
0032 TEST(detector_cuda, detector) {
0033   // memory resource
0034   vecmem::cuda::managed_memory_resource mng_mr;
0035 
0036   // create toy geometry
0037   auto [toy_det, names] = build_toy_detector<test::algebra>(mng_mr);
0038 
0039   auto ctx0 = typename detector_host_t::geometry_context();
0040 
0041   // host objects
0042   auto& volumes_host = toy_det.volumes();
0043   auto& surfaces_host = toy_det.surfaces();
0044   auto& transforms_host = toy_det.transform_store();
0045   auto& masks_host = toy_det.mask_store();
0046   auto& discs_host = masks_host.get<disc_id>();
0047   auto& cylinders_host = masks_host.get<cylinder_id>();
0048   auto& rectangles_host = masks_host.get<rectangle_id>();
0049 
0050   // copied output from device side
0051   vecmem::vector<det_volume_t> volumes_device(volumes_host.size(), &mng_mr);
0052   vecmem::vector<det_surface_t> surfaces_device(surfaces_host.size(), &mng_mr);
0053   vecmem::vector<transform_t> transforms_device(transforms_host.size(),
0054                                                 &mng_mr);
0055   vecmem::vector<rectangle_t> rectangles_device(rectangles_host.size(),
0056                                                 &mng_mr);
0057   vecmem::vector<disc_t> discs_device(discs_host.size(), &mng_mr);
0058   vecmem::vector<cylinder_t> cylinders_device(cylinders_host.size(), &mng_mr);
0059 
0060   // get data object for toy detector
0061   auto toy_det_data = detray::get_data(toy_det);
0062 
0063   // get data object for device outputs
0064   auto volumes_data = vecmem::get_data(volumes_device);
0065   auto surfaces_data = vecmem::get_data(surfaces_device);
0066   auto transforms_data = vecmem::get_data(transforms_device);
0067   auto rectangles_data = vecmem::get_data(rectangles_device);
0068   auto discs_data = vecmem::get_data(discs_device);
0069   auto cylinders_data = vecmem::get_data(cylinders_device);
0070 
0071   // run the test code to copy the objects
0072   detector_test(toy_det_data, volumes_data, surfaces_data, transforms_data,
0073                 rectangles_data, discs_data, cylinders_data);
0074 
0075   // check if the same volume objects are copied
0076   for (unsigned int i = 0u; i < volumes_host.size(); i++) {
0077     EXPECT_EQ(volumes_host[i] == volumes_device[i], true);
0078   }
0079 
0080   // check if the same surface objects are copied
0081   for (unsigned int i = 0u; i < surfaces_host.size(); i++) {
0082     EXPECT_EQ(surfaces_device[i] == surfaces_host[i], true);
0083   }
0084 
0085   // check if the same transform objects are copied
0086   for (unsigned int i = 0u; i < transforms_host.size(ctx0); i++) {
0087     EXPECT_EQ(transforms_host.at(i, ctx0) == transforms_device[i], true);
0088   }
0089 
0090   // check if the same masks are copied
0091   for (unsigned int i = 0u; i < rectangles_host.size(); i++) {
0092     EXPECT_EQ(rectangles_host[i] == rectangles_device[i], true);
0093   }
0094 
0095   for (unsigned int i = 0u; i < discs_host.size(); i++) {
0096     EXPECT_EQ(discs_host[i] == discs_device[i], true);
0097   }
0098 
0099   for (unsigned int i = 0u; i < cylinders_host.size(); i++) {
0100     EXPECT_EQ(cylinders_host[i] == cylinders_device[i], true);
0101   }
0102 }
0103 
0104 TEST(detector_cuda, detector_alignment) {
0105   // a few typedefs
0106   using test_algebra = test::algebra;
0107   using scalar = dscalar<test_algebra>;
0108   using point3 = dpoint3D<test_algebra>;
0109 
0110   // memory resources
0111   vecmem::host_memory_resource host_mr;
0112   vecmem::cuda::device_memory_resource dev_mr;
0113   vecmem::cuda::managed_memory_resource mng_mr;
0114 
0115   // helper object for performing memory copies to CUDA devices
0116   vecmem::cuda::copy cuda_cpy;
0117 
0118   // create toy geometry in host memory
0119   auto [det_host, names_host] = build_toy_detector<test_algebra>(host_mr);
0120 
0121   // copy static detector data (including the initial set of transforms) to
0122   // the device
0123   // use synchronous copy and fixed size buffers
0124   auto det_buff_static = detray::get_buffer(det_host, dev_mr, cuda_cpy);
0125 
0126   // ---------- construct an "aligned" transform store ---------
0127 
0128   // build a vector of aligned transforms on the host
0129   // for populating this vector take all transforms of the detector
0130   // and shift them by the same translation
0131   typename detector_host_t::transform_container tf_store_aligned_host;
0132 
0133   point3 shift{.1f * unit<scalar>::mm, .2f * unit<scalar>::mm,
0134                .3f * unit<scalar>::mm};
0135 
0136   tf_store_aligned_host.reserve(
0137       det_host.transform_store().size(),
0138       typename decltype(det_host)::transform_container::context_type{});
0139 
0140   for (const auto& tf : det_host.transform_store()) {
0141     point3 shifted = tf.translation() + shift;
0142     tf_store_aligned_host.push_back(
0143         transform_t{shifted, tf.x(), tf.y(), tf.z()});
0144   }
0145 
0146   // copy the vector of aligned transforms to the device
0147   // again, use synchronous copy and fixed size buffers
0148   auto tf_buff_aligned =
0149       get_buffer(tf_store_aligned_host, dev_mr, cuda_cpy, copy::sync,
0150                  vecmem::data::buffer_type::fixed_size);
0151 
0152   // Get the view of the aligned detector using the vector of aligned
0153   // transforms and the static part of the detector copied to the device
0154   // earlier
0155   auto detector_view_aligned =
0156       detail::misaligned_detector_view<detector_host_t>(det_buff_static,
0157                                                         tf_buff_aligned);
0158   // Get the view of the static detector
0159   auto detector_view_static = detray::get_data(det_buff_static);
0160 
0161   // make two vectors for surface transforms copied from device side
0162   vecmem::vector<transform_t> surfacexf_device_static(
0163       det_host.surfaces().size(), &mng_mr);
0164   vecmem::vector<transform_t> surfacexf_device_aligned(
0165       det_host.surfaces().size(), &mng_mr);
0166   // views of the above vectors
0167   auto surfacexf_data_static = vecmem::get_data(surfacexf_device_static);
0168   auto surfacexf_data_aligned = vecmem::get_data(surfacexf_device_aligned);
0169 
0170   // run the test code to extract the surface transforms for the static
0171   // and misaligned detector views and to store them into the vectors
0172   detector_alignment_test(detector_view_static, detector_view_aligned,
0173                           surfacexf_data_static, surfacexf_data_aligned);
0174 
0175   // check that the relevant transforms have been properly shifted
0176   for (unsigned int i = 0u; i < surfacexf_device_static.size(); i++) {
0177     auto translation_static = surfacexf_device_static[i].translation();
0178     auto translation_aligned = surfacexf_device_aligned[i].translation();
0179     auto translation_diff = translation_aligned - translation_static;
0180     EXPECT_POINT3_NEAR(translation_diff, shift, 1e-4);
0181   }
0182 }