26 #ifndef TILEDARRAY_TENSOR_UTILITY_H__INCLUDED
27 #define TILEDARRAY_TENSOR_UTILITY_H__INCLUDED
45 template <
typename T,
typename std::enable_if<
46 is_contiguous_tensor<T>::value>::type* =
nullptr>
48 return tensor.range();
57 template <
typename T,
typename std::enable_if<
58 !is_contiguous_tensor<T>::value>::type* =
nullptr>
60 return Range(tensor.range().lobound(), tensor.range().upbound());
73 template <
typename T1,
typename T2,
74 typename std::enable_if<!(is_shifted<T1>::value ||
75 is_shifted<T2>::value)>::type* =
nullptr>
91 template <
typename T1,
typename T2,
92 typename std::enable_if<!(is_shifted<T1>::value ||
93 is_shifted<T2>::value)>::type* =
nullptr>
96 return is_congruent(tensor1.range(), perm * tensor2.range());
109 template <
typename T1,
typename T2,
110 typename std::enable_if<is_shifted<T1>::value ||
111 is_shifted<T2>::value>::type* =
nullptr>
113 const auto rank1 = tensor1.range().rank();
114 const auto rank2 = tensor2.range().rank();
115 const auto*
const extent1 = tensor1.range().extent_data();
116 const auto*
const extent2 = tensor2.range().extent_data();
117 return (rank1 == rank2) && std::equal(extent1, extent1 + rank1, extent2);
129 template <
typename T>
146 template <
typename T1,
typename T2,
typename... Ts>
148 const T2& tensor2,
const Ts&... tensors) {
161 template <
typename T>
176 template <
typename T1,
typename T2,
typename... Ts>
178 const Ts&... tensors) {
191 template <
typename T>
193 const auto* MADNESS_RESTRICT
const stride = tensor.range().stride_data();
194 const auto* MADNESS_RESTRICT
const size = tensor.range().extent_data();
196 int i = int(tensor.range().rank()) - 1;
199 for (--i; i >= 0; --i) {
200 const auto stride_i = stride[i];
201 const auto size_i = size[i];
203 if (
volume != stride_i)
break;
220 template <
typename T1,
typename T2>
224 const auto* MADNESS_RESTRICT
const size1 = tensor1.range().extent_data();
225 const auto* MADNESS_RESTRICT
const stride1 = tensor1.range().stride_data();
226 const auto* MADNESS_RESTRICT
const size2 = tensor2.range().extent_data();
227 const auto* MADNESS_RESTRICT
const stride2 = tensor2.range().stride_data();
229 int i = int(tensor1.range().rank()) - 1;
230 auto volume1 = size1[i];
231 auto volume2 = size2[i];
233 for (--i; i >= 0; --i) {
234 const auto stride1_i = stride1[i];
235 const auto stride2_i = stride2[i];
236 const auto size1_i = size1[i];
237 const auto size2_i = size2[i];
239 if ((volume1 != stride1_i) || (volume2 != stride2_i))
break;
257 typename T1,
typename T2,
258 typename std::enable_if<!is_contiguous_tensor<T1>::value &&
259 is_contiguous_tensor<T2>::value>::type* =
nullptr>
260 inline typename T1::size_type
inner_size(
const T1& tensor1,
const T2&) {
274 typename T1,
typename T2,
275 typename std::enable_if<is_contiguous_tensor<T1>::value &&
276 !is_contiguous_tensor<T2>::value>::type* =
nullptr>
277 inline typename T1::size_type
inner_size(
const T1&,
const T2& tensor2) {
293 typename T1,
typename T2,
294 typename std::enable_if<!is_contiguous_tensor<T1>::value &&
295 !is_contiguous_tensor<T2>::value>::type* =
nullptr>
296 inline typename T1::size_type
inner_size(
const T1& tensor1,
const T2& tensor2) {
308 template <
typename T,
typename std::enable_if<
309 !is_contiguous_tensor<T>::value>::type* =
nullptr>
320 inline constexpr
bool empty() {
return true; }
329 template <
typename T1,
typename... Ts>
330 inline bool empty(
const T1& tensor1,
const Ts&... tensors) {
331 return tensor1.empty() ||
empty(tensors...);
337 #endif // TILEDARRAY_TENSOR_UTILITY_H__INCLUDED