9 #ifndef stk_util_parallel_ParallelIndex_hpp 10 #define stk_util_parallel_ParallelIndex_hpp 17 #include <stk_util/parallel/Parallel.hpp> 18 #include <stk_util/parallel/ParallelComm.hpp> 19 #include <stk_util/util/PairIter.hpp> 24 template <
class K,
class P>
25 struct ParallelIndexDecomp
30 Proc operator()(
const Proc proc_size,
const Key key )
const {
31 return ( key >> 8 ) % proc_size ;
45 template <
class K = u
int64_t,
class P =
unsigned,
class D = ParallelIndexDecomp<K, P> >
51 typedef std::pair<Key, Proc> KeyProc ;
53 #ifndef DOXYGEN_COMPILE 55 bool operator()(
const KeyProc & lhs,
const KeyProc & rhs )
const {
59 bool operator()(
const KeyProc & lhs,
const Key rhs )
const {
60 return lhs.first < rhs ;
65 bool operator()(
const KeyProc & lhs,
const KeyProc & rhs )
const {
74 const std::vector<Key> & local )
83 pack_map( all, local );
85 all.allocate_buffers( p_size / 4,
false );
87 pack_map( all, local );
91 unpack_map( all, m_key_proc );
93 sort_unique( m_key_proc );
103 void query(std::vector<KeyProc> & global )
const 107 CommAll all( m_comm );
109 pack_query( all, m_key_proc );
111 all.allocate_buffers( p_size / 4,
false );
113 pack_query( all, m_key_proc );
117 unpack_query( all, global );
119 sort_unique( global );
127 void query(
const std::vector<Key> & local,
128 std::vector<KeyProc> & global )
const 132 std::vector<KeyProc> tmp ;
135 CommAll all( m_comm );
137 pack_map( all, local );
139 all.allocate_buffers( p_size / 4,
false );
141 pack_map( all, local );
145 unpack_map( all, tmp );
151 CommAll all( m_comm );
153 pack_query( all, m_key_proc, tmp );
155 all.allocate_buffers( p_size / 4,
false );
157 pack_query( all, m_key_proc, tmp );
161 unpack_query( all, global );
163 sort_unique( global );
168 void sort_unique( std::vector<KeyProc> & key_proc )
const 170 typename std::vector<KeyProc>::iterator i = key_proc.begin();
171 typename std::vector<KeyProc>::iterator j = key_proc.end();
173 std::sort( i, j, LessKeyProc() );
174 i = std::unique( i, j, EqualKeyProc() );
175 key_proc.erase( i, j );
178 void pack_map( CommAll & all,
const std::vector<Key> & local )
const 180 const unsigned p_size = all.parallel_size();
182 typename std::vector<Key>::const_iterator i ;
184 for ( i = local.begin() ; i != local.end() ; ++i ) {
185 const Key value = *i ;
186 const unsigned proc = m_decomp( p_size, value );
187 CommBuffer & buf = all.send_buffer(proc);
188 buf.pack<Key>( value );
192 void unpack_map( CommAll & all, std::vector< KeyProc > & key_proc )
const 194 const unsigned p_size = all.parallel_size();
197 for (
unsigned p = 0 ; p < p_size ; ++p ) {
198 count += all.recv_buffer( p ).capacity() /
sizeof(Key);
202 key_proc.reserve( count );
206 for (
unsigned p = 0 ; p < p_size ; ++p ) {
207 CommBuffer & buf = all.recv_buffer( p );
209 while ( buf.remaining() ) {
210 buf.unpack<Key>( value.first );
211 key_proc.push_back( value );
216 void pack_query( CommAll & all,
const std::vector< KeyProc > & key_proc )
const 220 typename std::vector< KeyProc >::const_iterator i ;
222 for ( i = key_proc.begin() ; i != key_proc.end() ; ) {
223 value.first = i->first ;
225 const typename std::vector< KeyProc >::const_iterator i_beg = i ;
227 for ( ; i != key_proc.end() && value.first == i->first ; ++i )
230 const typename std::vector< KeyProc >::const_iterator i_end = i ;
232 for ( i = i_beg ; i != i_end ; ++i ) {
233 CommBuffer & buf = all.send_buffer( i->second );
235 typename std::vector< KeyProc >::const_iterator j ;
237 for ( j = i_beg ; j != i_end ; ++j ) {
239 value.second = j->second ;
240 buf.pack<KeyProc>( value );
247 void pack_query( CommAll & all,
248 const std::vector< KeyProc > & key_proc_map,
249 const std::vector< KeyProc > &
query )
const 253 for (
typename std::vector< KeyProc >::const_iterator i =
query.begin() ; i !=
query.end() ; ) {
254 value.first = i->first ;
256 typename std::vector< KeyProc >::const_iterator key_begin = std::lower_bound( key_proc_map.begin(), key_proc_map.end(), value.first, LessKeyProc() );
258 typename std::vector< KeyProc >::const_iterator key_end = key_begin;
259 while ( key_end != key_proc_map.end() && key_end->first == value.first)
262 for ( ; i !=
query.end() && value.first == i->first ; ++i ) {
263 CommBuffer & buf = all.send_buffer( i->second );
265 for (
typename std::vector< KeyProc >::const_iterator j = key_begin ; j != key_end ; ++j ) {
266 value.second = j->second ;
267 buf.pack<KeyProc>( value );
273 void unpack_query( CommAll & all, std::vector< KeyProc > & key_proc )
const 275 const unsigned p_size = all.parallel_size();
279 for (
unsigned p = 0 ; p < p_size ; ++p ) {
280 CommBuffer & buf = all.recv_buffer( p );
281 while ( buf.remaining() ) {
282 buf.unpack<KeyProc>( entry );
283 key_proc.push_back( entry );
295 std::vector<KeyProc> m_key_proc ;
ParallelIndex(ParallelMachine comm, const std::vector< Key > &local)
Construct with locally-submitted keys.
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
void query(const std::vector< Key > &local, std::vector< KeyProc > &global) const
Query which processors submitted the given keys. The local processor is in the output if it submitted...
Parallel cross-reference index for a collection of 'Key' keys.
void query(std::vector< KeyProc > &global) const
Query which other processors submitted the same keys that the local processor submitted.
eastl::iterator_traits< InputIterator >::difference_type count(InputIterator first, InputIterator last, const T &value)