20 #ifndef TILEDARRAY_ARRAY_H__INCLUDED 21 #define TILEDARRAY_ARRAY_H__INCLUDED 37 template <
typename,
typename>
class Tensor;
38 namespace expressions {
50 template <
typename Tile = Tensor<
double, Eigen::aligned_allocator<
double> >,
51 typename Policy = DensePolicy>
62 typedef typename impl_type::range_type::index
index;
75 std::shared_ptr<impl_type> pimpl_;
77 static madness::AtomicInt cleanup_counter_;
84 static void lazy_deleter(
const impl_type*
const pimpl) {
86 if(madness::initialized()) {
88 const madness::uniqueidT
id = pimpl->
id();
92 world.gop.lazy_sync(
id, [pimpl]() {
94 DistArray_::cleanup_counter_--;
97 catch(madness::MadnessException& e) {
98 fprintf(stderr,
"!! ERROR TiledArray: madness::MadnessException thrown in Array::lazy_deleter().\n" 100 "!! ERROR TiledArray: The exception has been absorbed.\n" 101 "!! ERROR TiledArray: rank=%i\n", e.what(),
world.rank());
106 catch(std::exception& e) {
107 fprintf(stderr,
"!! ERROR TiledArray: std::exception thrown in Array::lazy_deleter().\n" 109 "!! ERROR TiledArray: The exception has been absorbed.\n" 110 "!! ERROR TiledArray: rank=%i\n", e.what(),
world.rank());
116 fprintf(stderr,
"!! ERROR TiledArray: An unknown exception was thrown in Array::lazy_deleter().\n" 117 "!! ERROR TiledArray: The exception has been absorbed.\n" 118 "!! ERROR TiledArray: rank=%i\n",
world.rank());
135 static std::shared_ptr<impl_type>
137 std::shared_ptr<pmap_interface>
pmap)
147 "Array::Array() -- The size of the process map is not equal to the number of tiles in the TiledRange object.");
149 "Array::Array() -- The rank of the process map is not equal to that of the world object.");
151 "Array::Array() -- The number of processes in the process map is not equal to that of the world object.");
156 "Array::Array() -- The shape is not initialized.");
158 "Array::Array() -- The range of the shape is not equal to the tiles range.");
188 const std::shared_ptr<pmap_interface>&
pmap = std::shared_ptr<pmap_interface>()) :
202 const std::shared_ptr<pmap_interface>&
pmap = std::shared_ptr<pmap_interface>()) :
212 template <
typename OtherTile,
typename = std::enable_if_t<not std::is_same<DistArray_,DistArray<OtherTile,Policy>>::value>>
226 template <
typename OtherTile,
typename Op>
230 *
this = foreach<Tile,OtherTile,Op>(other, std::forward<Op>(op));
260 world.await([&]() {
return (cleanup_counter_ == 0); },
true);
262 printf(
"%i: Array lazy cleanup timeout with %i pending cleanup(s)\n",
263 world.rank(), int(cleanup_counter_));
273 pimpl_ = other.pimpl_;
283 madness::uniqueidT
id()
const {
return pimpl_->id(); }
290 return pimpl_->begin();
298 return pimpl_->cbegin();
306 return pimpl_->end();
314 return pimpl_->cend();
323 template <
typename Index>
324 Future<value_type>
find(
const Index& i)
const {
326 return pimpl_->get(i);
335 template <
typename Integer>
336 Future<value_type>
find(
const std::initializer_list<Integer>& i)
const {
337 return find<std::initializer_list<Integer>>(i);
346 template <
typename Index,
typename InIter>
347 typename std::enable_if<detail::is_input_iterator<InIter>::value>::type
348 set(
const Index& i, InIter first) {
350 pimpl_->set(i,
value_type(pimpl_->trange().make_tile_range(i), first));
359 template <
typename Integer,
typename InIter>
360 typename std::enable_if<detail::is_input_iterator<InIter>::value>::type
361 set(
const std::initializer_list<Integer>& i, InIter first) {
362 set<std::initializer_list<Integer>>(i, first);
371 template <
typename Index>
374 pimpl_->set(i,
value_type(pimpl_->trange().make_tile_range(i), value));
383 template <
typename Integer>
384 void set(
const std::initializer_list<Integer>& i,
386 set<std::initializer_list<Integer>>(i, value);
394 template <
typename Index>
395 void set(
const Index& i,
const Future<value_type>& f) {
405 template <
typename Integer>
406 void set(
const std::initializer_list<Integer>& i,
407 const Future<value_type>& f) {
408 set<std::initializer_list<Integer>>(i, f);
416 template <
typename Index>
427 template <
typename Integer>
428 void set(
const std::initializer_list<Integer>& i,
const value_type& v) {
429 set<std::initializer_list<Integer>>(i, v);
487 template <
typename Op>
491 auto it = pimpl_->pmap()->begin();
492 const auto end = pimpl_->pmap()->end();
493 for(; it !=
end; ++it) {
494 const auto index = *it;
495 if(! pimpl_->is_zero(
index)) {
501 Future<value_type> tile = pimpl_->world().taskq.add(
503 {
return op(array->
trange().make_tile_range(
index)); },
529 template <
typename Op>
537 for(
auto& idx:
range)
549 return pimpl_->trange();
557 return pimpl_->tiles_range();
570 return pimpl_->trange().elements_range();
575 return pimpl_->size();
585 const unsigned int n = 1u + std::count_if(vars.begin(), vars.end(),
586 [](
const char c) {
return c ==
','; });
587 if(
bool(pimpl_) && n != pimpl_->trange().tiles_range().rank()) {
588 if(TiledArray::get_default_world().rank() == 0) {
590 "The number of array annotation variables is not equal to the array dimension:" \
591 <<
"\n number of variables = " << n \
592 <<
"\n array dimension = " << pimpl_->trange().tiles_range().rank() );
595 TA_EXCEPTION(
"The number of array annotation variables is not equal to the array dimension.");
608 const unsigned int n = 1u + std::count_if(vars.begin(), vars.end(),
609 [](
const char c) {
return c ==
','; });
610 if(
bool(pimpl_) && n != pimpl_->trange().tiles_range().rank()) {
611 if(TiledArray::get_default_world().rank() == 0) {
613 "The number of array annotation variables is not equal to the array dimension:" \
614 <<
"\n number of variables = " << n \
615 <<
"\n array dimension = " << pimpl_->trange().tiles_range().rank() );
618 TA_EXCEPTION(
"The number of array annotation variables is not equal to the array dimension.");
627 return pimpl_->world();
635 return pimpl_->world();
641 return pimpl_->pmap();
647 const std::shared_ptr<pmap_interface>&
pmap()
const {
649 return pimpl_->pmap();
657 return pimpl_->is_dense();
677 template <
typename Index>
678 ProcessID
owner(
const Index& i)
const {
680 return pimpl_->owner(i);
690 template <
typename Index1>
691 ProcessID
owner(
const std::initializer_list<Index1>& i)
const {
692 return owner<std::initializer_list<Index1>>(i);
701 template <
typename Index>
704 return pimpl_->is_local(i);
713 template <
typename Index1>
714 bool is_local(
const std::initializer_list<Index1>& i)
const {
715 return is_local<std::initializer_list<Index1>>(i);
722 template <
typename Index>
725 return pimpl_->is_zero(i);
732 template <
typename Index1>
733 bool is_zero(
const std::initializer_list<Index1>& i)
const {
734 return is_zero<std::initializer_list<Index1>>(i);
745 if((! pimpl_->pmap()->is_replicated()) && (
world().size() > 1)) {
747 auto pmap = std::make_shared<detail::ReplicatedPmap>(
world(),
size());
753 std::make_shared<detail::Replicator<DistArray_>>(*
this, result);
758 madness::detail::deferred_cleanup(
world(), replicator);
777 template <
typename Index>
778 typename std::enable_if<std::is_integral<Index>::value>::type
779 check_index(
const Index i)
const {
782 "The ordinal index used to access an array tile is out of range.");
785 template <
typename Index>
786 typename std::enable_if<! std::is_integral<Index>::value>::type
787 check_index(
const Index& i)
const {
790 "The coordinate index used to access an array tile is out of range.");
792 "The number of elements in the coordinate index does not match the dimension of the array.");
795 template <
typename Index1>
796 void check_index(
const std::initializer_list<Index1>& i)
const {
797 check_index<std::initializer_list<Index1>>(i);
801 void check_pimpl()
const {
803 "The Array has not been initialized, likely reason: it was default constructed and used.");
809 template <
typename Tile,
typename Policy>
810 madness::AtomicInt DistArray<Tile, Policy>::cleanup_counter_;
812 #ifndef TILEDARRAY_HEADER_ONLY 815 class DistArray<Tensor<double, Eigen::aligned_allocator<double> >, DensePolicy>;
817 class DistArray<Tensor<float, Eigen::aligned_allocator<float> >, DensePolicy>;
819 class DistArray<Tensor<int, Eigen::aligned_allocator<int> >, DensePolicy>;
821 class DistArray<Tensor<long, Eigen::aligned_allocator<long> >, DensePolicy>;
828 class DistArray<Tensor<double, Eigen::aligned_allocator<double> >, SparsePolicy>;
830 class DistArray<Tensor<float, Eigen::aligned_allocator<float> >, SparsePolicy>;
832 class DistArray<Tensor<int, Eigen::aligned_allocator<int> >, SparsePolicy>;
834 class DistArray<Tensor<long, Eigen::aligned_allocator<long> >, SparsePolicy>;
840 #endif // TILEDARRAY_HEADER_ONLY 852 template <
typename Tile,
typename Policy>
853 inline std::ostream& operator<<(std::ostream& os, const DistArray<Tile, Policy>& a) {
854 if(a.world().rank() == 0) {
855 for(std::size_t i = 0; i < a.size(); ++i)
858 os << i <<
": " << tile <<
"\n";
861 a.world().gop.fence();
867 #endif // TILEDARRAY_ARRAY_H__INCLUDED DEPRECATED const trange_type::range_type & elements() const
TensorImpl_::range_type range_type
Elements/tiles range type.
TensorImpl_::shape_type shape_type
Shape type.
Distributed tensor iterator.
A (hyperrectangular) interval on , space of integer n-indices.
static void wait_for_lazy_cleanup(World &world, const double=60.0)
Wait for lazy tile cleanup.
Future< value_type > find(const Index &i) const
Find local or remote tile.
impl_type::shape_type shape_type
Shape type for array tiling.
void swap(DistArray_ &other)
Swap this array with other.
An N-dimensional tensor object.
const_iterator begin() const
Begin const iterator factory function.
void truncate(DistArray< Tile, DensePolicy > &array)
Truncate a dense Array.
void swap(Bitset< B > &b0, Bitset< B > &b1)
eval_trait< Tile >::type eval_type
The tile evaluation type.
const shape_type & shape() const
Shape accessor.
const trange_type & trange() const
Tiled range accessor.
TiledArray::expressions::TsrExpr< const DistArray_, true > operator()(const std::string &vars) const
Create a tensor expression.
impl_type::range_type range_type
Elements/tiles range type.
Type trait for extracting the numeric type of tensors and arrays.
ProcessID owner(const Index &i) const
Tile ownership.
TensorImpl_::size_type size_type
Size type.
DistArray(const DistArray< OtherTile, Policy > &other, Op &&op)
Unary transform constructor.
void make_replicated()
Convert a distributed array into a replicated array.
impl_type::const_iterator const_iterator
Local tile const iterator.
bool is_local(const std::initializer_list< Index1 > &i) const
Check if the tile at index i is stored locally.
bool is_initialized() const
Check if the array is initialized.
Type trait for extracting the scalar type of tensors and arrays.
DistArray()
Default constructor.
DistArray< Tile, Policy > DistArray_
This object's type.
impl_type::pmap_interface pmap_interface
Process map interface type.
Expression wrapper for array objects.
impl_type::value_type value_type
Tile type.
DistArray< Tile, Policy > clone(const DistArray< Tile, Policy > &arg)
Create a deep copy of an array.
DistArray(World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap=std::shared_ptr< pmap_interface >())
Sparse array constructor.
const trange_type::range_type & elements_range() const
Element range accessor.
TensorImpl_::trange_type trange_type
Tiled range type for this object.
impl_type::range_type::index index
Array coordinate index type.
bool is_zero(const Index &i) const
Check for zero tiles.
void fill_local(const element_type &value=element_type(), bool skip_set=false)
Fill all local tiles.
DistArray(World &world, const trange_type &trange, const std::shared_ptr< pmap_interface > &pmap=std::shared_ptr< pmap_interface >())
Dense array constructor.
DEPRECATED const std::shared_ptr< pmap_interface > & get_pmap() const
DEPRECATED const shape_type & get_shape() const
Tensor implementation and base for other tensor implementation objects.
void fill_random(bool skip_set=false)
impl_type::iterator iterator
Local tile iterator.
detail::scalar_type< Tile >::type scalar_type
The tile scalar type.
World & world() const
World accessor.
const_iterator end() const
End const iterator factory function.
TensorImpl_::policy_type policy_type
Policy type for this object.
TensorImpl_::pmap_interface pmap_interface
process map interface type
const madness::uniqueidT & id() const
Unique object id accessor.
impl_type::reference future
Future of value_type.
impl_type::policy_type policy_type
Policy type.
bool is_local(const Index &i) const
Check if the tile at index i is stored locally.
DistArray(const DistArray_ &other)
Copy constructor.
impl_type::trange_type trange_type
Tile range type.
TiledArray::detail::ArrayImpl< Tile, Policy > impl_type
DistArray(const DistArray< OtherTile, Policy > &other)
converting copy constructor
impl_type::size_type size_type
Size type.
iterator begin()
Begin iterator factory function.
DEPRECATED World & get_world() const
Future< value_type > find(const std::initializer_list< Integer > &i) const
Find local or remote tile.
DistArray_ clone() const
Create a deep copy of this array.
void init_tiles(Op &&op, bool skip_set=false)
Initialize (local) tiles with a user provided functor.
DistArray_ & operator=(const DistArray_ &other)
Copy constructor.
ProcessID owner(const std::initializer_list< Index1 > &i) const
Tile ownership.
iterator end()
End iterator factory function.
#define TA_USER_ASSERT(a, m)
World & world() const
World accessor.
bool is_zero(const std::initializer_list< Index1 > &i) const
Check for zero tiles.
const range_type & range() const
Tile range accessor.
detail::numeric_type< Tile >::type element_type
The tile element type.
impl_type::eval_type eval_type
The tile evaluation type.
void truncate()
Update shape data and remove tiles that are below the zero threshold.
impl_type::const_reference const_reference
future type
void init_elements(Op &&op, bool skip_set=false)
Initialize (local) elements with a user provided functor.
void fill(const element_type &value=element_type(), bool skip_set=false)
Fill all local tiles.
An N-dimensional shallow copy wrapper for tile objects.
madness::uniqueidT id() const
Global object id.
#define TA_USER_ERROR_MESSAGE(m)
impl_type::reference reference
future type
bool is_dense() const
Check dense/sparse.
const std::shared_ptr< pmap_interface > & pmap() const
Process map accessor.