ESYS13
Revision_
|
00001 00002 /******************************************************* 00003 * 00004 * Copyright (c) 2003-2012 by University of Queensland 00005 * Earth Systems Science Computational Center (ESSCC) 00006 * http://www.uq.edu.au/esscc 00007 * 00008 * Primary Business: Queensland, Australia 00009 * Licensed under the Open Software License version 3.0 00010 * http://www.opensource.org/licenses/osl-3.0.php 00011 * 00012 *******************************************************/ 00013 00014 00015 #if !defined escript_BinaryOp_20040315_H 00016 #define escript_BinaryOp_20040315_H 00017 #include "system_dep.h" 00018 00019 #include "DataTypes.h" 00020 #include "DataConstant.h" 00021 #include "DataTagged.h" 00022 #include "DataExpanded.h" 00023 #include "DataMaths.h" 00024 00033 namespace escript { 00041 template <class BinaryFunction> 00042 inline void binaryOp(DataTagged& left, const DataConstant& right, 00043 BinaryFunction operation) 00044 { 00045 // binaryOp(left,right.getPointDataView(),operation); 00046 // 00047 // perform the operation on each tagged value 00048 const DataTagged::DataMapType& lookup=left.getTagLookup(); 00049 DataTagged::DataMapType::const_iterator i; 00050 DataTagged::DataMapType::const_iterator lookupEnd=lookup.end(); 00051 DataTypes::ValueType& leftVec=left.getVectorRW(); 00052 const DataTypes::ShapeType& leftShape=left.getShape(); 00053 const DataTypes::ShapeType& rightShape=right.getShape(); 00054 double rvalue=right.getVectorRO()[0]; // for rank==0 00055 const DataTypes::ValueType& rightVec=right.getVectorRO(); // for rank>0 00056 if (right.getRank()==0) { 00057 for (i=lookup.begin();i!=lookupEnd;i++) { 00058 DataMaths::binaryOp(leftVec,leftShape,i->second,rvalue,operation); 00059 } 00060 } else { 00061 for (i=lookup.begin();i!=lookupEnd;i++) { 00062 DataMaths::binaryOp(leftVec, leftShape, i->second,rightVec,rightShape,0,operation); 00063 } 00064 } 00065 // 00066 // finally perform the operation on the default value 00067 if (right.getRank()==0) { 00068 DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rvalue,operation); 00069 } else { 00070 DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rightVec,rightShape,0,operation); 00071 } 00072 } 00073 00079 template <class BinaryFunction> 00080 inline void binaryOp(DataTagged& left, const DataTypes::ValueType& right, 00081 const DataTypes::ShapeType& shape, 00082 BinaryFunction operation) 00083 { 00084 // 00085 // perform the operation on each tagged value 00086 const DataTagged::DataMapType& lookup=left.getTagLookup(); 00087 DataTagged::DataMapType::const_iterator i; 00088 DataTagged::DataMapType::const_iterator lookupEnd=lookup.end(); 00089 DataTypes::ValueType& lvec=left.getVectorRW(); 00090 const DataTypes::ShapeType& lshape=left.getShape(); 00091 if (DataTypes::getRank(shape)==0) { 00092 for (i=lookup.begin();i!=lookupEnd;i++) { 00093 DataMaths::binaryOp(lvec, lshape,i->second,right[0],operation); 00094 } 00095 } else { 00096 for (i=lookup.begin();i!=lookupEnd;i++) { 00097 DataMaths::binaryOp(lvec, lshape, i->second,right,shape,0,operation); 00098 } 00099 } 00100 // 00101 // finally perform the operation on the default value 00102 if (DataTypes::getRank(shape)==0) { 00103 DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right[0],operation); 00104 } else { 00105 DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right, shape,0,operation); 00106 } 00107 } 00108 00109 00110 00111 00112 template <class BinaryFunction> 00113 inline void binaryOp(DataTagged& left, const DataTagged& right, 00114 BinaryFunction operation) 00115 { 00116 using namespace DataMaths; 00117 00118 int right_rank=right.getRank(); 00119 // 00120 // Add the right hand tag keys which can't currently be found on the left 00121 const DataTagged::DataMapType& rightLookup=right.getTagLookup(); 00122 DataTagged::DataMapType::const_iterator i; 00123 DataTagged::DataMapType::const_iterator rightLookupEnd=rightLookup.end(); 00124 for (i=rightLookup.begin();i!=rightLookupEnd;i++) { 00125 // 00126 // If the left does not already have a value assigned to this tag, 00127 // add the right hand tag to the left hand tag list and assign 00128 // the left's default value. 00129 if (!left.isCurrentTag(i->first)) { 00130 left.addTag(i->first); 00131 } 00132 } 00133 DataTypes::ValueType& leftVec=left.getVectorRW(); 00134 const DataTypes::ShapeType& leftShape=left.getShape(); 00135 // 00136 // Perform the operation. 00137 const DataTagged::DataMapType& leftLookup=left.getTagLookup(); 00138 DataTagged::DataMapType::const_iterator leftLookupEnd=leftLookup.end(); 00139 for (i=leftLookup.begin();i!=leftLookupEnd;i++) { 00140 if (right_rank==0) { 00141 binaryOp(leftVec,leftShape,i->second, right.getDataByTagRO(i->first,0),operation); 00142 00143 } else { // rank>0 00144 binaryOp(leftVec,leftShape,left.getOffsetForTag(i->first),right.getVectorRO(), right.getShape(), right.getOffsetForTag(i->first), operation); 00145 } 00146 } 00147 // 00148 // finally perform the operation on the default value 00149 if (right_rank==0) { 00150 binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO()[0],operation); 00151 } else { 00152 binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO(), right.getShape(), right.getDefaultOffset(), operation); 00153 } 00154 } 00155 00156 template <class BinaryFunction> 00157 inline void binaryOp(DataConstant& left, const DataConstant& right, 00158 BinaryFunction operation) 00159 { 00160 if (right.getRank()==0) { 00161 double r=right.getVectorRO()[0]; 00162 DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, r,operation); 00163 } else { 00164 DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, right.getVectorRO(),right.getShape(),0,operation); 00165 } 00166 00167 } 00168 00169 00170 00171 template <class BinaryFunction> 00172 inline void binaryOp(DataExpanded& left, const DataReady& right, 00173 BinaryFunction operation) 00174 { 00175 int i,j; 00176 DataTypes::ValueType::size_type numDPPSample=left.getNumDPPSample(); 00177 DataTypes::ValueType::size_type numSamples=left.getNumSamples(); 00178 if (right.getRank()==0) { 00179 00180 const DataTypes::ShapeType& leftShape=left.getShape(); 00181 DataTypes::ValueType& leftVec=left.getVectorRW(); 00182 // 00183 // This will call the double version of binaryOp 00184 #pragma omp parallel for private(i,j) schedule(static) 00185 for (i=0;i<numSamples;i++) { 00186 for (j=0;j<numDPPSample;j++) { 00187 DataMaths::binaryOp(leftVec,leftShape,left.getPointOffset(i,j), right.getVectorRO()[right.getPointOffset(i,j)] ,operation); 00188 } 00189 } 00190 } else { 00191 #pragma omp parallel for private(i,j) schedule(static) 00192 for (i=0;i<numSamples;i++) { 00193 for (j=0;j<numDPPSample;j++) { 00194 DataMaths::binaryOp(left.getVectorRW(),left.getShape(),left.getPointOffset(i,j), right.getVectorRO(), right.getShape(),right.getPointOffset(i,j), operation); 00195 } 00196 } 00197 } 00198 } 00199 00200 00201 } // end of namespace 00202 00203 #endif