Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 08:21:43

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 #include <boost/test/unit_test.hpp>
0010 
0011 #include "ActsExamples/EventData/CudaMuonHoughMaximum.hpp"
0012 #include "ActsExamples/Utilities/CudaStream.hpp"
0013 
0014 #include <array>
0015 #include <cstdint>
0016 #include <stdexcept>
0017 
0018 #include <cuda_runtime.h>
0019 
0020 namespace ActsTests {
0021 
0022 BOOST_AUTO_TEST_SUITE(EventDataSuite)
0023 
0024 BOOST_AUTO_TEST_CASE(CudaMuonHoughMaximumHostConstruction) {
0025   using MaximumBatch = ActsExamples::CudaHoughMaximumBatch;
0026 
0027   MaximumBatch maxima{3u, 2u};
0028 
0029   BOOST_CHECK_EQUAL(maxima.nBuckets(), 3u);
0030   BOOST_CHECK_EQUAL(maxima.capacityPerBucket(), 2u);
0031   BOOST_CHECK_EQUAL(maxima.totalCapacity(), 6u);
0032   BOOST_CHECK_EQUAL(maxima.totalAssociatedHits(), 0u);
0033 
0034   BOOST_CHECK(!maxima.empty());
0035   BOOST_CHECK(!maxima.isOnDevice());
0036   BOOST_CHECK(!maxima.hasAssociationStorage());
0037 
0038   BOOST_CHECK_EQUAL(maxima.nMaxima(0u), 0u);
0039   BOOST_CHECK_EQUAL(maxima.nMaxima(1u), 0u);
0040   BOOST_CHECK_EQUAL(maxima.nMaxima(2u), 0u);
0041 
0042   BOOST_CHECK_THROW(maxima.nAssociatedHits(0u, 0u), std::logic_error);
0043   BOOST_CHECK_THROW(maxima.associatedHitIndices(0u, 0u), std::logic_error);
0044 
0045   BOOST_CHECK_THROW(MaximumBatch(3u, 0u), std::invalid_argument);
0046   BOOST_CHECK_THROW(MaximumBatch(3u, 65u), std::invalid_argument);
0047 }
0048 
0049 BOOST_AUTO_TEST_CASE(CudaMuonHoughMaximumExactAssociationStorage) {
0050   int deviceCount = 0;
0051 
0052   if (cudaGetDeviceCount(&deviceCount) != cudaSuccess || deviceCount == 0) {
0053     BOOST_TEST_MESSAGE("No CUDA device found, skipping CUDA runtime test");
0054     return;
0055   }
0056 
0057   using MaximumBatch = ActsExamples::CudaHoughMaximumBatch;
0058 
0059   MaximumBatch maxima{3u, 2u};
0060   ActsExamples::CudaStream stream;
0061   maxima.moveToDevice(stream.get());
0062 
0063   BOOST_REQUIRE(maxima.isOnDevice());
0064 
0065   auto device = maxima.deviceArrays();
0066 
0067   BOOST_REQUIRE(device.nMaxima != nullptr);
0068   BOOST_REQUIRE(device.nAssociatedHits != nullptr);
0069   BOOST_CHECK_EQUAL(device.capacityPerBucket, 2u);
0070   BOOST_CHECK(device.associatedHitOffsets == nullptr);
0071   BOOST_CHECK(device.associatedHitIndices == nullptr);
0072   BOOST_CHECK_EQUAL(device.totalAssociatedHits, 0u);
0073 
0074   // Bucket 0 has two maxima, bucket 1 has one, bucket 2 has none.
0075   const std::array<std::uint32_t, 3u> nMaxima{2u, 1u, 0u};
0076 
0077   // Counts are stored bucket by bucket:
0078   // bucket 0 -> 3, 1
0079   // bucket 1 -> 2, unused
0080   // bucket 2 -> unused, unused
0081   const std::array<std::uint32_t, 6u> nAssociatedHits{3u, 1u, 2u, 0u, 0u, 0u};
0082 
0083   const std::array<ActsExamples::CoordType, 6u> tanBeta{42.0, 43.0, 44.0,
0084                                                         0.0,  0.0,  0.0};
0085 
0086   BOOST_REQUIRE_EQUAL(cudaMemcpy(device.nMaxima, nMaxima.data(),
0087                                  sizeof(nMaxima), cudaMemcpyHostToDevice),
0088                       cudaSuccess);
0089 
0090   BOOST_REQUIRE_EQUAL(
0091       cudaMemcpy(device.nAssociatedHits, nAssociatedHits.data(),
0092                  sizeof(nAssociatedHits), cudaMemcpyHostToDevice),
0093       cudaSuccess);
0094 
0095   BOOST_REQUIRE_EQUAL(cudaMemcpy(device.tanBeta, tanBeta.data(),
0096                                  sizeof(tanBeta), cudaMemcpyHostToDevice),
0097                       cudaSuccess);
0098 
0099   // Only nMaxima and nAssociatedHits are copied here.
0100   maxima.copyAssociationMetadataToHost(stream.get());
0101 
0102   BOOST_CHECK_EQUAL(maxima.nMaxima(0u), 2u);
0103   BOOST_CHECK_EQUAL(maxima.nMaxima(1u), 1u);
0104   BOOST_CHECK_EQUAL(maxima.nMaxima(2u), 0u);
0105 
0106   BOOST_CHECK_EQUAL(maxima.nAssociatedHits(0u, 0u), 3u);
0107   BOOST_CHECK_EQUAL(maxima.nAssociatedHits(0u, 1u), 1u);
0108   BOOST_CHECK_EQUAL(maxima.nAssociatedHits(1u, 0u), 2u);
0109 
0110   // tanBeta was deliberately not copied by the metadata-only transfer.
0111   BOOST_CHECK_EQUAL(maxima.tanBeta(0u, 0u), 0.0);
0112 
0113   maxima.allocateAssociationStorage(stream.get());
0114 
0115   BOOST_REQUIRE(maxima.hasAssociationStorage());
0116   BOOST_CHECK_EQUAL(maxima.totalAssociatedHits(), 6u);
0117 
0118   device = maxima.deviceArrays();
0119 
0120   BOOST_REQUIRE(device.associatedHitOffsets != nullptr);
0121   BOOST_REQUIRE(device.associatedHitIndices != nullptr);
0122   BOOST_CHECK_EQUAL(device.totalAssociatedHits, 6u);
0123 
0124   std::array<std::uint32_t, 7u> offsets{};
0125 
0126   BOOST_REQUIRE_EQUAL(cudaMemcpy(offsets.data(), device.associatedHitOffsets,
0127                                  sizeof(offsets), cudaMemcpyDeviceToHost),
0128                       cudaSuccess);
0129 
0130   const std::array<std::uint32_t, 7u> expectedOffsets{0u, 3u, 4u, 6u,
0131                                                       6u, 6u, 6u};
0132 
0133   BOOST_CHECK_EQUAL_COLLECTIONS(offsets.begin(), offsets.end(),
0134                                 expectedOffsets.begin(), expectedOffsets.end());
0135 
0136   const std::array<std::uint32_t, 6u> associatedIndices{10u, 11u, 12u,
0137                                                         20u, 30u, 31u};
0138 
0139   BOOST_REQUIRE_EQUAL(
0140       cudaMemcpy(device.associatedHitIndices, associatedIndices.data(),
0141                  sizeof(associatedIndices), cudaMemcpyHostToDevice),
0142       cudaSuccess);
0143 
0144   maxima.copyAssociatedHitIndicesToHost(stream.get());
0145 
0146   const std::array<std::uint32_t, 3u> expectedFirst{10u, 11u, 12u};
0147   const std::array<std::uint32_t, 1u> expectedSecond{20u};
0148   const std::array<std::uint32_t, 2u> expectedThird{30u, 31u};
0149 
0150   const auto first = maxima.associatedHitIndices(0u, 0u);
0151   const auto second = maxima.associatedHitIndices(0u, 1u);
0152   const auto third = maxima.associatedHitIndices(1u, 0u);
0153 
0154   BOOST_CHECK_EQUAL_COLLECTIONS(first.begin(), first.end(),
0155                                 expectedFirst.begin(), expectedFirst.end());
0156 
0157   BOOST_CHECK_EQUAL_COLLECTIONS(second.begin(), second.end(),
0158                                 expectedSecond.begin(), expectedSecond.end());
0159 
0160   BOOST_CHECK_EQUAL_COLLECTIONS(third.begin(), third.end(),
0161                                 expectedThird.begin(), expectedThird.end());
0162 
0163   // The ordinary maximum values are copied only by moveToHost(stream).
0164   maxima.moveToHost(stream.get());
0165 
0166   BOOST_CHECK_EQUAL(maxima.tanBeta(0u, 0u), 42.0);
0167   BOOST_CHECK_EQUAL(maxima.tanBeta(0u, 1u), 43.0);
0168   BOOST_CHECK_EQUAL(maxima.tanBeta(1u, 0u), 44.0);
0169 }
0170 
0171 BOOST_AUTO_TEST_SUITE_END()
0172 
0173 }  // namespace ActsTests