/[escript]/trunk/escript/src/DataLazy.h
ViewVC logotype

Contents of /trunk/escript/src/DataLazy.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2721 - (show annotations)
Fri Oct 16 05:40:12 2009 UTC (10 years, 8 months ago) by jfenwick
File MIME type: text/plain
File size: 16269 byte(s)
minval and maxval are now lazy operations (they weren't before).
Whether or not Lsup, sup and inf resolve their arguments before computing answers is controlled by the escriptParam 'RESOLVE_COLLECTIVE'.
Note: integrate() still forces a resolve.

Added some unit tests for operations which weren't tested before.
Added deepcopy implementations for lazy operations which got missed somehow.
1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2009 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 #if !defined escript_DataLazy_20081008_H
16 #define escript_DataLazy_20081008_H
17 #include "system_dep.h"
18
19 #include "DataAbstract.h"
20
21 #include <string>
22 #include <functional>
23
24 #include "LocalOps.h" // for tensor_binary_op
25 #include "BufferGroup.h"
26 #include "DataVector.h" // for ElementType
27
28
29 #define LAZY_NODE_STORAGE
30
31 namespace escript {
32
33 // For the purposes of unit testing and maintaining sanity, it is important that this enum be contiguous
34 enum ES_optype
35 {
36 UNKNOWNOP=0,
37 IDENTITY=1,
38 ADD=2,
39 SUB=3,
40 MUL=4,
41 DIV=5,
42 POW=6,
43 SIN=POW+1,
44 COS=SIN+1,
45 TAN=SIN+2,
46 ASIN=SIN+3,
47 ACOS=SIN+4,
48 ATAN=SIN+5,
49 SINH=SIN+6,
50 COSH=SIN+7,
51 TANH=SIN+8,
52 ERF=SIN+9,
53 ASINH=SIN+10,
54 ACOSH=SIN+11,
55 ATANH=SIN+12,
56 LOG10=ATANH+1,
57 LOG=LOG10+1,
58 SIGN=LOG10+2,
59 ABS=LOG10+3,
60 NEG=LOG10+4,
61 POS=LOG10+5,
62 EXP=LOG10+6,
63 SQRT=LOG10+7,
64 RECIP=LOG10+8,
65 GZ=RECIP+1,
66 LZ=GZ+1,
67 GEZ=GZ+2,
68 LEZ=GZ+3,
69 NEZ=GZ+4,
70 EZ=GZ+5,
71 SYM=EZ+1,
72 NSYM=SYM+1,
73 PROD=NSYM+1,
74 TRANS=PROD+1,
75 TRACE=TRANS+1,
76 SWAP=TRACE+1,
77 MINVAL=SWAP+1,
78 MAXVAL=MINVAL+1
79 };
80
81 ESCRIPT_DLL_API
82 const std::string&
83 opToString(ES_optype op);
84
85 /**
86 \class escript::DataLazy
87 \brief Wraps an expression tree of other DataObjects.
88 The data will be evaluated when required.
89
90
91 NOTE: This class assumes that the Data being pointed at are immutable.
92 */
93
94 class DataLazy;
95
96 typedef POINTER_WRAPPER_CLASS(DataLazy) DataLazy_ptr;
97 typedef POINTER_WRAPPER_CLASS(const DataLazy) const_DataLazy_ptr;
98
99 class DataLazy : public DataAbstract
100 {
101
102 typedef DataAbstract parent;
103 typedef DataTypes::ValueType ValueType;
104 typedef DataTypes::ShapeType ShapeType;
105
106 public:
107 /**
108 \brief Create an IDENTITY DataLazy for the given DataAbstract.
109 \param p DataAbstract to be wrapped.
110 \throws DataException if p is lazy data or it is not constant, tagged or expanded.
111 */
112 ESCRIPT_DLL_API
113 DataLazy(DataAbstract_ptr p);
114
115
116 /**
117 \brief Produce a DataLazy for a unary operation.
118 \param left DataAbstract to be operated on.
119 \param op unary operation to perform.
120 \throws DataException if op is not a unary operation or if p cannot be converted to a DataLazy.
121 Note that IDENTITY is not considered a unary operation.
122 */
123 ESCRIPT_DLL_API
124 DataLazy(DataAbstract_ptr left, ES_optype op);
125
126 /**
127 \brief Produce a DataLazy for a unary operation.
128 \param left DataAbstract to be operated on.
129 \param op unary operation to perform.
130 \param tol tolerance for operation
131 \throws DataException if op is not a unary operation or if p cannot be converted to a DataLazy.
132 Note that IDENTITY is not considered a unary operation.
133 */
134 ESCRIPT_DLL_API
135 DataLazy(DataAbstract_ptr left, ES_optype op, double tol);
136
137 /**
138 \brief Produce a DataLazy for a unary operation which requires a parameter.
139 \param left DataAbstract to be operated on.
140 \param op unary operation to perform.
141 \param axis_offset the parameter for the operation
142 \throws DataException if op is not a unary operation or if p cannot be converted to a DataLazy.
143 Note that IDENTITY is not considered a unary operation.
144 */
145 ESCRIPT_DLL_API
146 DataLazy(DataAbstract_ptr left, ES_optype op, int axis_offset);
147
148
149 /**
150 \brief Produce a DataLazy for a binary operation.
151 \param left left operand
152 \param right right operand
153 \param op unary operation to perform.
154 \throws DataException if op is not a binary operation or if left or right cannot be converted to a DataLazy.
155 */
156 ESCRIPT_DLL_API
157 DataLazy(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op);
158
159 /**
160 \brief Produce a DataLazy for a binary operation with additional paramters.
161 \param left left operand
162 \param right right operand
163 \param op unary operation to perform.
164 \param axis_offset
165 \param transpose
166 \throws DataException if op is not a binary operation requiring parameters or if left or right cannot be converted to a DataLazy.
167 */
168 ESCRIPT_DLL_API
169 DataLazy(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op, int axis_offset, int transpose);
170
171 /**
172 \brief Produce a DataLazy for a unary operation which requires two integer parameters.
173 \param left DataAbstract to be operated on.
174 \param op unary operation to perform.
175 \param axis0 the first parameter for the operation
176 \param axis1 the second parameter for the operation
177 \throws DataException if op is not a unary operation or if p cannot be converted to a DataLazy.
178 Note that IDENTITY is not considered a unary operation.
179 */
180 ESCRIPT_DLL_API
181 DataLazy(DataAbstract_ptr left, ES_optype op, const int axis0, const int axis1);
182
183 ESCRIPT_DLL_API
184 ~DataLazy();
185
186 /**
187 \brief Evaluate the lazy expression.
188 \return A DataReady with the value of the lazy expresion.
189 */
190 ESCRIPT_DLL_API
191 DataReady_ptr
192 resolve();
193
194 ESCRIPT_DLL_API
195 std::string
196 toString() const;
197
198 ESCRIPT_DLL_API
199 DataAbstract*
200 deepCopy();
201
202
203 /**
204 \brief
205 This method throws an exception. It does not really make sense to ask this question of lazy data.
206 */
207 ESCRIPT_DLL_API
208 ValueType::size_type
209 getLength() const;
210
211
212 ESCRIPT_DLL_API
213 DataAbstract*
214 getSlice(const DataTypes::RegionType& region) const;
215
216
217 DataTypes::ValueType::size_type
218 getPointOffset(int sampleNo,
219 int dataPointNo) const;
220
221 DataTypes::ValueType::size_type
222 getPointOffset(int sampleNo,
223 int dataPointNo);
224
225
226 /**
227 \return the number of samples which need to be stored to evaluate the expression.
228 */
229 ESCRIPT_DLL_API
230 int
231 getBuffsRequired() const;
232
233 /**
234 \return the largest samplesize required to evaluate the expression.
235 */
236 ESCRIPT_DLL_API
237 size_t
238 getMaxSampleSize() const;
239
240 /**
241 \return the size of the buffer required to evaulate a sample for this object
242 */
243 ESCRIPT_DLL_API
244 size_t
245 getSampleBufferSize() const;
246
247 /**
248 \brief Compute the value of the expression for the given sample.
249 \return Vector which stores the value of the subexpression for the given sample.
250 \param bg A BufferGroup to store intermediate results.
251 \param sampleNo Sample number to evaluate.
252 \param roffset (output parameter) the offset in the return vector where the result begins.
253
254 The return value will be an existing vector so do not deallocate it.
255 */
256 ESCRIPT_DLL_API
257 const ValueType*
258 resolveSample(BufferGroup& bg, int sampleNo, size_t& roffset);
259
260 /**
261 \brief if resolve() was called would it produce expanded data.
262 */
263 ESCRIPT_DLL_API
264 bool
265 actsExpanded() const;
266
267 /**
268 \brief Produces an IDENTITY DataLazy containing zero.
269 The result will have the same shape and functionspace as before.
270 */
271 ESCRIPT_DLL_API
272 virtual void
273 setToZero();
274
275 private:
276 DataReady_ptr m_id; // For IDENTITY nodes, stores a wrapped value.
277 DataLazy_ptr m_left, m_right; // operands for operation.
278 ES_optype m_op; // operation to perform.
279
280 int m_buffsRequired; // how many samples are required to evaluate this expression
281 size_t m_samplesize; // number of values required to store a sample
282
283 char m_readytype; // E for expanded, T for tagged, C for constant
284
285 int m_axis_offset; // required extra info for general tensor product
286 int m_transpose; // offset and transpose are used for swapaxes as well
287 int m_SL, m_SM, m_SR; // computed properties used in general tensor product
288
289
290 double m_tol; // required extra info for <>0 and ==0
291
292 size_t m_maxsamplesize; // largest samplesize required by any node in the expression
293 size_t m_children;
294 size_t m_height;
295
296 #ifdef LAZY_NODE_STORAGE
297
298 int* m_sampleids; // may be NULL
299 DataVector m_samples;
300
301 #endif // LAZY_NODE_STORAGE
302
303
304 #ifdef LAZY_NODE_STORAGE
305 /**
306 Allocates sample storage at each node
307 */
308 void LazyNodeSetup();
309
310
311 const DataTypes::ValueType*
312 resolveNodeUnary(int tid, int sampleNo, size_t& roffset);
313
314
315 const DataTypes::ValueType*
316 resolveNodeReduction(int tid, int sampleNo, size_t& roffset);
317
318 const DataTypes::ValueType*
319 resolveNodeSample(int tid, int sampleNo, size_t& roffset);
320
321 const DataTypes::ValueType*
322 resolveNodeBinary(int tid, int sampleNo, size_t& roffset);
323
324 const DataTypes::ValueType*
325 resolveNodeNP1OUT(int tid, int sampleNo, size_t& roffset);
326
327 const DataTypes::ValueType*
328 resolveNodeNP1OUT_P(int tid, int sampleNo, size_t& roffset);
329
330 const DataTypes::ValueType*
331 resolveNodeTProd(int tid, int sampleNo, size_t& roffset);
332
333 const DataTypes::ValueType*
334 resolveNodeNP1OUT_2P(int tid, int sampleNo, size_t& roffset);
335
336 #endif
337
338 /**
339 Does the work for toString.
340 */
341 void
342 intoString(std::ostringstream& oss) const;
343
344 /**
345 \brief Converts the DataLazy into an IDENTITY storing the value of the expression.
346 This method uses the original methods on the Data class to evaluate the expressions.
347 For this reason, it should not be used on DataExpanded instances. (To do so would defeat
348 the purpose of using DataLazy in the first place).
349 */
350 void
351 collapse(); // converts the node into an IDENTITY node
352
353
354 /**
355 \brief Evaluates the expression using methods on Data.
356 This does the work for the collapse method.
357 For reasons of efficiency do not call this method on DataExpanded nodes.
358 */
359 DataReady_ptr
360 collapseToReady();
361
362 /**
363 \brief resolve the expression can store it in the current node
364 The current node will be converted to an identity node.
365 */
366 void
367 resolveToIdentity();
368
369 /**
370 \brief helper method for resolveToIdentity and the identity constructor
371 */
372 void
373 makeIdentity(const DataReady_ptr& p);
374
375 /**
376 \brief resolve to a ReadyData object using a vector buffer.
377 */
378 DataReady_ptr
379 resolveVectorWorker();
380
381 #ifdef LAZY_NODE_STORAGE
382 /**
383 \brief resolve to a ReadyData object using storage at nodes
384 */
385 DataReady_ptr
386 resolveNodeWorker();
387 #endif
388
389 /**
390 \brief Compute the value of the expression for the given sample - using the vector buffer approach.
391 \return Vector which stores the value of the subexpression for the given sample.
392 \param v A vector to store intermediate results.
393 \param offset Index in v to begin storing results.
394 \param sampleNo Sample number to evaluate.
395 \param roffset (output parameter) the offset in the return vector where the result begins.
396
397 The return value will be an existing vector so do not deallocate it.
398 */
399 ESCRIPT_DLL_API
400 const ValueType*
401 resolveVectorSample(ValueType& v, size_t offset, int sampleNo, size_t& roffset);
402
403
404 /**
405 \brief Compute the value of the expression (unary operation) for the given sample.
406 \return Vector which stores the value of the subexpression for the given sample.
407 \param v A vector to store intermediate results.
408 \param offset Index in v to begin storing results.
409 \param sampleNo Sample number to evaluate.
410 \param roffset (output parameter) the offset in the return vector where the result begins.
411
412 The return value will be an existing vector so do not deallocate it.
413 If the result is stored in v it should be stored at the offset given.
414 Everything from offset to the end of v should be considered available for this method to use.
415 */
416 ValueType*
417 resolveUnary(ValueType& v, size_t offset,int sampleNo, size_t& roffset) const;
418
419 /**
420 \brief Compute the value of the expression (reduction operation) for the given sample.
421 \return Vector which stores the value of the subexpression for the given sample.
422 \param v A vector to store intermediate results.
423 \param offset Index in v to begin storing results.
424 \param sampleNo Sample number to evaluate.
425 \param roffset (output parameter) the offset in the return vector where the result begins.
426
427 The return value will be an existing vector so do not deallocate it.
428 If the result is stored in v it should be stored at the offset given.
429 Everything from offset to the end of v should be considered available for this method to use.
430 */
431 ValueType*
432 resolveReduction(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const;
433
434 /**
435 \brief Compute the value of the expression (unary non-pointwise operation) for the given sample.
436 \return Vector which stores the value of the subexpression for the given sample.
437 \param v A vector to store intermediate results.
438 \param offset Index in v to begin storing results.
439 \param sampleNo Sample number to evaluate.
440 \param roffset (output parameter) the offset in the return vector where the result begins.
441
442 The return value will be an existing vector so do not deallocate it.
443 If the result is stored in v it should be stored at the offset given.
444 Everything from offset to the end of v should be considered available for this method to use.
445
446 This method differs from the one above in that deals with operations that are not
447 point-wise. That is, the answer cannot just be written on top of the input.
448 Extra buffers are required for these operations.
449 */
450
451 ValueType*
452 resolveNP1OUT(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const;
453
454 /**
455 \brief Compute the value of the expression (unary operation) for the given sample.
456 \return Vector which stores the value of the subexpression for the given sample.
457 \param v A vector to store intermediate results.
458 \param offset Index in v to begin storing results.
459 \param sampleNo Sample number to evaluate.
460 \param roffset (output parameter) the offset in the return vector where the result begins.
461
462 The return value will be an existing vector so do not deallocate it.
463 If the result is stored in v it should be stored at the offset given.
464 Everything from offset to the end of v should be considered available for this method to use.
465 */
466 DataTypes::ValueType*
467 resolveNP1OUT_P(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const;
468
469 /**
470 \brief Compute the value of the expression (unary operation with int params) for the given sample.
471 \return Vector which stores the value of the subexpression for the given sample.
472 \param v A vector to store intermediate results.
473 \param offset Index in v to begin storing results.
474 \param sampleNo Sample number to evaluate.
475 \param roffset (output parameter) the offset in the return vector where the result begins.
476
477 The return value will be an existing vector so do not deallocate it.
478 If the result is stored in v it should be stored at the offset given.
479 Everything from offset to the end of v should be considered available for this method to use.
480 */
481 DataTypes::ValueType*
482 resolveNP1OUT_2P(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const;
483
484
485 /**
486 \brief Compute the value of the expression (binary operation) for the given sample.
487 \return Vector which stores the value of the subexpression for the given sample.
488 \param v A vector to store intermediate results.
489 \param offset Index in v to begin storing results.
490 \param sampleNo Sample number to evaluate.
491 \param roffset (output parameter) the offset in the return vector where the result begins.
492
493 The return value will be an existing vector so do not deallocate it.
494 If the result is stored in v it should be stored at the offset given.
495 Everything from offset to the end of v should be considered available for this method to use.
496 */
497 ValueType*
498 resolveBinary(ValueType& v, size_t offset,int sampleNo, size_t& roffset) const;
499
500 /**
501 \brief Compute the value of the expression (tensor product) for the given sample.
502 \return Vector which stores the value of the subexpression for the given sample.
503 \param v A vector to store intermediate results.
504 \param offset Index in v to begin storing results.
505 \param sampleNo Sample number to evaluate.
506 \param roffset (output parameter) the offset in the return vector where the result begins.
507
508 The return value will be an existing vector so do not deallocate it.
509 If the result is stored in v it should be stored at the offset given.
510 Everything from offset to the end of v should be considered available for this method to use.
511 */
512 DataTypes::ValueType*
513 resolveTProd(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const;
514
515 };
516
517 }
518 #endif

  ViewVC Help
Powered by ViewVC 1.1.26