1 |
|
2 |
/* $Id$ */ |
3 |
|
4 |
/******************************************************* |
5 |
* |
6 |
* Copyright 2003-2007 by ACceSS MNRF |
7 |
* Copyright 2007 by University of Queensland |
8 |
* |
9 |
* http://esscc.uq.edu.au |
10 |
* Primary Business: Queensland, Australia |
11 |
* Licensed under the Open Software License version 3.0 |
12 |
* http://www.opensource.org/licenses/osl-3.0.php |
13 |
* |
14 |
*******************************************************/ |
15 |
|
16 |
#if !defined escript_BinaryOp_20040315_H |
17 |
#define escript_BinaryOp_20040315_H |
18 |
#include "system_dep.h" |
19 |
|
20 |
#include "DataArrayView.h" |
21 |
#include "DataConstant.h" |
22 |
#include "DataTagged.h" |
23 |
#include "DataExpanded.h" |
24 |
|
25 |
namespace escript { |
26 |
/** |
27 |
\brief |
28 |
Perform the given binary operation. |
29 |
\param left Input/Output - The left hand side. |
30 |
\param right Input - The right hand side. |
31 |
\param operation Input - The operation to perform. |
32 |
*/ |
33 |
template <class BinaryFunction> |
34 |
inline void binaryOp(DataTagged& left, const DataConstant& right, |
35 |
BinaryFunction operation) |
36 |
{ |
37 |
binaryOp(left,right.getPointDataView(),operation); |
38 |
} |
39 |
|
40 |
template <class BinaryFunction> |
41 |
inline void binaryOp(DataTagged& left, const DataArrayView& right, |
42 |
BinaryFunction operation) |
43 |
{ |
44 |
// |
45 |
// perform the operation on each tagged value |
46 |
const DataTagged::DataMapType& lookup=left.getTagLookup(); |
47 |
DataTagged::DataMapType::const_iterator i; |
48 |
DataTagged::DataMapType::const_iterator lookupEnd=lookup.end(); |
49 |
DataArrayView& leftView=left.getPointDataView(); |
50 |
if (right.getRank()==0) { |
51 |
for (i=lookup.begin();i!=lookupEnd;i++) { |
52 |
leftView.binaryOp(i->second,right(),operation); |
53 |
} |
54 |
} else { |
55 |
for (i=lookup.begin();i!=lookupEnd;i++) { |
56 |
leftView.binaryOp(i->second,right,right.getOffset(),operation); |
57 |
} |
58 |
} |
59 |
// |
60 |
// finally perform the operation on the default value |
61 |
if (right.getRank()==0) { |
62 |
left.getDefaultValue().binaryOp(0,right(),operation); |
63 |
} else { |
64 |
left.getDefaultValue().binaryOp(right,operation); |
65 |
} |
66 |
} |
67 |
|
68 |
template <class BinaryFunction> |
69 |
inline void binaryOp(DataTagged& left, const DataTagged& right, |
70 |
BinaryFunction operation) |
71 |
{ |
72 |
int right_rank=right.getPointDataView().getRank(); |
73 |
// |
74 |
// Add the right hand tag keys which can't currently be found on the left |
75 |
const DataTagged::DataMapType& rightLookup=right.getTagLookup(); |
76 |
DataTagged::DataMapType::const_iterator i; |
77 |
DataTagged::DataMapType::const_iterator rightLookupEnd=rightLookup.end(); |
78 |
for (i=rightLookup.begin();i!=rightLookupEnd;i++) { |
79 |
// |
80 |
// If the left does not already have a value assigned to this tag, |
81 |
// add the right hand tag to the left hand tag list and assign |
82 |
// the left's default value. |
83 |
if (!left.isCurrentTag(i->first)) { |
84 |
left.addTaggedValue(i->first,left.getDefaultValue()); |
85 |
} |
86 |
} |
87 |
// |
88 |
// Perform the operation. |
89 |
const DataTagged::DataMapType& leftLookup=left.getTagLookup(); |
90 |
DataTagged::DataMapType::const_iterator leftLookupEnd=leftLookup.end(); |
91 |
for (i=leftLookup.begin();i!=leftLookupEnd;i++) { |
92 |
if (right_rank==0) { |
93 |
left.getDataPointByTag(i->first).binaryOp(i->second,right.getDataPointByTag(i->first)(),operation); |
94 |
} else { |
95 |
left.getDataPointByTag(i->first).binaryOp(right.getDataPointByTag(i->first),operation); |
96 |
} |
97 |
} |
98 |
// |
99 |
// finally perform the operation on the default value |
100 |
if (right_rank==0) { |
101 |
left.getDefaultValue().binaryOp(0,right.getDefaultValue()(),operation); |
102 |
} else { |
103 |
left.getDefaultValue().binaryOp(right.getDefaultValue(),operation); |
104 |
} |
105 |
} |
106 |
|
107 |
template <class BinaryFunction> |
108 |
inline void binaryOp(DataConstant& left, const DataConstant& right, |
109 |
BinaryFunction operation) |
110 |
{ |
111 |
// |
112 |
// As DataConstant there is only one point data |
113 |
binaryOp(left,right.getPointDataView(),operation); |
114 |
} |
115 |
|
116 |
template <class BinaryFunction> |
117 |
inline void binaryOp(DataConstant& left, const DataArrayView& right, |
118 |
BinaryFunction operation) |
119 |
{ |
120 |
// |
121 |
// perform an operand check, this will throw on error |
122 |
if (right.getRank()==0) { |
123 |
// |
124 |
// special case of applying a single value to the entire array |
125 |
left.getPointDataView().binaryOp(right(),operation); |
126 |
} else { |
127 |
left.getPointDataView().binaryOp(right,operation); |
128 |
} |
129 |
} |
130 |
|
131 |
template <class BinaryFunction> |
132 |
inline void binaryOp(DataExpanded& left, const DataAbstract& right, |
133 |
BinaryFunction operation) |
134 |
{ |
135 |
int i,j; |
136 |
DataArrayView::ValueType::size_type numDPPSample=left.getNumDPPSample(); |
137 |
DataArrayView::ValueType::size_type numSamples=left.getNumSamples(); |
138 |
if (right.getPointDataView().getRank()==0) { |
139 |
// |
140 |
// This will call the double version of binaryOp |
141 |
#pragma omp parallel for private(i,j) schedule(static) |
142 |
for (i=0;i<numSamples;i++) { |
143 |
for (j=0;j<numDPPSample;j++) { |
144 |
left.getPointDataView().binaryOp(left.getPointOffset(i,j), |
145 |
right.getPointDataView().getData(right.getPointOffset(i,j)), |
146 |
operation); |
147 |
} |
148 |
} |
149 |
} else { |
150 |
#pragma omp parallel for private(i,j) schedule(static) |
151 |
for (i=0;i<numSamples;i++) { |
152 |
for (j=0;j<numDPPSample;j++) { |
153 |
left.getPointDataView().binaryOp(left.getPointOffset(i,j), |
154 |
right.getPointDataView(), |
155 |
right.getPointOffset(i,j), |
156 |
operation); |
157 |
} |
158 |
} |
159 |
} |
160 |
} |
161 |
|
162 |
template <class BinaryFunction> |
163 |
inline void binaryOp(DataExpanded& left, const DataArrayView& right, |
164 |
BinaryFunction operation) |
165 |
{ |
166 |
int i,j; |
167 |
DataArrayView::ValueType::size_type numDPPSample=left.getNumDPPSample(); |
168 |
DataArrayView::ValueType::size_type numSamples=left.getNumSamples(); |
169 |
if (right.getRank()==0) { |
170 |
// |
171 |
// This will call the double version of binaryOp |
172 |
#pragma omp parallel for private(i,j) schedule(static) |
173 |
for (i=0;i<numSamples;i++) { |
174 |
for (j=0;j<numDPPSample;j++) { |
175 |
left.getPointDataView().binaryOp(left.getPointOffset(i,j), |
176 |
right(), |
177 |
operation); |
178 |
} |
179 |
} |
180 |
} else { |
181 |
#pragma omp parallel for private(i,j) schedule(static) |
182 |
for (i=0;i<numSamples;i++) { |
183 |
for (j=0;j<numDPPSample;j++) { |
184 |
left.getPointDataView().binaryOp(left.getPointOffset(i,j), |
185 |
right, |
186 |
0, |
187 |
operation); |
188 |
} |
189 |
} |
190 |
} |
191 |
} |
192 |
|
193 |
} // end of namespace |
194 |
|
195 |
#endif |