~ubuntu-branches/ubuntu/trusty/rheolef/trusty

« back to all changes in this revision

Viewing changes to skit/plib2/array.h

  • Committer: Package Import Robot
  • Author(s): Pierre Saramito
  • Date: 2012-04-06 09:12:21 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120406091221-m58me99p1nxqui49
Tags: 6.0-1
* New upstream release 6.0 (major changes):
  - massively distributed and parallel support
  - full FEM characteristic method (Lagrange-Gakerkin method) support
  - enhanced users documentation 
  - source code supports g++-4.7 (closes: #667356)
* debian/control: dependencies for MPI distributed solvers added
* debian/rules: build commands simplified
* debian/librheolef-dev.install: man1/* to man9/* added
* debian/changelog: package description rewritted (closes: #661689)

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
// -------------------------------------------------------------
96
96
namespace rheolef {
97
97
 
98
 
template <class T>
99
 
class array_seq_rep : public std::vector<T> {
 
98
template <class T, class A>
 
99
class array_seq_rep : public std::vector<T,A> {
100
100
public:
101
 
    typedef T                                       value_type;
102
 
    typedef typename std::vector<T>::size_type      size_type;
103
 
    typedef typename std::vector<T>::iterator       iterator;
104
 
    typedef typename std::vector<T>::const_iterator const_iterator;
105
 
    typedef typename std::vector<T>::const_reference const_reference;
106
 
    typedef typename std::vector<T>::reference      reference;
107
 
    typedef reference                               dis_reference;
108
 
    typedef distributor::communicator_type          communicator_type;
109
 
    typedef sequential                              memory_type;
 
101
    typedef T                                         value_type;
 
102
    typedef A                                         allocator_type;
 
103
    typedef typename A::difference_type               difference_type;
 
104
    typedef typename std::vector<T,A>::size_type      size_type;
 
105
    typedef typename std::vector<T,A>::iterator       iterator;
 
106
    typedef typename std::vector<T,A>::const_iterator const_iterator;
 
107
    typedef typename std::vector<T,A>::const_reference const_reference;
 
108
    typedef typename std::vector<T,A>::reference      reference;
 
109
    typedef reference                                 dis_reference;
 
110
    typedef distributor::communicator_type            communicator_type;
 
111
    typedef sequential                                memory_type;
110
112
 
111
 
    array_seq_rep (const distributor& ownership, const T& init_val = T());
 
113
    explicit array_seq_rep (const A& alloc = A());
 
114
    array_seq_rep (const distributor& ownership, const T& init_val = T(), const A& alloc = A());
112
115
    void resize   (const distributor& ownership, const T& init_val = T());
113
 
    array_seq_rep (size_type loc_size = 0,       const T& init_val = T());
 
116
    array_seq_rep (size_type loc_size = 0,       const T& init_val = T(), const A& alloc = A());
114
117
    void resize   (size_type loc_size = 0,       const T& init_val = T());
115
 
    array_seq_rep (const array_seq_rep<T>& x);
 
118
    array_seq_rep (const array_seq_rep<T,A>& x);
116
119
 
117
 
    size_type size() const { return std::vector<T>::size(); }
118
 
    iterator begin() { return std::vector<T>::begin(); }
119
 
    const_iterator begin() const { return std::vector<T>::begin(); }
120
 
    iterator end() { return std::vector<T>::end(); }
121
 
    const_iterator end() const { return std::vector<T>::end(); }
 
120
    A get_allocator() const { return std::vector<T,A>::get_allocator(); }
 
121
    size_type size() const { return std::vector<T,A>::size(); }
 
122
    iterator begin() { return std::vector<T,A>::begin(); }
 
123
    const_iterator begin() const { return std::vector<T,A>::begin(); }
 
124
    iterator end() { return std::vector<T,A>::end(); }
 
125
    const_iterator end() const { return std::vector<T,A>::end(); }
122
126
    const distributor& ownership() const { return _ownership; }
123
127
 
124
 
    reference       operator[] (size_type i)       { return std::vector<T>::operator[] (i); }
125
 
    const_reference operator[] (size_type i) const { return std::vector<T>::operator[] (i); }
 
128
    reference       operator[] (size_type i)       { return std::vector<T,A>::operator[] (i); }
 
129
    const_reference operator[] (size_type i) const { return std::vector<T,A>::operator[] (i); }
 
130
    const_reference dis_at (size_type dis_i) const { return operator[] (dis_i); }
126
131
   
127
 
    size_type dis_size () const { return std::vector<T>::size(); }
 
132
    size_type dis_size () const { return std::vector<T,A>::size(); }
128
133
    size_type first_index () const { return 0; }
129
 
    size_type last_index () const { return std::vector<T>::size(); }
 
134
    size_type last_index () const { return std::vector<T,A>::size(); }
130
135
    reference dis_entry (size_type dis_i) { return operator[](dis_i); }
 
136
    void reset_dis_indexes() const {}
131
137
    template<class SetOp> void dis_entry_assembly_begin (SetOp) {}
132
138
    template<class SetOp> void dis_entry_assembly_end (SetOp) {}
133
139
    void dis_entry_assembly_begin () {}
134
140
    void dis_entry_assembly_end () {}
135
141
    void repartition (                                        // old_numbering for *this
136
 
        const array_seq_rep<size_type>& partition,            // old_ownership
137
 
        array_seq_rep<T>&               new_array,            // new_ownership (created)
138
 
        array_seq_rep<size_type>&       old_numbering,        // new_ownership
139
 
        array_seq_rep<size_type>&       new_numbering) const  // old_ownership
 
142
        const array_seq_rep<size_type,A>& partition,          // old_ownership
 
143
        array_seq_rep<T,A>&               new_array,          // new_ownership (created)
 
144
        array_seq_rep<size_type,A>&       old_numbering,      // new_ownership
 
145
        array_seq_rep<size_type,A>&       new_numbering) const // old_ownership
140
146
    {
141
147
        error_macro ("not yet");
142
148
    }
 
149
    template<class A2>
 
150
    void reverse_permutation (                                // old_ownership for *this=iold2dis_inew
 
151
        array_seq_rep<size_type,A2>& inew2dis_iold) const;    // new_ownership
 
152
 
143
153
    idiststream& get_values (idiststream& s);
144
154
    odiststream& put_values (odiststream& s) const;
145
155
    template <class GetFunction> idiststream& get_values (idiststream& ips, GetFunction get_element);
153
163
// the distributed representation
154
164
// -------------------------------------------------------------
155
165
#ifdef _RHEOLEF_HAVE_MPI
156
 
template <class T>
157
 
class array_mpi_rep : public array_seq_rep<T> {
 
166
template <class T, class A>
 
167
class array_mpi_rep : public array_seq_rep<T,A> {
158
168
public:
159
169
 
160
170
// typedefs:
161
171
 
162
 
    typedef typename array_seq_rep<T>::value_type     value_type;
163
 
    typedef typename array_seq_rep<T>::size_type      size_type;
164
 
    typedef typename array_seq_rep<T>::reference      reference;
165
 
    typedef typename array_seq_rep<T>::iterator       iterator;
166
 
    typedef typename array_seq_rep<T>::const_iterator const_iterator;
167
 
    typedef distributor::communicator_type            communicator_type;
168
 
    typedef distributed                               memory_type;
 
172
    typedef array_seq_rep<T,A>                  base;
 
173
    typedef typename base::value_type           value_type;
 
174
    typedef typename base::size_type            size_type;
 
175
    typedef typename base::difference_type      difference_type;
 
176
    typedef typename base::reference            reference;
 
177
    typedef typename base::const_reference      const_reference;
 
178
    typedef typename base::iterator             iterator;
 
179
    typedef typename base::const_iterator       const_iterator;
 
180
    typedef distributor::communicator_type      communicator_type;
 
181
    typedef distributed                         memory_type;
 
182
    typedef std::map <size_type, T, std::less<size_type>, heap_allocator<std::pair<size_type,T> > > 
 
183
                                                scatter_map_type;
169
184
 
170
185
    struct dis_reference {
171
 
      dis_reference (array_mpi_rep<T>& x, size_type dis_i)
 
186
      dis_reference (array_mpi_rep<T,A>& x, size_type dis_i)
172
187
       : _x(x), _dis_i(dis_i) {}
173
188
 
174
189
      dis_reference& operator= (const T& value) {
181
196
      }
182
197
    // data:
183
198
    protected:
184
 
      array_mpi_rep<T>& _x;
185
 
      size_type         _dis_i;
 
199
      array_mpi_rep<T,A>& _x;
 
200
      size_type           _dis_i;
186
201
    };
187
202
 
188
203
// allocators:
189
204
 
190
 
#ifdef TO_CLEAN
191
 
    array_mpi_rep (
192
 
        size_type dis_size = 0,
193
 
        const T&  init_val = T(),
194
 
        size_type loc_size = distributor::decide); 
195
 
    void resize (
196
 
        size_type dis_size = 0,
197
 
        const T&  init_val = T(),
198
 
        size_type loc_size = distributor::decide);
199
 
#endif // TO_CLEAN
200
 
    array_mpi_rep (const distributor& ownership, const T&  init_val = T());
 
205
    array_mpi_rep (const distributor& ownership, const T&  init_val = T(), const A& alloc = A());
201
206
    void resize   (const distributor& ownership, const T&  init_val = T());
202
 
    array_mpi_rep (const array_mpi_rep<T>& x);
203
 
 
204
 
    size_type size() const       { return array_seq_rep<T>::size(); }
205
 
    const_iterator begin() const { return array_seq_rep<T>::begin(); }
206
 
    const_iterator end() const   { return array_seq_rep<T>::end(); }
207
 
    iterator begin()             { return array_seq_rep<T>::begin(); }
208
 
    iterator end()               { return array_seq_rep<T>::end(); }
209
 
 
210
 
    const distributor& ownership() const  { return array_seq_rep<T>::_ownership; }
 
207
    array_mpi_rep (const array_mpi_rep<T,A>& x);
 
208
 
 
209
    A get_allocator() const        { return base::get_allocator(); }
 
210
    size_type size() const         { return base::size(); }
 
211
    const_iterator begin() const   { return base::begin(); }
 
212
    const_iterator end() const     { return base::end(); }
 
213
    iterator begin()               { return base::begin(); }
 
214
    iterator end()                 { return base::end(); }
 
215
 
 
216
    const distributor& ownership() const  { return base::_ownership; }
211
217
    const mpi::communicator& comm() const { return ownership().comm(); }
212
218
    size_type first_index () const        { return ownership().first_index(); }
213
219
    size_type last_index () const         { return ownership().last_index(); }
225
231
    void dis_entry_assembly ()       { dis_entry_assembly_begin (); dis_entry_assembly_end (); }
226
232
 
227
233
    template<class Set, class Map>
228
 
    void get_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const;
229
 
 
230
 
    template<class Set>
231
 
    void set_dis_indexes (const Set& ext_idx_set) { get_dis_entry (ext_idx_set, _ext_x); }
232
 
 
233
 
    const T& dis_at (size_type dis_i) const;
234
 
 
 
234
    void append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const;
 
235
 
 
236
    template<class Set, class Map>
 
237
    void get_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const {
 
238
            ext_idx_map.clear();
 
239
            append_dis_entry (ext_idx_set, ext_idx_map);
 
240
        }
 
241
 
 
242
    template<class Set>
 
243
    void append_dis_indexes (const Set& ext_idx_set) const { append_dis_entry (ext_idx_set, _ext_x); }
 
244
 
 
245
    template<class Set>
 
246
    void set_dis_indexes    (const Set& ext_idx_set) const { get_dis_entry    (ext_idx_set, _ext_x); }
 
247
    void reset_dis_indexes() const;
 
248
 
 
249
    const_reference dis_at (size_type dis_i) const;
 
250
 
 
251
    // get all external pairs (dis_i, values):
 
252
    const scatter_map_type& get_dis_map_entries() const { return _ext_x; }
 
253
 
 
254
    template<class A2>
235
255
    void repartition (                                        // old_numbering for *this
236
 
        const array_mpi_rep<size_type>& partition,            // old_ownership
237
 
        array_mpi_rep<T>&               new_array,            // new_ownership (created)
238
 
        array_mpi_rep<size_type>&       old_numbering,        // new_ownership
239
 
        array_mpi_rep<size_type>&       new_numbering) const; // old_ownership
240
 
 
241
 
    void permutation_apply (                                  // old_numbering for *this
242
 
        const array_mpi_rep<size_type>& new_numbering,        // old_ownership
243
 
        array_mpi_rep<T>&               new_array) const;     // new_ownership (already allocated)
 
256
        const array_mpi_rep<size_type,A2>& partition,         // old_ownership
 
257
        array_mpi_rep<T,A>&                new_array,         // new_ownership (created)
 
258
        array_mpi_rep<size_type,A2>&       old_numbering,     // new_ownership
 
259
        array_mpi_rep<size_type,A2>&       new_numbering) const; // old_ownership
 
260
 
 
261
    template<class A2>
 
262
    void permutation_apply (                                   // old_numbering for *this
 
263
        const array_mpi_rep<size_type,A2>& new_numbering,      // old_ownership
 
264
        array_mpi_rep<T,A>&                new_array) const;   // new_ownership (already allocated)
 
265
 
 
266
    template<class A2>
 
267
    void reverse_permutation (                                // old_ownership for *this=iold2dis_inew
 
268
        array_mpi_rep<size_type,A2>& inew2dis_iold) const;    // new_ownership
244
269
 
245
270
    idiststream& get_values (idiststream& s);
246
271
    odiststream& put_values (odiststream& s) const;
247
272
    template <class GetFunction> idiststream& get_values (idiststream& ips, GetFunction get_element);
248
273
    template <class PutFunction> odiststream& put_values (odiststream& ops, PutFunction put_element) const;
249
 
    template <class PutFunction> odiststream& permuted_put_values (odiststream& ops, const array_mpi_rep<size_type>& perm,
 
274
    template <class PutFunction, class A2> odiststream& permuted_put_values (odiststream& ops, const array_mpi_rep<size_type,A2>& perm,
250
275
                PutFunction put_element) const;
251
276
    void dump (std::string name) const;
252
277
protected:
269
294
    };
270
295
    typedef typename is_container_of_mpi_datatype<T>::type is_container;
271
296
    typedef typename stash_traits<T,is_container>::mapped_type stash_value;
272
 
    typedef typename stash_traits<T,is_container>::map_type    map_type;
273
 
#ifdef TODO
274
 
    typedef std::map <size_type, T, std::less<size_type>, heap_allocator<std::pair<size_type,T> > >  scatter_map_type;
275
 
#endif // TODO
276
 
    typedef std::map <size_type, T>  scatter_map_type;
 
297
    typedef typename stash_traits<T,is_container>::map_type    stash_map_type;
277
298
 
278
299
    /** 2) message: for communication during assembly_begin(), assembly_end()
279
300
      */
280
301
    struct message_type {
281
 
        std::list<std::pair<size_t,mpi::request> >       waits;
282
 
        std::vector<std::pair<size_type,stash_value> >   data;
 
302
        std::list<std::pair<size_type,mpi::request>,A>    waits;
 
303
        std::vector<std::pair<size_type,stash_value>,A>   data;
283
304
    };
284
305
    /** 3) scatter (get_entry): specialized versions for T=container and T=simple type
285
306
      */
286
307
    template<class Set, class Map>
287
 
    void get_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, boost::mpl::true_) const;
 
308
    void append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, boost::mpl::true_) const;
288
309
    template<class Set, class Map>
289
 
    void get_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, boost::mpl::false_) const;
 
310
    void append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, boost::mpl::false_) const;
290
311
 
291
312
// data:
292
 
    map_type         _stash;            // for assembly msgs:
 
313
    stash_map_type   _stash;            // for assembly msgs:
293
314
    message_type     _send;
294
315
    message_type     _receive;
295
316
    size_type        _receive_max_size;
296
 
    scatter_map_type _ext_x;            // for ext values (scatter)
 
317
    mutable scatter_map_type _ext_x;            // for ext values (scatter)
297
318
};
298
319
#endif // _RHEOLEF_HAVE_MPI
299
320
// -------------------------------------------------------------
301
322
// the user-level class with memory-model parameter
302
323
// -------------------------------------------------------------
303
324
/*Class:array
304
 
NAME:  array - container in distributed environment (@PACKAGE@-@VERSION@)
 
325
NAME:  @code{array} - container in distributed environment (@PACKAGE@-@VERSION@)
305
326
SYNOPSYS:       
306
327
 STL-like vector container for a distributed memory machine model.
307
328
EXAMPLE:
310
331
     int main(int argc, char**argv) @{
311
332
        environment distributed(argc, argv);
312
333
        array<double> x(distributor(100), 3.14);
313
 
        dcout << x << endl;
 
334
        dout << x << endl;
314
335
     @}
315
336
   @end example
316
337
   The array<T> interface is similar to those of the std::vector<T> with the 
378
399
AUTHOR: Pierre.Saramito@imag.fr
379
400
End:
380
401
*/
381
 
template <class T, class M = rheo_default_memory_model>
 
402
template <class T, class M = rheo_default_memory_model, class A = std::allocator<T> >
382
403
class array {
383
404
public:
384
405
    typedef M memory_type;
385
 
    typedef typename std::vector<T>::size_type      size_type;
386
 
    typedef typename std::vector<T>::iterator       iterator;
387
 
    typedef typename std::vector<T>::const_iterator const_iterator;
 
406
    typedef typename std::vector<T,A>::size_type      size_type;
 
407
    typedef typename std::vector<T,A>::iterator       iterator;
 
408
    typedef typename std::vector<T,A>::const_iterator const_iterator;
388
409
};
389
410
//<verbatim:
390
 
template <class T>
391
 
class array<T,sequential> : public smart_pointer<array_seq_rep<T> > {
 
411
template <class T, class A>
 
412
class array<T,sequential,A> : public smart_pointer<array_seq_rep<T,A> > {
392
413
public:
393
414
 
394
415
// typedefs:
395
416
 
396
 
    typedef array_seq_rep<T>              rep;
 
417
    typedef array_seq_rep<T,A>            rep;
397
418
    typedef smart_pointer<rep>            base;
398
419
 
399
420
    typedef sequential                    memory_type;
400
421
    typedef typename rep::size_type       size_type;
 
422
    typedef typename rep::difference_type difference_type;
401
423
    typedef typename rep::value_type      value_type;
402
424
    typedef typename rep::reference       reference;
403
425
    typedef typename rep::dis_reference   dis_reference;
408
430
// allocators:
409
431
 
410
432
 
411
 
    array       (size_type loc_size = 0,       const T& init_val = T());
 
433
    array       (size_type loc_size = 0,       const T& init_val = T(), const A& alloc = A());
412
434
    void resize (size_type loc_size = 0,       const T& init_val = T());
413
 
    array       (const distributor& ownership, const T& init_val = T());
 
435
    array       (const distributor& ownership, const T& init_val = T(), const A& alloc = A());
414
436
    void resize (const distributor& ownership, const T& init_val = T());
415
437
 
416
438
// local accessors & modifiers:
417
439
 
 
440
    A get_allocator() const              { return base::data().get_allocator(); }
418
441
    size_type     size () const          { return base::data().size(); }
419
442
    size_type dis_size () const          { return base::data().dis_size(); }
420
443
    const distributor& ownership() const { return base::data().ownership(); }
422
445
 
423
446
    reference       operator[] (size_type i)       { return base::data().operator[] (i); }
424
447
    const_reference operator[] (size_type i) const { return base::data().operator[] (i); }
 
448
    reference       operator() (size_type i)       { return base::data().operator[] (i); }
 
449
    const_reference operator() (size_type i) const { return base::data().operator[] (i); }
 
450
    const_reference dis_at (size_type dis_i) const { return operator[] (dis_i); }
425
451
 
426
452
          iterator begin()       { return base::data().begin(); }
427
453
    const_iterator begin() const { return base::data().begin(); }
432
458
 
433
459
    dis_reference dis_entry (size_type dis_i) { return base::data().dis_entry(dis_i); }
434
460
    void dis_entry_assembly()                 {}
435
 
    template<class SetOp>
436
 
    void dis_entry_assembly(SetOp my_set_op)        {}
437
 
    template<class SetOp>
438
 
    void dis_entry_assembly_begin (SetOp my_set_op) {}
439
 
    template<class SetOp>
440
 
    void dis_entry_assembly_end (SetOp my_set_op)   {}
 
461
    template<class SetOp> void dis_entry_assembly(SetOp my_set_op)        {}
 
462
    template<class SetOp> void dis_entry_assembly_begin (SetOp my_set_op) {}
 
463
    template<class SetOp> void dis_entry_assembly_end (SetOp my_set_op)   {}
 
464
 
 
465
    void reset_dis_indexes() const {}
 
466
    template<class Set> void set_dis_indexes    (const Set& ext_idx_set) const {}
 
467
    template<class Set> void append_dis_indexes (const Set& ext_idx_set) const {}
 
468
    template<class Set, class Map> void append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const {}
 
469
    template<class Set, class Map> void get_dis_entry    (const Set& ext_idx_set, Map& ext_idx_map) const {}
441
470
 
442
471
// apply a partition:
443
472
 
444
473
    template<class RepSize>
445
 
    void repartition (                             // old_numbering for *this
446
 
        const RepSize&       partition,            // old_ownership
447
 
        array<T,sequential>& new_array,            // new_ownership (created)
448
 
        RepSize&             old_numbering,        // new_ownership
449
 
        RepSize&             new_numbering) const  // old_ownership
 
474
    void repartition (                               // old_numbering for *this
 
475
        const RepSize&         partition,            // old_ownership
 
476
        array<T,sequential,A>& new_array,            // new_ownership (created)
 
477
        RepSize&               old_numbering,        // new_ownership
 
478
        RepSize&               new_numbering) const  // old_ownership
450
479
        { return base::data().repartition (partition, new_array, old_numbering, new_numbering); }
451
480
 
452
481
    template<class RepSize>
453
 
    void permutation_apply (                     // old_numbering for *this
454
 
        const RepSize&        new_numbering,     // old_ownership
455
 
        array<T,sequential>&  new_array) const   // new_ownership (already allocated)
 
482
    void permutation_apply (                       // old_numbering for *this
 
483
        const RepSize&          new_numbering,     // old_ownership
 
484
        array<T,sequential,A>&  new_array) const   // new_ownership (already allocated)
456
485
        { return base::data().permutation_apply (new_numbering, new_array); }
457
486
 
 
487
    void reverse_permutation (                                 // old_ownership for *this=iold2dis_inew
 
488
        array<size_type,sequential,A>& inew2dis_iold) const   // new_ownership
 
489
        { base::data().reverse_permutation (inew2dis_iold.data()); }
 
490
 
458
491
// i/o:
459
492
 
460
493
    odiststream& put_values (odiststream& ops) const { return base::data().put_values(ops); }
466
499
    void dump (std::string name) const { return base::data().dump(name); }
467
500
};
468
501
//>verbatim:
469
 
template <class T>
 
502
template <class T, class A>
470
503
inline
471
 
array<T,sequential>::array (
 
504
array<T,sequential,A>::array (
472
505
        size_type loc_size,
473
 
        const T&  init_val)
474
 
 : base(new_macro(rep(loc_size,init_val)))
 
506
        const T&  init_val,
 
507
        const A&  alloc)
 
508
 : base(new_macro(rep(loc_size,init_val,alloc)))
475
509
{
476
510
}
477
 
template <class T>
 
511
template <class T, class A>
478
512
inline
479
 
array<T,sequential>::array (
 
513
array<T,sequential,A>::array (
480
514
        const distributor& ownership,
481
 
        const T&           init_val)
482
 
 : base(new_macro(rep(ownership,init_val)))
 
515
        const T&           init_val,
 
516
        const A&           alloc)
 
517
 : base(new_macro(rep(ownership,init_val,alloc)))
483
518
{
484
519
}
485
 
template <class T>
 
520
template <class T, class A>
486
521
inline
487
522
void
488
 
array<T,sequential>::resize (
 
523
array<T,sequential,A>::resize (
489
524
        size_type loc_size,
490
525
        const T&  init_val)
491
526
{
492
527
  base::data().resize (loc_size,init_val);
493
528
}
494
 
template <class T>
 
529
template <class T, class A>
495
530
inline
496
531
void
497
 
array<T,sequential>::resize (
 
532
array<T,sequential,A>::resize (
498
533
        const distributor& ownership,
499
534
        const T&           init_val)
500
535
{
502
537
}
503
538
#ifdef _RHEOLEF_HAVE_MPI
504
539
//<verbatim:
505
 
template <class T>
506
 
class array<T,distributed> : public smart_pointer<array_mpi_rep<T> > {
 
540
template <class T, class A>
 
541
class array<T,distributed,A> : public smart_pointer<array_mpi_rep<T,A> > {
507
542
public:
508
543
 
509
544
// typedefs:
510
545
 
511
 
    typedef array_mpi_rep<T>              rep;
 
546
    typedef array_mpi_rep<T,A>            rep;
512
547
    typedef smart_pointer<rep>            base;
513
548
 
514
549
    typedef distributed                   memory_type;
515
550
    typedef typename rep::size_type       size_type;
 
551
    typedef typename rep::difference_type difference_type;
516
552
    typedef typename rep::value_type      value_type;
517
553
    typedef typename rep::reference       reference;
518
554
    typedef typename rep::dis_reference   dis_reference;
519
555
    typedef typename rep::iterator        iterator;
520
556
    typedef typename rep::const_reference const_reference;
521
557
    typedef typename rep::const_iterator  const_iterator;
 
558
    typedef typename rep::scatter_map_type scatter_map_type;
522
559
 
523
560
// allocators:
524
561
 
525
 
    array       (const distributor& ownership = distributor(), const T& init_val = T());
 
562
    array       (const distributor& ownership = distributor(), const T& init_val = T(), const A& alloc = A());
526
563
    void resize (const distributor& ownership = distributor(), const T& init_val = T());
527
564
 
528
565
// local accessors & modifiers:
529
566
 
 
567
    A get_allocator() const              { return base::data().get_allocator(); }
530
568
    size_type     size () const          { return base::data().size(); }
531
569
    size_type dis_size () const          { return base::data().dis_size(); }
532
570
    const distributor& ownership() const { return base::data().ownership(); }
534
572
 
535
573
    reference       operator[] (size_type i)       { return base::data().operator[] (i); }
536
574
    const_reference operator[] (size_type i) const { return base::data().operator[] (i); }
 
575
    reference       operator() (size_type i)       { return base::data().operator[] (i); }
 
576
    const_reference operator() (size_type i) const { return base::data().operator[] (i); }
537
577
 
538
578
          iterator begin()       { return base::data().begin(); }
539
579
    const_iterator begin() const { return base::data().begin(); }
543
583
// global accessor:
544
584
 
545
585
    template<class Set, class Map>
546
 
    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); }
547
 
 
548
 
    template<class Set>
549
 
    void set_dis_indexes (const Set& ext_idx_set)  { base::data().set_dis_indexes (ext_idx_set); }
 
586
    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); }
 
587
 
 
588
    template<class Set, class Map>
 
589
    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); }
 
590
 
 
591
    template<class Set>
 
592
    void append_dis_indexes (const Set& ext_idx_set) const { base::data().append_dis_indexes (ext_idx_set); }
 
593
    void reset_dis_indexes() const { base::data().reset_dis_indexes(); }
 
594
 
 
595
    template<class Set>
 
596
    void set_dis_indexes    (const Set& ext_idx_set) const { base::data().set_dis_indexes (ext_idx_set); }
550
597
 
551
598
    const T& dis_at (size_type dis_i) const { return base::data().dis_at (dis_i); }
552
599
 
 
600
    // get all external pairs (dis_i, values):
 
601
    const scatter_map_type& get_dis_map_entries() const { return base::data().get_dis_map_entries(); }
 
602
 
553
603
// global modifiers (for compatibility with distributed interface):
554
604
 
555
605
    dis_reference dis_entry (size_type dis_i)       { return base::data().dis_entry(dis_i); }
574
624
        { return base::data().repartition (partition.data(), new_array.data(), old_numbering.data(), new_numbering.data()); }
575
625
 
576
626
    template<class RepSize>
577
 
    void permutation_apply (                     // old_numbering for *this
578
 
        const RepSize&        new_numbering,     // old_ownership
579
 
        array<T,distributed>& new_array) const   // new_ownership (already allocated)
 
627
    void permutation_apply (                       // old_numbering for *this
 
628
        const RepSize&          new_numbering,     // old_ownership
 
629
        array<T,distributed,A>& new_array) const   // new_ownership (already allocated)
580
630
        { base::data().permutation_apply (new_numbering.data(), new_array.data()); }
581
631
 
 
632
    void reverse_permutation (                                 // old_ownership for *this=iold2dis_inew
 
633
        array<size_type,distributed,A>& inew2dis_iold) const   // new_ownership
 
634
        { base::data().reverse_permutation (inew2dis_iold.data()); }
 
635
 
582
636
// i/o:
583
637
 
584
638
    odiststream& put_values (odiststream& ops) const { return base::data().put_values(ops); }
589
643
    idiststream& get_values (idiststream& ips, GetFunction get_element)       { return base::data().get_values(ips, get_element); }
590
644
    template <class PutFunction>
591
645
    odiststream& put_values (odiststream& ops, PutFunction put_element) const { return base::data().put_values(ops, put_element); }
592
 
    template <class PutFunction> odiststream& permuted_put_values (
593
 
                odiststream& ops, const array<size_type,distributed>& perm, PutFunction put_element) const 
 
646
    template <class PutFunction, class A2> odiststream& permuted_put_values (
 
647
                odiststream& ops, const array<size_type,distributed,A2>& perm, PutFunction put_element) const 
594
648
                                                                     { return base::data().permuted_put_values (ops, perm.data(), put_element); }
595
649
};
596
650
//>verbatim:
597
 
template <class T>
 
651
template <class T, class A>
598
652
inline
599
 
array<T,distributed>::array (
 
653
array<T,distributed,A>::array (
600
654
        const distributor& ownership,
601
 
        const T&           init_val)
602
 
 : base(new_macro(rep(ownership,init_val)))
 
655
        const T&           init_val,
 
656
        const A&           alloc)
 
657
 : base(new_macro(rep(ownership,init_val,alloc)))
603
658
{
604
659
}
605
 
template <class T>
 
660
template <class T, class A>
606
661
inline
607
662
void
608
 
array<T,distributed>::resize (
 
663
array<T,distributed,A>::resize (
609
664
        const distributor& ownership,
610
665
        const T         &  init_val)
611
666
{
616
671
// -------------------------------------------------------------
617
672
// i/o with operator<< & >>
618
673
// -------------------------------------------------------------
619
 
template <class T>
 
674
template <class T, class A>
620
675
inline
621
676
idiststream&
622
 
operator >> (idiststream& ips,  array<T,sequential>& x)
 
677
operator >> (idiststream& ips,  array<T,sequential,A>& x)
623
678
624
679
    return x.get_values(ips); 
625
680
}
626
 
template <class T> 
 
681
template <class T, class A>
627
682
inline
628
683
odiststream&
629
 
operator << (odiststream& ops, const array<T,sequential>& x)
 
684
operator << (odiststream& ops, const array<T,sequential,A>& x)
630
685
{
631
686
    return x.put_values(ops);
632
687
}
633
688
#ifdef _RHEOLEF_HAVE_MPI
634
 
template <class T>
 
689
template <class T, class A>
635
690
inline
636
691
idiststream&
637
 
operator >> (idiststream& ips,  array<T,distributed>& x)
 
692
operator >> (idiststream& ips,  array<T,distributed,A>& x)
638
693
639
694
    return x.get_values(ips); 
640
695
}
641
 
template <class T> 
 
696
template <class T, class A>
642
697
inline
643
698
odiststream&
644
 
operator << (odiststream& ops, const array<T,distributed>& x)
 
699
operator << (odiststream& ops, const array<T,distributed,A>& x)
645
700
{
646
701
    return x.put_values(ops);
647
702
}