Back to home page

EIC code displayed by LXR

 
 

    


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

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 #pragma once
0010 
0011 // Project include(s).
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 
0014 // Test include(s).
0015 #include "detray/test/device/device_fixture.hpp"
0016 #include "detray/test/framework/types.hpp"
0017 
0018 // VecMem include(s).
0019 #include <vecmem/containers/data/vector_view.hpp>
0020 #include <vecmem/containers/device_vector.hpp>
0021 #include <vecmem/containers/vector.hpp>
0022 #include <vecmem/memory/memory_resource.hpp>
0023 
0024 // GoogleTest include(s).
0025 #include <gtest/gtest.h>
0026 
0027 // System include(s).
0028 #include <cmath>
0029 #include <memory>
0030 
0031 namespace detray::test {
0032 
0033 /// Data fixture for matrix test cases
0034 template <detray::concepts::algebra A>
0035 class matrix_fixture : public device_fixture<dscalar<A>> {
0036   using index_t = dindex_type<A>;
0037   using scalar_t = dscalar<A>;
0038   template <index_t R, index_t C>
0039   using matrix_t = dmatrix<A, R, C>;
0040 
0041   using result_t = scalar_t;
0042   using base_fixture = device_fixture<result_t>;
0043 
0044  public:
0045   /// Constructor, setting up the inputs for all of the tests
0046   matrix_fixture(vecmem::memory_resource& mr) : base_fixture(mr) {}
0047 
0048  protected:
0049   /// Function setting things up for a test
0050   virtual void SetUp() override {
0051     // Set up the result vectors
0052     base_fixture::SetUp();
0053 
0054     // Set up the input vectors.
0055     m_m1 = std::make_unique<vecmem::vector<matrix_t<6, 4>>>(this->size(),
0056                                                             &this->resource());
0057     m_m2 = std::make_unique<vecmem::vector<matrix_t<2, 2>>>(this->size(),
0058                                                             &this->resource());
0059 
0060     // Initialise the input and output vectors.
0061     for (std::size_t i = 0u; i < this->size(); ++i) {
0062       for (std::size_t j = 0u; j < 6u; ++j) {
0063         for (std::size_t k = 0u; k < 4u; ++k) {
0064           detray::getter::element(m_m1->at(i), j, k) =
0065               static_cast<scalar_t>(j * 20.3 + k * 10.5);
0066         }
0067       }
0068 
0069       detray::getter::element(m_m2->at(i), 0u, 0u) = 4;
0070       detray::getter::element(m_m2->at(i), 0u, 1u) = 3;
0071       detray::getter::element(m_m2->at(i), 1u, 0u) = 12;
0072       detray::getter::element(m_m2->at(i), 1u, 1u) = 13;
0073     }
0074   }
0075 
0076   /// Function tearing things down after the test
0077   virtual void TearDown() override {
0078     // Delete the matrices.
0079     m_m1.reset();
0080     m_m2.reset();
0081 
0082     // Tear down the base class.
0083     base_fixture::TearDown();
0084   }
0085 
0086   /// @name Inputs for the tests
0087   /// @{
0088   std::unique_ptr<vecmem::vector<matrix_t<6, 4>>> m_m1;
0089   std::unique_ptr<vecmem::vector<matrix_t<2, 2>>> m_m2;
0090   /// @}
0091 
0092 };  // class matrix_test_fixture
0093 
0094 /// Functor running @c test_device_basics::matrix64_ops
0095 template <detray::concepts::algebra A>
0096 class matrix64_ops_functor {
0097   using index_t = dindex_type<A>;
0098   using scalar_t = dscalar<A>;
0099   template <index_t R, index_t C>
0100   using matrix_t = dmatrix<A, R, C>;
0101 
0102  public:
0103   DETRAY_HOST_DEVICE void operator()(
0104       std::size_t i, vecmem::data::vector_view<const matrix_t<6, 4>> m,
0105       vecmem::data::vector_view<scalar_t> output) const {
0106     // Create the VecMem vector(s).
0107     vecmem::device_vector<const matrix_t<6, 4>> vec_m(m);
0108     vecmem::device_vector<scalar_t> vec_output(output);
0109 
0110     // Perform the operation.
0111     auto ii = static_cast<typename decltype(vec_output)::size_type>(i);
0112     vec_output[ii] = matrix64_ops(vec_m[ii]);
0113   }
0114 
0115  private:
0116   /// Perform some trivial operations on an asymmetrix matrix
0117   DETRAY_HOST_DEVICE
0118   scalar_t matrix64_ops(const matrix_t<6, 4>& m) const {
0119     using namespace algebra;
0120 
0121     matrix_t<6, 4> m2;
0122     for (std::size_t i = 0u; i < 6u; ++i) {
0123       for (std::size_t j = 0u; j < 4u; ++j) {
0124         detray::getter::element(m2, i, j) = detray::getter::element(m, i, j);
0125       }
0126     }
0127 
0128     scalar_t result = 0.;
0129     for (std::size_t i = 0u; i < 6u; ++i) {
0130       for (std::size_t j = 0u; j < 4u; ++j) {
0131         result += 0.6f * detray::getter::element(m, i, j) +
0132                   0.7f * detray::getter::element(m2, i, j);
0133       }
0134     }
0135 
0136     // Test set_zero
0137     detray::matrix::set_zero(m2);
0138     for (std::size_t i = 0u; i < 6u; ++i) {
0139       for (std::size_t j = 0u; j < 4u; ++j) {
0140         result += 0.4f * detray::getter::element(m2, i, j);
0141       }
0142     }
0143 
0144     // Test set_identity
0145     detray::matrix::set_identity(m2);
0146     for (std::size_t i = 0u; i < 6u; ++i) {
0147       for (std::size_t j = 0u; j < 4u; ++j) {
0148         result += 0.3f * detray::getter::element(m2, i, j);
0149       }
0150     }
0151 
0152     // Test block operations
0153     auto b13 = detray::getter::block<1, 3>(m2, 0, 0);
0154     auto b13_tp = detray::matrix::transpose(b13);
0155     detray::getter::element(b13_tp, 0, 0) = 1;
0156     detray::getter::element(b13_tp, 1, 0) = 2;
0157     detray::getter::element(b13_tp, 2, 0) = 3;
0158     detray::getter::set_block(m2, b13_tp, 0, 0);
0159 
0160     auto b32 = detray::getter::block<3, 2>(m2, 2, 2);
0161     detray::getter::element(b32, 0, 0) = 4;
0162     detray::getter::element(b32, 0, 1) = 3;
0163     detray::getter::element(b32, 1, 0) = 12;
0164     detray::getter::element(b32, 1, 1) = 13;
0165     detray::getter::element(b32, 2, 0) = 5;
0166     detray::getter::element(b32, 2, 1) = 6;
0167 
0168     detray::getter::set_block(m2, b32, 2, 2);
0169     for (std::size_t i = 0u; i < 6u; ++i) {
0170       for (std::size_t j = 0u; j < 4u; ++j) {
0171         result += 0.57f * detray::getter::element(m2, i, j);
0172       }
0173     }
0174 
0175     return result;
0176   }
0177 };
0178 
0179 /// Functor running @c test_device_basics::matrix22_ops
0180 template <detray::concepts::algebra A>
0181 class matrix22_ops_functor {
0182   using index_t = dindex_type<A>;
0183   using scalar_t = dscalar<A>;
0184   template <index_t R, index_t C>
0185   using matrix_t = dmatrix<A, R, C>;
0186 
0187  public:
0188   DETRAY_HOST_DEVICE void operator()(
0189       std::size_t i, vecmem::data::vector_view<const matrix_t<2, 2>> m,
0190       vecmem::data::vector_view<scalar_t> output) const {
0191     // Create the VecMem vector(s).
0192     vecmem::device_vector<const matrix_t<2, 2>> vec_m(m);
0193     vecmem::device_vector<scalar_t> vec_output(output);
0194 
0195     // Perform the operation.
0196     auto ii = static_cast<typename decltype(vec_output)::size_type>(i);
0197     vec_output[ii] = matrix22_ops(vec_m[ii]);
0198   }
0199 
0200  private:
0201   /// Perform some trivial operations on an asymmetrix matrix
0202   DETRAY_HOST_DEVICE
0203   scalar_t matrix22_ops(const matrix_t<2, 2>& m22) const {
0204     // Test 2 X 2 matrix determinant
0205     auto m22_det = detray::matrix::determinant(m22);
0206 
0207     // Test 2 X 2 matrix inverse
0208     auto m22_inv = detray::matrix::inverse(m22);
0209 
0210     matrix_t<3, 3> m33;
0211     detray::getter::element(m33, 0, 0) = 1;
0212     detray::getter::element(m33, 0, 1) = 5;
0213     detray::getter::element(m33, 0, 2) = 7;
0214     detray::getter::element(m33, 1, 0) = 3;
0215     detray::getter::element(m33, 1, 1) = 5;
0216     detray::getter::element(m33, 1, 2) = 6;
0217     detray::getter::element(m33, 2, 0) = 2;
0218     detray::getter::element(m33, 2, 1) = 8;
0219     detray::getter::element(m33, 2, 2) = 9;
0220 
0221     // Test 3 X 3 matrix determinant
0222     auto m33_det = detray::matrix::determinant(m33);
0223 
0224     // Test 3 X 3 matrix inverse
0225     auto m33_inv = detray::matrix::inverse(m33);
0226 
0227     // Test Zero
0228     auto m23 = detray::matrix::zero<matrix_t<2, 3>>();
0229     detray::getter::element(m23, 0, 0) += 2;
0230     detray::getter::element(m23, 0, 1) += 3;
0231     detray::getter::element(m23, 0, 2) += 4;
0232     detray::getter::element(m23, 1, 0) += 5;
0233     detray::getter::element(m23, 1, 1) += 6;
0234     detray::getter::element(m23, 1, 2) += 7;
0235 
0236     // Test scalar X Matrix
0237     m23 = 2. * m23;
0238 
0239     // Test Transpose
0240     auto m32 = detray::matrix::transpose(m23);
0241 
0242     // Test Identity and (Matrix + Matrix)
0243     m32 = m32 + detray::matrix::identity<matrix_t<3, 2>>();
0244 
0245     // Test Matrix X scalar
0246     m32 = m32 * 2.;
0247 
0248     // Test Matrix multiplication
0249     auto new_m22 = m22_inv * m23 * m33_inv * m32;
0250 
0251     scalar_t result = 0;
0252     result += m22_det;
0253     result += m33_det;
0254     result += detray::getter::element(new_m22, 0, 0);
0255     result += detray::getter::element(new_m22, 0, 1);
0256     result += detray::getter::element(new_m22, 1, 0);
0257     result += detray::getter::element(new_m22, 1, 1);
0258 
0259     return result;
0260   }
0261 };
0262 
0263 }  // namespace detray::test