20 #ifndef TILEDARRAY_TILE_H__INCLUDED
21 #define TILEDARRAY_TILE_H__INCLUDED
93 typename tensor_type::ordinal_type;
96 typename tensor_type::reference;
98 typename tensor_type::const_reference;
99 using iterator =
typename tensor_type::iterator;
101 typename tensor_type::const_iterator;
102 using pointer =
typename tensor_type::pointer;
104 typename tensor_type::const_pointer;
111 std::shared_ptr<tensor_type> pimpl_;
127 template <
typename Arg,
128 typename =
typename std::enable_if<
130 not std::is_convertible<Arg, Tile_>::value &&
132 Arg,
Tile_>::value>::type>
134 : pimpl_(std::make_shared<
tensor_type>(std::forward<Arg>(arg))) {}
136 template <
typename Arg1,
typename Arg2,
typename... Args>
137 Tile(Arg1&& arg1, Arg2&& arg2, Args&&... args)
138 : pimpl_(std::make_shared<
tensor_type>(std::forward<Arg1>(arg1),
139 std::forward<Arg2>(arg2),
140 std::forward<Args>(args)...)) {}
155 *pimpl_ = std::move(
tensor);
161 bool empty()
const {
return pimpl_ ? pimpl_->empty() :
true; }
189 decltype(
auto)
end()
const {
return std::end(
tensor()); }
224 template <
typename Ordinal,
225 std::enable_if_t<std::is_integral<Ordinal>::value>* =
nullptr>
229 return tensor().data()[ord];
239 template <
typename Ordinal,
240 std::enable_if_t<std::is_integral<Ordinal>::value>* =
nullptr>
244 return tensor().data()[ord];
254 template <
typename Index,
255 std::enable_if_t<detail::is_integral_range_v<Index>>* =
nullptr>
269 template <
typename Index,
270 std::enable_if_t<detail::is_integral_range_v<Index>>* =
nullptr>
284 template <
typename Index,
285 typename = std::enable_if_t<std::is_integral_v<Index>>>
299 template <
typename Index,
300 typename = std::enable_if_t<std::is_integral_v<Index>>>
314 template <
typename Index,
315 std::enable_if_t<detail::is_integral_range_v<Index>>* =
nullptr>
329 template <
typename Index,
330 std::enable_if_t<detail::is_integral_range_v<Index>>* =
nullptr>
344 template <
typename Index,
345 typename = std::enable_if_t<std::is_integral_v<Index>>>
359 template <
typename Index,
360 typename = std::enable_if_t<std::is_integral_v<Index>>>
420 template <
typename Index1,
typename Index2,
421 typename = std::enable_if_t<detail::is_integral_range_v<Index1> &&
422 detail::is_integral_range_v<Index2>>>
423 decltype(
auto)
block(const Index1& lower_bound, const Index2& upper_bound) {
430 template <
typename Index1,
typename Index2,
431 typename = std::enable_if_t<detail::is_integral_range_v<Index1> &&
432 detail::is_integral_range_v<Index2>>>
433 decltype(
auto)
block(const Index1& lower_bound,
434 const Index2& upper_bound)
const {
461 template <
typename Index1,
typename Index2,
462 typename = std::enable_if_t<std::is_integral_v<Index1> &&
463 std::is_integral_v<Index2>>>
464 decltype(
auto)
block(const std::initializer_list<Index1>& lower_bound,
465 const std::initializer_list<Index2>& upper_bound) {
472 template <
typename Index1,
typename Index2,
473 typename = std::enable_if_t<std::is_integral_v<Index1> &&
474 std::is_integral_v<Index2>>>
475 decltype(
auto)
block(const std::initializer_list<Index1>& lower_bound,
476 const std::initializer_list<Index2>& upper_bound)
const {
518 template <
typename PairRange,
519 typename = std::enable_if_t<detail::is_gpair_range_v<PairRange>>>
520 decltype(
auto)
block(const PairRange& bounds) {
526 template <
typename PairRange,
527 typename = std::enable_if_t<detail::is_gpair_range_v<PairRange>>>
528 decltype(
auto)
block(const PairRange& bounds)
const {
550 template <
typename Index,
551 typename = std::enable_if_t<std::is_integral_v<Index>>>
553 const std::initializer_list<std::initializer_list<Index>>& bounds) {
559 template <
typename Index,
560 typename = std::enable_if_t<std::is_integral_v<Index>>>
562 const std::initializer_list<std::initializer_list<Index>>& bounds)
const {
571 template <
typename Archive,
573 Archive>::value>::type* =
nullptr>
576 bool empty = !
static_cast<bool>(pimpl_);
584 template <
typename Archive,
586 Archive>::value>::type* =
nullptr>
598 pimpl_ = std::make_shared<T>(std::move(
tensor));
618 template <
typename T>
620 return Tile<T>(std::forward<T>(t));
632 template <
typename Arg>
637 #if __cplusplus <= 201402L
645 template <
typename Arg>
660 template <
typename Arg,
typename Perm,
661 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
662 inline decltype(
auto)
permute(const
Tile<Arg>& arg, const Perm& perm) {
675 template <
typename Arg,
typename Index,
676 typename = std::enable_if_t<detail::is_integral_range_v<Index>>>
677 inline decltype(
auto)
shift(const
Tile<Arg>& arg, const Index& range_shift) {
688 template <
typename Arg,
typename Index,
689 typename = std::enable_if_t<std::is_integral_v<Index>>>
691 const std::initializer_list<Index>& range_shift) {
702 template <
typename Arg,
typename Index,
703 typename = std::enable_if_t<detail::is_integral_range_v<Index>>>
716 template <
typename Arg,
typename Index,
717 typename = std::enable_if_t<std::is_integral_v<Index>>>
719 const std::initializer_list<Index>& range_shift) {
733 template <
typename Left,
typename Right>
734 inline decltype(
auto)
add(const
Tile<Left>& left, const
Tile<Right>& right) {
748 typename Left,
typename Right,
typename Scalar,
749 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
750 inline decltype(
auto)
add(const
Tile<Left>& left, const
Tile<Right>& right,
751 const Scalar factor) {
764 template <
typename Left,
typename Right,
typename Perm,
765 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
766 inline decltype(
auto)
add(const
Tile<Left>& left, const
Tile<Right>& right,
783 typename Left,
typename Right,
typename Scalar,
typename Perm,
784 typename std::enable_if<detail::is_numeric_v<Scalar> &&
785 detail::is_permutation_v<Perm>>::type* =
nullptr>
786 inline decltype(
auto)
add(const
Tile<Left>& left, const
Tile<Right>& right,
787 const Scalar factor, const Perm& perm) {
799 typename Arg,
typename Scalar,
800 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
801 inline decltype(
auto)
add(const
Tile<Arg>& arg, const Scalar value) {
815 typename Arg,
typename Scalar,
typename Perm,
816 typename std::enable_if<detail::is_numeric_v<Scalar> &&
817 detail::is_permutation_v<Perm>>::type* =
nullptr>
818 inline decltype(
auto)
add(const
Tile<Arg>& arg, const Scalar value,
830 template <
typename Result,
typename Arg>
846 typename Result,
typename Arg,
typename Scalar,
847 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
849 const Scalar factor) {
862 typename Result,
typename Scalar,
863 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
878 template <
typename Left,
typename Right>
879 inline decltype(
auto)
subt(const
Tile<Left>& left, const
Tile<Right>& right) {
892 typename Left,
typename Right,
typename Scalar,
893 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
894 inline decltype(
auto)
subt(const
Tile<Left>& left, const
Tile<Right>& right,
895 const Scalar factor) {
908 template <
typename Left,
typename Right,
typename Perm,
909 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
910 inline decltype(
auto)
subt(const
Tile<Left>& left, const
Tile<Right>& right,
926 typename Left,
typename Right,
typename Scalar,
typename Perm,
927 typename std::enable_if<detail::is_numeric_v<Scalar> &&
928 detail::is_permutation_v<Perm>>::type* =
nullptr>
929 inline decltype(
auto)
subt(const
Tile<Left>& left, const
Tile<Right>& right,
930 const Scalar factor, const Perm& perm) {
941 typename Arg,
typename Scalar,
942 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
943 inline decltype(
auto)
subt(const
Tile<Arg>& arg, const Scalar value) {
956 typename Arg,
typename Scalar,
typename Perm,
957 typename std::enable_if<detail::is_numeric_v<Scalar> &&
958 detail::is_permutation_v<Perm>>::type* =
nullptr>
959 inline decltype(
auto)
subt(const
Tile<Arg>& arg, const Scalar value,
971 template <
typename Result,
typename Arg>
986 typename Result,
typename Arg,
typename Scalar,
987 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
989 const Scalar factor) {
1001 typename Result,
typename Scalar,
1002 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1017 template <
typename Left,
typename Right>
1018 inline decltype(
auto)
mult(const
Tile<Left>& left, const
Tile<Right>& right) {
1031 typename Left,
typename Right,
typename Scalar,
1032 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1033 inline decltype(
auto)
mult(const
Tile<Left>& left, const
Tile<Right>& right,
1034 const Scalar factor) {
1047 template <
typename Left,
typename Right,
typename Perm,
1048 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
1049 inline decltype(
auto)
mult(const
Tile<Left>& left, const
Tile<Right>& right,
1065 typename Left,
typename Right,
typename Scalar,
typename Perm,
1066 typename std::enable_if<detail::is_numeric_v<Scalar> &&
1067 detail::is_permutation_v<Perm>>::type* =
nullptr>
1068 inline decltype(
auto)
mult(const
Tile<Left>& left, const
Tile<Right>& right,
1069 const Scalar factor, const Perm& perm) {
1080 template <
typename Result,
typename Arg>
1095 typename Result,
typename Arg,
typename Scalar,
1096 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1098 const Scalar factor) {
1117 template <
typename Left,
typename Right,
typename Op>
1121 binary(left.tensor(), right.tensor(), std::forward<Op>(op)));
1137 template <
typename Left,
typename Right,
typename Op,
typename Perm,
1138 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
1140 Op&& op, const Perm& perm) {
1142 binary(left.tensor(), right.tensor(), std::forward<Op>(op), perm));
1156 template <
typename Left,
typename Right,
typename Op>
1172 typename Arg,
typename Scalar,
1173 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1174 inline decltype(
auto)
scale(const
Tile<Arg>& arg, const Scalar factor) {
1187 typename Arg,
typename Scalar,
typename Perm,
1188 typename std::enable_if<detail::is_numeric_v<Scalar> &&
1189 detail::is_permutation_v<Perm>>::type* =
nullptr>
1190 inline decltype(
auto)
scale(const
Tile<Arg>& arg, const Scalar factor,
1202 typename Result,
typename Scalar,
1203 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1217 template <
typename Arg>
1230 template <
typename Arg,
typename Perm,
1231 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
1232 inline decltype(
auto)
neg(const
Tile<Arg>& arg, const Perm& perm) {
1242 template <
typename Result>
1255 template <
typename Arg>
1267 template <
typename Arg,
typename Scalar,
1268 typename std::enable_if<
1269 TiledArray::detail::is_numeric_v<Scalar>>::type* =
nullptr>
1270 inline decltype(
auto)
conj(const
Tile<Arg>& arg, const Scalar factor) {
1281 template <
typename Arg,
typename Perm,
1282 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
1283 inline decltype(
auto)
conj(const
Tile<Arg>& arg, const Perm& perm) {
1297 typename Arg,
typename Scalar,
typename Perm,
1298 typename std::enable_if<TiledArray::detail::is_numeric_v<Scalar> &&
1299 detail::is_permutation_v<Perm>>::type* =
nullptr>
1300 inline decltype(
auto)
conj(const
Tile<Arg>& arg, const Scalar factor,
1310 template <
typename Result>
1323 template <
typename Result,
typename Scalar,
1324 typename std::enable_if<
1325 TiledArray::detail::is_numeric_v<Scalar>>::type* =
nullptr>
1343 template <
typename Arg,
typename Op>
1358 template <
typename Arg,
typename Op,
typename Perm,
1359 typename = std::enable_if_t<detail::is_permutation_v<Perm>>>
1360 inline decltype(
auto)
unary(const
Tile<Arg>& arg,
Op&& op, const Perm& perm) {
1373 template <
typename Result,
typename Op>
1394 typename Left,
typename Right,
typename Scalar,
1395 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1396 inline decltype(
auto)
gemm(const
Tile<Left>& left, const
Tile<Right>& right,
1397 const Scalar factor,
1398 const math::GemmHelper& gemm_config) {
1400 gemm(left.tensor(), right.tensor(), factor, gemm_config));
1419 typename Result,
typename Left,
typename Right,
typename Scalar,
1420 typename std::enable_if<detail::is_numeric_v<Scalar>>::type* =
nullptr>
1454 template <
typename Result,
typename Left,
typename Right,
1455 typename ElementMultiplyAddOp,
1456 typename std::enable_if<std::is_invocable_r_v<
1457 void, std::remove_reference_t<ElementMultiplyAddOp>,
1458 typename Result::value_type&,
const typename Left::value_type&,
1459 const typename Right::value_type&>>::type* =
nullptr>
1463 ElementMultiplyAddOp&& element_multiplyadd_op) {
1465 std::forward<ElementMultiplyAddOp>(element_multiplyadd_op));
1476 template <
typename Arg>
1478 return trace(arg.tensor());
1484 template <
typename Arg>
1486 : std::true_type {};
1495 template <
typename Arg>
1497 return sum(arg.tensor());
1505 template <
typename Arg>
1516 template <
typename Arg>
1526 template <
typename Arg>
1528 return norm(arg.tensor());
1538 template <
typename Arg,
typename ResultType>
1548 template <
typename Arg>
1550 return max(arg.tensor());
1558 template <
typename Arg>
1560 return min(arg.tensor());
1568 template <
typename Arg>
1578 template <
typename Arg>
1590 template <
typename Left,
typename Right>
1591 inline decltype(
auto)
dot(const
Tile<Left>& left, const
Tile<Right>& right) {
1592 return dot(left.tensor(), right.tensor());
1601 template <
typename Left,
typename Right>
1603 const
Tile<Right>& right) {
1618 template <
typename T>
1626 template <
typename Allocator,
typename T>
1630 std::declval<TiledArray::Cast<
1631 TiledArray::Tensor<typename T::value_type, Allocator>, T>>()(
1632 std::declval<const T&>()))>> {
1642 template <
typename T1,
typename T2>
1649 template <
typename T1,
typename T2>
1656 #endif // TILEDARRAY_TILE_H__INCLUDED