Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dots.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 
25 // Performs the operation: z = <x, y>
26 template <class data_type, int ytype>
27 void Rocblas::calcDot( void *yout, const Attribute *x, const Attribute *z,
28  const MPI_Comm *comm, const Attribute *mults) {
29 
31  "Unsupported attribute type");
33  (std::string("Incompatible data types between ")+
34  x->fullname()+" and "+z->fullname()).c_str());
35 
36  int num_dims = z->size_of_components();
37  COM_assertion_msg( num_dims == x->size_of_components(),
38  (std::string("Numbers of components do not match between ")+
39  x->fullname()+" and "+z->fullname()).c_str());
40 
41  std::vector<const Pane*> xpanes, zpanes, mpanes;
42  std::vector<Pane*> ypanes;
43 
44  z->window()->panes(zpanes);
45  x->window()->panes(xpanes);
46 
47  COM_assertion_msg( xpanes.size() == zpanes.size(),
48  (std::string("Numbers of panes do not match between ")+
49  x->window()->name()+" and "+z->window()->name()).c_str());
50 
51  std::vector<const Pane*>::const_iterator zit, zend, xit;
52  Pane **yit=NULL;
53 
54  Attribute *y=NULL;
55  data_type *yval=NULL;
56 
57  if ( ytype == BLAS_VOID) {
58  yval = reinterpret_cast<data_type *>( yout);
59  *yval = data_type(0);
60  }
61  else {
62  y = reinterpret_cast<Attribute *>(yout);
63 
64  if ( !y->is_windowed()) {
65  y->window()->panes(ypanes);
66  COM_assertion_msg(xpanes.size() == ypanes.size(),
67  (std::string("Numbers of panes do not match between ")+
68  x->fullname()+" and "+y->fullname()).c_str());
69  yit = &ypanes[0];
70  }
71  else {
73  (std::string("Numbers of items do not match between ")+
74  x->fullname()+" and "+y->fullname()).c_str());
75  yval = reinterpret_cast<data_type *>( y->pointer());
76 
77  COM_assertion_msg( yval, (std::string("Caught NULL pointer in ")+
78  y->fullname()).c_str());
79  }
80  }
81 
82  const int ynum_dims = ytype != BLAS_VOID?y->size_of_components():0;
83  COM_assertion_msg( ytype==BLAS_VOID || (ynum_dims==1 || ynum_dims==num_dims),
84  (std::string("Numbers of components do not match between ")+
85  z->fullname()+" and "+y->fullname()).c_str());
86 
87  // Initialize pointer to multiplicities
88  const Pane ** mit=NULL;
89  const int *mval=NULL;
90  if ( mults != NULL) {
92  mults->size_of_components()==1,
93  (std::string("Multiplier ")+mults->fullname()+
94  "must be integer scalars.").c_str());
95 
96  mults->window()->panes(mpanes);
97  COM_assertion_msg(xpanes.size() == mpanes.size(),
98  (std::string("Numbers of panes do not match between ")+
99  x->window()->name()+" and "+
100  mults->window()->name()).c_str());
101  mit = &mpanes[0];
102  }
103 
104  // Initialize y to 0 for BLAS_VOID or window attribute
105  if ( ytype == BLAS_VOID) {
106  *yval = data_type(0);
107  }
108  else {
109  if ( y->is_windowed()) {
110  for ( int i=0; i<ynum_dims; ++i) yval[i] = data_type(0);
111  }
112  }
113 
114  for( zit=zpanes.begin(), zend=zpanes.end(), xit=xpanes.begin();
115  zit!=zend; ++zit, ++xit, yit+=( ytype!=BLAS_VOID && yit)) {
116  const 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(),
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;
129 
130  Attribute *py = y;
131  if ( ytype != BLAS_VOID && !y->is_windowed()) {
132  // Obtain py and initialize to 0
133  py = (*yit)->attribute(y->id());
134  const int ynum_comp = py->size_of_components();
135  const int ylen = py->size_of_items();
136  COM_assertion_msg( ylen==1 || ylen==length,
137  (std::string("Numbers of items do not match between ")+
138  y->fullname()+" and "+z->fullname()+
139  " on pane "+to_str((*zit)->id())).c_str());
140 
141  yval = reinterpret_cast<data_type *>( py->pointer());
142 
143  if ( py->stride()==ynum_comp) {
144  for ( int i=0, ni=ynum_comp*ylen; i<ni; ++i) yval[i] = data_type(0);
145  }
146  else {
147  // Loop through the number of components
148  for (int i=0; i<ynum_comp; ++i) {
149  Attribute *py_i = ynum_comp>1?(*yit)->attribute( y->id()+i+1):py;
150  data_type *yv_i = reinterpret_cast<data_type*>(py_i->pointer());
151  const int strd=get_stride<BLAS_VEC2D>(py_i);
152  // loop through the stride
153  for ( int j=0, nj=ylen*strd; j<nj; j+=strd) yv_i[j] = data_type(0);
154  }
155  }
156  }
157  int ystrd = get_stride<ytype>(py);
158  const bool ystg = py && (ynum_dims!=num_dims || ynum_dims!=ystrd);
159 
160  // Obtain the multiplier
161  if ( mults != NULL) {
162  const Attribute *pm = (*mit)->attribute(mults->id());
164  (std::string("Numbers of items do not match between ")+
165  mults->fullname()+" and "+z->fullname()+
166  " on pane "+to_str((*zit)->id())).c_str());
167 
168  mval = reinterpret_cast<const int*>( pm->pointer());
169  ++mit;
170  }
171 
172  // Optimized version for contiguous attributes
173  if ( !xstg && !zstg && !ystg && mval == NULL) {
174  const data_type *xval = (const data_type *)px->pointer();
175  const data_type *zval = (const data_type *)pz->pointer();
176 
177  //Loop for each element/node and for each dimension
178  for(Size i = 0, s = length*num_dims; i<s; ++i, ++xval, ++zval)
179  getref<data_type,ytype,0>(yval,i,0,1) += *xval* *zval;
180  }
181  else { // General version
182  //Loop for each dimension.
183  for(int i = 0; i < num_dims; ++i) {
184  const Attribute *pz_i = num_dims==1?pz:(*zit)->attribute(z->id()+i+1);
185  const data_type *zval = (const data_type *)pz_i->pointer();
186  zstrd=get_stride<BLAS_VEC2D>(pz_i);
187 
188  const Attribute *px_i = num_dims==1?px:(*xit)->attribute(x->id()+i+1);
189  const data_type *xval = (const data_type *)px_i->pointer();
190  xstrd=get_stride<BLAS_VEC2D>(px_i);
191 
192  if ( ytype != BLAS_VOID && !y->is_windowed()) {
193  Attribute *py_i=ynum_dims==1?py:(*yit)->attribute(y->id()+i+1);
194  yval = reinterpret_cast<data_type *>( py_i->pointer());
195  ystrd = get_stride<ytype>( py_i);
196  }
197 
198  if ( mval != NULL) {
199  //Loop for each element/node.
200  for(int j=0; j<length; ++j, xval+=xstrd,zval+=zstrd)
201  getref<data_type,ytype,1>( yval,j,i,ystrd) += *xval* *zval / mval[j];
202  }
203  else
204  for(int j=0; j<length; ++j, xval+=xstrd,zval+=zstrd)
205  getref<data_type,ytype,1>( yval,j,i,ystrd) += *xval* *zval;
206  }
207  }
208  }
209 
210  if ( ( ytype==BLAS_VOID || ytype==BLAS_SCALAR || ytype==BLAS_VEC)
211  && comm && *comm!=MPI_COMM_NULL && COMMPI_Initialized()) {
212  int n = (ytype == BLAS_VEC) ? num_dims : 1;
213  COM_Type att_type = x->data_type();
214 
215  data_type t = *yval;
216  if ( att_type == COM_INT || att_type == COM_INTEGER) {
217  MPI_Allreduce( &t, yval, n, MPI_INT, MPI_SUM, *comm);
218  }
219  else {
220  MPI_Allreduce( &t, yval, n, MPI_DOUBLE, MPI_SUM, *comm);
221  }
222  }
223 }
224 
225 //Wrapper for dot product that produces a single scalar answer.
227  const MPI_Comm *comm, const Attribute *mults) {
228  COM_Type att_type = x->data_type();
229  const int zncomp = z->size_of_components();
230 
231  if ( att_type == COM_INT || att_type == COM_INTEGER) {
232  if ( z->is_windowed()) {
233  if ( zncomp == 1)
234  calcDot<int,BLAS_SCALAR>(z, x, y, comm, mults);
235  else
236  calcDot<int,BLAS_VEC>(z, x, y, comm, mults);
237  }
238  else {
239  if ( zncomp == 1)
240  calcDot<int,BLAS_SCNE>(z, x, y, comm, mults);
241  else
242  calcDot<int,BLAS_VEC2D>(z, x, y, comm, mults);
243  }
244  }
245  else {
246  COM_assertion_msg( att_type==COM_DOUBLE || att_type==COM_DOUBLE_PRECISION,
247  (std::string("Unsupported data type in ")+
248  x->fullname()).c_str());
249  if ( z->is_windowed()) {
250  if ( zncomp == 1)
251  calcDot<double,BLAS_SCALAR>(z, x, y, comm, mults);
252  else
253  calcDot<double,BLAS_VEC>(z, x, y, comm, mults);
254  }
255  else {
256  if ( zncomp == 1)
257  calcDot<double,BLAS_SCNE>(z, x, y, comm, mults);
258  else
259  calcDot<double,BLAS_VEC2D>(z, x, y, comm, mults);
260  }
261  }
262 }
263 
264 void Rocblas::dot_scalar_MPI( const Attribute *x, const Attribute *y, void *z,
265  const MPI_Comm *comm, const Attribute *mults) {
266  COM_Type att_type = x->data_type();
267 
268  if(att_type == COM_INT || att_type == COM_INTEGER)
269  calcDot<int,BLAS_VOID>(z, x, y, comm, mults);
270  else {
271  COM_assertion_msg(att_type == COM_DOUBLE||att_type == COM_DOUBLE_PRECISION,
272  (std::string("Unsupported data type in ")+
273  x->fullname()).c_str());
274  calcDot<double,BLAS_VOID>(z, x, y, comm, mults);
275  }
276 }
277 
279 void Rocblas::dot(const Attribute *x, const Attribute *y, Attribute *z,
280  const Attribute*mults)
281 { dot_MPI( x, y, z, NULL, mults); }
282 
283 void Rocblas::dot_scalar( const Attribute *x, const Attribute *y, void *z,
284  const Attribute *mults)
285 { dot_scalar_MPI( x, y, z, NULL, mults); }
286 
289  const Attribute*mults)
290 { dot_MPI( x, x, y, NULL, mults); }
291 
293 void Rocblas::nrm2_scalar(const Attribute *x, void *y,
294  const Attribute*mults)
295 { dot_scalar_MPI ( x, x, y, NULL, mults); }
296 
299  const MPI_Comm *comm, const Attribute*mults)
300 { dot_MPI ( x, x, y, comm, mults); }
301 
303 void Rocblas::nrm2_scalar_MPI(const Attribute *x, void *y,//
304  const MPI_Comm *comm, const Attribute *mults)
305 { dot_scalar_MPI ( x, x, y, comm, mults); }
306 
307 
308 
309 
310 
311 
312 
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
A Pane object contains a mesh, pane attribute, and field variables.
Definition: Pane.h:43
static void calcDot(void *zout, const Attribute *x, const Attribute *y, const MPI_Comm *comm=NULL, const Attribute *mults=NULL)
Performs the operation: z = &lt;x, y&gt;
Definition: dots.C:27
static void nrm2_scalar(const Attribute *x, void *y, const Attribute *mults=NULL)
Wrapper for 2-norm with y as a scalar pointer.
Definition: dots.C:293
An Attribute object is a data member of a window.
Definition: Attribute.h:51
void int int REAL REAL * y
Definition: read.cpp:74
static void nrm2_MPI(const Attribute *x, Attribute *y, const MPI_Comm *comm=NULL, const Attribute *mults=NULL)
Wrapper for 2-norm with MPI.
Definition: dots.C:298
#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 dot_scalar_MPI(const Attribute *x, const Attribute *y, void *z, const MPI_Comm *comm=NULL, const Attribute *mults=NULL)
Wrapper for 2-norm with z as a scalar pointer.
Definition: dots.C:264
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 dot_scalar(const Attribute *x, const Attribute *y, void *z, const Attribute *mults=NULL)
Wrapper for 2-norm with z as a scalar pointer.
Definition: dots.C:283
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
const NT & n
int stride() const
Obtain the stride of the attribute in base datatype.
Definition: Attribute.h:233
Definition for Rocblas API.
static std::string to_str(int i)
Definition: Rocblas.h:283
static void nrm2_scalar_MPI(const Attribute *x, void *y, const MPI_Comm *comm, const Attribute *mults=NULL)
Wrapper for 2-norm with y as a scalar pointer with MPI.
Definition: dots.C:303
unsigned int Size
Definition: Rocblas.h:38
j indices j
Definition: Indexing.h:6
void int int REAL REAL REAL *z blockDim dim * ni
Definition: read.cpp:77
void int * nj
Definition: read.cpp:74
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 nrm2(const Attribute *x, Attribute *y, const Attribute *mults=NULL)
Wrapper for 2-norm.
Definition: dots.C:288
static void dot(const Attribute *x, const Attribute *y, Attribute *z, const Attribute *mults=NULL)
Wrapper for dot product.
Definition: dots.C:279
void panes(std::vector< int > &ps, int rank=-2)
Obtain all the local panes of the window.
Definition: Window.C:809
static void dot_MPI(const Attribute *x, const Attribute *y, Attribute *z, const MPI_Comm *comm=NULL, const Attribute *mults=NULL)
Wrapper for dot product.
Definition: dots.C:226
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 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
int size_of_components() const
Obtain the number of components in the attribute.
Definition: Attribute.h:203