/[escript]/branches/arrexp_2137_win/escript/src/DataAbstract.h
ViewVC logotype

Contents of /branches/arrexp_2137_win/escript/src/DataAbstract.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2212 - (show annotations)
Wed Jan 14 00:15:00 2009 UTC (10 years, 5 months ago) by jfenwick
File MIME type: text/plain
File size: 13668 byte(s)
Executive summary:

This commit adds copy on write checks to operations involving shared data. 

Changes:

new #defines:
~~~~~~~~~~~~~
Data.cpp has ASSIGNMENT_MEANS_DEEPCOPY (defaults to undefined).
Defining this will put the data = operator back to making deep copies instead
of sharing data (now the default.)

Data:
~~~~~
. Added exclusiveWrite method to copy the underlying data if it is shared.
. Some operators which took python objects now call the c++ versions intead of duplicating code.

DataAbstract and offspring:
~~~~~~~~~~~~~~~~~~~~~~~~~~~
. Added method to determine whether the data is currently shared.
. Added getVectorRO to children of DataReady.
. Added getTagRO.

. Operations which modify values in place (or return modifiable pointers) now use
a macro to check for sharing. In the case where a modification attempt is detected, it throws an exception. In the future, I will enable this only for debugging.

. This shold not really have been required but the compiler was not choosing the use the const version as I would have liked. Besides, this makes things explict.

. Moved (and de-inlined) getVector in DataConstant (It was virtual in a parent class).

Unit tests:
~~~~~~~~~~~
Added both python and c++ unit tests to check known cases of sharing and "inplace"
modification operations.

General:
~~~~~~~~
Removed some commented out code.

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 #if !defined escript_DataAbstract_20040315_H
16 #define escript_DataAbstract_20040315_H
17 #include "system_dep.h"
18
19 #include "DataTypes.h"
20 #include "FunctionSpace.h"
21
22 #include <boost/scoped_ptr.hpp>
23 #include <boost/python/numeric.hpp>
24
25 #include "DataException.h"
26
27 #include <string>
28 #include <fstream>
29
30 #include "Pointers.h"
31
32 namespace escript {
33
34 /**
35 \brief
36 DataAbstract provides an abstract interface for the class of containers
37 which hold ESyS data.
38
39 Description:
40 DataAbstract provides an abstract interface for the class of containers
41 which hold ESyS data. The container may be thought of as a 2 dimensional
42 array of data points where one dimension corresponds to the number of samples
43 and the other to the number of data points per sample as defined by the function
44 space associated with each Data object. The data points themselves are arrays of
45 doubles of rank 0-4.
46 */
47
48 class DataAbstract;
49
50 typedef POINTER_WRAPPER_CLASS(DataAbstract) DataAbstract_ptr;
51 typedef POINTER_WRAPPER_CLASS(const DataAbstract) const_DataAbstract_ptr;
52
53 class DataReady;
54
55 typedef POINTER_WRAPPER_CLASS(DataReady) DataReady_ptr;
56 typedef POINTER_WRAPPER_CLASS(const DataReady) const_DataReady_ptr;
57
58 class DataAbstract : public REFCOUNT_BASE_CLASS(DataAbstract)
59 {
60
61 public:
62
63 typedef DataTypes::ValueType ValueType;
64 typedef DataTypes::ShapeType ShapeType;
65
66 /**
67 \brief Return shared pointer managing this object.
68
69 If there is not already a shared pointer managing this object then create one.
70 Once a shared pointer is created for an object, the deallocation of the object
71 must be handled by shared_ptr.
72
73 \warning So, do not call this on an automatic object.
74 Do not call this in a method where you do not pass the shared_pointer out and
75 you need the object to outlast the method.
76
77 Note: This is _not_ equivalent to weak_ptr::lock.
78
79 */
80 ESCRIPT_DLL_API
81 DataAbstract_ptr getPtr();
82 ESCRIPT_DLL_API
83 const_DataAbstract_ptr getPtr() const;
84
85
86
87 /**
88 \brief
89 Constructor for DataAbstract.
90
91 Description:
92 Constructor for DataAbstract.
93
94 \param what - Input - A description of what this data represents.
95 */
96 ESCRIPT_DLL_API
97 DataAbstract(const FunctionSpace& what, const ShapeType& shape, bool isDataEmpty=false);
98
99 /**
100 \brief
101 Destructor for DataAbstract.
102 */
103 ESCRIPT_DLL_API
104 virtual
105 ~DataAbstract();
106
107 /**
108 \brief
109 Write the data as a string.
110 */
111 ESCRIPT_DLL_API
112 virtual
113 std::string
114 toString() const = 0;
115
116 /**
117 \brief Return a deep copy of the current object.
118 */
119 ESCRIPT_DLL_API
120 virtual
121 DataAbstract*
122 deepCopy()=0;
123
124 /**
125 \brief Return a data object with all points resolved.
126 */
127 ESCRIPT_DLL_API
128 virtual
129 DataReady_ptr
130 resolve()=0;
131
132 /**
133 \brief
134 dumps the object into a netCDF file
135 */
136 ESCRIPT_DLL_API
137 virtual
138 void
139 dump(const std::string fileName) const;
140
141 /**
142 \brief
143 Return the number of data points per sample.
144 */
145 ESCRIPT_DLL_API
146 int
147 getNumDPPSample() const;
148
149 /**
150 \brief
151 Return the number of samples.
152 */
153 ESCRIPT_DLL_API
154 int
155 getNumSamples() const;
156
157 /**
158 \brief
159 Return the shape information for the point data.
160
161 The omission of a non-constant form is deliberate.
162 */
163 ESCRIPT_DLL_API
164 const DataTypes::ShapeType&
165 getShape() const;
166
167 /**
168 \brief
169 Return the rank information for the point data.
170 */
171 ESCRIPT_DLL_API
172 unsigned int
173 getRank() const;
174
175
176
177 /**
178 \brief
179 Return the offset for the given sample. This returns the offset for the given
180 point into the container holding the point data.
181
182 \param sampleNo - Input - sample number.
183 \param dataPointNo - Input - data point number.
184 */
185 ESCRIPT_DLL_API
186 virtual
187 ValueType::size_type
188 getPointOffset(int sampleNo,
189 int dataPointNo) const = 0;
190
191 ESCRIPT_DLL_API
192 virtual
193 ValueType::size_type
194 getPointOffset(int sampleNo,
195 int dataPointNo) = 0;
196
197
198 /**
199 \brief
200 Return the number of doubles stored for this Data object.
201 */
202 ESCRIPT_DLL_API
203 virtual
204 ValueType::size_type
205 getLength() const = 0;
206
207 /**
208 \brief
209 Return the sample data for the given tag key.
210 NB: If the data isn't tagged an exception will be thrown.
211 */
212 ESCRIPT_DLL_API
213 virtual
214 double*
215 getSampleDataByTag(int tag);
216
217 /**
218 This method is used primarily for LazyData.
219 \return the size of the buffer required to evaulate a sample for this object.
220 */
221 ESCRIPT_DLL_API
222 virtual size_t
223 getSampleBufferSize() const=0;
224
225
226
227 /**
228 \brief
229 Check this and the given RHS operands are compatible. Throws
230 an exception if they aren't.
231
232 \param right - Input - The right hand side.
233 */
234 ESCRIPT_DLL_API
235 void
236 operandCheck(const DataAbstract& right) const;
237
238 /**
239 \brief
240 Return true if a valid sample point number.
241 */
242 ESCRIPT_DLL_API
243 bool
244 validSamplePointNo(int samplePointNo) const;
245
246 /**
247 \brief
248 Return true if a valid sample number.
249 */
250 ESCRIPT_DLL_API
251 bool
252 validSampleNo(int sampleNo) const;
253
254
255 /**
256 \brief
257 Return the function space associated with this Data object.
258 */
259 ESCRIPT_DLL_API
260 const
261 FunctionSpace&
262 getFunctionSpace() const;
263
264 /**
265 \brief
266 Return the given slice from this object.
267
268 NB: The caller is responsible for managing the object created.
269 */
270 ESCRIPT_DLL_API
271 virtual
272 DataAbstract*
273 getSlice(const DataTypes::RegionType& region) const = 0;
274
275
276
277 /**
278 \brief
279 setTaggedValue
280
281 Description:
282 Assign the given value to the given tag.
283
284 NB: If the data isn't tagged an exception will be thrown.
285
286 \param tagKey - Input - Integer key.
287 \param pointshape - Input - the shape of the value parameter.
288 \param value - Input -
289 */
290 ESCRIPT_DLL_API
291 virtual
292 void
293 setTaggedValue(int tagKey,
294 const DataTypes::ShapeType& pointshape,
295 const DataTypes::ValueType& value,
296 int dataOffset=0);
297
298
299 /**
300 \brief
301 Copy a double value to the data point dataPointNo of sample sampleNo in this object.
302
303 Description:
304 Copy a double value to the data point dataPointNo of sample sampleNo in this object.
305
306 \param sampleNo Input - sample number
307 \param dataPointNo Input - data point of the sample
308 \param value Input - new values for the data point
309 */
310 ESCRIPT_DLL_API
311 virtual void
312 copyToDataPoint(const int sampleNo, const int dataPointNo, const double value);
313
314 /**
315 \brief
316 Copy the numarray object to the data point dataPointNo of sample sampleNo in this object.
317
318 Description:
319 Copy the numarray object to the data point dataPointNo of sample sampleNo in this object.
320
321 \param sampleNo Input - sample number
322 \param dataPointNo Input - data point of the sample
323 \param value Input - new values for the data point
324 */
325 ESCRIPT_DLL_API
326 virtual void
327 copyToDataPoint(const int sampleNo, const int dataPointNo, const WrappedArray& value);
328
329
330 /**
331 \brief
332 Return the tag number associated with the given data-point number.
333
334 If the object cannot be referenced by tag numbers, an exception
335 will be thrown.
336 */
337 ESCRIPT_DLL_API
338 virtual
339 int
340 getTagNumber(int dpno);
341
342 /**
343 \brief
344 Computes a symmetric matrix (A + AT) / 2
345
346 \param ev - Output - a symmetric matrix
347
348 */
349 ESCRIPT_DLL_API
350 virtual void
351 symmetric(DataAbstract* ev);
352
353 /**
354 \brief
355 Computes a nonsymmetric matrix (A - AT) / 2
356
357 \param ev - Output - a nonsymmetric matrix
358
359 */
360 ESCRIPT_DLL_API
361 virtual void
362 nonsymmetric(DataAbstract* ev);
363
364 /**
365 \brief
366 Computes the trace of a matrix
367
368 \param ev - Output - the trace of a matrix
369
370 */
371 ESCRIPT_DLL_API
372 virtual void
373 trace(DataAbstract* ev, int axis_offset);
374
375 /**
376 \brief
377 Transpose each data point of this Data object around the given axis.
378
379 \param ev - Output - the transpose of a matrix
380
381 */
382 ESCRIPT_DLL_API
383 virtual void
384 transpose(DataAbstract* ev, int axis_offset);
385
386 /**
387 \brief
388 swaps components axis0 and axis1
389
390 \param ev - Output - swapped components
391
392 */
393 ESCRIPT_DLL_API
394 virtual void
395 swapaxes(DataAbstract* ev, int axis0, int axis1);
396 /**
397 \brief
398 solves the eigenvalue problem this*V=ev*V for the eigenvalues ev
399
400 \param ev - Output - eigenvalues in increasing order at each data point
401
402 */
403 ESCRIPT_DLL_API
404 virtual void
405 eigenvalues(DataAbstract* ev);
406
407 /**
408 \brief
409 sets values to zero
410
411 */
412 ESCRIPT_DLL_API
413 virtual void
414 setToZero();
415
416 /**
417 \brief
418 solves the eigenvalue problem this*V=ev*V for the eigenvalues ev and eigenvectors V
419
420 \param ev - Output - eigenvalues in increasing order at each data point
421 \param V - Output - corresponding eigenvectors. They are normalized such that their length is one
422 and the first nonzero component is positive.
423 \param tol - Input - eigenvalue with relative distance tol are treated as equal.
424
425 */
426
427 ESCRIPT_DLL_API
428 virtual void
429 eigenvalues_and_eigenvectors(DataAbstract* ev,DataAbstract* V,const double tol=1.e-13);
430
431 /**
432 \brief
433 reorders data sample ordered by reference_ids to the ordering of the functions space
434
435 \param reference_ids - Input - reference_ids used for current ordering
436 */
437 ESCRIPT_DLL_API
438 virtual void
439 reorderByReferenceIDs(int *reference_ids);
440
441
442
443 /**
444 \brief
445 Return the number of values in the shape for this object.
446 */
447 ESCRIPT_DLL_API
448 unsigned int
449 getNoValues() const;
450
451
452 ESCRIPT_DLL_API
453 bool isLazy() const; // a test to determine if this object is an instance of DataLazy
454
455 ESCRIPT_DLL_API
456 virtual
457 bool
458 isConstant() const {return false;}
459
460 ESCRIPT_DLL_API
461 virtual
462 bool
463 isExpanded() const {return false;}
464
465
466 /**
467 \brief
468 Return true if this Data is expanded or resolves to expanded.
469 That is, if it has a separate value for each datapoint in the sample.
470 */
471 virtual
472 bool
473 actsExpanded() const {return false;}
474
475 virtual
476 bool
477 isTagged() const {return false;}
478
479 ESCRIPT_DLL_API
480 bool isEmpty() const; // a fast test to determine if this object is an instance of DataEmpty
481
482 protected:
483
484 /**
485 \brief Returns true if this object is not shared.
486 For internal use only. - It may not be particularly fast
487 */
488 ESCRIPT_DLL_API
489 bool checkNoSharing() const;
490
491 private:
492
493 //
494 // The number of samples in this Data object.
495 // This is derived directly from the FunctionSpace.
496 int m_noSamples;
497
498 //
499 // The number of data points per sample in this Data object.
500 // This is derived directly from the FunctionSpace.
501 int m_noDataPointsPerSample;
502
503 //
504 // A FunctionSpace which provides a description of the data associated
505 // with this Data object.
506 FunctionSpace m_functionSpace;
507
508 //
509 // The shape of the points stored in this view
510 DataTypes::ShapeType m_shape;
511
512 //
513 // The number of values in each point
514 unsigned int m_novalues;
515
516 //
517 // The rank of the points stored in this view
518 unsigned int m_rank;
519
520 //
521 // Is this an instance of DataEmpty?
522 bool m_isempty;
523 };
524
525 inline
526 bool
527 DataAbstract::isEmpty() const
528 {
529 return m_isempty;
530 }
531
532 // inline
533 // DataTypes::ValueType::const_reference
534 // DataAbstract::getDataAtOffset(DataTypes::ValueType::size_type i) const
535 // {
536 // if (isLazy())
537 // {
538 // throw DataException("Programmer error - getDataAtOffset() not permitted on Lazy Data.");
539 // }
540 // DataReady* d;
541 // return (dynamic_cast<const DataReady*>(this))->getVector()[i];
542 // // return getVector()[i];
543 // }
544
545 // inline
546 // DataTypes::ValueType::reference
547 // DataAbstract::getDataAtOffset(DataTypes::ValueType::size_type i)
548 // {
549 // if (isLazy())
550 // {
551 // throw DataException("Programmer error - getDataAtOffset() not permitted on Lazy Data.");
552 // }
553 // return dynamic_cast<DataReady*>(this)->getVector()[i];
554 // // return getVector()[i];
555 // }
556
557
558 inline
559 bool
560 DataAbstract::validSamplePointNo(int samplePointNo) const
561 {
562 return ((0 <= samplePointNo) && (samplePointNo < m_noDataPointsPerSample));
563 }
564
565 inline
566 bool
567 DataAbstract::validSampleNo(int sampleNo) const
568 {
569 return ((0 <= sampleNo) && (sampleNo < m_noSamples));
570 }
571
572 inline
573 int
574 DataAbstract::getNumDPPSample() const
575 {
576 if (isEmpty())
577 {
578 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
579 }
580 return m_noDataPointsPerSample;
581 }
582
583 inline
584 int
585 DataAbstract::getNumSamples() const
586 {
587 if (isEmpty())
588 {
589 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
590 }
591 return m_noSamples;
592 }
593
594 inline
595 const
596 FunctionSpace&
597 DataAbstract::getFunctionSpace() const
598 {
599 return m_functionSpace;
600 }
601
602 inline
603 const DataTypes::ShapeType&
604 DataAbstract::getShape() const
605 {
606 if (isEmpty())
607 {
608 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
609 }
610 return m_shape;
611 }
612
613 inline
614 unsigned int
615 DataAbstract::getRank() const
616 {
617 if (isEmpty())
618 {
619 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
620 }
621 return m_rank;
622 }
623
624 inline
625 unsigned int
626 DataAbstract::getNoValues() const
627 {
628 if (isEmpty())
629 {
630 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
631 }
632 return m_novalues;
633 }
634
635
636 } // end of namespace
637
638 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26