.TH "disarray" 4rheolef "Sat Mar 13 2021" "Version 7.1" "rheolef" \" -*- nroff -*- .ad l .nh .SH NAME disarray \- distributed container (rheolef-7\&.1) .SH "DESCRIPTION" .PP This class provides a \fCstd::vector\fP like container for a distributed memory model array\&. .PP The \fCdisarray\fP interface is similar to those of the \fCstd::vector\fP with the addition of some communication features for a distributed memory model\&. .SH "EXAMPLE" .PP .PP .nf int main (int argc, char**argv) { environment distributed(argc, argv); distributor ownership (100); disarray x (ownership, 3.14); dout << x << endl; } .fi .PP .SH "NOTATION" .PP There are two kind of indexes: .PP \fCdis_i\fP .PP .RS 4 This index refers to the complete array\&. It is valid on all processes\&. .RE .PP \fCi\fP .PP .RS 4 This index refers to the subset of the array that is owned by the current process\&. It is valid only on the local process\&. .RE .PP 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\&. \fCvalue = x[i]\fP and \fCx[i] = value\fP, respectively\&. .PP 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: .PP \fCx\&.dis_entry(dis_i) = value\fP .PP .RS 4 write access at any location .RE .PP \fCvalue = x\&.dis_at(dis_i)\fP .PP .RS 4 read access at any location .RE .PP In order to optimize communications, they should be grouped\&. .SH "GROUPED WRITES" .PP Loop on any \fCdis_i\fP and write your value: .PP .nf for (...) { x.dis_entry (dis_i) = value; } .fi .PP Finally, perform all communications in one pass: .PP .nf x.dis_entry_assembly(); .fi .PP After this command, each value is stored in \fCx\fP, at its right place, depending on \fCdis_i\fP and its \fCownership\fP\&. Note that, when \fCdis_i\fP is owned by the current process, the value is directly written as \fCx[i] = value\fP and no communication are generated\&. .SH "GROUPED READS" .PP First, define the set of indexes that you want to access: .PP .nf std::set dis_i_set; .fi .PP Then, loop on \fCdis_i\fP all these indexes and append it to this set: .PP .nf for (...) { dis_i_set.insert (dis_i); } .fi .PP Next, perform communications: .PP .nf x.set_dis_indexes (dis_i_set); .fi .PP After this command, each values associated to the \fCdis_i\fP index, and that belongs to the index set, is also available also on the current processor: .PP .nf for (...) { value = x.dis_at (dis_i); } .fi .PP Note that, when \fCdis_i\fP is owned by the current process, the value is directly read as \fCvalue = x[i]\fP and no communication are generated\&. .SH "TEMPLATE PARAMETERS" .PP Recall that the \fCstd::class\fP that takes two template parameters, a \fCT\fP one for the stored elements and a \fCA\fP one for the memory allocator, the present \fCdisarray\fP class take three template parameters: .PP .IP "\(bu" 2 \fCT\fP: the stored object type .IP "\(bu" 2 \fCM\fP: the memory model, i\&.e\&. \fCsequential\fP or \fCdistributed\fP, by default \fCdefault_memory_model\fP with is defined at the \fBconfiguration\fP stage .IP "\(bu" 2 \fCA\fP: the memory allocator, by default \fCstd::allocator\fP .PP .SH "CONSTRUCTOR" .PP In the \fCsequential\fP case, the class interface provides a simplified constructor: .PP .nf int local_size = 100; disarray x (local_size, init_val); .fi .PP This declaration is similar to those of a \fCstd::vector\fP one: no communications are possible\&. In order to enable communication, your have to replace the \fClocal_size\fP by information on how the array is distributed in memory: .PP .nf distributor ownership (100); disarray x (ownership, 3.14); .fi .PP The \fBdistributor(4)\fP class does this job\&. .SH "IMPLEMENTATION" .PP This documentation has been generated from file linalg/lib/disarray\&.h .PP .PP .nf template class disarray : public smart_pointer > { public: // typedefs: typedef disarray_rep rep; typedef smart_pointer base; typedef distributed memory_type; typedef typename rep::size_type size_type; typedef typename rep::difference_type difference_type; typedef typename rep::value_type value_type; typedef typename rep::reference reference; typedef typename rep::dis_reference dis_reference; typedef typename rep::iterator iterator; typedef typename rep::const_reference const_reference; typedef typename rep::const_iterator const_iterator; typedef typename rep::scatter_map_type scatter_map_type; // allocators: 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()); // local accessors & modifiers: 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); } 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(); } const_iterator begin() const { return base::data()\&.begin(); } iterator end() { return base::data()\&.end(); } const_iterator end() const { return base::data()\&.end(); } // global accessor: template 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 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 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& ext_idx_set) const { base::data()\&.get_dis_indexes (ext_idx_set); } template 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); } // get all external pairs (dis_i, values): const scatter_map_type& get_dis_map_entries() const { return base::data()\&.get_dis_map_entries(); } // global modifiers (for compatibility with distributed interface): dis_reference dis_entry (size_type dis_i) { return base::data()\&.dis_entry(dis_i); } template::type> void dis_entry_assembly_begin (SetOp my_set_op = SetOp()) { base::data()\&.dis_entry_assembly_begin (my_set_op); } template::type> void dis_entry_assembly_end (SetOp my_set_op = SetOp()) { base::data()\&.dis_entry_assembly_end (my_set_op); } template::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::type>(); } void dis_entry_assembly_end() { base::data()\&.template dis_entry_assembly_end::type>(); } void dis_entry_assembly() { dis_entry_assembly_begin(); dis_entry_assembly_end(); } // apply a partition: template void repartition ( // old_numbering for *this const RepSize& partition, // old_ownership disarray& new_disarray, // new_ownership (created) RepSize& old_numbering, // new_ownership RepSize& new_numbering) const // old_ownership { return base::data()\&.repartition (partition\&.data(), new_disarray\&.data(), old_numbering\&.data(), new_numbering\&.data()); } template void permutation_apply ( // old_numbering for *this const RepSize& new_numbering, // old_ownership disarray& new_disarray) const // new_ownership (already allocated) { base::data()\&.permutation_apply (new_numbering\&.data(), new_disarray\&.data()); } void reverse_permutation ( // old_ownership for *this=iold2dis_inew disarray& inew2dis_iold) const // new_ownership { base::data()\&.reverse_permutation (inew2dis_iold\&.data()); } // i/o: 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 idiststream& get_values (idiststream& ips, GetFunction get_element) { return base::data()\&.get_values(ips, get_element); } template odiststream& put_values (odiststream& ops, PutFunction put_element) const { return base::data()\&.put_values(ops, put_element); } template odiststream& permuted_put_values ( odiststream& ops, const disarray& perm, PutFunction put_element) const { return base::data()\&.permuted_put_values (ops, perm\&.data(), put_element); } }; .fi .PP .SH AUTHOR Pierre Saramito .SH COPYRIGHT Copyright (C) 2000-2018 Pierre Saramito GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.