00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00046
00047
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];
00055 const DataTypes::ValueType& rightVec=right.getVectorRO();
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
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
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
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
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
00127
00128
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
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 {
00144 binaryOp(leftVec,leftShape,left.getOffsetForTag(i->first),right.getVectorRO(), right.getShape(), right.getOffsetForTag(i->first), operation);
00145 }
00146 }
00147
00148
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
00161 DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, right.getVectorRO(),right.getShape(),0,operation);
00162
00163 }
00164
00165
00166
00167 template <class BinaryFunction>
00168 inline void binaryOp(DataExpanded& left, const DataReady& right,
00169 BinaryFunction operation)
00170 {
00171 int i,j;
00172 DataTypes::ValueType::size_type numDPPSample=left.getNumDPPSample();
00173 DataTypes::ValueType::size_type numSamples=left.getNumSamples();
00174 if (right.getRank()==0) {
00175
00176 const DataTypes::ShapeType& leftShape=left.getShape();
00177 DataTypes::ValueType& leftVec=left.getVectorRW();
00178
00179
00180 #pragma omp parallel for private(i,j) schedule(static)
00181 for (i=0;i<numSamples;i++) {
00182 for (j=0;j<numDPPSample;j++) {
00183 DataMaths::binaryOp(leftVec,leftShape,left.getPointOffset(i,j), right.getVectorRO()[right.getPointOffset(i,j)] ,operation);
00184 }
00185 }
00186 } else {
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(left.getVectorRW(),left.getShape(),left.getPointOffset(i,j), right.getVectorRO(), right.getShape(),right.getPointOffset(i,j), operation);
00191 }
00192 }
00193 }
00194 }
00195
00196
00197 }
00198
00199 #endif