/[escript]/branches/clazy/escriptcore/src/DataLazy.cpp
ViewVC logotype

Contents of /branches/clazy/escriptcore/src/DataLazy.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1879 - (show annotations)
Tue Oct 14 03:54:42 2008 UTC (10 years, 6 months ago) by jfenwick
Original Path: branches/schroedinger/escript/src/DataLazy.cpp
File size: 9053 byte(s)
Branch commit.
About to make some changes.

1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2008 by University of Queensland
5 * Earth Systems Science Computational Center (ESSCC)
6 * http://www.uq.edu.au/esscc
7 *
8 * Primary Business: Queensland, Australia
9 * Licensed under the Open Software License version 3.0
10 * http://www.opensource.org/licenses/osl-3.0.php
11 *
12 *******************************************************/
13
14
15 #include "DataLazy.h"
16 #ifdef USE_NETCDF
17 #include <netcdfcpp.h>
18 #endif
19 #ifdef PASO_MPI
20 #include <mpi.h>
21 #endif
22 #include "FunctionSpace.h"
23 #include "DataTypes.h"
24 #include "Data.h"
25
26 using namespace std;
27 using namespace boost;
28
29 namespace escript
30 {
31
32 const std::string&
33 opToString(ES_optype op);
34
35 namespace
36 {
37
38 // return the FunctionSpace of the result of "left op right"
39 FunctionSpace
40 resultFS(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
41 {
42 // perhaps this should call interpolate and throw or something?
43 // maybe we need an interpolate node -
44 // that way, if interpolate is required in any other op we can just throw a
45 // programming error exception.
46
47
48 if (left->getFunctionSpace()!=right->getFunctionSpace())
49 {
50 throw DataException("FunctionSpaces not equal - interpolation not supported on lazy data.");
51 }
52 return left->getFunctionSpace();
53 }
54
55 // return the shape of the result of "left op right"
56 DataTypes::ShapeType
57 resultShape(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
58 {
59 if (left->getShape()!=right->getShape())
60 {
61 throw DataException("Shapes not the same - shapes must match for lazy data.");
62 }
63 return left->getShape();
64 }
65
66 size_t
67 resultLength(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
68 {
69 switch(op)
70 {
71 // case IDENTITY: return left->getLength();
72 case ADD: // the length is preserved in these ops
73 case SUB:
74 case MUL:
75 case DIV: return left->getLength();
76 default:
77 throw DataException("Programmer Error - attempt to getLength() for operator "+opToString(op)+".");
78
79 }
80 }
81
82 int
83 calcBuffs(const DataLazy_ptr& left, const DataLazy_ptr& right, ES_optype op)
84 {
85 switch(op)
86 {
87 case IDENTITY: return 0;
88 case ADD: // the length is preserved in these ops
89 case SUB:
90 case MUL:
91 case DIV: return max(left->getBuffsRequired(),right->getBuffsRequired());
92 default:
93 throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");
94 }
95 }
96
97 string ES_opstrings[]={"UNKNOWN","IDENTITY","+","-","*","/"};
98 int ES_opcount=5;
99
100 // void performOp(ValueType& v, int startOffset, ES_optype op, int m_samplesize)
101 // {
102 // switch(op)
103 // {
104 // case ADD: DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),
105 // startOffset+m_samplesize,plus<double>());
106 // break;
107 // case SUB: DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),
108 // startOffset+m_samplesize,minus<double>());
109 // break;
110 // case MUL: DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),
111 // startOffset+m_samplesize,multiplies<double>());
112 // break;
113 // case DIV: DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),
114 // startOffset+m_samplesize,divides<double>());
115 // break;
116 // default:
117 // throw DataException("Programmer Error - attempt to performOp() for operator "+opToString(op)+".");
118 // }
119 //
120 // }
121
122 } // end anonymous namespace
123
124
125 const std::string&
126 opToString(ES_optype op)
127 {
128 if (op<0 || op>=ES_opcount)
129 {
130 op=UNKNOWNOP;
131 }
132 return ES_opstrings[op];
133 }
134
135
136 DataLazy::DataLazy(DataAbstract_ptr p)
137 : parent(p->getFunctionSpace(),p->getShape()),
138 m_op(IDENTITY)
139 {
140 if (p->isLazy())
141 {
142 // TODO: fix this. We could make the new node a copy of p?
143 // I don't want identity of Lazy.
144 // Question: Why would that be so bad?
145 // Answer: We assume that the child of ID is something we can call getVector on
146 throw DataException("Programmer error - attempt to create identity from a DataLazy.");
147 }
148 else
149 {
150 m_id=dynamic_pointer_cast<DataReady>(p);
151 }
152 m_length=p->getLength();
153 m_buffsRequired=0;
154 m_samplesize=getNumDPPSample()*getNoValues();
155 cout << "(1)Lazy created with " << m_samplesize << endl;
156 }
157
158 DataLazy::DataLazy(DataLazy_ptr left, DataLazy_ptr right, ES_optype op)
159 : parent(resultFS(left,right,op), resultShape(left,right,op)),
160 m_left(left),
161 m_right(right),
162 m_op(op)
163 {
164 m_length=resultLength(m_left,m_right,m_op);
165 m_samplesize=getNumDPPSample()*getNoValues();
166 m_buffsRequired=calcBuffs(m_left, m_right, m_op);
167 cout << "(2)Lazy created with " << m_samplesize << endl;
168 }
169
170 DataLazy::DataLazy(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
171 : parent(resultFS(left,right,op), resultShape(left,right,op)),
172 m_op(op)
173 {
174 if (left->isLazy())
175 {
176 m_left=dynamic_pointer_cast<DataLazy>(left);
177 }
178 else
179 {
180 m_left=DataLazy_ptr(new DataLazy(left));
181 }
182 if (right->isLazy())
183 {
184 m_right=dynamic_pointer_cast<DataLazy>(right);
185 }
186 else
187 {
188 m_right=DataLazy_ptr(new DataLazy(right));
189 }
190
191 m_length=resultLength(m_left,m_right,m_op);
192 m_samplesize=getNumDPPSample()*getNoValues();
193 m_buffsRequired=calcBuffs(m_left, m_right,m_op);
194 cout << "(3)Lazy created with " << m_samplesize << endl;
195 }
196
197
198 DataLazy::~DataLazy()
199 {
200 }
201
202
203 int
204 DataLazy::getBuffsRequired() const
205 {
206 return m_buffsRequired;
207 }
208
209 void
210 DataLazy::resolveSample(ValueType& v,int sampleNo, size_t offset ) const
211 {
212 if (m_op==IDENTITY) // copy the contents into the vector
213 {
214 cout << "Begin ID" << endl;
215 cout << "dpps=" << getNumDPPSample() << " novals=" << getNoValues() << endl;
216 const ValueType& vec=m_id->getVector();
217 size_t srcOffset=m_id->getPointOffset(sampleNo, 0);
218 cout << "v.size()=" << v.size() << " vec=" << vec.size() << endl;
219 for (size_t i=0;i<m_samplesize;++i,++srcOffset,++offset)
220 {
221 cout << "Trying offset=" << offset << " srcOffset=" << srcOffset << endl;
222 v[offset]=vec[srcOffset];
223 }
224 cout << "End ID" << endl;
225 return;
226 }
227 size_t rightoffset=offset+m_samplesize;
228 m_left->resolveSample(v,sampleNo,offset);
229 m_right->resolveSample(v,sampleNo,rightoffset);
230 // for (int i=0;i<getNumDPPSample();++i)
231 {
232 switch(m_op)
233 {
234 case ADD: // since these are pointwise ops, pretend each sample is one point
235 tensor_binary_operation(m_samplesize,&(v[offset]),&(v[rightoffset]),&(v[offset]),plus<double>());
236 break;
237 case SUB:
238 tensor_binary_operation(m_samplesize,&(v[offset]),&(v[rightoffset]),&(v[offset]),minus<double>());
239 break;
240 case MUL:
241 tensor_binary_operation(m_samplesize,&(v[offset]),&(v[rightoffset]),&(v[offset]),multiplies<double>());
242 break;
243 case DIV:
244 tensor_binary_operation(m_samplesize,&(v[offset]),&(v[rightoffset]),&(v[offset]),divides<double>());
245 break;
246 default:
247 throw DataException("Programmer error - do not know how to resolve operator "+opToString(m_op)+".");
248 }
249 }
250 }
251
252 DataReady_ptr
253 DataLazy::resolve()
254 {
255 // This is broken! We need to have a buffer per thread!
256 // so the allocation of v needs to move inside the loop somehow
257
258 cout << "Sample size=" << m_samplesize << endl;
259 cout << "Buffers=" << m_buffsRequired << endl;
260
261 ValueType v(m_samplesize*max(1,m_buffsRequired));
262 cout << "Buffer created with size=" << v.size() << endl;
263 ValueType dummy(getNoValues());
264 DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),dummy);
265 ValueType& resvec=result->getVector();
266 DataReady_ptr resptr=DataReady_ptr(result);
267 int sample;
268 #pragma omp parallel for private(sample) schedule(static)
269 for (sample=0;sample<getNumSamples();++sample)
270 {
271 resolveSample(v,sample,0);
272 for (int i=0;i<m_samplesize;++i) // copy values into the output vector
273 {
274 resvec[i]=v[i];
275 }
276 }
277 return resptr;
278 }
279
280 std::string
281 DataLazy::toString() const
282 {
283 return "Lazy evaluation object. No details available.";
284 }
285
286 // Note that in this case, deepCopy does not make copies of the leaves.
287 // Hopefully copy on write (or whatever we end up using) will take care of this.
288 DataAbstract*
289 DataLazy::deepCopy()
290 {
291 if (m_op==IDENTITY)
292 {
293 return new DataLazy(m_left); // we don't need to copy the child here
294 }
295 return new DataLazy(m_left->deepCopy()->getPtr(),m_right->deepCopy()->getPtr(),m_op);
296 }
297
298
299 DataTypes::ValueType::size_type
300 DataLazy::getLength() const
301 {
302 return m_length;
303 }
304
305
306 DataAbstract*
307 DataLazy::getSlice(const DataTypes::RegionType& region) const
308 {
309 throw DataException("getSlice - not implemented for Lazy objects.");
310 }
311
312 DataTypes::ValueType::size_type
313 DataLazy::getPointOffset(int sampleNo,
314 int dataPointNo) const
315 {
316 throw DataException("getPointOffset - not implemented for Lazy objects - yet.");
317 }
318
319 // // The startOffset is where to write results in the output vector v
320 // void
321 // DataLazy::processSample(ValueType& v, int sampleNo, size_t startOffset)
322 // {
323 // m_left.processSample(v,sampleNo,startOffset);
324 // m_right.processSample(v,sampleNo,startOffset+getSampleSize());
325 // int i;
326 // #pragma omp parallel for private(i) schedule(static)
327 // for (i=0;i<getSampleSize();++i)
328 // {
329 // performOp(v,startOffset+i*m_pointsize,ES_optype,m_samplesize);
330 // }
331 // }
332
333
334 } // end namespace

  ViewVC Help
Powered by ViewVC 1.1.26