IgANet
IGAnets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
tensorarray.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <array>
18#include <initializer_list>
19
20#include <core/core.hpp>
21#include <core/options.hpp>
22#include <utils/container.hpp>
23
24namespace iganet::utils {
25
26template <std::size_t N> using TensorArray = std::array<torch::Tensor, N>;
27
33
37template <typename... Ts>
38inline constexpr TensorArray<sizeof...(Ts)>
39to_tensorArray(std::initializer_list<Ts> &&...lists) {
40 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists),
41 torch::IntArrayRef{-1}, Options<Ts>{})...};
42}
43
44template <typename... Ts>
45inline constexpr TensorArray<sizeof...(Ts)>
46to_tensorArray(torch::IntArrayRef sizes, std::initializer_list<Ts> &&...lists) {
47 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists), sizes,
48 Options<Ts>{})...};
49}
50
51template <typename... Ts, typename T>
52inline constexpr TensorArray<sizeof...(Ts)>
54 std::initializer_list<Ts> &&...lists) {
55 static_assert(
56 (std::is_same_v<T, Ts> && ...),
57 "Type mismatch between Options<T> and std::initializer_list<Ts>");
58 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists),
59 torch::IntArrayRef{-1}, options)...};
60}
61
62template <typename... Ts, typename T>
63inline constexpr TensorArray<sizeof...(Ts)>
64to_tensorArray(torch::IntArrayRef sizes, const iganet::Options<T> &options,
65 std::initializer_list<Ts> &&...lists) {
66 static_assert(
67 (std::is_same_v<T, Ts> && ...),
68 "Type mismatch between Options<T> and std::initializer_list<Ts>");
69 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists), sizes,
70 options)...};
71}
73
77template <typename T, std::size_t N>
78auto to_tensorAccessor(const torch::Tensor &tensor) {
79 return tensor.accessor<T, N>();
80}
81
82template <typename T, std::size_t N>
83auto to_tensorAccessor(const torch::Tensor &tensor,
84 c10::DeviceType deviceType) {
85
86 if (deviceType != tensor.device().type()) {
87 auto tensor_device = tensor.to(deviceType);
88 auto accessor = tensor_device.accessor<T, N>();
89 return std::tuple(tensor_device, accessor);
90 } else {
91 auto accessor = tensor.accessor<T, N>();
92 return std::tuple(tensor, accessor);
93 }
94}
96
97namespace detail {
101template <typename T, std::size_t N, std::size_t... Is>
102auto to_tensorAccessor(const TensorArray<sizeof...(Is)> &tensorArray,
103 std::index_sequence<Is...>) {
104 return std::array<torch::TensorAccessor<T, N>, sizeof...(Is)>{
105 tensorArray[Is].template accessor<T, N>()...};
106}
107
108template <typename T, std::size_t N, std::size_t... Is>
109auto to_tensorAccessor(const TensorArray<sizeof...(Is)> &tensorArray,
110 c10::DeviceType deviceType, std::index_sequence<Is...>) {
111 std::array<torch::TensorBase, sizeof...(Is)> tensorArray_device{
112 tensorArray[Is].to(deviceType)...};
113 std::array<torch::TensorAccessor<T, N>, sizeof...(Is)> accessors{
114 tensorArray_device[Is].template accessor<T, N>()...};
115 return std::tuple(tensorArray_device, accessors);
116}
117
118template <typename T, std::size_t N, size_t... Dims, std::size_t... Is>
120 c10::DeviceType deviceType, std::index_sequence<Is...>) {
121 std::array<torch::TensorBase, sizeof...(Is)> tensorArray_device{
122 blocktensor[Is]->to(deviceType)...};
123 std::array<torch::TensorAccessor<T, N>, sizeof...(Is)> accessors{
124 tensorArray_device[Is].template accessor<T, N>()...};
125 return std::tuple(tensorArray_device, accessors);
126}
128} // namespace detail
129
133template <typename T, std::size_t N, std::size_t M>
134auto to_tensorAccessor(const TensorArray<M> &tensorArray) {
135 return detail::to_tensorAccessor<T, N>(tensorArray,
136 std::make_index_sequence<M>());
137}
138
139template <typename T, std::size_t N, std::size_t M>
140auto to_tensorAccessor(const TensorArray<M> &tensorArray,
141 c10::DeviceType deviceType) {
142 return detail::to_tensorAccessor<T, N>(tensorArray, deviceType,
143 std::make_index_sequence<M>());
144}
145
146template <typename T, std::size_t N, std::size_t... Dims>
148 c10::DeviceType deviceType) {
149 return detail::to_tensorAccessor<T, N, Dims...>(
150 blocktensor, deviceType, std::make_index_sequence<(Dims * ...)>());
151}
153
154} // namespace iganet::utils
155
156#define TENSORARRAY_FORALL(obj, func, ...) \
157 []<std::size_t N>(const ::iganet::utils::TensorArray<N> &tensorArray) { \
158 ::iganet::utils::TensorArray<N> result; \
159 for (std::size_t i = 0; i < N; ++i) \
160 result[i] = tensorArray[i].func(__VA_ARGS__); \
161 return result; \
162 }(obj)
163
164namespace std {
165
167template <std::size_t N>
168inline std::ostream &operator<<(std::ostream &os,
169 const std::array<torch::Tensor, N> &obj) {
170 at::optional<std::string> name_ = c10::demangle(typeid(obj).name());
171
172#if defined(_WIN32)
173 // Windows adds "struct" or "class" as a prefix.
174 if (name_->find("struct ") == 0) {
175 name_->erase(name_->begin(), name_->begin() + 7);
176 } else if (name_->find("class ") == 0) {
177 name_->erase(name_->begin(), name_->begin() + 6);
178 }
179#endif // defined(_WIN32)
180
181 os << *name_ << "(\n";
182 for (std::size_t i = 0; i < N; ++i) {
183 os << obj[i] << "\n";
184
185 if (iganet::is_verbose(os))
186 os << "[ " << obj[i].options() << " ]\n";
187 }
188
189 os << ")";
190
191 return os;
192}
193
194} // namespace std
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:104
Container utility functions.
Core components.
auto to_tensorAccessor(const TensorArray< sizeof...(Is)> &tensorArray, std::index_sequence< Is... >)
Converts a std::array of torch::Tensor objects to an array of torch::TensorAccessor objects.
Definition tensorarray.hpp:102
Definition blocktensor.hpp:24
TensorArray< 4 > TensorArray4
Definition tensorarray.hpp:32
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:26
constexpr TensorArray< sizeof...(Ts)> to_tensorArray(std::initializer_list< Ts > &&...lists)
Converts a set of std::initializer_list objects to a TensorArray object.
Definition tensorarray.hpp:39
auto to_tensor(const std::array< T, N > &array, torch::IntArrayRef sizes=torch::IntArrayRef{-1}, const iganet::Options< T > &options=iganet::Options< T >{})
Converts a std::array to torch::Tensor.
Definition container.hpp:56
TensorArray< 3 > TensorArray3
Definition tensorarray.hpp:31
TensorArray< 0 > TensorArray0
Definition tensorarray.hpp:28
TensorArray< 1 > TensorArray1
Definition tensorarray.hpp:29
auto to_tensorAccessor(const torch::Tensor &tensor)
Converts a torch::Tensor object to a torch::TensorAccessor object.
Definition tensorarray.hpp:78
TensorArray< 2 > TensorArray2
Definition tensorarray.hpp:30
Forward declaration of BlockTensor.
Definition blocktensor.hpp:43
bool is_verbose(std::ostream &os)
Definition core.hpp:831
STL namespace.
std::ostream & operator<<(std::ostream &os, const std::array< T, N > &obj)
Print (as string) a std::array of generic objects.
Definition core.hpp:842
Options.