Warning, file /acts/Examples/CudaMuonSegmentFitting/src/CudaMuonSpacePoint.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/EventData/CudaMuonSpacePoint.hpp"
0010
0011 #include <stdexcept>
0012 #include <utility>
0013
0014 #include <cuda_runtime.h>
0015
0016 #include "CudaUtilities.hpp"
0017
0018 namespace {
0019
0020 using namespace ActsExamples;
0021
0022 template <typename T>
0023 void resizeColumn(std::vector<T>& column, std::size_t size) {
0024 column.resize(size);
0025 }
0026
0027 void resizeHostData(ActsExamples::CudaMuonSpacePointHostData& host,
0028 std::size_t size) {
0029 resizeColumn(host.geometryId, size);
0030 resizeColumn(host.muonId, size);
0031
0032 resizeColumn(host.localPositionX, size);
0033 resizeColumn(host.localPositionY, size);
0034 resizeColumn(host.localPositionZ, size);
0035
0036 resizeColumn(host.sensorDirectionX, size);
0037 resizeColumn(host.sensorDirectionY, size);
0038 resizeColumn(host.sensorDirectionZ, size);
0039
0040 resizeColumn(host.toNextSensorX, size);
0041 resizeColumn(host.toNextSensorY, size);
0042 resizeColumn(host.toNextSensorZ, size);
0043
0044 resizeColumn(host.planeNormalX, size);
0045 resizeColumn(host.planeNormalY, size);
0046 resizeColumn(host.planeNormalZ, size);
0047
0048 resizeColumn(host.covariance0, size);
0049 resizeColumn(host.covariance1, size);
0050 resizeColumn(host.covariance2, size);
0051
0052 resizeColumn(host.driftRadius, size);
0053 resizeColumn(host.time, size);
0054 }
0055
0056 void allocateDeviceData(ActsExamples::CudaMuonSpacePointArrays& device,
0057 std::size_t spacePointCount, std::size_t bucketCount) {
0058 allocateDeviceColumn(device.geometryId, spacePointCount);
0059 allocateDeviceColumn(device.muonId, spacePointCount);
0060
0061 allocateDeviceColumn(device.localPositionX, spacePointCount);
0062 allocateDeviceColumn(device.localPositionY, spacePointCount);
0063 allocateDeviceColumn(device.localPositionZ, spacePointCount);
0064
0065 allocateDeviceColumn(device.sensorDirectionX, spacePointCount);
0066 allocateDeviceColumn(device.sensorDirectionY, spacePointCount);
0067 allocateDeviceColumn(device.sensorDirectionZ, spacePointCount);
0068
0069 allocateDeviceColumn(device.toNextSensorX, spacePointCount);
0070 allocateDeviceColumn(device.toNextSensorY, spacePointCount);
0071 allocateDeviceColumn(device.toNextSensorZ, spacePointCount);
0072
0073 allocateDeviceColumn(device.planeNormalX, spacePointCount);
0074 allocateDeviceColumn(device.planeNormalY, spacePointCount);
0075 allocateDeviceColumn(device.planeNormalZ, spacePointCount);
0076
0077 allocateDeviceColumn(device.covariance0, spacePointCount);
0078 allocateDeviceColumn(device.covariance1, spacePointCount);
0079 allocateDeviceColumn(device.covariance2, spacePointCount);
0080
0081 allocateDeviceColumn(device.driftRadius, spacePointCount);
0082 allocateDeviceColumn(device.time, spacePointCount);
0083
0084 allocateDeviceColumn(device.bucketStart, bucketCount);
0085 allocateDeviceColumn(device.bucketEnd, bucketCount);
0086 }
0087
0088 void freeDeviceData(ActsExamples::CudaMuonSpacePointArrays& device) noexcept {
0089 freeDeviceColumn(device.geometryId);
0090 freeDeviceColumn(device.muonId);
0091
0092 freeDeviceColumn(device.localPositionX);
0093 freeDeviceColumn(device.localPositionY);
0094 freeDeviceColumn(device.localPositionZ);
0095
0096 freeDeviceColumn(device.sensorDirectionX);
0097 freeDeviceColumn(device.sensorDirectionY);
0098 freeDeviceColumn(device.sensorDirectionZ);
0099
0100 freeDeviceColumn(device.toNextSensorX);
0101 freeDeviceColumn(device.toNextSensorY);
0102 freeDeviceColumn(device.toNextSensorZ);
0103
0104 freeDeviceColumn(device.planeNormalX);
0105 freeDeviceColumn(device.planeNormalY);
0106 freeDeviceColumn(device.planeNormalZ);
0107
0108 freeDeviceColumn(device.covariance0);
0109 freeDeviceColumn(device.covariance1);
0110 freeDeviceColumn(device.covariance2);
0111
0112 freeDeviceColumn(device.driftRadius);
0113 freeDeviceColumn(device.time);
0114
0115 freeDeviceColumn(device.bucketStart);
0116 freeDeviceColumn(device.bucketEnd);
0117 }
0118
0119 void copyHostToDevice(ActsExamples::CudaMuonSpacePointArrays& device,
0120 const ActsExamples::CudaMuonSpacePointHostData& host) {
0121 copyColumnToDevice(device.geometryId, host.geometryId);
0122 copyColumnToDevice(device.muonId, host.muonId);
0123
0124 copyColumnToDevice(device.localPositionX, host.localPositionX);
0125 copyColumnToDevice(device.localPositionY, host.localPositionY);
0126 copyColumnToDevice(device.localPositionZ, host.localPositionZ);
0127
0128 copyColumnToDevice(device.sensorDirectionX, host.sensorDirectionX);
0129 copyColumnToDevice(device.sensorDirectionY, host.sensorDirectionY);
0130 copyColumnToDevice(device.sensorDirectionZ, host.sensorDirectionZ);
0131
0132 copyColumnToDevice(device.toNextSensorX, host.toNextSensorX);
0133 copyColumnToDevice(device.toNextSensorY, host.toNextSensorY);
0134 copyColumnToDevice(device.toNextSensorZ, host.toNextSensorZ);
0135
0136 copyColumnToDevice(device.planeNormalX, host.planeNormalX);
0137 copyColumnToDevice(device.planeNormalY, host.planeNormalY);
0138 copyColumnToDevice(device.planeNormalZ, host.planeNormalZ);
0139
0140 copyColumnToDevice(device.covariance0, host.covariance0);
0141 copyColumnToDevice(device.covariance1, host.covariance1);
0142 copyColumnToDevice(device.covariance2, host.covariance2);
0143
0144 copyColumnToDevice(device.driftRadius, host.driftRadius);
0145 copyColumnToDevice(device.time, host.time);
0146
0147 copyColumnToDevice(device.bucketStart, host.bucketStart);
0148 copyColumnToDevice(device.bucketEnd, host.bucketEnd);
0149 }
0150
0151 void copyDeviceToHost(ActsExamples::CudaMuonSpacePointHostData& host,
0152 const ActsExamples::CudaMuonSpacePointArrays& device) {
0153 copyColumnToHost(host.geometryId, device.geometryId);
0154 copyColumnToHost(host.muonId, device.muonId);
0155
0156 copyColumnToHost(host.localPositionX, device.localPositionX);
0157 copyColumnToHost(host.localPositionY, device.localPositionY);
0158 copyColumnToHost(host.localPositionZ, device.localPositionZ);
0159
0160 copyColumnToHost(host.sensorDirectionX, device.sensorDirectionX);
0161 copyColumnToHost(host.sensorDirectionY, device.sensorDirectionY);
0162 copyColumnToHost(host.sensorDirectionZ, device.sensorDirectionZ);
0163
0164 copyColumnToHost(host.toNextSensorX, device.toNextSensorX);
0165 copyColumnToHost(host.toNextSensorY, device.toNextSensorY);
0166 copyColumnToHost(host.toNextSensorZ, device.toNextSensorZ);
0167
0168 copyColumnToHost(host.planeNormalX, device.planeNormalX);
0169 copyColumnToHost(host.planeNormalY, device.planeNormalY);
0170 copyColumnToHost(host.planeNormalZ, device.planeNormalZ);
0171
0172 copyColumnToHost(host.covariance0, device.covariance0);
0173 copyColumnToHost(host.covariance1, device.covariance1);
0174 copyColumnToHost(host.covariance2, device.covariance2);
0175
0176 copyColumnToHost(host.driftRadius, device.driftRadius);
0177 copyColumnToHost(host.time, device.time);
0178
0179 copyColumnToHost(host.bucketStart, device.bucketStart);
0180 copyColumnToHost(host.bucketEnd, device.bucketEnd);
0181 }
0182
0183 std::size_t countSpacePoints(
0184 const ActsExamples::MuonSpacePointContainer& spacePoints) {
0185 std::size_t totalSize = 0;
0186
0187 for (const auto& bucket : spacePoints) {
0188 totalSize += bucket.size();
0189 }
0190
0191 return totalSize;
0192 }
0193
0194 }
0195
0196 namespace ActsExamples {
0197
0198 CudaMuonSpacePointProxy::CudaMuonSpacePointProxy(
0199 const CudaMuonSpacePointContainer& container, std::size_t index) noexcept
0200 : m_container{&container}, m_index{index} {}
0201
0202 const MuonSpacePoint::MuonId& CudaMuonSpacePointProxy::id() const {
0203 m_idCache = MuonSpacePoint::MuonId{m_container->m_host.muonId[m_index]};
0204 return m_idCache;
0205 }
0206
0207 const Acts::GeometryIdentifier& CudaMuonSpacePointProxy::geometryId() const {
0208 m_geometryIdCache =
0209 Acts::GeometryIdentifier{m_container->m_host.geometryId[m_index]};
0210 return m_geometryIdCache;
0211 }
0212
0213 const Acts::Vector3& CudaMuonSpacePointProxy::localPosition() const {
0214 m_localPositionCache = Acts::Vector3{
0215 m_container->m_host.localPositionX[m_index],
0216 m_container->m_host.localPositionY[m_index],
0217 m_container->m_host.localPositionZ[m_index],
0218 };
0219
0220 return m_localPositionCache;
0221 }
0222
0223 const Acts::Vector3& CudaMuonSpacePointProxy::sensorDirection() const {
0224 m_sensorDirectionCache = Acts::Vector3{
0225 m_container->m_host.sensorDirectionX[m_index],
0226 m_container->m_host.sensorDirectionY[m_index],
0227 m_container->m_host.sensorDirectionZ[m_index],
0228 };
0229
0230 return m_sensorDirectionCache;
0231 }
0232
0233 const Acts::Vector3& CudaMuonSpacePointProxy::planeNormal() const {
0234 m_planeNormalCache = Acts::Vector3{
0235 m_container->m_host.planeNormalX[m_index],
0236 m_container->m_host.planeNormalY[m_index],
0237 m_container->m_host.planeNormalZ[m_index],
0238 };
0239
0240 return m_planeNormalCache;
0241 }
0242
0243 const Acts::Vector3& CudaMuonSpacePointProxy::toNextSensor() const {
0244 m_toNextSensorCache = Acts::Vector3{
0245 m_container->m_host.toNextSensorX[m_index],
0246 m_container->m_host.toNextSensorY[m_index],
0247 m_container->m_host.toNextSensorZ[m_index],
0248 };
0249
0250 return m_toNextSensorCache;
0251 }
0252
0253 const std::array<double, 3>& CudaMuonSpacePointProxy::covariance() const {
0254 m_covarianceCache = {
0255 m_container->m_host.covariance0[m_index],
0256 m_container->m_host.covariance1[m_index],
0257 m_container->m_host.covariance2[m_index],
0258 };
0259
0260 return m_covarianceCache;
0261 }
0262
0263 double CudaMuonSpacePointProxy::driftRadius() const {
0264 return m_container->m_host.driftRadius[m_index];
0265 }
0266
0267 double CudaMuonSpacePointProxy::time() const {
0268 return m_container->m_host.time[m_index];
0269 }
0270
0271 bool CudaMuonSpacePointProxy::isStraw() const {
0272 return id().technology() == MuonSpacePoint::MuonId::TechField::Mdt;
0273 }
0274
0275 bool CudaMuonSpacePointProxy::hasTime() const {
0276 return id().measuresTime();
0277 }
0278
0279 bool CudaMuonSpacePointProxy::measuresLoc0() const {
0280 return id().measuresPhi();
0281 }
0282
0283 bool CudaMuonSpacePointProxy::measuresLoc1() const {
0284 return id().measuresEta();
0285 }
0286
0287 CudaMuonSpacePointPtr::CudaMuonSpacePointPtr(
0288 const CudaMuonSpacePointContainer& container, std::size_t index) noexcept
0289 : m_proxy{container, index}, m_valid{true} {}
0290
0291 CudaMuonSpacePointContainer::CudaMuonSpacePointContainer(size_type size)
0292 : m_size{size} {
0293 resizeHostData(m_host, m_size);
0294 }
0295
0296 CudaMuonSpacePointContainer::CudaMuonSpacePointContainer(
0297 const MuonSpacePointContainer& spacePoints)
0298 : CudaMuonSpacePointContainer{countSpacePoints(spacePoints)} {
0299 m_host.bucketStart.reserve(spacePoints.size());
0300 m_host.bucketEnd.reserve(spacePoints.size());
0301
0302 size_type index = 0;
0303
0304 for (const MuonSpacePointBucket& bucket : spacePoints) {
0305 const size_type bucketBegin = index;
0306
0307 for (const MuonSpacePoint& spacePoint : bucket) {
0308 setGeometryId(index, spacePoint.geometryId().value());
0309 setId(index, spacePoint.id().toInt());
0310
0311 defineCoordinates(index, spacePoint.localPosition(),
0312 spacePoint.sensorDirection(),
0313 spacePoint.toNextSensor());
0314
0315 setRadius(index, spacePoint.driftRadius());
0316 setTime(index, spacePoint.time());
0317
0318 const auto& covariance = spacePoint.covariance();
0319 setCovariance(index, covariance[0], covariance[1], covariance[2]);
0320
0321 ++index;
0322 }
0323
0324
0325 addBucket(bucketBegin, index);
0326 }
0327 }
0328
0329 CudaMuonSpacePointContainer::CudaMuonSpacePointContainer(
0330 CudaMuonSpacePointContainer&& other) noexcept
0331 : m_size{std::exchange(other.m_size, 0)},
0332 m_host{std::move(other.m_host)},
0333 m_device{std::exchange(other.m_device, {})},
0334 m_onDevice{std::exchange(other.m_onDevice, false)} {}
0335
0336 CudaMuonSpacePointContainer& CudaMuonSpacePointContainer::operator=(
0337 CudaMuonSpacePointContainer&& other) noexcept {
0338 if (this != &other) {
0339 clearDevice();
0340
0341 m_size = std::exchange(other.m_size, 0);
0342 m_host = std::move(other.m_host);
0343 m_device = std::exchange(other.m_device, {});
0344 m_onDevice = std::exchange(other.m_onDevice, false);
0345 }
0346
0347 return *this;
0348 }
0349
0350 CudaMuonSpacePointContainer::~CudaMuonSpacePointContainer() noexcept {
0351 clearDevice();
0352 }
0353
0354 CudaMuonSpacePointContainer::size_type CudaMuonSpacePointContainer::bucketStart(
0355 size_type bucket) const {
0356 checkBucket(bucket);
0357 return m_host.bucketStart[bucket];
0358 }
0359
0360 CudaMuonSpacePointContainer::size_type CudaMuonSpacePointContainer::bucketEnd(
0361 size_type bucket) const {
0362 checkBucket(bucket);
0363 return m_host.bucketEnd[bucket];
0364 }
0365
0366 void CudaMuonSpacePointContainer::addBucket(size_type start, size_type end) {
0367 if (start > end || end > m_size) {
0368 throw std::out_of_range(
0369 std::format("CudaMuonSpacePointContainer invalid bucket range "
0370 "[{:};{:}]. Allowed [0;{:})",
0371 start, end, m_size));
0372 }
0373
0374 m_host.bucketStart.push_back(static_cast<std::uint32_t>(start));
0375 m_host.bucketEnd.push_back(static_cast<std::uint32_t>(end));
0376 }
0377
0378 void CudaMuonSpacePointContainer::setGeometryId(
0379 size_type index, Acts::GeometryIdentifier::Value geometryId) {
0380 checkIndex(index);
0381 m_host.geometryId[index] = geometryId;
0382 }
0383
0384 void CudaMuonSpacePointContainer::setId(size_type index, std::uint32_t muonId) {
0385 checkIndex(index);
0386 m_host.muonId[index] = muonId;
0387 }
0388
0389 void CudaMuonSpacePointContainer::defineCoordinates(
0390 size_type index, const Acts::Vector3& position,
0391 const Acts::Vector3& sensorDirection, const Acts::Vector3& toNextSensor) {
0392 checkIndex(index);
0393
0394 m_host.localPositionX[index] = position.x();
0395 m_host.localPositionY[index] = position.y();
0396 m_host.localPositionZ[index] = position.z();
0397
0398 m_host.sensorDirectionX[index] = sensorDirection.x();
0399 m_host.sensorDirectionY[index] = sensorDirection.y();
0400 m_host.sensorDirectionZ[index] = sensorDirection.z();
0401
0402 m_host.toNextSensorX[index] = toNextSensor.x();
0403 m_host.toNextSensorY[index] = toNextSensor.y();
0404 m_host.toNextSensorZ[index] = toNextSensor.z();
0405
0406
0407 const Acts::Vector3 planeNormal =
0408 sensorDirection.cross(toNextSensor).normalized();
0409
0410 m_host.planeNormalX[index] = planeNormal.x();
0411 m_host.planeNormalY[index] = planeNormal.y();
0412 m_host.planeNormalZ[index] = planeNormal.z();
0413 }
0414
0415 void CudaMuonSpacePointContainer::setRadius(size_type index, double radius) {
0416 checkIndex(index);
0417 m_host.driftRadius[index] = radius;
0418 }
0419
0420 void CudaMuonSpacePointContainer::setTime(size_type index, double time) {
0421 checkIndex(index);
0422 m_host.time[index] = time;
0423 }
0424
0425 void CudaMuonSpacePointContainer::setCovariance(size_type index, double cov0,
0426 double cov1, double cov2) {
0427 checkIndex(index);
0428
0429 m_host.covariance0[index] = cov0;
0430 m_host.covariance1[index] = cov1;
0431 m_host.covariance2[index] = cov2;
0432 }
0433
0434 void CudaMuonSpacePointContainer::moveToDevice() {
0435 clearDevice();
0436
0437 allocateDeviceData(m_device, m_size, bucketCount());
0438 copyHostToDevice(m_device, m_host);
0439
0440 m_onDevice = true;
0441 }
0442
0443 void CudaMuonSpacePointContainer::moveToHost() {
0444 if (!m_onDevice) {
0445 return;
0446 }
0447
0448 copyDeviceToHost(m_host, m_device);
0449 }
0450
0451 void CudaMuonSpacePointContainer::clearDevice() noexcept {
0452 freeDeviceData(m_device);
0453 m_device = {};
0454 m_onDevice = false;
0455 }
0456
0457 CudaMuonSpacePointContainer::value_type CudaMuonSpacePointContainer::at(
0458 size_type index) const {
0459 checkIndex(index);
0460 return value_type{*this, index};
0461 }
0462
0463 inline void CudaMuonSpacePointContainer::checkIndex(size_type index) const {
0464 if (index >= m_size) {
0465 throw std::out_of_range(std::format(
0466 "CudaMuonSpacePointContainer index {:}out of range. Max allowed: {:}",
0467 index, m_size - 1));
0468 }
0469 }
0470
0471 void CudaMuonSpacePointContainer::checkBucket(size_type bucket) const {
0472 if (bucket >= bucketCount()) {
0473 throw std::out_of_range(std::format(
0474 "CudaMuonSpacePointContainer bucket {:} out of range. Max allowed: {:}",
0475 bucket, bucketCount() - 1));
0476 }
0477 }
0478
0479
0480
0481 void CudaMuonSpacePointContainer::setLogicalLayer(size_type index,
0482 std::uint32_t layer) {
0483 checkIndex(index);
0484
0485 static constexpr std::uint32_t fourBit = 0xFu;
0486 static constexpr std::uint32_t layerShift = 17u;
0487
0488 if (layer > fourBit) {
0489 throw std::out_of_range(
0490 "CudaMuonSpacePointContainer logical layer out of range");
0491 }
0492
0493 std::uint32_t rawId = m_host.muonId[index];
0494
0495
0496 rawId &= ~(fourBit << layerShift);
0497
0498
0499 rawId |= ((layer & fourBit) << layerShift);
0500
0501 m_host.muonId[index] = rawId;
0502 }
0503
0504 }