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 <options.hpp>
21#include <utils/container.hpp>
22
23#include <torch/torch.h>
24
25namespace iganet {
26namespace utils {
27
28template <std::size_t N> using TensorArray = std::array<torch::Tensor, N>;
29
35
39template <typename... Ts>
40inline constexpr TensorArray<sizeof...(Ts)>
41to_tensorArray(std::initializer_list<Ts> &&...lists) {
42 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists),
43 torch::IntArrayRef{-1}, Options<Ts>{})...};
44}
45
46template <typename... Ts>
47inline constexpr TensorArray<sizeof...(Ts)>
48to_tensorArray(torch::IntArrayRef sizes, std::initializer_list<Ts> &&...lists) {
49 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists), sizes,
50 Options<Ts>{})...};
51}
52
53template <typename... Ts, typename T>
54inline constexpr TensorArray<sizeof...(Ts)>
56 std::initializer_list<Ts> &&...lists) {
57 static_assert(
58 (std::is_same_v<T, Ts> && ...),
59 "Type mismatch between Options<T> and std::initializer_list<Ts>");
60 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists),
61 torch::IntArrayRef{-1}, options)...};
62}
63
64template <typename... Ts, typename T>
65inline constexpr TensorArray<sizeof...(Ts)>
66to_tensorArray(torch::IntArrayRef sizes, const iganet::Options<T> &options,
67 std::initializer_list<Ts> &&...lists) {
68 static_assert(
69 (std::is_same_v<T, Ts> && ...),
70 "Type mismatch between Options<T> and std::initializer_list<Ts>");
71 return {to_tensor(std::forward<std::initializer_list<Ts>>(lists), sizes,
72 options)...};
73}
75
79template <typename T, std::size_t N>
80auto to_tensorAccessor(const torch::Tensor &tensor) {
81 return tensor.template accessor<T, N>();
82}
83
84template <typename T, std::size_t N>
85auto to_tensorAccessor(const torch::Tensor &tensor,
86 c10::DeviceType deviceType) {
87
88 if (deviceType != tensor.device().type()) {
90 auto accessor = tensor_device.template accessor<T, N>();
91 return std::tuple(tensor_device, accessor);
92 } else {
93 auto accessor = tensor.template accessor<T, N>();
94 return std::tuple(tensor, accessor);
95 }
96}
98
99namespace detail {
103template <typename T, std::size_t N, std::size_t... Is>
105 std::index_sequence<Is...>) {
106 return std::array<torch::TensorAccessor<T, N>, sizeof...(Is)>{
107 tensorArray[Is].template accessor<T, N>()...};
108}
109
110template <typename T, std::size_t N, std::size_t... Is>
112 c10::DeviceType deviceType, std::index_sequence<Is...>) {
113 std::array<torch::TensorBase, sizeof...(Is)> tensorArray_device{
114 tensorArray[Is].to(deviceType)...};
115 std::array<torch::TensorAccessor<T, N>, sizeof...(Is)> accessors{
116 tensorArray_device[Is].template accessor<T, N>()...};
117 return std::tuple(tensorArray_device, accessors);
118}
119
120template <typename T, std::size_t N, size_t... Dims, std::size_t... Is>
122 c10::DeviceType deviceType, std::index_sequence<Is...>) {
123 std::array<torch::TensorBase, sizeof...(Is)> tensorArray_device{
124 blocktensor[Is]->to(deviceType)...};
125 std::array<torch::TensorAccessor<T, N>, sizeof...(Is)> accessors{
126 tensorArray_device[Is].template accessor<T, N>()...};
127 return std::tuple(tensorArray_device, accessors);
128}
130} // namespace detail
131
135template <typename T, std::size_t N, std::size_t M>
137 return detail::to_tensorAccessor<T, N>(tensorArray,
138 std::make_index_sequence<M>());
139}
140
141template <typename T, std::size_t N, std::size_t M>
143 c10::DeviceType deviceType) {
144 return detail::to_tensorAccessor<T, N>(tensorArray, deviceType,
145 std::make_index_sequence<M>());
146}
147
148template <typename T, std::size_t N, std::size_t... Dims>
150 c10::DeviceType deviceType) {
151 return detail::to_tensorAccessor<T, N, Dims...>(
152 blocktensor, deviceType, std::make_index_sequence<(Dims * ...)>());
153}
155
156} // namespace utils
157} // namespace iganet
158
159#define TENSORARRAY_FORALL(obj, func, ...) \
160 []<std::size_t N>(const ::iganet::utils::TensorArray<N> &tensorArray) { \
161 ::iganet::utils::TensorArray<N> result; \
162 for (std::size_t i = 0; i < N; ++i) \
163 result[i] = tensorArray[i].func(__VA_ARGS__); \
164 return result; \
165 }(obj)
166
167namespace std {
168
170template <std::size_t N>
171inline std::ostream &operator<<(std::ostream &os,
172 const std::array<torch::Tensor, N> &obj) {
173 at::optional<std::string> name_ = c10::demangle(typeid(obj).name());
174
175#if defined(_WIN32)
176 // Windows adds "struct" or "class" as a prefix.
177 if (name_->find("struct ") == 0) {
178 name_->erase(name_->begin(), name_->begin() + 7);
179 } else if (name_->find("class ") == 0) {
180 name_->erase(name_->begin(), name_->begin() + 6);
181 }
182#endif // defined(_WIN32)
183
184#ifdef __CUDACC__
185#pragma nv_diag_suppress 186
186#endif
187
188 os << *name_ << "(\n";
189 for (std::size_t i = 0; i < N; ++i) {
190 os << obj[i] << "\n";
191
192 if (iganet::is_verbose(os))
193 os << "[ " << obj[i].options() << " ]\n";
194 }
195
196#ifdef __CUDACC__
197#pragma nv_diag_default 186
198#endif
199
200 os << ")";
201
202 return os;
203}
204
205} // namespace std
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:90
Container utility functions.
auto to_tensorAccessor(const TensorArray< sizeof...(Is)> &tensorArray, std::index_sequence< Is... >)
Converts an std::array of torch::Tensor objects to an array of torch::TensorAccessor objects.
Definition tensorarray.hpp:104
TensorArray< 4 > TensorArray4
Definition tensorarray.hpp:34
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:28
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:41
auto to_tensor(const std::array< T, N > &array, torch::IntArrayRef sizes=torch::IntArrayRef{-1}, const iganet::Options< T > &options=iganet::Options< T >{})
Converts an std::array to torch::Tensor.
Definition container.hpp:60
TensorArray< 3 > TensorArray3
Definition tensorarray.hpp:33
TensorArray< 0 > TensorArray0
Definition tensorarray.hpp:30
TensorArray< 1 > TensorArray1
Definition tensorarray.hpp:31
auto to_tensorAccessor(const torch::Tensor &tensor)
Converts a torch::Tensor object to a torch::TensorAccessor object.
Definition tensorarray.hpp:80
TensorArray< 2 > TensorArray2
Definition tensorarray.hpp:32
Forward declaration of BlockTensor.
Definition blocktensor.hpp:46
Definition boundary.hpp:22
bool is_verbose(std::ostream &os)
Definition core.hpp:831
constexpr bool is_SplineType_v
Alias to the value of is_SplineType.
Definition bspline.hpp:3243
STL namespace.
std::ostream & operator<<(std::ostream &os, const std::array< T, N > &obj)
Print (as string) an std::array of generic objects.
Definition core.hpp:842
Options.