Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
common/initialization.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <algorithm>
8#include <cstddef>
9#include <stdexcept>
10#include <type_traits>
11
12namespace uni20
13{
14
17{
18 explicit constexpr uninitialized_t() = default;
19};
20
22inline constexpr uninitialized_t uninitialized{};
23
26{
27 Zero,
29};
30
36template <typename T>
37inline constexpr bool enable_uninitialized_storage =
38 std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>;
39
40template <typename Real>
41inline constexpr bool enable_uninitialized_storage<uni20::detail::standard_complex<Real>> =
42 std::is_trivially_destructible_v<uni20::detail::standard_complex<Real>>;
43
45template <typename T>
46concept uninitialized_ok = enable_uninitialized_storage<std::remove_cv_t<T>>;
47
48namespace detail
49{
50
51template <typename T>
52inline constexpr bool zero_initializable_v = [] {
53 if constexpr (is_complex_v<T>)
54 {
55 using real_type = typename T::value_type;
56 return requires { T{real_type{0}, real_type{0}}; };
57 }
58 else if constexpr (is_scalar_v<T>)
59 {
60 return requires { T{0}; };
61 }
62 else
63 {
64 return requires { T{}; };
65 }
66}();
67
68template <typename T>
69 requires zero_initializable_v<T>
70T zero_value()
71{
72 if constexpr (is_complex_v<T>)
73 {
74 using real_type = typename T::value_type;
75 return T{real_type{0}, real_type{0}};
76 }
77 else if constexpr (is_scalar_v<T>)
78 {
79 return T{0};
80 }
81 else
82 {
83 return T{};
84 }
85}
86
87template <typename T>
88inline constexpr bool has_signaling_nan_v = [] {
89 if constexpr (is_complex_v<T>)
90 {
91 return has_signaling_nan_v<typename T::value_type>;
92 }
93 else if constexpr (is_real_v<T>)
94 {
95 // A numeric specialization need not implement every optional capability.
96 return requires { requires uni20::numeric_limits<T>::has_signaling_NaN; };
97 }
98 else
99 {
100 return false;
101 }
102}();
103
104template <typename T>
105 requires has_signaling_nan_v<T>
106T signaling_nan_value()
107{
108 if constexpr (is_complex_v<T>)
109 {
111 return T{value, value};
112 }
113 else
114 {
116 }
117}
118
124template <typename T> void initialize_host_elements(T* data, std::size_t count, StorageInitialization initialization)
125{
126 if (count == 0) return;
127 if (initialization == StorageInitialization::Zero)
128 {
129 if constexpr (!zero_initializable_v<T>)
130 {
131 throw std::invalid_argument("Zero initialization requires an element type with a zero/default value");
132 }
133 else if constexpr (std::is_assignable_v<T&, T>)
134 {
135 for (std::size_t i = 0; i < count; ++i)
136 data[i] = zero_value<T>();
137 }
138 return;
139 }
140#if UNI20_FILL_UNINITIALIZED_SNAN
141 if constexpr (uninitialized_ok<T> && has_signaling_nan_v<T>)
142 {
143 std::fill_n(data, count, signaling_nan_value<T>());
144 }
145#endif
146 if constexpr (uninitialized_ok<T>)
147 {
148 memory_diagnostics::mark_uninitialized(data, count * sizeof(T));
149 }
150}
151
152} // namespace detail
153} // namespace uni20
Whether raw allocation may establish storage for T without construction.
Definition common/initialization.hpp:46
locale_t value
Definition data_table.cpp:49
Definition async/async.hpp:26
constexpr uninitialized_t uninitialized
Explicit allocation tag for overwrite outputs and scratch space.
Definition common/initialization.hpp:22
constexpr bool enable_uninitialized_storage
Opt a type into allocation without construction or destruction.
Definition common/initialization.hpp:37
StorageInitialization
Numerical initialization requested from a storage implementation.
Definition common/initialization.hpp:26
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16
Request storage whose numerical values must be written before being read.
Definition common/initialization.hpp:17
constexpr uninitialized_t()=default