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