Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:10

0001 /*
0002  * SPDX-PackageName: "covfie, a part of the ACTS project"
0003  * SPDX-FileCopyrightText: 2022 CERN
0004  * SPDX-License-Identifier: MPL-2.0
0005  */
0006 
0007 #pragma once
0008 
0009 #include <cassert>
0010 #include <cstring>
0011 #include <memory>
0012 #include <utility>
0013 
0014 #include <covfie/core/concepts.hpp>
0015 #include <covfie/core/parameter_pack.hpp>
0016 #include <covfie/core/qualifiers.hpp>
0017 #include <covfie/core/utility/binary_io.hpp>
0018 #include <covfie/core/utility/nd_size.hpp>
0019 #include <covfie/core/vector.hpp>
0020 
0021 namespace covfie::backend {
0022 template <
0023     concepts::vector_descriptor _output_vector_t,
0024     typename _index_t = std::size_t>
0025 struct array {
0026     using this_t = array<_output_vector_t, _index_t>;
0027     static constexpr bool is_initial = true;
0028 
0029     using contravariant_input_t =
0030         covfie::vector::scalar_d<covfie::vector::vector_d<_index_t, 1>>;
0031     using covariant_output_t =
0032         covfie::vector::array_reference_vector_d<_output_vector_t>;
0033 
0034     using vector_t = std::decay_t<typename covariant_output_t::vector_t>;
0035 
0036     using configuration_t = utility::nd_size<contravariant_input_t::dimensions>;
0037 
0038     static constexpr uint32_t IO_MAGIC_HEADER = 0xAB010000;
0039 
0040     struct owning_data_t {
0041         using parent_t = this_t;
0042 
0043         owning_data_t()
0044             : m_size(0)
0045             , m_ptr({})
0046         {
0047         }
0048 
0049         owning_data_t(owning_data_t &&) = default;
0050         owning_data_t & operator=(owning_data_t &&) = default;
0051 
0052         explicit owning_data_t(std::size_t n)
0053             : m_size(n)
0054             , m_ptr(std::make_unique<vector_t[]>(n))
0055         {
0056         }
0057 
0058         explicit owning_data_t(configuration_t conf)
0059             : owning_data_t(conf[0])
0060         {
0061         }
0062 
0063         explicit owning_data_t(parameter_pack<owning_data_t> && conf)
0064             : owning_data_t(std::move(conf.x))
0065         {
0066         }
0067 
0068         explicit owning_data_t(parameter_pack<configuration_t> && conf)
0069             : owning_data_t(conf.x[0])
0070         {
0071         }
0072 
0073         explicit owning_data_t(
0074             std::size_t size, std::unique_ptr<vector_t[]> && ptr
0075         )
0076             : m_size(size)
0077             , m_ptr(std::move(ptr))
0078         {
0079         }
0080 
0081         owning_data_t(const owning_data_t & o)
0082             : m_size(o.m_size)
0083             , m_ptr(std::make_unique<vector_t[]>(m_size))
0084         {
0085             assert(m_size == 0 || m_ptr);
0086 
0087             if (o.m_ptr && m_size > 0) {
0088                 std::memcpy(
0089                     m_ptr.get(), o.m_ptr.get(), m_size * sizeof(vector_t)
0090                 );
0091             }
0092         }
0093 
0094         owning_data_t & operator=(const owning_data_t & o)
0095         {
0096             m_size = o.m_size;
0097             m_ptr = std::make_unique<vector_t[]>(m_size);
0098 
0099             assert(m_size == 0 || m_ptr);
0100 
0101             if (o.m_ptr && m_size > 0) {
0102                 std::memcpy(
0103                     m_ptr.get(), o.m_ptr.get(), m_size * sizeof(vector_t)
0104                 );
0105             }
0106         }
0107 
0108         configuration_t get_configuration() const
0109         {
0110             return {m_size};
0111         }
0112 
0113         static owning_data_t read_binary(std::istream & fs)
0114         {
0115             utility::read_io_header(fs, IO_MAGIC_HEADER);
0116 
0117             uint32_t float_width = utility::read_binary<uint32_t>(fs);
0118 
0119             if (float_width != 4 && float_width != 8) {
0120                 throw std::runtime_error(
0121                     "Float type is neither IEEE 754 single- nor "
0122                     "double-precision, binary input is not supported."
0123                 );
0124             }
0125 
0126             auto size =
0127                 utility::read_binary<std::decay_t<decltype(m_size)>>(fs);
0128             std::unique_ptr<vector_t[]> ptr =
0129                 std::make_unique<vector_t[]>(size);
0130 
0131             for (std::size_t i = 0; i < size; ++i) {
0132                 for (std::size_t j = 0; j < _output_vector_t::size; ++j) {
0133                     using scalar_t = typename _output_vector_t::type;
0134                     if (float_width == 4) {
0135                         ptr[i][j] =
0136                             static_cast<scalar_t>(utility::read_binary<float>(fs
0137                             ));
0138                     } else if (float_width == 8) {
0139                         ptr[i][j] = static_cast<scalar_t>(
0140                             utility::read_binary<double>(fs)
0141                         );
0142                     } else {
0143                         throw std::logic_error("Float width is unexpected.");
0144                     }
0145                 }
0146             }
0147 
0148             utility::read_io_footer(fs, IO_MAGIC_HEADER);
0149 
0150             return owning_data_t(size, std::move(ptr));
0151         }
0152 
0153         static void write_binary(std::ostream & fs, const owning_data_t & o)
0154         {
0155             utility::write_io_header(fs, IO_MAGIC_HEADER);
0156 
0157             uint32_t float_width;
0158 
0159             if constexpr (std::
0160                               is_same_v<typename _output_vector_t::type, float>)
0161             {
0162                 float_width = 4;
0163             } else if constexpr (std::is_same_v<
0164                                      typename _output_vector_t::type,
0165                                      double>)
0166             {
0167                 float_width = 8;
0168             } else {
0169                 throw std::logic_error(
0170                     "Float type is neither IEEE 754 single- nor "
0171                     "double-precision, binary output is not supported."
0172                 );
0173             }
0174 
0175             fs.write(
0176                 reinterpret_cast<const char *>(&float_width),
0177                 sizeof(std::decay_t<decltype(float_width)>)
0178             );
0179 
0180             fs.write(
0181                 reinterpret_cast<const char *>(&o.m_size),
0182                 sizeof(std::decay_t<decltype(o.m_size)>)
0183             );
0184 
0185             for (std::size_t i = 0; i < o.m_size; ++i) {
0186                 for (std::size_t j = 0; j < _output_vector_t::size; ++j) {
0187                     fs.write(
0188                         reinterpret_cast<const char *>(&o.m_ptr[i][j]),
0189                         sizeof(typename _output_vector_t::type)
0190                     );
0191                 }
0192             }
0193 
0194             utility::write_io_footer(fs, IO_MAGIC_HEADER);
0195         }
0196 
0197         uint64_t get_size() const
0198         {
0199             return m_size;
0200         }
0201 
0202         std::unique_ptr<vector_t[]> get_host_array() const
0203         {
0204             std::unique_ptr<vector_t[]> rv =
0205                 std::make_unique<vector_t[]>(m_size);
0206             std::memcpy(rv.get(), m_ptr.get(), m_size * sizeof(vector_t));
0207             return rv;
0208         }
0209 
0210         uint64_t m_size;
0211         std::unique_ptr<vector_t[]> m_ptr;
0212     };
0213 
0214     struct non_owning_data_t {
0215         using parent_t = this_t;
0216 
0217         non_owning_data_t(const owning_data_t & o)
0218             : m_size(o.m_size)
0219             , m_ptr(o.m_ptr.get())
0220         {
0221         }
0222 
0223         COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
0224         at(typename contravariant_input_t::vector_t i) const
0225         {
0226             assert(i < m_size);
0227             return m_ptr[i];
0228         }
0229 
0230         uint64_t m_size;
0231         typename decltype(owning_data_t::m_ptr)::pointer m_ptr;
0232     };
0233 };
0234 }