Rheolef  7.2
an efficient C++ finite element environment
scatter_message.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_SCATTER_MESSAGE_H
2 #define _RHEOLEF_SCATTER_MESSAGE_H
23 //
24 // create distributed to sequential scatter context
25 // inspirated from petsc-2.0/vpscat.c: VecScatterCreate_PtoS(...)
26 //
27 #include "rheolef/compiler.h"
28 #ifdef _RHEOLEF_HAVE_MPI
29 namespace rheolef {
30 
31 
32 template<class Container, bool T_is_MPI_simple = false>
33 class scatter_message {};
34 
35 // =====================================================================================
36 // when Container::value_type is a fixed-size type (i.e. a simple MPI data type)
37 // =====================================================================================
38 template<class Container>
39 class scatter_message<Container,false> {
40 public:
41  typedef typename Container::size_type size_type;
42  typedef typename Container::value_type value_type;
43  typedef typename Container::allocator_type allocator_type;
45 
46 // data:
47 protected:
49  Container _values; // n_data
50  std::vector<size_type> _indices; // n_data
51  std::vector<size_type> _procs; // n_proc
52  std::vector<size_type> _starts; // n_proc+1
53 
54 public:
55 // data accessors:
56  const Container& values () const { return _values; }
57  Container& values () { return _values; }
58  const std::vector<size_type>& indices() const { return _indices; }
59  std::vector<size_type>& indices() { return _indices; }
60  const std::vector<size_type>& procs () const { return _procs; }
61  std::vector<size_type>& procs () { return _procs; }
62  const std::vector<size_type>& starts () const { return _starts; }
63  std::vector<size_type>& starts () { return _starts; }
64 
65  std::list<std::pair<size_type,mpi::request> > requests; // n_proc
66  std::vector<mpi::status> sstatus; // n_status
67 
68  std::vector<size_type> local_slots; // n_local
69  std::vector<size_type> local_slots_nonmatching;
70  bool local_nonmatching_computed;// n_local_nonmatching
75 
76 // allocator:
77 
78  scatter_message(const value_type& init_value = value_type(), const allocator_type& alloc = allocator_type())
79  : _init_value (init_value),
80  _values(alloc),
81  _indices(),
82  _procs(),
83  _starts(),
84  requests(),
85  sstatus(),
86  local_slots(),
87  local_slots_nonmatching(),
88  local_nonmatching_computed(false),
89  local_n_nonmatching(0),
90  local_is_copy(false),
91  local_copy_start(0),
92  local_copy_length(0)
93  {}
94  void resize (size_type n_data, size_type nproc) {
95  _values.resize (n_data, _init_value);
96  _indices.resize (n_data);
97  _procs.resize (nproc);
98  _starts.resize (nproc+1);
99  }
100  template <class InputIterator>
101  void load_values (InputIterator x);
102 
103  template<class OutputIterator, class SetOp>
104  void store_values (OutputIterator y, size_type i_receive, SetOp op) const;
105 
106 // accessors:
107 
108  size_type n_proc() const { return _procs.size(); }
109  size_type n_data() const { return _indices.size(); }
110  size_type n_status() const { return sstatus.size(); }
111  size_type n_local() const { return local_slots.size(); }
112  size_type n_local_nonmatching() const { return local_slots_nonmatching.size(); }
113 };
114 // =====================================================================================
115 // when Container::value_type is also a container variable-sized type (e.g. index_set)
116 // =====================================================================================
117 template<class Container>
118 class scatter_message<Container,true> : public scatter_message<std::vector<typename Container::size_type>, false> {
119 public:
121 
122  typedef typename base::size_type size_type;
123  typedef typename Container::value_type value_type; // e.g. index_set
124  typedef typename value_type::value_type base_value_type; // e.g. size_type when value_type=index_set
125 
126 // data:
127 protected:
128  std::vector<base_value_type> _multi_values; // n_multi_data
129  std::vector<size_type> _multi_indices; // n_multi_data
130  std::vector<size_type> _multi_procs; // n_multi_proc
131  std::vector<size_type> _multi_starts; // n_multi_proc+1
132  std::vector<size_type> _ptr; // n_data+1
133  std::vector<size_type> _multi_irecv2base_irecv; // empty-msg, when zero data sz
134 
135 public:
136 // data accessors:
137  const std::vector<base_value_type>& values () const { return _multi_values; }
138  std::vector<base_value_type>& values () { return _multi_values; }
139 
140  const std::vector<size_type>& indices() const { return _multi_indices; }
141  std::vector<size_type>& indices() { return _multi_indices; }
142  const std::vector<size_type>& procs () const { return _multi_procs; }
143  std::vector<size_type>& procs () { return _multi_procs; }
144  const std::vector<size_type>& starts () const { return _multi_starts; }
145  std::vector<size_type>& starts () { return _multi_starts; }
146 
147  base& get_base() { return *this; }
148 
149 // allocators:
150 
152  : base(),
153  _multi_values(),
154  _multi_indices(),
155  _multi_procs(),
156  _multi_starts(),
157  _ptr(),
158  _multi_irecv2base_irecv()
159  {}
160 
161  void multi_init ();
162 
163  template <class InputIterator>
164  void load_values (InputIterator x);
165 
166  template<class OutputIterator, class SetOp>
167  void store_values (OutputIterator y, size_type i_receive, SetOp op) const;
168 
169 // accessors:
170 
171  size_type n_proc() const { return _multi_procs.size(); }
172  size_type n_data() const { return _multi_indices.size(); }
173 };
174 
175 
176 } // namespace rheolef
177 // -------------------------------------------------------------
178 // not inlined : longer code
179 // -------------------------------------------------------------
180 #include "rheolef/scatter_message.icc"
181 
182 #endif // _RHEOLEF_HAVE_MPI
183 #endif // _RHEOLEF_SCATTER_MESSAGE_H
field::size_type size_type
Definition: branch.cc:430
scatter_message(const value_type &init_value=value_type(), const allocator_type &alloc=allocator_type())
void resize(size_type n_data, size_type nproc)
std::list< std::pair< size_type, mpi::request > > requests
const std::vector< size_type > & indices() const
std::vector< size_type > local_slots_nonmatching
const std::vector< size_type > & starts() const
const std::vector< size_type > & procs() const
const std::vector< base_value_type > & values() const
scatter_message< std::vector< typename Container::size_type >, false > base
std::vector< base_value_type > _multi_values
const std::vector< size_type > & indices() const
std::vector< size_type > _multi_irecv2base_irecv
std::vector< base_value_type > & values()
const std::vector< size_type > & starts() const
const std::vector< size_type > & procs() const
result_type value_type
This file is part of Rheolef.