Back to home page

EIC code displayed by LXR

 
 

    


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

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 <algorithm>
0010 #include <iostream>
0011 #include <type_traits>
0012 #include <variant>
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 <concepts::field_backend _backend_t>
0023 struct clamp {
0024     using this_t = clamp<_backend_t>;
0025     static constexpr bool is_initial = false;
0026 
0027     using backend_t = _backend_t;
0028 
0029     using contravariant_input_t = typename backend_t::contravariant_input_t;
0030     using covariant_output_t = typename backend_t::covariant_output_t;
0031 
0032     struct configuration_t {
0033         typename contravariant_input_t::vector_t min, max;
0034     };
0035 
0036     static constexpr uint32_t IO_MAGIC_HEADER = 0xAB020002;
0037 
0038     struct owning_data_t {
0039         using parent_t = this_t;
0040 
0041         owning_data_t() = default;
0042 
0043         template <typename... Args>
0044         explicit owning_data_t(parameter_pack<configuration_t, Args...> && args)
0045             : m_min(args.x.min)
0046             , m_max(args.x.max)
0047             , m_backend(std::move(args.xs))
0048         {
0049         }
0050 
0051         explicit owning_data_t(
0052             const configuration_t & c, typename backend_t::owning_data_t && b
0053         )
0054             : m_min(c.min)
0055             , m_max(c.max)
0056             , m_backend(std::forward<typename backend_t::owning_data_t>(b))
0057         {
0058         }
0059 
0060         explicit owning_data_t(parameter_pack<owning_data_t> && conf)
0061             : owning_data_t(std::move(conf.x))
0062         {
0063         }
0064 
0065         template <typename... Args>
0066         requires(std::same_as<
0067                  typename backend_t::configuration_t,
0068                  utility::nd_size<
0069                      backend_t::contravariant_input_t::
0070                          dimensions>>) explicit owning_data_t(Args... args)
0071             : m_backend(std::forward<Args>(args)...)
0072         {
0073             m_min.fill(static_cast<typename contravariant_input_t::scalar_t>(0)
0074             );
0075 
0076             for (std::size_t i = 0; i < contravariant_input_t::dimensions; ++i)
0077             {
0078                 m_max[i] = m_backend.get_configuration()[i];
0079             }
0080         }
0081 
0082         typename backend_t::owning_data_t & get_backend(void)
0083         {
0084             return m_backend;
0085         }
0086 
0087         const typename backend_t::owning_data_t & get_backend(void) const
0088         {
0089             return m_backend;
0090         }
0091 
0092         configuration_t get_configuration(void) const
0093         {
0094             return {m_min, m_max};
0095         }
0096 
0097         static owning_data_t read_binary(std::istream & fs)
0098         {
0099             utility::read_io_header(fs, IO_MAGIC_HEADER);
0100 
0101             auto min = utility::read_binary<decltype(m_min)>(fs);
0102             auto max = utility::read_binary<decltype(m_max)>(fs);
0103             typename backend_t::owning_data_t be =
0104                 backend_t::owning_data_t::read_binary(fs);
0105 
0106             utility::read_io_footer(fs, IO_MAGIC_HEADER);
0107 
0108             return owning_data_t(configuration_t{min, max}, std::move(be));
0109         }
0110 
0111         static void write_binary(std::ostream & fs, const owning_data_t & o)
0112         {
0113             utility::write_io_header(fs, IO_MAGIC_HEADER);
0114 
0115             fs.write(
0116                 reinterpret_cast<const char *>(&o.m_min),
0117                 sizeof(decltype(m_min))
0118             );
0119             fs.write(
0120                 reinterpret_cast<const char *>(&o.m_max),
0121                 sizeof(decltype(m_max))
0122             );
0123 
0124             backend_t::owning_data_t::write_binary(fs, o.m_backend);
0125 
0126             utility::write_io_footer(fs, IO_MAGIC_HEADER);
0127         }
0128 
0129         typename contravariant_input_t::vector_t m_min, m_max;
0130         typename backend_t::owning_data_t m_backend;
0131     };
0132 
0133     struct non_owning_data_t {
0134         using parent_t = this_t;
0135 
0136         non_owning_data_t(const owning_data_t & src)
0137             : m_min(src.m_min)
0138             , m_max(src.m_max)
0139             , m_backend(src.m_backend)
0140         {
0141         }
0142 
0143         template <std::size_t... Is>
0144         COVFIE_HOST_DEVICE typename contravariant_input_t::vector_t
0145         adjust(typename contravariant_input_t::vector_t coord, std::index_sequence<Is...>)
0146             const
0147         {
0148             return {std::clamp(coord[Is], m_min[Is], m_max[Is])...};
0149         }
0150 
0151         COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
0152         at(typename contravariant_input_t::vector_t coord) const
0153         {
0154             return m_backend.at(adjust(
0155                 coord,
0156                 std::make_index_sequence<contravariant_input_t::dimensions>{}
0157             ));
0158         }
0159 
0160         typename backend_t::non_owning_data_t & get_backend(void)
0161         {
0162             return m_backend;
0163         }
0164 
0165         const typename backend_t::non_owning_data_t & get_backend(void) const
0166         {
0167             return m_backend;
0168         }
0169 
0170         typename contravariant_input_t::vector_t m_min, m_max;
0171         typename backend_t::non_owning_data_t m_backend;
0172     };
0173 };
0174 }