23 #ifndef TILEDARRAY_MATH_BTAS_H__INCLUDED 24 #define TILEDARRAY_MATH_BTAS_H__INCLUDED 26 #include "TiledArray/config.h" 32 #include <btas/features.h> 33 #include <btas/generic/axpy_impl.h> 34 #include <btas/generic/permute.h> 35 #include <btas/tensor.h> 37 #include <madness/world/archive.h> 51 template <CBLAS_ORDER Order,
typename... Args>
53 const btas::RangeNd<Order, Args...>& range) {
55 "TiledArray::detail::make_ta_range(btas::RangeNd<Order,...>): " 56 "not supported for col-major Order");
65 template <
typename... Args>
67 const btas::BaseRangeNd<Args...>& range2) {
68 const auto rank = range1.
rank();
69 if (rank == range2.rank()) {
72 const auto lobound_match =
73 std::equal(range1_lobound_data, range1_lobound_data + rank,
74 cbegin(range2.lobound()));
77 return std::equal(range1_upbound_data, range1_upbound_data + rank,
78 cbegin(range2.upbound()));
85 template <
typename T,
typename Range,
typename Storage>
87 const btas::Tensor<T, Range, Storage>& arg,
89 btas::Tensor<T, Range, Storage> result;
90 std::vector<size_t> p(perm.
dim());
97 template <
typename T,
typename Range,
typename Storage>
98 void add_to(btas::Tensor<T, Range, Storage>& result,
99 const btas::Tensor<T, Range, Storage>& arg) {
104 template <
typename T,
typename Range,
typename Storage>
105 btas::Tensor<T, Range, Storage>
mult(
106 const btas::Tensor<T, Range, Storage>& arg1,
107 const btas::Tensor<T, Range, Storage>& arg2) {
112 template <
typename T,
typename Range,
typename Storage>
113 btas::Tensor<T, Range, Storage>
mult(
114 const btas::Tensor<T, Range, Storage>& arg1,
115 const btas::Tensor<T, Range, Storage>& arg2,
121 template <
typename T,
typename Range,
typename Storage>
123 btas::Tensor<T, Range, Storage>& result,
124 const btas::Tensor<T, Range, Storage>& arg) {
128 template <
typename T,
typename Range,
typename Storage>
129 btas::Tensor<T, Range, Storage>
gemm(
130 const btas::Tensor<T, Range, Storage>& left,
131 const btas::Tensor<T, Range, Storage>& right, T factor,
140 typedef btas::Tensor<T, Range, Storage> Tensor;
147 std::cbegin(right.range().lobound())));
150 std::cbegin(right.range().upbound())));
152 std::cbegin(left.range().extent()), std::cbegin(right.range().extent())));
155 integer m = 1, n = 1, k = 1;
160 (gemm_helper.
left_op() == madness::cblas::NoTrans ? k : m);
162 (gemm_helper.
right_op() == madness::cblas::NoTrans ? n : k);
165 factor, left.data(), lda, right.data(), ldb, T(0),
171 template <
typename T,
typename Range,
typename Storage>
172 void gemm(btas::Tensor<T, Range, Storage>& result,
173 const btas::Tensor<T, Range, Storage>& left,
174 const btas::Tensor<T, Range, Storage>& right, T factor,
190 std::cbegin(result.range().lobound())));
193 std::cbegin(result.range().upbound())));
196 std::cbegin(result.range().extent())));
201 std::cbegin(right.range().lobound()),
202 std::cbegin(result.range().lobound())));
204 std::cbegin(right.range().upbound()),
205 std::cbegin(result.range().upbound())));
208 std::cbegin(result.range().extent())));
213 std::cbegin(right.range().lobound())));
216 std::cbegin(right.range().upbound())));
218 std::cbegin(left.range().extent()), std::cbegin(right.range().extent())));
226 (gemm_helper.
left_op() == madness::cblas::NoTrans ? k : m);
228 (gemm_helper.
right_op() == madness::cblas::NoTrans ? n : k);
231 factor, left.data(), lda, right.data(), ldb, T(1),
238 template <
typename T,
typename Range,
typename Storage>
239 typename btas::Tensor<T, Range, Storage>::value_type
trace(
240 const btas::Tensor<T, Range, Storage>& arg);
242 template <
typename T,
typename Range,
typename Storage>
243 typename btas::Tensor<T, Range, Storage>::value_type
sum(
244 const btas::Tensor<T, Range, Storage>& arg);
246 template <
typename T,
typename Range,
typename Storage>
247 typename btas::Tensor<T, Range, Storage>::value_type
product(
248 const btas::Tensor<T, Range, Storage>& arg);
252 template <
typename T,
typename Range,
typename Storage>
254 const btas::Tensor<T, Range, Storage>& arg) {
255 integer
size = arg.size();
262 template <
typename T,
typename Range,
typename Storage>
263 typename btas::Tensor<T, Range, Storage>::value_type
norm(
264 const btas::Tensor<T, Range, Storage>& arg);
266 template <
typename T,
typename Range,
typename Storage>
267 typename btas::Tensor<T, Range, Storage>::value_type
max(
268 const btas::Tensor<T, Range, Storage>& arg);
270 template <
typename T,
typename Range,
typename Storage>
271 typename btas::Tensor<T, Range, Storage>::value_type
min(
272 const btas::Tensor<T, Range, Storage>& arg);
274 template <
typename T,
typename Range,
typename Storage>
275 typename btas::Tensor<T, Range, Storage>::value_type
abs_max(
276 const btas::Tensor<T, Range, Storage>& arg);
278 template <
typename T,
typename Range,
typename Storage>
279 typename btas::Tensor<T, Range, Storage>::value_type
abs_min(
280 const btas::Tensor<T, Range, Storage>& arg);
284 template <
typename Perm>
295 template <
typename T,
typename... Args>
298 template <
typename T,
typename... Args>
300 :
public std::true_type {};
307 template <
typename T,
typename Allocator,
typename Range_,
typename Storage>
309 btas::Tensor<T, Range_, Storage>> {
310 auto operator()(
const btas::Tensor<T, Range_, Storage>& arg)
const {
313 std::copy(btas::cbegin(arg), btas::cend(arg), begin(result));
322 #ifdef BTAS_HAS_BOOST_CONTAINER 323 template <
class Archive,
typename T, std::
size_t N,
typename A>
324 struct ArchiveLoadImpl<Archive, boost::container::small_vector<T, N, A>> {
325 static inline void load(
const Archive& ar,
326 boost::container::small_vector<T, N, A>& x) {
330 for (
auto& xi : x) ar& xi;
334 template <
class Archive,
typename T, std::
size_t N,
typename A>
335 struct ArchiveStoreImpl<Archive, boost::container::small_vector<T, N, A>> {
336 static inline void store(
const Archive& ar,
337 const boost::container::small_vector<T, N, A>& x) {
339 for (
const auto& xi : x) ar& xi;
344 template <
class Archive,
typename T>
345 struct ArchiveLoadImpl<Archive,
btas::varray<T>> {
346 static inline void load(
const Archive& ar, btas::varray<T>& x) {
347 typename btas::varray<T>::size_type n{};
350 for (
typename btas::varray<T>::value_type& xi : x) ar& xi;
354 template <
class Archive,
typename T>
355 struct ArchiveStoreImpl<Archive,
btas::varray<T>> {
356 static inline void store(
const Archive& ar,
const btas::varray<T>& x) {
358 for (
const typename btas::varray<T>::value_type& xi : x) ar& xi;
362 template <
class Archive, CBLAS_ORDER _Order,
typename _Index>
363 struct ArchiveLoadImpl<Archive,
btas::BoxOrdinal<_Order, _Index>> {
364 static inline void load(
const Archive& ar,
365 btas::BoxOrdinal<_Order, _Index>& o) {
366 typename btas::BoxOrdinal<_Order, _Index>::stride_type stride{};
367 typename btas::BoxOrdinal<_Order, _Index>::value_type offset{};
369 ar& stride& offset& cont;
370 o = btas::BoxOrdinal<_Order, _Index>(std::move(stride), std::move(offset),
375 template <
class Archive, CBLAS_ORDER _Order,
typename _Index>
376 struct ArchiveStoreImpl<Archive,
btas::BoxOrdinal<_Order, _Index>> {
377 static inline void store(
const Archive& ar,
378 const btas::BoxOrdinal<_Order, _Index>& o) {
379 ar& o.stride() & o.offset() & o.contiguous();
383 template <
class Archive, CBLAS_ORDER _Order,
typename _Index,
typename _Ordinal>
384 struct ArchiveLoadImpl<Archive,
btas::RangeNd<_Order, _Index, _Ordinal>> {
385 static inline void load(
const Archive& ar,
386 btas::RangeNd<_Order, _Index, _Ordinal>& r) {
387 typedef typename btas::BaseRangeNd<
388 btas::RangeNd<_Order, _Index, _Ordinal>>::index_type index_type;
389 index_type lobound{}, upbound{};
391 ar& lobound& upbound& ordinal;
392 r = btas::RangeNd<_Order, _Index, _Ordinal>(
393 std::move(lobound), std::move(upbound), std::move(ordinal));
397 template <
class Archive, CBLAS_ORDER _Order,
typename _Index,
typename _Ordinal>
398 struct ArchiveStoreImpl<Archive,
btas::RangeNd<_Order, _Index, _Ordinal>> {
399 static inline void store(
const Archive& ar,
400 const btas::RangeNd<_Order, _Index, _Ordinal>& r) {
401 ar& r.lobound() & r.upbound() & r.ordinal();
405 template <
class Archive,
typename _T,
class _Range,
class _Store>
406 struct ArchiveLoadImpl<Archive,
btas::Tensor<_T, _Range, _Store>> {
407 static inline void load(
const Archive& ar,
408 btas::Tensor<_T, _Range, _Store>& t) {
412 t = btas::Tensor<_T, _Range, _Store>(std::move(range), std::move(store));
416 template <
class Archive,
typename _T,
class _Range,
class _Store>
417 struct ArchiveStoreImpl<Archive,
btas::Tensor<_T, _Range, _Store>> {
418 static inline void store(
const Archive& ar,
419 const btas::Tensor<_T, _Range, _Store>& t) {
420 ar& t.range() & t.storage();
btas::Tensor< T, Range, Storage > gemm(const btas::Tensor< T, Range, Storage > &left, const btas::Tensor< T, Range, Storage > &right, T factor, const TiledArray::math::GemmHelper &gemm_helper)
static void load(const Archive &ar, btas::RangeNd< _Order, _Index, _Ordinal > &r)
A (hyperrectangular) interval on , space of integer n-indices.
static void load(const Archive &ar, btas::BoxOrdinal< _Order, _Index > &o)
void compute_matrix_sizes(integer &m, integer &n, integer &k, const Left &left, const Right &right) const
Compute the matrix dimension that can be used in a *GEMM call.
static void load(const Archive &ar, btas::Tensor< _T, _Range, _Store > &t)
bool left_result_congruent(const Left &left, const Result &result) const
Test that the outer dimensions of left are congruent (have equal extent) with that of the result tens...
btas::Tensor< T, Range, Storage >::value_type abs_min(const btas::Tensor< T, Range, Storage > &arg)
An N-dimensional tensor object.
bool right_result_congruent(const Right &right, const Result &result) const
Test that the outer dimensions of right are congruent (have equal extent) with that of the result ten...
const_iterator end() const
End element iterator factory function.
madness::cblas::CBLAS_TRANSPOSE right_op() const
bool left_right_congruent(const Left &left, const Right &right) const
Test that the inner dimensions of left are congruent (have equal extent) with that of right...
btas::Tensor< T, Range, Storage > permute(const btas::Tensor< T, Range, Storage > &arg, const TiledArray::Permutation &perm)
Computes the result of applying permutation perm to arg.
static void store(const Archive &ar, const btas::varray< T > &x)
unsigned int result_rank() const
Result rank accessor.
unsigned int rank() const
Rank accessor.
R make_result_range(const Left &left, const Right &right) const
Construct a result range based on left and right ranges.
btas::Tensor< T, Range, Storage >::value_type squared_norm(const btas::Tensor< T, Range, Storage > &arg)
size_t size(const DistArray< Tile, Policy > &a)
const size_type * upbound_data() const
Range upper bound data accessor.
index_type dim() const
Domain size accessor.
static void store(const Archive &ar, const btas::Tensor< _T, _Range, _Store > &t)
btas::Tensor< T, Range, Storage >::value_type min(const btas::Tensor< T, Range, Storage > &arg)
btas::Tensor< T, Range, Storage >::value_type abs_max(const btas::Tensor< T, Range, Storage > &arg)
btas::Tensor< T, Range, Storage >::value_type norm(const btas::Tensor< T, Range, Storage > &arg)
static void store(const Archive &ar, const btas::RangeNd< _Order, _Index, _Ordinal > &r)
btas::Tensor< T, Range, Storage > mult(const btas::Tensor< T, Range, Storage > &arg1, const btas::Tensor< T, Range, Storage > &arg2)
result[i] = arg1[i] * arg2[i]
void axpy(DistArray< Tile, Policy > &y, typename DistArray< Tile, Policy >::element_type a, const DistArray< Tile, Policy > &x)
auto operator()(const btas::Tensor< T, Range_, Storage > &arg) const
DistArray< Tile, Policy > copy(const DistArray< Tile, Policy > &a)
btas::Tensor< T, Range, Storage >::value_type sum(const btas::Tensor< T, Range, Storage > &arg)
static void store(const Archive &ar, const btas::BoxOrdinal< _Order, _Index > &o)
unsigned int right_rank() const
Right-hand argument rank accessor.
T dot(const integer n, const T *x, const U *y)
void gemm(madness::cblas::CBLAS_TRANSPOSE op_a, madness::cblas::CBLAS_TRANSPOSE op_b, const integer m, const integer n, const integer k, const S1 alpha, const T1 *a, const integer lda, const T2 *b, const integer ldb, const S2 beta, T3 *c, const integer ldc)
Contraction to *GEMM helper.
Permutation of a sequence of objects indexed by base-0 indices.
const size_type * lobound_data() const
Range lower bound data accessor.
const TiledArray::Range & make_ta_range(const TiledArray::Range &range)
void add_to(btas::Tensor< T, Range, Storage > &result, const btas::Tensor< T, Range, Storage > &arg)
result[i] += arg[i]
btas::Tensor< T, Range, Storage >::value_type max(const btas::Tensor< T, Range, Storage > &arg)
madness::cblas::CBLAS_TRANSPOSE left_op() const
TiledArray::Range permute(const TiledArray::Range &r, const Perm &p)
#define TA_USER_ASSERT(a, m)
btas::Tensor< T, Range, Storage >::value_type trace(const btas::Tensor< T, Range, Storage > &arg)
btas::Tensor< T, Range, Storage > & mult_to(btas::Tensor< T, Range, Storage > &result, const btas::Tensor< T, Range, Storage > &arg)
result[i] *= arg[i]
const_iterator begin() const
Begin element iterator factory function.
static void load(const Archive &ar, btas::varray< T > &x)
unsigned int left_rank() const
Left-hand argument rank accessor.
btas::Tensor< T, Range, Storage >::value_type product(const btas::Tensor< T, Range, Storage > &arg)
bool operator==(const TiledArray::Range &range1, const btas::BaseRangeNd< Args... > &range2)