distributed container
Description
This class provides a std::vector
like container for a distributed memory model array.
The disarray
interface is similar to those of the std::vector
with the addition of some communication features for a distributed memory model.
Example
int main (int argc, char**argv) {
environment distributed(argc, argv);
distributor ownership (100);
disarray<double> x (ownership, 3.14);
dout << x << endl;
}
Notation
There are two kind of indexes:
dis_i
This index refers to the complete array. It is valid on all processes.
i
This index refers to the subset of the array that is owned by the current process. It is valid only on the local process.
Read and write accessors to the subset of the array that is owned by the current process are still denoted by square brackets, e.g. value = x[i]
and x[i] = value
, respectively.
Read and write accessors to the complete array, including array subsets that are owned by some others processors, are introduced with the help of new member functions:
x.dis_entry(dis_i) = value
write access at any location
value = x.dis_at(dis_i)
read access at any location
In order to optimize communications, they should be grouped.
Grouped writes
Loop on any dis_i
and write your value:
for (...) {
x.dis_entry (dis_i) = value;
}
Finally, perform all communications in one pass:
x.dis_entry_assembly();
After this command, each value is stored in x
, at its right place, depending on dis_i
and its ownership
. Note that, when dis_i
is owned by the current process, the value is directly written as x[i] = value
and no communication are generated.
Grouped reads
First, define the set of indexes that you want to access:
std::set<size_t> dis_i_set;
Then, loop on dis_i
all these indexes and append it to this set:
for (...) {
dis_i_set.insert (dis_i);
}
Next, perform communications:
x.set_dis_indexes (dis_i_set);
After this command, each values associated to the dis_i
index, and that belongs to the index set, is also available also on the current processor:
for (...) {
value = x.dis_at (dis_i);
}
Note that, when dis_i
is owned by the current process, the value is directly read as value = x[i]
and no communication are generated.
Template parameters
Recall that the std::class
that takes two template parameters, a T
one for the stored elements and a A
one for the memory allocator, the present disarray
class take three template parameters:
T
: the stored object type
M
: the memory model, i.e. sequential
or distributed
, by default default_memory_model
with is defined at the Configuration stage
A
: the memory allocator, by default std::allocator
Constructor
In the sequential
case, the class interface provides a simplified constructor:
int local_size = 100;
disarray<double,sequential> x (local_size, init_val);
This declaration is similar to those of a std::vector
one: no communications are possible. In order to enable communication, your have to replace the local_size
by information on how the array is distributed in memory:
distributor ownership (100);
disarray<double> x (ownership, 3.14);
The distributor
class does this job.
Implementation
This documentation has been generated from file linalg/lib/disarray.h
template <class T, class A>
class disarray<
T,distributed,
A> :
public smart_pointer<disarray_rep<T,distributed,A> > {
public:
typedef disarray_rep<T,distributed,A>
rep;
typedef smart_pointer<rep> base;
typedef typename rep::scatter_map_type scatter_map_type;
disarray (
const distributor& ownership = distributor(),
const T& init_val =
T(),
const A& alloc =
A());
void resize (
const distributor& ownership = distributor(),
const T& init_val =
T());
A get_allocator()
const {
return base::data().get_allocator(); }
size_type size ()
const {
return base::data().size(); }
size_type dis_size ()
const {
return base::data().dis_size(); }
const distributor& ownership() const { return base::data().ownership(); }
const communicator& comm()
const {
return base::data().comm(); }
reference operator[] (
size_type i) {
return base::data().operator[] (i); }
const_reference operator[] (
size_type i)
const {
return base::data().operator[] (i); }
iterator begin() {
return base::data().begin(); }
iterator end() {
return base::data().end(); }
template<class Set, class Map>
void append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const { base::data().append_dis_entry (ext_idx_set, ext_idx_map); }
template<class Set, class Map>
void get_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const { base::data().get_dis_entry (ext_idx_set, ext_idx_map); }
template<class Set>
void append_dis_indexes (const Set& ext_idx_set) const { base::data().append_dis_indexes (ext_idx_set); }
void reset_dis_indexes() const { base::data().reset_dis_indexes(); }
void get_dis_indexes (std::set<size_type>& ext_idx_set) const { base::data().get_dis_indexes (ext_idx_set); }
template<class Set>
void set_dis_indexes (const Set& ext_idx_set) const { base::data().set_dis_indexes (ext_idx_set); }
const T& dis_at (
size_type dis_i)
const {
return base::data().dis_at (dis_i); }
const scatter_map_type& get_dis_map_entries() const { return base::data().get_dis_map_entries(); }
dis_reference dis_entry (
size_type dis_i) {
return base::data().dis_entry(dis_i); }
template<class SetOp = typename details::default_set_op_traits<T>::type>
void dis_entry_assembly_begin (SetOp my_set_op = SetOp()) { base::data().dis_entry_assembly_begin (my_set_op); }
template<class SetOp = typename details::default_set_op_traits<T>::type>
void dis_entry_assembly_end (SetOp my_set_op = SetOp()) { base::data().dis_entry_assembly_end (my_set_op); }
template<class SetOp = typename details::default_set_op_traits<T>::type>
void dis_entry_assembly (SetOp my_set_op = SetOp()) { base::data().dis_entry_assembly (my_set_op); }
void dis_entry_assembly_begin() { base::data().template dis_entry_assembly_begin<typename details::default_set_op_traits<T>::type>(); }
void dis_entry_assembly_end() { base::data().template dis_entry_assembly_end<typename details::default_set_op_traits<T>::type>(); }
void dis_entry_assembly() { dis_entry_assembly_begin(); dis_entry_assembly_end(); }
template<class RepSize>
void repartition (
const RepSize& partition,
disarray<T,distributed>& new_disarray,
RepSize& old_numbering,
RepSize& new_numbering) const
{ return base::data().repartition (partition.data(), new_disarray.data(), old_numbering.data(), new_numbering.data()); }
template<class RepSize>
void permutation_apply (
const RepSize& new_numbering,
disarray<T,distributed,A>& new_disarray) const
{ base::data().permutation_apply (new_numbering.data(), new_disarray.data()); }
void reverse_permutation (
disarray<size_type,distributed,A>& inew2dis_iold) const
{ base::data().reverse_permutation (inew2dis_iold.data()); }
odiststream& put_values (odiststream& ops) const { return base::data().put_values(ops); }
idiststream& get_values (idiststream& ips) { return base::data().get_values(ips); }
void dump (std::string name)
const {
return base::data().dump(name); }
template <class GetFunction>
idiststream& get_values (idiststream& ips, GetFunction get_element) { return base::data().get_values(ips, get_element); }
template <class PutFunction>
odiststream& put_values (odiststream& ops, PutFunction put_element) const { return base::data().put_values(ops, put_element); }
template <class PutFunction, class A2> odiststream& permuted_put_values (
odiststream& ops, const disarray<size_type,distributed,A2>& perm, PutFunction put_element) const
{ return base::data().permuted_put_values (ops, perm.data(), put_element); }
};
field::size_type size_type
see the communicator page for the full documentation
base::size_type size_type
base::const_reference const_reference
base::const_iterator const_iterator
A::difference_type difference_type
base::reference reference
disarray_rep< T, sequential, A > rep
rep::base::const_iterator const_iterator
rep::base::iterator iterator
rep::base::size_type size_type
verbose clean transpose logscale grid shrink ball stereo iso volume skipvtk deformation fastfieldload lattice reader_on_stdin color format format format format format format format format format format format format format format format format format format dump
t operator()(const t &a, const t &b)