~chaffra/+junk/trilinos

« back to all changes in this revision

Viewing changes to packages/phdmesh/include/util/ParallelReduce.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme, Christophe Prud'homme, Johannes Ring
  • Date: 2009-12-13 12:53:22 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091213125322-in0nrdjc55deqsw9
Tags: 10.0.3.dfsg-1
[Christophe Prud'homme]
* New upstream release

[Johannes Ring]
* debian/patches/libname.patch: Add prefix 'libtrilinos_' to all
  libraries. 
* debian/patches/soname.patch: Add soversion to libraries.
* debian/watch: Update download URL.
* debian/control:
  - Remove python-numeric from Build-Depends (virtual package).
  - Remove automake and autotools from Build-Depends and add cmake to
    reflect switch to CMake.
  - Add python-support to Build-Depends.
* debian/rules: 
  - Cleanup and updates for switch to CMake.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <iosfwd>
33
33
#include <string>
34
34
#include <util/Parallel.hpp>
35
 
#include <util/FixedArray.hpp>
 
35
#include <util/SimpleArrayOps.hpp>
36
36
 
37
37
//------------------------------------------------------------------------
38
38
 
64
64
 *    ParallelMachine comm = ... ;
65
65
 *    double a[5] ;
66
66
 *    int    b[3] ;
67
 
 *    all_reduce( comm , ReduceSum<5>( a ) & ReduceMax<3>( b ) );
 
67
 *    all_reduce( comm , Sum<5>( a ) , Max<3>( b ) , ... );
68
68
 *
69
 
 *  Reduction options include:
70
 
 *    ReduceSum   <N>( T * )   // Summation
71
 
 *    ReduceProd  <N>( T * )   // Product
72
 
 *    ReduceMax   <N>( T * )   // Maximum
73
 
 *    ReduceMin   <N>( T * )   // Minimum
74
 
 *    ReduceBitOr <N>( T * )   // Bit-wise OR
75
 
 *    ReduceBitAnd<N>( T * )   // Bit-wise AND
 
69
 *  Reduction options include Sum, Prod, Max, Min, BitOr, and BitAnd
76
70
 */
77
 
template < class ReduceOp >
78
 
void all_reduce( ParallelMachine , const ReduceOp & );
79
71
 
80
72
}
81
73
 
83
75
//----------------------------------------------------------------------
84
76
 
85
77
namespace phdmesh {
 
78
 
 
79
extern "C" {
 
80
typedef void (*ParallelReduceOp)
 
81
  ( void * inv , void * outv , int * , ParallelDatatype * );
 
82
}
 
83
 
 
84
void all_reduce_internal( ParallelMachine  arg_comm ,
 
85
                          ParallelReduceOp arg_op ,
 
86
                          void           * arg_in ,
 
87
                          void           * arg_out ,
 
88
                          unsigned         arg_len );
 
89
 
86
90
namespace {
 
91
 
87
92
// Blank namespace so that this class produces local symbols,
88
93
// avoiding complaints from a linker of multiple-define symbols.
89
94
 
90
95
struct ReduceEnd {
91
 
  struct WorkType {};
92
 
  void copyin(  WorkType & ) const {}
93
 
  void copyout( WorkType & ) const {}
94
 
  static void op( WorkType & , WorkType & ) {}
 
96
  struct BufferType {};
 
97
  void copyin(  BufferType & ) const {}
 
98
  void copyout( BufferType & ) const {}
 
99
  static void op( BufferType & , BufferType & ) {}
95
100
};
96
101
 
97
102
// Workhorse class for aggregating reduction operations.
98
103
 
99
 
template <class Op, typename T, class Next>
 
104
template < class Oper , class Next = ReduceEnd >
100
105
struct Reduce {
101
 
 
102
 
  typedef T Type ;
103
 
  enum { N = Op::N };
104
 
 
105
 
  struct WorkType {
106
 
    typename Next::WorkType m_next ;
107
 
    Type                    m_value[N];
 
106
  typedef typename Oper::type Type ;
 
107
  enum { N = Oper::N };
 
108
 
 
109
  struct BufferType {
 
110
    Type                      m_value[N];
 
111
    typename Next::BufferType m_next ;
108
112
  };
109
113
 
110
114
  Next   m_next ;
111
 
  Type * m_value ;
112
 
 
113
 
  // Copy values into buffer:
114
 
  void copyin( WorkType & w ) const
115
 
    { Copy<N>( w.m_value , m_value ); m_next.copyin( w.m_next ); }
116
 
      
117
 
  // Copy value out from buffer:
118
 
  void copyout( WorkType & w ) const
119
 
    { Copy<N>( m_value , w.m_value ); m_next.copyout( w.m_next ); }
120
 
 
121
 
  // Reduction function
122
 
  static void op( WorkType & out , WorkType & in )
123
 
    { Op( out.m_value , in.m_value ); Next::op( out.m_next , in.m_next ); }
124
 
 
125
 
  // Aggregate reduction operations, use '&' for left-to-right evaluation
126
 
  template<class OpB, typename TB>
127
 
  Reduce<OpB, TB, Reduce<Op,T,Next> >
128
 
    operator & ( const Reduce<OpB,TB,ReduceEnd> & rhs )
129
 
      { return Reduce<OpB, TB, Reduce<Op,T,Next> >( rhs , *this ); }
130
 
 
131
 
  // Constructor for aggregation:
132
 
  Reduce( const Reduce<Op,T, ReduceEnd> & arg_val , const Next & arg_next )
133
 
    : m_next( arg_next ), m_value( arg_val.m_value ) {}
134
 
 
135
 
  // Constructor for aggregate member:
136
 
  explicit Reduce( Type * arg_value )
137
 
   : m_next(), m_value( arg_value ) {}
 
115
  Type * m_ptr ;
 
116
 
 
117
  Next & set( const Oper & arg ) { m_ptr = arg.ptr ; return m_next ; }
 
118
 
 
119
  void reduce( ParallelMachine comm ) const ;
 
120
 
 
121
  void copyin( BufferType & b ) const
 
122
    { Copy<N>( b.m_value , m_ptr ); m_next.copyin( b.m_next ); }
 
123
 
 
124
  void copyout( BufferType & b ) const
 
125
    { Copy<N>( m_ptr , b.m_value ); m_next.copyout( b.m_next ); }
 
126
 
 
127
  static void op( BufferType & dst , BufferType & src )
 
128
    { Oper::op(dst.m_value,src.m_value); Next::op(dst.m_next,src.m_next); }
138
129
 
139
130
  static void void_op( void*inv, void*inoutv, int*, ParallelDatatype*);
140
131
};
141
132
 
142
 
template <class Op, typename T, class Next>
143
 
void Reduce<Op,T,Next>::void_op( void*inv, void*inoutv,int*,ParallelDatatype*)
144
 
{
145
 
  op( * reinterpret_cast<WorkType*>( inoutv ) ,
146
 
      * reinterpret_cast<WorkType*>( inv ) );
147
 
}
148
 
 
149
 
}
150
 
}
 
133
template <class Oper, class Next>
 
134
void Reduce<Oper,Next>::void_op( void*inv, void*inoutv,int*,ParallelDatatype*)
 
135
{
 
136
  op( * reinterpret_cast<BufferType*>( inoutv ) ,
 
137
      * reinterpret_cast<BufferType*>( inv ) );
 
138
}
 
139
 
 
140
template <class Oper, class Next>
 
141
void Reduce<Oper,Next>::reduce( ParallelMachine comm ) const
 
142
{
 
143
  ParallelReduceOp f = reinterpret_cast<ParallelReduceOp>( & void_op );
 
144
  BufferType inbuf , outbuf ;
 
145
  copyin( inbuf );
 
146
  all_reduce_internal( comm , f , & inbuf , & outbuf , sizeof(BufferType) );
 
147
  copyout( outbuf );
 
148
}
 
149
 
 
150
} // namespace
 
151
} // namespace phdmesh
151
152
 
152
153
//----------------------------------------------------------------------
153
154
//----------------------------------------------------------------------
154
155
 
155
156
namespace phdmesh {
156
157
 
157
 
template<unsigned N, typename T>
158
 
inline
159
 
Reduce< Sum<N> , T, ReduceEnd> ReduceSum( T * value )
160
 
{ return Reduce< Sum<N>, T, ReduceEnd >( value ); }
161
 
 
162
 
template<unsigned N, typename T>
163
 
inline
164
 
Reduce< Prod<N>, T, ReduceEnd > ReduceProd( T * value )
165
 
{ return Reduce< Prod<N>, T, ReduceEnd >( value ); }
166
 
 
167
 
template<unsigned N, typename T>
168
 
inline
169
 
Reduce< Max<N>, T, ReduceEnd> ReduceMax( T * value )
170
 
{ return Reduce< Max<N>, T, ReduceEnd>( value ); }
171
 
 
172
 
template<unsigned N, typename T>
173
 
inline
174
 
Reduce< Min<N>, T, ReduceEnd> ReduceMin( T * value )
175
 
{ return Reduce<Min<N>, T, ReduceEnd>( value ); }
176
 
 
177
 
template<unsigned N, typename T>
178
 
inline
179
 
Reduce< BitOr<N>, T, ReduceEnd> ReduceBitOr( T * value )
180
 
{ return Reduce< BitOr<N>, T, ReduceEnd>( value ); }
181
 
 
182
 
template<unsigned N, typename T>
183
 
inline
184
 
Reduce< BitAnd<N>, T, ReduceEnd> ReduceBitAnd( T * value )
185
 
{ return Reduce< BitAnd<N>, T, ReduceEnd>( value ); }
186
 
 
187
 
//----------------------------------------------------------------------
188
 
// all_reduce( comm , ReduceSum<5>( A ) & ReduceMax<3>( B ) );
189
 
 
190
 
extern "C" {
191
 
typedef void (*ParallelReduceOp)
192
 
  ( void * inv , void * outv , int * , ParallelDatatype * );
193
 
}
194
 
 
195
 
void all_reduce( ParallelMachine  arg_comm ,
196
 
                 ParallelReduceOp arg_op ,
197
 
                 void           * arg_in ,
198
 
                 void           * arg_out ,
199
 
                 unsigned         arg_len );
200
 
 
201
 
namespace {
202
 
 
203
 
template < class ReduceOp >
204
 
void all_reduce_driver( ParallelMachine comm , const ReduceOp & op )
205
 
{
206
 
  typedef typename ReduceOp::WorkType WorkType ;
207
 
 
208
 
  WorkType inbuf , outbuf ;
209
 
 
210
 
  ParallelReduceOp f =
211
 
    reinterpret_cast<ParallelReduceOp>( & ReduceOp::void_op );
212
 
  op.copyin( inbuf );
213
 
  all_reduce( comm , f , & inbuf, & outbuf, sizeof(WorkType) );
214
 
  op.copyout( outbuf );
215
 
}
216
 
 
217
 
}
218
 
 
219
 
template < class ReduceOp >
220
 
inline
221
 
void all_reduce( ParallelMachine comm , const ReduceOp & op )
222
 
{ all_reduce_driver<ReduceOp>( comm , op ); }
 
158
template < class Op1 >
 
159
inline
 
160
void all_reduce( ParallelMachine comm , const Op1 & op1 )
 
161
{
 
162
  Reduce< Op1 > work ;
 
163
  work.set( op1 );
 
164
  work.reduce( comm );
 
165
}
 
166
 
 
167
template < class Op1 , class Op2 >
 
168
inline
 
169
void all_reduce( ParallelMachine comm , const Op1 & op1 ,
 
170
                                        const Op2 & op2 )
 
171
{
 
172
  Reduce< Op1 ,
 
173
  Reduce< Op2 > > work ;
 
174
  work.set( op1 ).set( op2 );
 
175
  work.reduce( comm );
 
176
}
 
177
 
 
178
template < class Op1 , class Op2 , class Op3 >
 
179
inline
 
180
void all_reduce( ParallelMachine comm , const Op1 & op1 ,
 
181
                                        const Op2 & op2 ,
 
182
                                        const Op3 & op3 )
 
183
{
 
184
  Reduce< Op1 ,
 
185
  Reduce< Op2 ,
 
186
  Reduce< Op3 > > > work ;
 
187
  work.set( op1 ).set( op2 ).set( op3 );
 
188
  work.reduce( comm );
 
189
}
 
190
 
 
191
template < class Op1 , class Op2 , class Op3 , class Op4 >
 
192
inline
 
193
void all_reduce( ParallelMachine comm , const Op1 & op1 ,
 
194
                                        const Op2 & op2 ,
 
195
                                        const Op3 & op3 ,
 
196
                                        const Op4 & op4 )
 
197
{
 
198
  Reduce< Op1 ,
 
199
  Reduce< Op2 ,
 
200
  Reduce< Op3 ,
 
201
  Reduce< Op4 > > > > work ;
 
202
  work.set( op1 ).set( op2 ).set( op3 ).set( op4 );
 
203
  work.reduce( comm );
 
204
}
 
205
 
 
206
template < class Op1 , class Op2 , class Op3 , class Op4 ,
 
207
           class Op5 >
 
208
inline
 
209
void all_reduce( ParallelMachine comm , const Op1 & op1 ,
 
210
                                        const Op2 & op2 ,
 
211
                                        const Op3 & op3 ,
 
212
                                        const Op4 & op4 ,
 
213
                                        const Op5 & op5 )
 
214
{
 
215
  Reduce< Op1 ,
 
216
  Reduce< Op2 ,
 
217
  Reduce< Op3 ,
 
218
  Reduce< Op4 ,
 
219
  Reduce< Op5 > > > > > work ;
 
220
  work.set( op1 ).set( op2 ).set( op3 ).set( op4 ).set( op5 );
 
221
  work.reduce( comm );
 
222
}
 
223
 
 
224
template < class Op1 , class Op2 , class Op3 , class Op4 ,
 
225
           class Op5 , class Op6 >
 
226
inline
 
227
void all_reduce( ParallelMachine comm , const Op1 & op1 ,
 
228
                                        const Op2 & op2 ,
 
229
                                        const Op3 & op3 ,
 
230
                                        const Op4 & op4 ,
 
231
                                        const Op5 & op5 ,
 
232
                                        const Op6 & op6 )
 
233
{
 
234
  Reduce< Op1 ,
 
235
  Reduce< Op2 ,
 
236
  Reduce< Op3 ,
 
237
  Reduce< Op4 ,
 
238
  Reduce< Op5 ,
 
239
  Reduce< Op6 > > > > > > work ;
 
240
  work.set( op1 ).set( op2 ).set( op3 ).set( op4 ).set( op5 ).set( op6 );
 
241
  work.reduce( comm );
 
242
}
223
243
 
224
244
}
225
245