Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
op2args.C
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 #include <functional>
24 #include <cmath>
25 #include <cstdlib>
26 #include <iostream>
27 #include "Rocblas.h"
28 
29 //Function object that implements an assignment.
30 template <class T_src, class T_trg>
31 struct Rocblas::assn : std::unary_function<T_src,T_trg> {
32  void operator()(T_trg &x, const T_src &y)
33  { x = y; }
34 };
35 
36 //Function object that implements a random number generator.
37 template <class T>
38 struct Rocblas::random : std::unary_function<T,T> {
39  void operator()(T &z, const T &a)
40  { int s = std::rand(); z = s%a; }
41 };
42 
43 template <>
44 struct Rocblas::random<double> : std::unary_function<double,double> {
45  void operator()(double &z, const double &a)
46  { int s = std::rand(); z = (a*s)/RAND_MAX; }
47 };
48 
49 //Function object that implements a swap.
50 template <class T>
51 struct Rocblas::swapp : std::unary_function<T,T> {
52  void operator()(T &x, T &y) {
53  T temp = x;
54  x = y;
55  y = temp;
56  }
57 };
58 
59 //Function object that implements a max operation.
60 template <class T>
61 struct Rocblas::maxv : std::unary_function<T,T> {
62  void operator()(const T &x, T &y) {
63  y = std::max( x, y);
64  }
65 };
66 
67 //Function object that implements a min operation.
68 template <class T>
69 struct Rocblas::minv : std::unary_function<T,T> {
70  void operator()(const T &x, T &y) {
71  y = std::min( x, y);
72  }
73 };
74 
75 //Function object that implements a sum operation.
76 template <class T>
77 struct Rocblas::sumv : std::unary_function<T,T> {
78  void operator()(const T &x, T &y) {
79  y = x + y;
80  }
81 };
82 
83 //Function object that implements a negation.
84 template <class T>
85 struct Rocblas::nega : std::unary_function<T,T> {
86  void operator()(T &x, const T &y) {
87  x = -y;
88  }
89 };
90 
91 //Function object that implements sqrt.
92 template <class T>
93 struct Rocblas::sqrta : std::unary_function<T,T> {
94  void operator()(T &x, const T &y) {
95  x = (T)std::sqrt((double)y);
96  }
97 };
98 
99 //Function object that implements acos.
100 template <class T>
101 struct Rocblas::acosa : std::unary_function<T,T> {
102  void operator()(T &x, const T &y) {
103  x = (T)std::acos((double)y);
104  }
105 };
106 
107 template < class T1, class T2> bool compare_types() { return true; }
108 template <> bool compare_types<int,int>() { return false; }
109 template <> bool compare_types<char,char>() { return false; }
110 template <> bool compare_types<double,double>() { return false; }
111 
112 // Performs the operation: y op z
113 template <class FuncType, int ytype>
114 void Rocblas::gen2arg( Attribute *z, void *yin, FuncType opp) {
115  typedef typename FuncType::argument_type argument_type;
116  typedef typename FuncType::result_type result_type;
117 
118  int num_dims = z->size_of_components();
119 
120  std::vector<Pane*> zpanes;
121  std::vector<Pane*>::iterator zit, zend;
122  z->window()->panes(zpanes);
123 
124  std::vector<Pane*> ypanes;
125  Pane **yit=NULL;
126  Attribute *y=NULL;
127  argument_type *yval=NULL;
128 
129  if ( ytype == BLAS_VOID) {
130  yval = reinterpret_cast<argument_type *>( yin);
131 
132  COM_assertion_msg( yval, std::string("Caught NULL pointer in scalar \
133 operand when processing "+z->fullname()).c_str());
134  }
135  else {
136  y = reinterpret_cast<Attribute *>(yin);
137  bool type_coercion = compare_types<argument_type,result_type>();
138 
139  COM_assertion_msg( type_coercion ||
141  (std::string("Incompatible data types between ")+
142  z->fullname()+" and "+y->fullname()).c_str());
143 
144  if ( !y->is_windowed()) {
145  y->window()->panes(ypanes);
146  COM_assertion_msg(zpanes.size() == ypanes.size(),
147  (std::string("Numbers of panes do not match between ")+
148  y->window()->name()+" and "+z->window()->name()).c_str());
149  yit = &ypanes[0];
150  }
151  else {
152  if ( y->size_of_items()!=1) {
153  std::cout << "Rocbals Error: The size-of-items of attribute "
154  << y->fullname() << " on pane " << y->pane()->id()
155  << " is " << y->size_of_items() << std::endl;
156  COM_assertion_msg( y->size_of_items()==1, "If an argument is a window \
157 attribute, then its number of items must be 1.");
158  }
159 
160  yval = reinterpret_cast<argument_type *>( y->pointer());
161 
162  COM_assertion_msg( yval, (std::string("Caught NULL pointer in ")+
163  y->fullname()).c_str());
164  }
165  }
166 
167  const int ynum_dims = ytype != BLAS_VOID?y->size_of_components():0;
168  COM_assertion_msg( ytype==BLAS_VOID || (ynum_dims==1 || ynum_dims==num_dims),
169  (std::string("Numbers of components do not match between ")+
170  y->fullname()+" and "+z->fullname()).c_str());
171 
172  if ( z->is_windowed()) {
173  COM_assertion_msg( ytype == BLAS_VOID || y->is_windowed(),
174  (std::string("Wrong type of operand")+
175  y->fullname()).c_str());
176  int zs=get_stride<BLAS_VEC2D>(z);
177  int ys=get_stride<ytype>(y);
178  result_type *zval = (result_type *)z->pointer();
179  int length = z->size_of_items();
180 
181  COM_assertion_msg( length==0 || ytype == BLAS_VOID || zval && yval,
182  (std::string("Caught NULL pointer in w-attribute ")+
183  z->fullname()+" or "+y->fullname()).c_str());
184 
185  if ( (length==1 || num_dims == zs) && ytype != BLAS_VEC) {
186  for ( Size i = 0, s = num_dims*length; i < s; ++i, ++zval)
187  opp( *zval, getref<argument_type,ytype,0>(yval,i,0,1));
188  }
189  else {
190  for(int i = 0; i < num_dims; ++i) {
191  Attribute *z_i = num_dims==1?z:z+i+1;
192  zval = (result_type *)z_i->pointer();
193  zs = get_stride<BLAS_VEC2D>(z_i);
194 
195  if ( ytype != BLAS_VOID) {
196  Attribute *y_i=ynum_dims==1?y:y+i+1;
197  yval = reinterpret_cast<argument_type *>( y_i->pointer());
198  ys = get_stride<ytype>( y_i);
199  }
200 
201  for(int j=0; j<length; ++j, zval+=zs)
202  opp( *zval, getref<argument_type,ytype,1>(yval,j,i,ys));
203  }
204  }
205  return;
206  }
207  // otherwise:
208 
209  for( zit=zpanes.begin(), zend=zpanes.end(); zit!=zend;
210  ++zit, yit+=( ytype!=BLAS_VOID&&yit)) {
211  Attribute *pz = (*zit)->attribute(z->id());
212  const int length = pz->size_of_items();
213  int zstrd=get_stride<BLAS_VEC2D>(pz);
214  const bool zstg = length>1 && num_dims!=zstrd;
215 
216  Attribute *py = ytype!=BLAS_VOID&&yit?(*yit)->attribute(y->id()):y;
217  int ystrd = get_stride<ytype>(py);
218  const bool ystg = py && (ynum_dims!=num_dims || ynum_dims!=ystrd);
219  COM_assertion_msg( ytype!=BLAS_SCNE && ytype!=BLAS_VEC2D ||
220  length == int(py->size_of_items()) || ystrd==0,
221  (std::string("Numbers of items do not match between ")+
222  y->fullname()+" and "+z->fullname()+
223  " on pane "+to_str((*zit)->id())).c_str());
224 
225  // Optimized version for contiguous attributes
226  if ( !zstg && !ystg && ytype != BLAS_VEC &&
227  (ytype != BLAS_SCNE || num_dims==1)) {
228  result_type *zval = reinterpret_cast<result_type *>(pz->pointer());
229 
230  if ( ytype != BLAS_VOID && yit)
231  yval = reinterpret_cast<argument_type *>(py->pointer());
232 
233  COM_assertion_msg( length==0 || ytype == BLAS_VOID || zval && yval,
234  (std::string("Caught NULL pointer in ")+
235  z->fullname()+" or "+y->fullname()+" on pane "+
236  to_str( (*zit)->id())).c_str());
237 
238  if ( zval)
239  //Loop for each element/node and for each dimension
240  for(int i = 0, s = length*num_dims; i < s; ++i, ++zval)
241  opp(*zval, getref<argument_type,ytype,0>(yval,i,0,1));
242  }
243  else { // General version
244  //Loop for each dimension.
245  for(int i = 0; i < num_dims; ++i) {
246  Attribute *pz_i = num_dims==1?pz:(*zit)->attribute(z->id()+i+1);
247  result_type *zval = (result_type *)pz_i->pointer();
248  zstrd=get_stride<BLAS_VEC2D>(pz_i);
249 
250  if ( ytype != BLAS_VOID && yit) {
251  Attribute *py_i=ynum_dims==1?py:(*yit)->attribute(y->id()+i+1);
252  yval = reinterpret_cast<argument_type *>( py_i->pointer());
253  ystrd = get_stride<ytype>( py_i);
254  }
255 
256  COM_assertion_msg( length==0 || ytype == BLAS_VOID || zval && yval,
257  (std::string("Caught NULL pointer in ")+
258  z->fullname()+" or "+y->fullname()+" on pane "+
259  to_str( (*zit)->id())).c_str());
260 
261  if ( zval)
262  for(int j=0; j < length; ++j, zval+=zstrd)
263  opp( *zval, getref<argument_type,ytype,1>(yval,j,i,ystrd));
264  }
265  }
266  }
267 }
268 
269 
270 //Wrapper for swap.
272  switch ( x->id()) {
273  case COM::COM_ATTS: {
275  "Aggregate attributes for swap must match.");
276 
277  // Obtain all the attributes of their corresponding windows
278  std::vector< Attribute*> x_attrs;
279  x->window()->attributes( x_attrs);
280 
281  std::vector< Attribute*> y_attrs;
282  y->window()->attributes( y_attrs);
283 
284  COM_assertion_msg( x_attrs.size() == y_attrs.size(),
285  (std::string("Numbers of attributes do not match between ")+
286  x->window()->name()+" and "+y->window()->name()).c_str());
287  // Copy all the individual attributes
288  for ( int i=x_attrs.size()-1; i>=0; --i)
289  swap( x_attrs[i], y_attrs[i]);
290  return;
291  }
292  case COM::COM_MESH:
293  case COM::COM_PMESH:
294  case COM::COM_CONN:
295  case COM::COM_ALL:
296  COM_assertion_msg(false, "Only the aggregate attribute atts is supported");
297  default: ;
298  }
299 
300  COM_Type att_type = x->data_type();
301 
302  if(att_type == COM_INT || att_type == COM_INTEGER)
303  gen2arg<swapp<int>,BLAS_VEC2D>(x, y, swapp<int>());
304  else if(att_type == COM_CHAR)
305  gen2arg<swapp<char>,BLAS_VEC2D>(x, y, swapp<char>());
306  else {
307  COM_assertion_msg(att_type == COM_DOUBLE || att_type == COM_DOUBLE_PRECISION,
308  (std::string("Unsupported data type in ")+
309  x->fullname()).c_str());
310  gen2arg<swapp<double>,BLAS_VEC2D>(x, y, swapp<double>());
311  }
312 }
313 
314 template < class Op>
316  int xncomp = x->size_of_components();
317 
318  if ( x->is_windowed()) {
319  if ( xncomp == 1)
320  gen2arg<Op,BLAS_SCALAR>(z, const_cast<Attribute*>(x), Op());
321  else
322  gen2arg<Op,BLAS_VEC>(z, const_cast<Attribute*>(x), Op());
323  }
324  else {
325  if ( xncomp == 1)
326  gen2arg<Op,BLAS_SCNE>(z, const_cast<Attribute*>(x), Op());
327  else
328  gen2arg<Op,BLAS_VEC2D>(z, const_cast<Attribute*>(x), Op());
329  }
330 }
331 
332 //Wrapper for copy.
334  switch ( x->id()) {
335  case COM::COM_ATTS: {
337  "Aggregate attributes for copy must match.");
338 
339  // Obtain all the attributes of their corresponding windows
340  std::vector< const Attribute*> x_attrs;
341  x->window()->attributes( x_attrs);
342 
343  std::vector< Attribute*> z_attrs;
344  z->window()->attributes( z_attrs);
345 
346  // Copy all the individual attributes
347  COM_assertion_msg( x_attrs.size() == z_attrs.size(),
348  (std::string("Numbers of attributes do not match between ")+
349  x->window()->name()+" and "+z->window()->name()).c_str());
350 
351  for ( int i=x_attrs.size()-1; i>=0; --i)
352  copy( x_attrs[i], z_attrs[i]);
353  return;
354  }
355  case COM::COM_MESH:
356  case COM::COM_PMESH:
357  case COM::COM_CONN:
358  case COM::COM_ALL:
359  COM_assertion_msg(false, "Only the aggregate attribute atts is supported");
360  default: ;
361  }
362 
363  COM_Type src_type = x->data_type(), trg_type = z->data_type();
364 
365  if ( src_type == COM_INT || src_type == COM_INTEGER) {
366  if ( trg_type == COM_DOUBLE || trg_type == COM_DOUBLE_PRECISION)
367  copy_helper<assn<int,double> >( x, z);
368  else
369  copy_helper<assn<int,int> >( x, z);
370  }
371  else if ( src_type == COM_CHAR) {
372  if ( trg_type == COM_INT || trg_type == COM_INTEGER)
373  copy_helper<assn<char,int> >( x, z);
374  else if ( trg_type == COM_DOUBLE || trg_type == COM_DOUBLE_PRECISION)
375  copy_helper<assn<char,double> >( x, z);
376  else
377  copy_helper<assn<char,char> >( x, z);
378  }
379  else {
380  COM_assertion_msg( src_type==COM_DOUBLE || src_type==COM_DOUBLE_PRECISION,
381  (std::string("Unsupported data type in ")+
382  x->fullname()).c_str());
383  copy_helper<assn<double,double> >( x, z);
384  }
385 }
386 
387 //Wrapper for rand.
389  switch ( x->id()) {
390  case COM::COM_ATTS: {
392  "Aggregate attributes for copy must match.");
393 
394  // Obtain all the attributes of their corresponding windows
395  std::vector< const Attribute*> x_attrs;
396  x->window()->attributes( x_attrs);
397 
398  std::vector< Attribute*> z_attrs;
399  z->window()->attributes( z_attrs);
400 
401  // Copy all the individual attributes
402  COM_assertion_msg( x_attrs.size() == z_attrs.size(),
403  (std::string("Numbers of attributes do not match between ")+
404  x->window()->name()+" and "+z->window()->name()).c_str());
405 
406  for ( int i=x_attrs.size()-1; i>=0; --i)
407  rand( x_attrs[i], z_attrs[i]);
408  return;
409  }
410  case COM::COM_MESH:
411  case COM::COM_PMESH:
412  case COM::COM_CONN:
413  case COM::COM_ALL:
414  COM_assertion_msg(false, "Only the aggregate attribute atts is supported");
415  default: ;
416  }
417 
418  COM_Type att_type = x->data_type();
419  const int xncomp = x->size_of_components();
420 
421  if ( att_type == COM_INT || att_type == COM_INTEGER) {
422  if ( x->is_windowed()) {
423  if ( xncomp == 1)
424  gen2arg<random<int>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), random<int>());
425  else
426  gen2arg<random<int>,BLAS_VEC>(z, const_cast<Attribute*>(x), random<int>());
427  }
428  else {
429  if ( xncomp == 1)
430  gen2arg<random<int>,BLAS_SCNE>(z, const_cast<Attribute*>(x), random<int>());
431  else
432  gen2arg<random<int>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), random<int>());
433  }
434  }
435  else {
436  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
437  (std::string("Unsupported data type in ")+
438  x->fullname()).c_str());
439  if ( x->is_windowed()) {
440  if ( xncomp == 1)
441  gen2arg<random<double>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), random<double>());
442  else
443  gen2arg<random<double>,BLAS_VEC>(z, const_cast<Attribute*>(x), random<double>());
444  }
445  else {
446  if ( xncomp == 1)
447  gen2arg<random<double>,BLAS_SCNE>(z, const_cast<Attribute*>(x), random<double>());
448  else
449  gen2arg<random<double>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), random<double>());
450  }
451  }
452 }
453 
454 //Wrapper for neg.
456  COM_Type att_type = x->data_type();
457  const int xncomp = x->size_of_components();
458 
459  if ( att_type == COM_INT || att_type == COM_INTEGER) {
460  if ( x->is_windowed()) {
461  if ( xncomp == 1)
462  gen2arg<nega<int>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), nega<int>());
463  else
464  gen2arg<nega<int>,BLAS_VEC>(z, const_cast<Attribute*>(x), nega<int>());
465  }
466  else {
467  if ( xncomp == 1)
468  gen2arg<nega<int>,BLAS_SCNE>(z, const_cast<Attribute*>(x), nega<int>());
469  else
470  gen2arg<nega<int>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), nega<int>());
471  }
472  }
473  else if ( att_type == COM_CHAR) {
474  if ( x->is_windowed()) {
475  if ( xncomp == 1)
476  gen2arg<nega<char>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), nega<char>());
477  else
478  gen2arg<nega<char>,BLAS_VEC>(z, const_cast<Attribute*>(x), nega<char>());
479  }
480  else {
481  if ( xncomp == 1)
482  gen2arg<nega<char>,BLAS_SCNE>(z, const_cast<Attribute*>(x), nega<char>());
483  else
484  gen2arg<nega<char>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), nega<char>());
485  }
486  }
487  else {
488  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
489  (std::string("Unsupported data type in ")+
490  x->fullname()).c_str());
491  if ( x->is_windowed()) {
492  if ( xncomp == 1)
493  gen2arg<nega<double>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), nega<double>());
494  else
495  gen2arg<nega<double>,BLAS_VEC>(z, const_cast<Attribute*>(x), nega<double>());
496  }
497  else {
498  if ( xncomp == 1)
499  gen2arg<nega<double>,BLAS_SCNE>(z, const_cast<Attribute*>(x), nega<double>());
500  else
501  gen2arg<nega<double>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), nega<double>());
502  }
503  }
504 }
505 
506 //Wrapper for sqrt.
508  COM_Type att_type = x->data_type();
509  const int xncomp = x->size_of_components();
510 
511  if ( att_type == COM_INT || att_type == COM_INTEGER) {
512  if ( x->is_windowed()) {
513  if ( xncomp == 1)
514  gen2arg<sqrta<int>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), sqrta<int>());
515  else
516  gen2arg<sqrta<int>,BLAS_VEC>(z, const_cast<Attribute*>(x), sqrta<int>());
517  }
518  else {
519  if ( xncomp == 1)
520  gen2arg<sqrta<int>,BLAS_SCNE>(z, const_cast<Attribute*>(x), sqrta<int>());
521  else
522  gen2arg<sqrta<int>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), sqrta<int>());
523  }
524  }
525  else {
526  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
527  (std::string("Unsupported data type in ")+
528  x->fullname()).c_str());
529  if ( x->is_windowed()) {
530  if ( xncomp == 1)
531  gen2arg<sqrta<double>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), sqrta<double>());
532  else
533  gen2arg<sqrta<double>,BLAS_VEC>(z, const_cast<Attribute*>(x), sqrta<double>());
534  }
535  else {
536  if ( xncomp == 1)
537  gen2arg<sqrta<double>,BLAS_SCNE>(z, const_cast<Attribute*>(x), sqrta<double>());
538  else
539  gen2arg<sqrta<double>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), sqrta<double>());
540  }
541  }
542 }
543 
544 //Wrapper for acos.
546  COM_Type att_type = x->data_type();
547  const int xncomp = x->size_of_components();
548 
549  if ( att_type == COM_INT || att_type == COM_INTEGER) {
550  if ( x->is_windowed()) {
551  if ( xncomp == 1)
552  gen2arg<acosa<int>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), acosa<int>());
553  else
554  gen2arg<acosa<int>,BLAS_VEC>(z, const_cast<Attribute*>(x), acosa<int>());
555  }
556  else {
557  if ( xncomp == 1)
558  gen2arg<acosa<int>,BLAS_SCNE>(z, const_cast<Attribute*>(x), acosa<int>());
559  else
560  gen2arg<acosa<int>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), acosa<int>());
561  }
562  }
563  else {
564  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
565  (std::string("Unsupported data type in ")+
566  x->fullname()).c_str());
567  if ( x->is_windowed()) {
568  if ( xncomp == 1)
569  gen2arg<acosa<double>,BLAS_SCALAR>(z, const_cast<Attribute*>(x), acosa<double>());
570  else
571  gen2arg<acosa<double>,BLAS_VEC>(z, const_cast<Attribute*>(x), acosa<double>());
572  }
573  else {
574  if ( xncomp == 1)
575  gen2arg<acosa<double>,BLAS_SCNE>(z, const_cast<Attribute*>(x), acosa<double>());
576  else
577  gen2arg<acosa<double>,BLAS_VEC2D>(z, const_cast<Attribute*>(x), acosa<double>());
578  }
579  }
580 }
581 
582 //Operation wrapper for copy (x is a scalar pointer).
583 void Rocblas::copy_scalar(const void *x, Attribute *z) {
584  COM_Type att_type = z->data_type();
585 
586  typedef assn<int,int> assn_int;
587  typedef assn<char,char> assn_chr;
588  typedef assn<double,double> assn_dbl;
589 
590  if ( att_type == COM_INT || att_type == COM_INTEGER)
591  gen2arg<assn_int,BLAS_VOID>(z, const_cast<void*>(x), assn_int());
592  else if ( att_type == COM_DOUBLE || att_type == COM_DOUBLE_PRECISION) {
593  gen2arg<assn_dbl,BLAS_VOID>(z, const_cast<void*>(x), assn_dbl());
594  }
595  else {
596  COM_assertion_msg( att_type==COM_CHAR,
597  (std::string("Unsupported data type in ")+
598  z->fullname()).c_str());
599  gen2arg<assn_chr,BLAS_VOID>(z, const_cast<void*>(x), assn_chr());
600  }
601 }
602 
603 // Generate a random number between 0 and $a$ for each entry in z
604 void Rocblas::rand_scalar(const void *a, Attribute *z) {
605  COM_Type att_type = z->data_type();
606 
607  if ( att_type == COM_INT || att_type == COM_INTEGER)
608  gen2arg<random<int>,BLAS_VOID>(z, const_cast<void*>(a), random<int>());
609  else {
610  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
611  (std::string("Unsupported data type in ")+
612  z->fullname()).c_str());
613  gen2arg<random<double>,BLAS_VOID>(z, const_cast<void*>(a), random<double>());
614  }
615 }
616 
618 
619 MPI_Op convert2mpiop( int i) {
620  switch (i) {
621  case BLAS_MIN: return MPI_MIN;
622  case BLAS_MAX: return MPI_MAX;
623  case BLAS_SUM: return MPI_SUM;
624  default: COM_assertion(false); return MPI_SUM; // Should never reach here.
625  }
626 }
627 
628 //Wrapper for reduce operations (including max, min, sum).
629 template <class OPint, class OPdbl, int OPMPI>
631  const MPI_Comm *comm, int initialI, double initialD) {
632  COM_Type att_type = z->data_type();
633  const int zncomp = z->size_of_components();
634 
635  if ( att_type == COM_INT || att_type == COM_INTEGER) {
636  copy_scalar( &initialI, z);
637 
638  if ( z->is_windowed()) {
639  if ( zncomp == 1)
640  gen2arg<OPint,BLAS_SCALAR>(const_cast<Attribute*>(x), z, OPint());
641  else
642  gen2arg<OPint,BLAS_VEC>(const_cast<Attribute*>(x), z, OPint());
643 
644  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
645  std::vector<int> t((int*)z->pointer(), ((int*)z->pointer())+zncomp);
646  MPI_Allreduce( &t[0], z->pointer(), zncomp, MPI_INT,
647  convert2mpiop(OPMPI), *comm);
648  }
649  }
650  else {
651  if ( zncomp == 1)
652  gen2arg<OPint,BLAS_SCNE>(const_cast<Attribute*>(x), z, OPint());
653  else
654  gen2arg<OPint,BLAS_VEC2D>(const_cast<Attribute*>(x), z, OPint());
655  }
656  }
657  else if ( att_type == COM_CHAR) {
658  copy_scalar( &initialI, z);
659 
660  if ( z->is_windowed()) {
661  if ( zncomp == 1)
662  gen2arg<OPint,BLAS_SCALAR>(const_cast<Attribute*>(x), z, OPint());
663  else
664  gen2arg<OPint,BLAS_VEC>(const_cast<Attribute*>(x), z, OPint());
665 
666  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
667  std::vector<char> t((char*)z->pointer(), ((char*)z->pointer())+zncomp);
668  MPI_Allreduce( &t[0], z->pointer(), zncomp, MPI_CHAR,
669  convert2mpiop(OPMPI), *comm);
670  }
671  }
672  else {
673  if ( zncomp == 1)
674  gen2arg<OPint,BLAS_SCNE>(const_cast<Attribute*>(x), z, OPint());
675  else
676  gen2arg<OPint,BLAS_VEC2D>(const_cast<Attribute*>(x), z, OPint());
677  }
678  }
679  else {
680  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
681  (std::string("Unsupported data type in ")+
682  z->fullname()).c_str());
683  copy_scalar( &initialD, z);
684 
685  if ( z->is_windowed()) {
686  if ( zncomp == 1)
687  gen2arg<OPdbl,BLAS_SCALAR>(const_cast<Attribute*>(x), z, OPdbl());
688  else
689  gen2arg<OPdbl,BLAS_VEC>(const_cast<Attribute*>(x), z, OPdbl());
690 
691  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
692  std::vector<double> t( (double*)z->pointer(),
693  ((double*)z->pointer())+zncomp);
694  MPI_Allreduce( &t[0], z->pointer(), zncomp, MPI_DOUBLE,
695  convert2mpiop(OPMPI), *comm);
696  }
697  }
698  else {
699  if ( zncomp == 1)
700  gen2arg<OPdbl,BLAS_SCNE>(const_cast<Attribute*>(x), z, OPdbl());
701  else
702  gen2arg<OPdbl,BLAS_VEC2D>(const_cast<Attribute*>(x), z, OPdbl());
703  }
704  }
705 }
706 
707 //Wrapper for max.
708 void Rocblas::max_MPI(const Attribute *x, Attribute *z, const MPI_Comm *comm) {
709  reduce_MPI< maxv<int>, maxv<double>, BLAS_MAX>( x, z, comm,
710  -0x7FFFFFFF, -HUGE_VAL);
711 }
712 
713 //Wrapper for min.
714 void Rocblas::min_MPI(const Attribute *x, Attribute *z, const MPI_Comm *comm) {
715  reduce_MPI< minv<int>, minv<double>, BLAS_MIN>( x, z, comm,
716  0x7FFFFFFF, HUGE_VAL);
717 }
718 
719 //Wrapper for sum.
720 void Rocblas::sum_MPI(const Attribute *x, Attribute *z, const MPI_Comm *comm) {
721  reduce_MPI< sumv<int>, sumv<double>, BLAS_SUM>( x, z, comm, 0, 0);
722 }
723 
724 //Operation wrapper for reduce operations (x is a scalar pointer).
725 template <class OPint, class OPdbl, int OPMPI>
727  const MPI_Comm *comm, int initialI, double initialD) {
728  COM_Type att_type = x->data_type();
729 
730  if ( att_type == COM_INT || att_type == COM_INTEGER) {
731  *(int*)y = initialI;
732  gen2arg<OPint,BLAS_VOID>(const_cast<Attribute*>(x), y, OPint());
733 
734  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
735  int t = *(int*)y;
736  MPI_Allreduce( &t, y, 1, MPI_INT, convert2mpiop(OPMPI), *comm);
737  }
738  }
739  else if ( att_type == COM_CHAR) {
740  *(char*)y = initialI;
741  gen2arg<OPint,BLAS_VOID>(const_cast<Attribute*>(x), y, OPint());
742 
743  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
744  char t = *(char*)y;
745  MPI_Allreduce( &t, y, 1, MPI_CHAR, convert2mpiop(OPMPI), *comm);
746  }
747  }
748  else {
749  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
750  (std::string("Unsupported data type in ")+
751  x->fullname()).c_str());
752  *(double*)y = initialD;
753  gen2arg<OPdbl,BLAS_VOID>(const_cast<Attribute*>(x), y, OPdbl());
754 
755  if ( comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
756  double t = *(double*)y;
757  MPI_Allreduce( &t, y, 1, MPI_DOUBLE, convert2mpiop(OPMPI), *comm);
758  }
759  }
760 }
761 
762 //Operation wrapper for max (y is a scalar pointer).
763 void Rocblas::max_scalar_MPI(const Attribute *x, void *y,
764  const MPI_Comm* comm) {
765  reduce_scalar_MPI< maxv<int>, maxv<double>, BLAS_MAX>(x, y, comm,
766  -0x7FFFFFFF, -HUGE_VAL);
767 
768 }
769 
770 //Operation wrapper for min (y is a scalar pointer).
771 void Rocblas::min_scalar_MPI(const Attribute *x, void *y,
772  const MPI_Comm *comm) {
773  reduce_scalar_MPI< minv<int>, minv<double>, BLAS_MIN>( x, y, comm,
774  0x7FFFFFFF, HUGE_VAL);
775 }
776 
777 //Operation wrapper for sum (y is a scalar pointer).
778 void Rocblas::sum_scalar_MPI(const Attribute *x, void *y,
779  const MPI_Comm *comm) {
780  reduce_scalar_MPI< sumv<int>, sumv<double>, BLAS_SUM>( x, y, comm, 0, 0);
781 }
782 
783 
784 
785 
786 
787 
static void reduce_MPI(const Attribute *x, Attribute *z, const MPI_Comm *comm, int, double)
Definition: op2args.C:630
void operator()(T &x, T &y)
Definition: op2args.C:52
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
void operator()(T &x, const T &y)
Definition: op2args.C:86
A Pane object contains a mesh, pane attribute, and field variables.
Definition: Pane.h:43
bool compare_types< double, double >()
Definition: op2args.C:110
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
void operator()(T &x, const T &y)
Definition: op2args.C:94
void operator()(const T &x, T &y)
Definition: op2args.C:70
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MAX
An Attribute object is a data member of a window.
Definition: Attribute.h:51
void int int REAL REAL * y
Definition: read.cpp:74
#define COM_assertion_msg(EX, msg)
double s
Definition: blastest.C:80
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
bool is_windowed() const
Checks whether the attribute is associated with the window.
Definition: Attribute.h:188
static void rand(const Attribute *a, Attribute *z)
Generate a random number between 0 and $a$ for each entry in z.
Definition: op2args.C:388
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MIN
void operator()(const T &x, T &y)
Definition: op2args.C:78
C/C++ Data types.
Definition: roccom_basic.h:129
static void max_scalar_MPI(const Attribute *x, void *y, const MPI_Comm *comm=NULL)
Operation wrapper for max (y is a scalar pointer).
Definition: op2args.C:763
void operator()(double &z, const double &a)
Definition: op2args.C:45
bool compare_types< char, char >()
Definition: op2args.C:109
const std::string & name() const
Obtain the window&#39;s name.
Definition: Window.h:92
double sqrt(double d)
Definition: double.h:73
const Window * window() const
Obtain a constant pointer to the parent window of the attribute.
Definition: Attribute.C:80
void operator()(T &z, const T &a)
Definition: op2args.C:39
void attributes(std::vector< Attribute * > &as)
Obtain all the attributes of the pane.
Definition: Window.h:328
double length(Vector3D *const v, int n)
static void min_MPI(const Attribute *x, Attribute *y, const MPI_Comm *comm=NULL)
Wrapper for min.
Definition: op2args.C:714
static void max_MPI(const Attribute *x, Attribute *y, const MPI_Comm *comm=NULL)
Wrapper for max.
Definition: op2args.C:708
static void acos(const Attribute *x, Attribute *y)
Wrapper for acos (y=acos(x)).
Definition: op2args.C:545
const void * pointer() const
Obtain a constant pointer to the physical address.
Definition: Attribute.h:150
bool compare_types()
Definition: op2args.C:107
void int int int REAL REAL REAL * z
Definition: write.cpp:76
bool compare_types< int, int >()
Definition: op2args.C:108
int COM_compatible_types(COM_Type type1, COM_Type type2)
Definition: roccom_c++.h:563
static void min_scalar_MPI(const Attribute *x, void *y, const MPI_Comm *comm=NULL)
Operation wrapper for min (y is a scalar pointer).
Definition: op2args.C:771
void operator()(T_trg &x, const T_src &y)
Definition: op2args.C:32
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
static void sum_scalar_MPI(const Attribute *x, void *y, const MPI_Comm *comm=NULL)
Operation wrapper for sum (y is a scalar pointer).
Definition: op2args.C:778
void operator()(const T &x, T &y)
Definition: op2args.C:62
static void sum_MPI(const Attribute *x, Attribute *y, const MPI_Comm *comm=NULL)
Wrapper for sum.
Definition: op2args.C:720
static void reduce_scalar_MPI(const Attribute *x, void *y, const MPI_Comm *comm, int, double)
Definition: op2args.C:726
Definition for Rocblas API.
static void neg(const Attribute *x, Attribute *y)
Wrapper for neg (y=-x).
Definition: op2args.C:455
static std::string to_str(int i)
Definition: Rocblas.h:283
const Pane * pane() const
Obtain a constant pointer to the owner pane of the attribute.
Definition: Attribute.h:172
static void copy_helper(const Attribute *x, Attribute *z)
Definition: op2args.C:315
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
static void gen2arg(Attribute *z, void *yin, FuncType opp)
Performs the operation opp(x, y)
Definition: op2args.C:114
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
Definition: op2args.C:583
unsigned int Size
Definition: Rocblas.h:38
void operator()(T &x, const T &y)
Definition: op2args.C:102
j indices j
Definition: Indexing.h:6
static void rand_scalar(const void *a, Attribute *z)
Generate a random number between 0 and $a$ for each entry in z.
Definition: op2args.C:604
static void swap(Attribute *x, Attribute *y)
Wrapper for swap.
Definition: op2args.C:271
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
Definition: op2args.C:333
double rand()
Return a random variable between [0,1] with respect to an uniform distribution.
Definition: CImg.h:4833
CImg< _cimg_Tfloat > acos(const CImg< T > &instance)
Definition: CImg.h:6051
COM_Type data_type() const
Obtain the data type of each component of the attribute.
Definition: Attribute.h:197
int id() const
Obtain the id (or index) of the attribute.
Definition: Attribute.h:120
int COMMPI_Initialized()
Definition: commpi.h:168
static void sqrt(const Attribute *x, Attribute *y)
Wrapper for sqrt (y=sqrt(x)).
Definition: op2args.C:507
void panes(std::vector< int > &ps, int rank=-2)
Obtain all the local panes of the window.
Definition: Window.C:809
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
int id() const
Get the ID of the pane.
Definition: Pane.h:96
int size_of_items() const
Obtain the number of items in the attribute.
Definition: Attribute.C:111
std::string fullname() const
Obtain the full name of the attribute including window name suitable for printing out error messages...
Definition: Attribute.C:82
MPI_Op convert2mpiop(int i)
Definition: op2args.C:619
int size_of_components() const
Obtain the number of components in the attribute.
Definition: Attribute.h:203