28 #ifndef util_ParallelComm_hpp
29 #define util_ParallelComm_hpp
33 #include <util/Basics.hpp>
34 #include <util/Parallel.hpp>
67 const unsigned num_msg_bound ,
68 unsigned & num_msg_maximum ,
69 const unsigned *
const send_size ,
70 unsigned *
const recv_size ,
71 bool local_flag =
false );
76 const unsigned *
const send_size ,
77 unsigned *
const recv_size ,
78 bool local_flag =
false );
86 template<
typename T>
void pack(
const T & value );
89 template<
typename T>
void pack(
const T * value ,
size_t number );
92 template<
typename T>
void unpack( T & value );
95 template<
typename T>
void unpack( T * value ,
size_t number );
98 template<
typename T>
void peek( T & value );
101 template<
typename T>
void peek( T * value ,
size_t number );
104 template<
typename T>
void skip(
size_t number );
112 size_t capacity()
const ;
118 size_t size()
const ;
126 ptrdiff_t remaining()
const ;
129 void * buffer()
const ;
135 friend class CommAll ;
136 friend class CommGather ;
137 friend class CommBroadcast ;
139 static CommBuffer * allocate(
const unsigned,
const unsigned *
const );
140 static void deallocate(
const unsigned , CommBuffer * );
142 void pack_overflow()
const ;
143 void unpack_overflow()
const ;
145 CommBuffer(
const CommBuffer & );
146 CommBuffer & operator = (
const CommBuffer & );
148 typedef unsigned char * ucharp ;
160 ParallelMachine parallel()
const {
return m_comm ; }
161 unsigned parallel_size()
const {
return m_size ; }
162 unsigned parallel_rank()
const {
return m_rank ; }
165 CommBuffer & send_buffer(
unsigned )
const ;
168 CommBuffer & recv_buffer(
unsigned )
const ;
183 bool allocate_buffers( ParallelMachine ,
184 const unsigned num_msg_bounds ,
185 const unsigned *
const send_size ,
186 const unsigned *
const recv_size ,
187 const bool local_flag =
false );
202 explicit CommAll( ParallelMachine );
210 bool allocate_buffers(
const unsigned num_msg_bounds ,
211 const bool symmetric =
false ,
212 const bool local_flag =
false );
220 void swap_send_recv();
225 void reset_buffers();
231 CommAll(
const CommAll & );
232 CommAll & operator = (
const CommAll & );
234 void rank_error(
const char * ,
unsigned )
const ;
236 bool allocate_buffers(
const unsigned *
const send_size ,
237 const unsigned *
const recv_size ,
240 ParallelMachine m_comm ;
245 CommBuffer * m_send ;
246 CommBuffer * m_recv ;
251 class CommBroadcast {
254 ParallelMachine parallel()
const {
return m_comm ; }
255 unsigned parallel_size()
const {
return m_size ; }
256 unsigned parallel_rank()
const {
return m_rank ; }
259 CommBuffer & send_buffer();
262 CommBuffer & recv_buffer();
266 CommBroadcast( ParallelMachine ,
unsigned root_rank );
270 bool allocate_buffer(
const bool local_flag =
false );
277 CommBroadcast(
const CommBroadcast & );
278 CommBroadcast & operator = (
const CommBroadcast & );
280 ParallelMachine m_comm ;
283 unsigned m_root_rank ;
284 CommBuffer m_buffer ;
292 ParallelMachine parallel()
const {
return m_comm ; }
293 unsigned parallel_size()
const {
return m_size ; }
294 unsigned parallel_rank()
const {
return m_rank ; }
298 CommGather( ParallelMachine ,
unsigned root_rank ,
unsigned send_size );
300 CommBuffer & send_buffer() {
return m_send ; }
304 CommBuffer & recv_buffer(
unsigned );
311 CommGather(
const CommBroadcast & );
312 CommGather & operator = (
const CommBroadcast & );
314 ParallelMachine m_comm ;
317 unsigned m_root_rank ;
319 CommBuffer * m_recv ;
332 template<
unsigned N>
struct CommBufferAlign ;
335 struct CommBufferAlign<1> {
336 static size_t align(
size_t ) {
return 0 ; }
340 struct CommBufferAlign {
341 static size_t align(
size_t i ) { i %= N ;
return i ? ( N - i ) : 0 ; }
346 void CommBuffer::pack(
const T & value )
348 enum { Size =
sizeof(T) };
349 size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
351 if ( m_end < m_ptr + nalign + Size ) { pack_overflow(); }
352 while ( nalign ) { --nalign ; *m_ptr = 0 ; ++m_ptr ; }
353 T * tmp =
reinterpret_cast<T*
>(m_ptr);
355 m_ptr =
reinterpret_cast<ucharp
>( ++tmp );
358 m_ptr += nalign + Size ;
364 void CommBuffer::pack(
const T * value ,
size_t number )
366 enum { Size =
sizeof(T) };
367 size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
369 if ( m_end < m_ptr + nalign + number * Size ) { pack_overflow(); }
370 while ( nalign ) { --nalign ; *m_ptr = 0 ; ++m_ptr ; }
371 T * tmp =
reinterpret_cast<T*
>(m_ptr);
372 while ( number ) { --number ; *tmp = *value ; ++tmp ; ++value ; }
373 m_ptr =
reinterpret_cast<ucharp
>( tmp );
376 m_ptr += nalign + number * Size ;
382 void CommBuffer::skip(
size_t number )
384 enum { Size =
sizeof(T) };
385 m_ptr += CommBufferAlign<Size>::align( m_ptr - m_beg ) + Size * number ;
386 if ( m_beg && m_end < m_ptr ) { unpack_overflow(); }
391 void CommBuffer::unpack( T & value )
393 enum { Size =
sizeof(T) };
394 const size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
395 T * tmp =
reinterpret_cast<T*
>( m_ptr + nalign );
397 m_ptr =
reinterpret_cast<ucharp
>( ++tmp );
398 if ( m_end < m_ptr ) { unpack_overflow(); }
403 void CommBuffer::unpack( T * value ,
size_t number )
405 enum { Size =
sizeof(T) };
406 const size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
407 T * tmp =
reinterpret_cast<T*
>( m_ptr + nalign );
408 while ( number ) { --number ; *value = *tmp ; ++tmp ; ++value ; }
409 m_ptr =
reinterpret_cast<ucharp
>( tmp );
410 if ( m_end < m_ptr ) { unpack_overflow(); }
415 void CommBuffer::peek( T & value )
417 enum { Size =
sizeof(T) };
418 const size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
419 T * tmp =
reinterpret_cast<T*
>( m_ptr + nalign );
421 if ( m_end < reinterpret_cast<ucharp>(++tmp) ) { unpack_overflow(); }
426 void CommBuffer::peek( T * value ,
size_t number )
428 enum { Size =
sizeof(T) };
429 const size_t nalign = CommBufferAlign<Size>::align( m_ptr - m_beg );
430 T * tmp =
reinterpret_cast<T*
>( m_ptr + nalign );
431 while ( number ) { --number ; *value = *tmp ; ++tmp ; ++value ; }
432 if ( m_end < reinterpret_cast<ucharp>(tmp) ) { unpack_overflow(); }
436 void CommBuffer::reset()
440 size_t CommBuffer::capacity()
const
441 {
return m_end - m_beg ; }
444 size_t CommBuffer::size()
const
445 {
return m_ptr - m_beg ; }
448 ptrdiff_t CommBuffer::remaining()
const
449 {
return m_end - m_ptr ; }
452 void * CommBuffer::buffer()
const
453 {
return static_cast<void*
>( m_beg ); }
459 CommBuffer & CommAll::send_buffer(
unsigned p )
const
461 if ( m_size <= p ) { rank_error(
"send_buffer",p); }
466 CommBuffer & CommAll::recv_buffer(
unsigned p )
const
468 if ( m_size <= p ) { rank_error(
"recv_buffer",p); }
bool comm_dense_sizes(ParallelMachine, const unsigned *const send_size, unsigned *const recv_size, bool local_flag=false)
bool comm_sizes(ParallelMachine, const unsigned num_msg_bound, unsigned &num_msg_maximum, const unsigned *const send_size, unsigned *const recv_size, bool local_flag=false)