Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
op3args.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 "Rocblas.h"
24 #include <cmath>
25 #include <cstdlib>
26 
27 //Function object that implements a limit1 operation.
28 template <class T>
29 struct Rocblas::limit1v : std::binary_function<T,T,T> {
30  T operator()(T x, T y) {
31  if ( x>=0&&y>=0 || x<=0&&y<=0)
32  return std::abs(x)<std::abs(y)?x:y;
33  else
34  return 0;
35  }
36 };
37 
38 //Function object that implements a maxof operation.
39 template <class T>
40 struct Rocblas::maxof : std::binary_function<T,T,T> {
41  T operator()(T x, T y) {
42  if (x<y) return y;
43  else return x;
44  }
45 };
46 
47 // Performs the operation: z = x op y
48 template <class FuncType, int ytype>
49 void Rocblas::calc( Attribute *z, const Attribute *x, const void *yin,
50  FuncType opp, bool swap)
51 {
52  typedef typename FuncType::result_type data_type;
53 
55  (std::string("Unsupported data type in ")+
56  x->fullname()).c_str());
58  (std::string("Incompatible data types between ")+
59  x->fullname()+" and "+z->fullname()).c_str());
60 
61  int num_dims = z->size_of_components();
62  COM_assertion_msg( num_dims == x->size_of_components(),
63  (std::string("Numbers of components do not match between ")+
64  x->fullname()+" and "+z->fullname()).c_str());
65 
66  std::vector<Pane*> zpanes;
67  std::vector<const Pane*> xpanes, ypanes;
68 
69  z->window()->panes(zpanes);
70  x->window()->panes(xpanes);
71 
72  COM_assertion_msg( xpanes.size() == zpanes.size(),
73  (std::string("Numbers of panes do not match between ")+
74  x->window()->name()+" and "+z->window()->name()).c_str());
75 
76  std::vector<Pane*>::iterator zit, zend;
77  std::vector<const Pane*>::const_iterator xit;
78  const Pane **yit=NULL;
79 
80  const Attribute *y=NULL;
81  const data_type *yval=NULL;
82 
83  // Obtain yval for BLAS_VOID or window attributes
84  if ( ytype==BLAS_VOID)
85  yval = reinterpret_cast<const data_type *>( yin);
86  else {
87  y = reinterpret_cast<const Attribute *>(yin);
88 
89  if ( !y->is_windowed()) {
90  y->window()->panes(ypanes);
91  COM_assertion_msg(xpanes.size() == ypanes.size(),
92  (std::string("Numbers of panes do not match between ")+
93  x->window()->name()+" and "+
94  y->window()->name()).c_str());
95  yit = &ypanes[0];
96  }
97  else {
99  (std::string("Numbers of items do not match between ")+
100  x->fullname()+" and "+y->fullname()).c_str());
101 
102  yval = reinterpret_cast<const data_type *>( y->pointer());
103 
104  COM_assertion_msg( yval, (std::string("Caught NULL pointer in ")+
105  y->fullname()).c_str());
106  }
107  }
108 
109  const int ynum_dims = ytype!=BLAS_VOID ? y->size_of_components() : 0;
110  COM_assertion_msg( ytype==BLAS_VOID || (ynum_dims==1 || ynum_dims==num_dims),
111  (std::string("Numbers of components do not match between ")+
112  z->fullname()+" and "+y->fullname()).c_str());
113 
114  for( zit=zpanes.begin(), zend=zpanes.end(), xit=xpanes.begin(); zit!=zend;
115  ++zit, ++xit, yit+=( ytype!=BLAS_VOID && yit!=NULL)) {
116  Attribute *pz = (*zit)->attribute(z->id());
117  const int length = pz->size_of_items();
118  int zstrd=get_stride<BLAS_VEC2D>(pz);
119  const bool zstg = num_dims!=zstrd;
120 
121  const Attribute *px = (*xit)->attribute(x->id());
122  int xstrd = get_stride<BLAS_VEC2D>(px);
123  COM_assertion_msg(length == px->size_of_items() || xstrd==0,
124  (std::string("Numbers of items do not match between ")+
125  x->fullname()+" and "+z->fullname()+
126  " on pane "+to_str((*zit)->id())).c_str());
127 
128  const bool xstg = num_dims!=xstrd || xstrd==0;
129 
130  const Attribute *py = (ytype!=BLAS_VOID&&yit)?(*yit)->attribute(y->id()):y;
131  int ystrd = get_stride<ytype>(py);
132  COM_assertion_msg( ytype!=BLAS_SCNE && ytype!=BLAS_VEC2D ||
133  (length == int(py->size_of_items()) || ystrd==0),
134  (std::string("Numbers of items do not match between ")+
135  y->fullname()+" and "+z->fullname()+
136  " on pane "+to_str((*zit)->id())).c_str());
137 
138  const bool ystg = py && (ynum_dims!=num_dims || ynum_dims!=ystrd);
139 
140  // Optimized version for contiguous attributes
141  if ( !xstg && !zstg && !ystg && ytype != BLAS_VEC
142  && (ytype != BLAS_SCNE || num_dims==1)) {
143  const data_type *xval = (const data_type *)px->pointer();
144  data_type *zval = (data_type *)pz->pointer();
145 
146  // Get address for y if y is not window attribute
147  if ( ytype != BLAS_VOID && yit)
148  yval = reinterpret_cast<const data_type *>(py->pointer());
149 
150  //Loop for each element/node and for each dimension
151  if ( swap == false)
152  for(Size i = 0, s = length*num_dims; i<s; ++i, ++zval, ++xval)
153  *zval = opp( *xval, getref<data_type,ytype,0>(yval,i,0,1));
154  else
155  for(Size i = 0, s = length*num_dims; i<s; ++i, ++zval, ++xval)
156  *zval = opp( getref<data_type,ytype,0>(yval,i,0,1), *xval);
157  }
158  else { // General version
159  //Loop for each dimension.
160  for(int i = 0; i < num_dims; ++i) {
161  Attribute *pz_i = num_dims==1?pz:(*zit)->attribute(z->id()+i+1);
162  data_type *zval = (data_type *)pz_i->pointer();
163  zstrd=get_stride<BLAS_VEC2D>(pz_i);
164 
165  const Attribute *px_i = num_dims==1?px:(*xit)->attribute(x->id()+i+1);
166  const data_type *xval = (const data_type *)px_i->pointer();
167  xstrd=get_stride<BLAS_VEC2D>(px_i);
168 
169  if ( ytype != BLAS_VOID && yit) {
170  const Attribute *py_i=ynum_dims==1?py:(*yit)->attribute(y->id()+i+1);
171  yval = reinterpret_cast<const data_type *>( py_i->pointer());
172  ystrd = get_stride<ytype>( py_i);
173  }
174 
175  // Loop for each element/node.
176  if ( swap == false) {
177  for(int j = 0; j < length; ++j, zval+=zstrd, xval+=xstrd)
178  *zval = opp( *xval, getref<data_type,ytype,1>(yval,j,i,ystrd));
179  }
180  else {
181  for(int j = 0; j < length; ++j, zval+=zstrd, xval+=xstrd)
182  *zval = opp( getref<data_type,ytype,1>(yval,j,i,ystrd), *xval);
183  }
184  } // end for i
185  } // end if
186  } // end for
187 }
188 
189 
190 //Chooses which calc function to call based on type of y.
191 template <class FuncType>
193  FuncType opp)
194 {
195  typedef typename FuncType::result_type data_type;
196 
197  if (x->is_windowed()) {
198  if ( x->size_of_components() == 1)
199  calc<FuncType,BLAS_SCALAR>(z, y, x, opp, true);
200  else
201  calc<FuncType,BLAS_VEC>(z, y, x, opp, true);
202  }
203  else if (y->is_windowed()) {
204  if ( y->size_of_components() == 1)
205  calc<FuncType,BLAS_SCALAR>(z, x, y, opp, false);
206  else
207  calc<FuncType,BLAS_VEC>(z, x, y, opp, false);
208  }
209  else if ( x->size_of_components()<y->size_of_components()) {
210  calc<FuncType,BLAS_SCNE>(z, y, x, opp, true);
211  }
212  else {
213  if ( y->size_of_components() == 1)
214  calc<FuncType,BLAS_SCNE>(z, x, y, opp, false);
215  else
216  calc<FuncType,BLAS_VEC2D>(z, x, y, opp, false);
217  }
218 }
219 
220 //Operation wrapper for addition.
221 void Rocblas::add(const Attribute *x, const Attribute *y, Attribute *z)
222 {
223  COM_Type att_type = z->data_type();
224 
225  if(att_type == COM_INT || att_type == COM_INTEGER)
226  calcChoose(x, y, z, std::plus<int>());
227  else {
228  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
229  (std::string("Unsupported data type in ")+
230  z->fullname()).c_str());
231 
232  calcChoose(x, y, z, std::plus<double>());
233  }
234 }
235 
236 //Operation wrapper for subtraction.
237 void Rocblas::sub(const Attribute *x, const Attribute *y, Attribute *z)
238 {
239  COM_Type att_type = z->data_type();
240 
241  if(att_type == COM_INT || att_type == COM_INTEGER)
242  calcChoose(x, y, z, std::minus<int>());
243  else {
244  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
245  (std::string("Unsupported data type in ")+
246  z->fullname()).c_str());
247 
248  calcChoose(x, y, z, std::minus<double>());
249  }
250 }
251 
252 //Operation wrapper for multiplication.
253 void Rocblas::mul(const Attribute *x, const Attribute *y, Attribute *z)
254 {
255  COM_Type att_type = z->data_type();
256 
257  if(att_type == COM_INT || att_type == COM_INTEGER)
258  calcChoose(x, y, z, std::multiplies<int>());
259  else {
260  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
261  (std::string("Unsupported data type in ")+
262  z->fullname()).c_str());
263 
264  calcChoose(x, y, z, std::multiplies<double>());
265  }
266 }
267 
268 //Operation wrapper for division.
269 void Rocblas::div(const Attribute *x, const Attribute *y, Attribute *z)
270 {
271  COM_Type att_type = z->data_type();
272 
273  if(att_type == COM_INT || att_type == COM_INTEGER)
274  calcChoose(x, y, z, std::divides<int>());
275  else {
276  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
277  (std::string("Unsupported data type in ")+
278  z->fullname()).c_str());
279  calcChoose(x, y, z, std::divides<double>());
280  }
281 }
282 
283 //Operation wrapper for limit1.
285 {
286  COM_Type att_type = z->data_type();
287 
288  if(att_type == COM_INT || att_type == COM_INTEGER)
289  calcChoose(x, y, z, limit1v<int>());
290  else {
291  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
292  (std::string("Unsupported data type in ")+
293  z->fullname()).c_str());
294  calcChoose(x, y, z, limit1v<double>());
295  }
296 }
297 
298 //Operation wrapper for addition with y as a scalar pointer.
299 void Rocblas::add_scalar(const Attribute *x, const void *y, Attribute *z,
300  int swap)
301 {
302  COM_Type att_type = z->data_type();
303 
304  if(att_type == COM_INT || att_type == COM_INTEGER)
305  calc<std::plus<int>,BLAS_VOID>(z, x, y, std::plus<int>(), swap);
306  else {
307  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
308  (std::string("Unsupported data type in ")+
309  z->fullname()).c_str());
310  calc<std::plus<double>,BLAS_VOID>(z, x, y, std::plus<double>(), swap);
311  }
312 }
313 
314 //Operation wrapper for max of
315 void Rocblas::maxof_scalar(const Attribute *x, const void *y, Attribute *z,
316  int swap)
317 {
318  COM_Type att_type = z->data_type();
319 
320  if(att_type == COM_INT || att_type == COM_INTEGER)
321  calc<maxof<int>,BLAS_VOID>(z, x, y, maxof<int>(), swap);
322  else {
323  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
324  (std::string("Unsupported data type in ")+
325  z->fullname()).c_str());
326  calc<maxof<double>,BLAS_VOID>(z, x, y, maxof<double>(), swap);
327  }
328 }
329 
330 //Operation wrapper for subtraction with y as a scalar pointer.
331 void Rocblas::sub_scalar(const Attribute *x, const void *y, Attribute *z,
332  int swap)
333 {
334  COM_Type att_type = z->data_type();
335 
336  if(att_type == COM_INT || att_type == COM_INTEGER)
337  calc<std::minus<int>,BLAS_VOID>(z, x, y, std::minus<int>(), swap);
338  else {
339  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
340  (std::string("Unsupported data type in ")+
341  z->fullname()).c_str());
342  calc<std::minus<double>,BLAS_VOID>(z, x, y, std::minus<double>(), swap);
343  }
344 }
345 
346 //Operation wrapper for multiplication with y as a scalar pointer.
347 void Rocblas::mul_scalar(const Attribute *x, const void *y, Attribute *z,
348  int swap)
349 {
350  COM_Type att_type = z->data_type();
351 
352  if(att_type == COM_INT || att_type == COM_INTEGER)
353  calc<std::multiplies<int>,BLAS_VOID>(z, x, y, std::multiplies<int>(), swap);
354  else {
355  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
356  (std::string("Unsupported data type in ")+
357  z->fullname()).c_str());
358  calc<std::multiplies<double>,BLAS_VOID>(z, x, y, std::multiplies<double>(), swap);
359  }
360 }
361 
362 //Operation wrapper for division with y as a scalar pointer.
363 void Rocblas::div_scalar(const Attribute *x, const void *y, Attribute *z,
364  int swap)
365 {
366  COM_Type att_type = z->data_type();
367 
368  if(att_type == COM_INT || att_type == COM_INTEGER)
369  calc<std::divides<int>,BLAS_VOID>(z, x, y, std::divides<int>(), swap);
370  else {
371  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
372  (std::string("Unsupported data type in ")+
373  z->fullname()).c_str());
374  calc<std::divides<double>,BLAS_VOID>(z, x, y, std::divides<double>(), swap);
375  }
376 }
377 
378 
379 
380 
381 
382 
static void div_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for division with y as a scalar pointer.
Definition: op3args.C:363
static void sub(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for subtraction.
Definition: op3args.C:237
void swap(int &a, int &b)
Definition: buildface.cpp:88
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
T operator()(T x, T y)
Definition: op3args.C:30
A Pane object contains a mesh, pane attribute, and field variables.
Definition: Pane.h:43
static void calc(Attribute *z, const Attribute *x, const void *yin, FuncType opp, bool swap=false)
Performs the operation: z = x op y.
Definition: op3args.C:49
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
bool is_windowed() const
Checks whether the attribute is associated with the window.
Definition: Attribute.h:188
static void limit1(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for limit1.
Definition: op3args.C:284
const std::string & name() const
Obtain the window&#39;s name.
Definition: Window.h:92
const Window * window() const
Obtain a constant pointer to the parent window of the attribute.
Definition: Attribute.C:80
double length(Vector3D *const v, int n)
const void * pointer() const
Obtain a constant pointer to the physical address.
Definition: Attribute.h:150
static void add(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for addition.
Definition: op3args.C:221
static void mul_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for multiplication with y as a scalar pointer.
Definition: op3args.C:347
void int int int REAL REAL REAL * z
Definition: write.cpp:76
int COM_compatible_types(COM_Type type1, COM_Type type2)
Definition: roccom_c++.h:563
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
static void div(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for division.
Definition: op3args.C:269
static void calcChoose(const Attribute *x, const Attribute *y, Attribute *z, FuncType opp)
Chooses which calc function to call based on type of y.
Definition: op3args.C:192
Definition for Rocblas API.
static std::string to_str(int i)
Definition: Rocblas.h:283
unsigned int Size
Definition: Rocblas.h:38
j indices j
Definition: Indexing.h:6
T operator()(T x, T y)
Definition: op3args.C:41
NT abs(const NT &x)
Definition: number_utils.h:130
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
static void maxof_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for addition with y as a scalar pointer.
Definition: op3args.C:315
void panes(std::vector< int > &ps, int rank=-2)
Obtain all the local panes of the window.
Definition: Window.C:809
static void add_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for addition with y as a scalar pointer.
Definition: op3args.C:299
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
static void mul(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for multiplication.
Definition: op3args.C:253
int size_of_components() const
Obtain the number of components in the attribute.
Definition: Attribute.h:203
static void sub_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for subtraction with y as a scalar pointer.
Definition: op3args.C:331