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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1811 - (show annotations)
Thu Sep 25 23:11:13 2008 UTC (10 years, 3 months ago) by ksteube
File MIME type: text/plain
File size: 87925 byte(s)
Copyright updated in all files

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 /** \file Data.h */
16
17 #ifndef DATA_H
18 #define DATA_H
19 #include "system_dep.h"
20
21 #include "DataAbstract.h"
22 #include "DataAlgorithm.h"
23 #include "FunctionSpace.h"
24 #include "BinaryOp.h"
25 #include "UnaryOp.h"
26 #include "DataException.h"
27 #include "DataTypes.h"
28
29 extern "C" {
30 #include "DataC.h"
31 /* #include "paso/Paso.h" doesn't belong in this file...causes trouble for BruceFactory.cpp */
32 }
33
34 #include "esysmpi.h"
35 #include <string>
36 #include <algorithm>
37 #include <sstream>
38
39
40 #include <boost/shared_ptr.hpp>
41 #include <boost/python/object.hpp>
42 #include <boost/python/tuple.hpp>
43 #include <boost/python/numeric.hpp>
44
45 namespace escript {
46
47 //
48 // Forward declaration for various implementations of Data.
49 class DataConstant;
50 class DataTagged;
51 class DataExpanded;
52
53 /**
54 \brief
55 Data represents a collection of datapoints.
56
57 Description:
58 Internally, the datapoints are actually stored by a DataAbstract object.
59 The specific instance of DataAbstract used may vary over the lifetime
60 of the Data object.
61 Some methods on this class return references (eg getShape()).
62 These references should not be used after an operation which changes the underlying DataAbstract object.
63 Doing so will lead to invalid memory access.
64 This should not affect any methods exposed via boost::python.
65 */
66 class Data {
67
68 public:
69
70 // These typedefs allow function names to be cast to pointers
71 // to functions of the appropriate type when calling unaryOp etc.
72 typedef double (*UnaryDFunPtr)(double);
73 typedef double (*BinaryDFunPtr)(double,double);
74
75
76 /**
77 Constructors.
78 */
79
80 /**
81 \brief
82 Default constructor.
83 Creates a DataEmpty object.
84 */
85 ESCRIPT_DLL_API
86 Data();
87
88 /**
89 \brief
90 Copy constructor.
91 WARNING: Only performs a shallow copy.
92 */
93 ESCRIPT_DLL_API
94 Data(const Data& inData);
95
96 /**
97 \brief
98 Constructor from another Data object. If "what" is different from the
99 function space of inData the inData are tried to be interpolated to what,
100 otherwise a shallow copy of inData is returned.
101 */
102 ESCRIPT_DLL_API
103 Data(const Data& inData,
104 const FunctionSpace& what);
105
106 /**
107 \brief Copy Data from an existing vector
108 */
109
110 ESCRIPT_DLL_API
111 Data(const DataTypes::ValueType& value,
112 const DataTypes::ShapeType& shape,
113 const FunctionSpace& what=FunctionSpace(),
114 bool expanded=false);
115
116 /**
117 \brief
118 Constructor which creates a Data from a DataArrayView shape.
119
120 \param value - Input - Single value applied to all Data.
121 \param dataPointShape - Input - The shape of each data point.
122 \param what - Input - A description of what this data represents.
123 \param expanded - Input - Flag, if true fill the entire container with
124 the given value. Otherwise a more efficient storage
125 mechanism will be used.
126 */
127 ESCRIPT_DLL_API
128 Data(double value,
129 const DataTypes::ShapeType& dataPointShape=DataTypes::ShapeType(),
130 const FunctionSpace& what=FunctionSpace(),
131 bool expanded=false);
132
133 /**
134 \brief
135 Constructor which performs a deep copy of a region from another Data object.
136
137 \param inData - Input - Input Data object.
138 \param region - Input - Region to copy.
139 */
140 ESCRIPT_DLL_API
141 Data(const Data& inData,
142 const DataTypes::RegionType& region);
143
144 /**
145 \brief
146 Constructor which copies data from a python numarray.
147
148 \param value - Input - Data value for a single point.
149 \param what - Input - A description of what this data represents.
150 \param expanded - Input - Flag, if true fill the entire container with
151 the value. Otherwise a more efficient storage
152 mechanism will be used.
153 */
154 ESCRIPT_DLL_API
155 Data(const boost::python::numeric::array& value,
156 const FunctionSpace& what=FunctionSpace(),
157 bool expanded=false);
158
159 /**
160 \brief
161 Constructor which copies data from any object that can be converted into
162 a python numarray.
163
164 \param value - Input - Input data.
165 \param what - Input - A description of what this data represents.
166 \param expanded - Input - Flag, if true fill the entire container with
167 the value. Otherwise a more efficient storage
168 mechanism will be used.
169 */
170 ESCRIPT_DLL_API
171 Data(const boost::python::object& value,
172 const FunctionSpace& what=FunctionSpace(),
173 bool expanded=false);
174
175 /**
176 \brief
177 Constructor which creates a DataConstant.
178 Copies data from any object that can be converted
179 into a numarray. All other parameters are copied from other.
180
181 \param value - Input - Input data.
182 \param other - Input - contains all other parameters.
183 */
184 ESCRIPT_DLL_API
185 Data(const boost::python::object& value,
186 const Data& other);
187
188 /**
189 \brief
190 Constructor which creates a DataConstant of "shape" with constant value.
191 */
192 ESCRIPT_DLL_API
193 Data(double value,
194 const boost::python::tuple& shape=boost::python::make_tuple(),
195 const FunctionSpace& what=FunctionSpace(),
196 bool expanded=false);
197
198
199
200 /**
201 \brief Create a Data using an existing DataAbstract. Warning: The new object assumes ownership of the pointer!
202 Once you have passed the pointer, do not delete it.
203 */
204 ESCRIPT_DLL_API
205 Data(DataAbstract* underlyingdata);
206
207
208 /**
209 \brief
210 Destructor
211 */
212 ESCRIPT_DLL_API
213 ~Data();
214
215 /**
216 \brief Make this object a deep copy of "other".
217 */
218 ESCRIPT_DLL_API
219 void
220 copy(const Data& other);
221
222 /**
223 \brief Return a pointer to a deep copy of this object.
224 */
225 ESCRIPT_DLL_API
226 Data*
227 copySelf();
228
229
230
231
232 /**
233 Member access methods.
234 */
235
236 /**
237 \brief
238 switches on update protection
239
240 */
241 ESCRIPT_DLL_API
242 void
243 setProtection();
244
245 /**
246 \brief
247 Returns trueif the data object is protected against update
248
249 */
250 ESCRIPT_DLL_API
251 bool
252 isProtected() const;
253
254 /**
255 \brief
256 Return the values of a data point on this process
257 */
258 ESCRIPT_DLL_API
259 const boost::python::numeric::array
260 getValueOfDataPoint(int dataPointNo);
261
262 /**
263 \brief
264 sets the values of a data-point from a python object on this process
265 */
266 ESCRIPT_DLL_API
267 void
268 setValueOfDataPointToPyObject(int dataPointNo, const boost::python::object& py_object);
269
270 /**
271 \brief
272 sets the values of a data-point from a numarray object on this process
273 */
274 ESCRIPT_DLL_API
275 void
276 setValueOfDataPointToArray(int dataPointNo, const boost::python::numeric::array&);
277
278 /**
279 \brief
280 sets the values of a data-point on this process
281 */
282 ESCRIPT_DLL_API
283 void
284 setValueOfDataPoint(int dataPointNo, const double);
285
286 /**
287 \brief
288 Return the value of the specified data-point across all processors
289 */
290 ESCRIPT_DLL_API
291 const boost::python::numeric::array
292 getValueOfGlobalDataPoint(int procNo, int dataPointNo);
293
294 /**
295 \brief
296 Return the tag number associated with the given data-point.
297
298 */
299 ESCRIPT_DLL_API
300 int
301 getTagNumber(int dpno);
302
303 /**
304 \brief
305 Return the C wrapper for the Data object.
306 */
307 ESCRIPT_DLL_API
308 escriptDataC
309 getDataC();
310
311
312
313
314
315
316 // REMOVE ME
317 // ESCRIPT_DLL_API
318 // void
319 // CompareDebug(const Data& rd);
320
321
322 /**
323 \brief
324 Return the C wrapper for the Data object - const version.
325 */
326 ESCRIPT_DLL_API
327 escriptDataC
328 getDataC() const;
329
330 /**
331 \brief
332 Write the data as a string. For large amounts of data, a summary is printed.
333 */
334 ESCRIPT_DLL_API
335 std::string
336 toString() const;
337
338
339 // /**
340 /* \brief
341 Return the DataArrayView of the point data. This essentially contains
342 the shape information for each data point although it also may be used
343 to manipulate the point data.*/
344 // */
345 // ESCRIPT_DLL_API
346 // inline
347 // const DataArrayView&
348 // getPointDataView() const
349 // {
350 // return m_data->getPointDataView();
351 // }
352
353 /**
354 \brief
355 Whatever the current Data type make this into a DataExpanded.
356 */
357 ESCRIPT_DLL_API
358 void
359 expand();
360
361 /**
362 \brief
363 If possible convert this Data to DataTagged. This will only allow
364 Constant data to be converted to tagged. An attempt to convert
365 Expanded data to tagged will throw an exception.
366 ==>*
367 */
368 ESCRIPT_DLL_API
369 void
370 tag();
371
372 /**
373 \brief
374 Return true if this Data is expanded.
375 */
376 ESCRIPT_DLL_API
377 bool
378 isExpanded() const;
379
380 /**
381 \brief
382 Return true if this Data is tagged.
383 */
384 ESCRIPT_DLL_API
385 bool
386 isTagged() const;
387
388 /**
389 \brief
390 Return true if this Data is constant.
391 */
392 ESCRIPT_DLL_API
393 bool
394 isConstant() const;
395
396 /**
397 \brief
398 Return true if this Data holds an instance of DataEmpty. This is _not_ the same as asking if the object
399 contains datapoints.
400 */
401 ESCRIPT_DLL_API
402 bool
403 isEmpty() const;
404
405 /**
406 \brief
407 Return the function space.
408 */
409 ESCRIPT_DLL_API
410 inline
411 const FunctionSpace&
412 getFunctionSpace() const
413 {
414 return m_data->getFunctionSpace();
415 }
416
417 /**
418 \brief
419 Return a copy of the function space.
420 */
421 ESCRIPT_DLL_API
422 const FunctionSpace
423 getCopyOfFunctionSpace() const;
424
425 /**
426 \brief
427 Return the domain.
428 */
429 ESCRIPT_DLL_API
430 inline
431 const AbstractDomain&
432 getDomain() const
433 {
434 return getFunctionSpace().getDomain();
435 }
436
437 /**
438 \brief
439 Return a copy of the domain.
440 */
441 ESCRIPT_DLL_API
442 const AbstractDomain
443 getCopyOfDomain() const;
444
445 /**
446 \brief
447 Return the rank of the point data.
448 */
449 ESCRIPT_DLL_API
450 inline
451 int
452 getDataPointRank() const
453 {
454 // return m_data->getPointDataView().getRank();
455 return m_data->getRank();
456 }
457
458 /**
459 \brief
460 Return the number of data points
461 */
462 ESCRIPT_DLL_API
463 inline
464 int
465 getNumDataPoints() const
466 {
467 return getNumSamples() * getNumDataPointsPerSample();
468 }
469 /**
470 \brief
471 Return the number of samples.
472 */
473 ESCRIPT_DLL_API
474 inline
475 int
476 getNumSamples() const
477 {
478 return m_data->getNumSamples();
479 }
480
481 /**
482 \brief
483 Return the number of data points per sample.
484 */
485 ESCRIPT_DLL_API
486 inline
487 int
488 getNumDataPointsPerSample() const
489 {
490 return m_data->getNumDPPSample();
491 }
492
493
494 /**
495 \brief
496 Return the number of values in the shape for this object.
497 */
498 ESCRIPT_DLL_API
499 int
500 getNoValues() const
501 {
502 return m_data->getNoValues();
503 }
504
505
506 /**
507 \brief
508 dumps the object into a netCDF file
509 */
510 ESCRIPT_DLL_API
511 void
512 dump(const std::string fileName) const;
513 /**
514 \brief
515 Return the sample data for the given sample no. This is not the
516 preferred interface but is provided for use by C code.
517 \param sampleNo - Input - the given sample no.
518 */
519 ESCRIPT_DLL_API
520 inline
521 DataAbstract::ValueType::value_type*
522 getSampleData(DataAbstract::ValueType::size_type sampleNo)
523 {
524 return m_data->getSampleData(sampleNo);
525 }
526
527 /**
528 \brief
529 Return the sample data for the given tag. If an attempt is made to
530 access data that isn't tagged an exception will be thrown.
531 \param tag - Input - the tag key.
532 */
533 ESCRIPT_DLL_API
534 inline
535 DataAbstract::ValueType::value_type*
536 getSampleDataByTag(int tag)
537 {
538 return m_data->getSampleDataByTag(tag);
539 }
540
541 // /**
542 /* \brief
543 Return a view into the data for the data point specified.
544 NOTE: Construction of the DataArrayView is a relatively expensive
545 operation.
546 \param sampleNo - Input -
547 \param dataPointNo - Input -*/
548 // */
549 // ESCRIPT_DLL_API
550 // inline
551 // DataArrayView
552 // getDataPoint(int sampleNo,
553 // int dataPointNo)
554 // {
555 // return m_data->getDataPoint(sampleNo,dataPointNo);
556 // }
557
558
559 /**
560 \brief
561 Return a view into the data for the data point specified.
562 NOTE: Construction of the DataArrayView is a relatively expensive
563 operation.
564 \param sampleNo - Input -
565 \param dataPointNo - Input -
566 */
567 ESCRIPT_DLL_API
568 DataTypes::ValueType::const_reference
569 getDataPoint(int sampleNo, int dataPointNo) const;
570
571
572 ESCRIPT_DLL_API
573 DataTypes::ValueType::reference
574 getDataPoint(int sampleNo, int dataPointNo);
575
576
577
578 /**
579 \brief
580 Return the offset for the given sample and point within the sample
581 */
582 ESCRIPT_DLL_API
583 inline
584 DataTypes::ValueType::size_type
585 getDataOffset(int sampleNo,
586 int dataPointNo)
587 {
588 return m_data->getPointOffset(sampleNo,dataPointNo);
589 }
590
591 /**
592 \brief
593 Return a reference to the data point shape.
594 */
595 ESCRIPT_DLL_API
596 inline
597 const DataTypes::ShapeType&
598 getDataPointShape() const
599 {
600 return m_data->getShape();
601 }
602
603 /**
604 \brief
605 Return the data point shape as a tuple of integers.
606 */
607 ESCRIPT_DLL_API
608 const boost::python::tuple
609 getShapeTuple() const;
610
611 /**
612 \brief
613 Return the size of the data point. It is the product of the
614 data point shape dimensions.
615 */
616 ESCRIPT_DLL_API
617 int
618 getDataPointSize() const;
619
620 /**
621 \brief
622 Return the number of doubles stored for this Data.
623 */
624 ESCRIPT_DLL_API
625 DataTypes::ValueType::size_type
626 getLength() const;
627
628
629
630 /**
631 \brief
632 Assign the given value to the tag assocciated with name. Implicitly converts this
633 object to type DataTagged. Throws an exception if this object
634 cannot be converted to a DataTagged object or name cannot be mapped onto a tag key.
635 \param tagKey - Input - Integer key.
636 \param value - Input - Value to associate with given key.
637 ==>*
638 */
639 ESCRIPT_DLL_API
640 void
641 setTaggedValueByName(std::string name,
642 const boost::python::object& value);
643
644 /**
645 \brief
646 Assign the given value to the tag. Implicitly converts this
647 object to type DataTagged if it is constant.
648
649 \param tagKey - Input - Integer key.
650 \param value - Input - Value to associate with given key.
651 ==>*
652 */
653 ESCRIPT_DLL_API
654 void
655 setTaggedValue(int tagKey,
656 const boost::python::object& value);
657
658
659 // /**
660 // \brief
661 // Assign the given value to the tag. Implicitly converts this
662 // object to type DataTagged if it is constant.
663 //
664 // \param tagKey - Input - Integer key.
665 // \param value - Input - Value to associate with given key.
666 // ==>*
667 // */
668 // ESCRIPT_DLL_API
669 // void
670 // setTaggedValueFromCPP(int tagKey,
671 // const DataArrayView& value);
672
673 /**
674 \brief
675 Assign the given value to the tag. Implicitly converts this
676 object to type DataTagged if it is constant.
677
678 \param tagKey - Input - Integer key.
679 \param pointshape - Input - The shape of the value parameter
680 \param value - Input - Value to associate with given key.
681 \param dataOffset - Input - Offset of the begining of the point within the value parameter
682 */
683 ESCRIPT_DLL_API
684 void
685 setTaggedValueFromCPP(int tagKey,
686 const DataTypes::ShapeType& pointshape,
687 const DataTypes::ValueType& value,
688 int dataOffset=0);
689
690
691
692 /**
693 \brief
694 Copy other Data object into this Data object where mask is positive.
695 */
696 ESCRIPT_DLL_API
697 void
698 copyWithMask(const Data& other,
699 const Data& mask);
700
701 /**
702 Data object operation methods and operators.
703 */
704
705 /**
706 \brief
707 set all values to zero
708 *
709 */
710 ESCRIPT_DLL_API
711 void
712 setToZero();
713
714 /**
715 \brief
716 Interpolates this onto the given functionspace and returns
717 the result as a Data object.
718 *
719 */
720 ESCRIPT_DLL_API
721 Data
722 interpolate(const FunctionSpace& functionspace) const;
723 /**
724 \brief
725 Calculates the gradient of the data at the data points of functionspace.
726 If functionspace is not present the function space of Function(getDomain()) is used.
727 *
728 */
729 ESCRIPT_DLL_API
730 Data
731 gradOn(const FunctionSpace& functionspace) const;
732
733 ESCRIPT_DLL_API
734 Data
735 grad() const;
736
737 /**
738 \brief
739 Calculate the integral over the function space domain.
740 *
741 */
742 ESCRIPT_DLL_API
743 boost::python::numeric::array
744 integrate() const;
745
746 /**
747 \brief
748 Returns 1./ Data object
749 *
750 */
751 ESCRIPT_DLL_API
752 Data
753 oneOver() const;
754 /**
755 \brief
756 Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
757 *
758 */
759 ESCRIPT_DLL_API
760 Data
761 wherePositive() const;
762
763 /**
764 \brief
765 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
766 *
767 */
768 ESCRIPT_DLL_API
769 Data
770 whereNegative() const;
771
772 /**
773 \brief
774 Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
775 *
776 */
777 ESCRIPT_DLL_API
778 Data
779 whereNonNegative() const;
780
781 /**
782 \brief
783 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
784 *
785 */
786 ESCRIPT_DLL_API
787 Data
788 whereNonPositive() const;
789
790 /**
791 \brief
792 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
793 *
794 */
795 ESCRIPT_DLL_API
796 Data
797 whereZero(double tol=0.0) const;
798
799 /**
800 \brief
801 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
802 *
803 */
804 ESCRIPT_DLL_API
805 Data
806 whereNonZero(double tol=0.0) const;
807
808 /**
809 \brief
810 Return the maximum absolute value of this Data object.
811 *
812 */
813 ESCRIPT_DLL_API
814 double
815 Lsup() const;
816
817 /**
818 \brief
819 Return the maximum value of this Data object.
820 *
821 */
822 ESCRIPT_DLL_API
823 double
824 sup() const;
825
826 /**
827 \brief
828 Return the minimum value of this Data object.
829 *
830 */
831 ESCRIPT_DLL_API
832 double
833 inf() const;
834
835 /**
836 \brief
837 Return the absolute value of each data point of this Data object.
838 *
839 */
840 ESCRIPT_DLL_API
841 Data
842 abs() const;
843
844 /**
845 \brief
846 Return the maximum value of each data point of this Data object.
847 *
848 */
849 ESCRIPT_DLL_API
850 Data
851 maxval() const;
852
853 /**
854 \brief
855 Return the minimum value of each data point of this Data object.
856 *
857 */
858 ESCRIPT_DLL_API
859 Data
860 minval() const;
861
862 /**
863 \brief
864 Return the (sample number, data-point number) of the data point with
865 the minimum value in this Data object.
866 */
867 ESCRIPT_DLL_API
868 const boost::python::tuple
869 minGlobalDataPoint() const;
870
871 ESCRIPT_DLL_API
872 void
873 calc_minGlobalDataPoint(int& ProcNo, int& DataPointNo) const;
874 /**
875 \brief
876 Return the sign of each data point of this Data object.
877 -1 for negative values, zero for zero values, 1 for positive values.
878 *
879 */
880 ESCRIPT_DLL_API
881 Data
882 sign() const;
883
884 /**
885 \brief
886 Return the symmetric part of a matrix which is half the matrix plus its transpose.
887 *
888 */
889 ESCRIPT_DLL_API
890 Data
891 symmetric() const;
892
893 /**
894 \brief
895 Return the nonsymmetric part of a matrix which is half the matrix minus its transpose.
896 *
897 */
898 ESCRIPT_DLL_API
899 Data
900 nonsymmetric() const;
901
902 /**
903 \brief
904 Return the trace of a matrix
905 *
906 */
907 ESCRIPT_DLL_API
908 Data
909 trace(int axis_offset) const;
910
911 /**
912 \brief
913 Transpose each data point of this Data object around the given axis.
914 *
915 */
916 ESCRIPT_DLL_API
917 Data
918 transpose(int axis_offset) const;
919
920 /**
921 \brief
922 Return the eigenvalues of the symmetric part at each data point of this Data object in increasing values.
923 Currently this function is restricted to rank 2, square shape, and dimension 3.
924 *
925 */
926 ESCRIPT_DLL_API
927 Data
928 eigenvalues() const;
929
930 /**
931 \brief
932 Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.
933 the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than
934 tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the
935 first non-zero entry is positive.
936 Currently this function is restricted to rank 2, square shape, and dimension 3
937 *
938 */
939 ESCRIPT_DLL_API
940 const boost::python::tuple
941 eigenvalues_and_eigenvectors(const double tol=1.e-12) const;
942
943 /**
944 \brief
945 swaps the components axis0 and axis1
946 *
947 */
948 ESCRIPT_DLL_API
949 Data
950 swapaxes(const int axis0, const int axis1) const;
951
952 /**
953 \brief
954 Return the error function erf of each data point of this Data object.
955 *
956 */
957 ESCRIPT_DLL_API
958 Data
959 erf() const;
960
961 /**
962 \brief
963 Return the sin of each data point of this Data object.
964 *
965 */
966 ESCRIPT_DLL_API
967 Data
968 sin() const;
969
970 /**
971 \brief
972 Return the cos of each data point of this Data object.
973 *
974 */
975 ESCRIPT_DLL_API
976 Data
977 cos() const;
978
979 /**
980 \brief
981 Return the tan of each data point of this Data object.
982 *
983 */
984 ESCRIPT_DLL_API
985 Data
986 tan() const;
987
988 /**
989 \brief
990 Return the asin of each data point of this Data object.
991 *
992 */
993 ESCRIPT_DLL_API
994 Data
995 asin() const;
996
997 /**
998 \brief
999 Return the acos of each data point of this Data object.
1000 *
1001 */
1002 ESCRIPT_DLL_API
1003 Data
1004 acos() const;
1005
1006 /**
1007 \brief
1008 Return the atan of each data point of this Data object.
1009 *
1010 */
1011 ESCRIPT_DLL_API
1012 Data
1013 atan() const;
1014
1015 /**
1016 \brief
1017 Return the sinh of each data point of this Data object.
1018 *
1019 */
1020 ESCRIPT_DLL_API
1021 Data
1022 sinh() const;
1023
1024 /**
1025 \brief
1026 Return the cosh of each data point of this Data object.
1027 *
1028 */
1029 ESCRIPT_DLL_API
1030 Data
1031 cosh() const;
1032
1033 /**
1034 \brief
1035 Return the tanh of each data point of this Data object.
1036 *
1037 */
1038 ESCRIPT_DLL_API
1039 Data
1040 tanh() const;
1041
1042 /**
1043 \brief
1044 Return the asinh of each data point of this Data object.
1045 *
1046 */
1047 ESCRIPT_DLL_API
1048 Data
1049 asinh() const;
1050
1051 /**
1052 \brief
1053 Return the acosh of each data point of this Data object.
1054 *
1055 */
1056 ESCRIPT_DLL_API
1057 Data
1058 acosh() const;
1059
1060 /**
1061 \brief
1062 Return the atanh of each data point of this Data object.
1063 *
1064 */
1065 ESCRIPT_DLL_API
1066 Data
1067 atanh() const;
1068
1069 /**
1070 \brief
1071 Return the log to base 10 of each data point of this Data object.
1072 *
1073 */
1074 ESCRIPT_DLL_API
1075 Data
1076 log10() const;
1077
1078 /**
1079 \brief
1080 Return the natural log of each data point of this Data object.
1081 *
1082 */
1083 ESCRIPT_DLL_API
1084 Data
1085 log() const;
1086
1087 /**
1088 \brief
1089 Return the exponential function of each data point of this Data object.
1090 *
1091 */
1092 ESCRIPT_DLL_API
1093 Data
1094 exp() const;
1095
1096 /**
1097 \brief
1098 Return the square root of each data point of this Data object.
1099 *
1100 */
1101 ESCRIPT_DLL_API
1102 Data
1103 sqrt() const;
1104
1105 /**
1106 \brief
1107 Return the negation of each data point of this Data object.
1108 *
1109 */
1110 ESCRIPT_DLL_API
1111 Data
1112 neg() const;
1113
1114 /**
1115 \brief
1116 Return the identity of each data point of this Data object.
1117 Simply returns this object unmodified.
1118 *
1119 */
1120 ESCRIPT_DLL_API
1121 Data
1122 pos() const;
1123
1124 /**
1125 \brief
1126 Return the given power of each data point of this Data object.
1127
1128 \param right Input - the power to raise the object to.
1129 *
1130 */
1131 ESCRIPT_DLL_API
1132 Data
1133 powD(const Data& right) const;
1134
1135 /**
1136 \brief
1137 Return the given power of each data point of this boost python object.
1138
1139 \param right Input - the power to raise the object to.
1140 *
1141 */
1142 ESCRIPT_DLL_API
1143 Data
1144 powO(const boost::python::object& right) const;
1145
1146 /**
1147 \brief
1148 Return the given power of each data point of this boost python object.
1149
1150 \param left Input - the bases
1151 *
1152 */
1153
1154 ESCRIPT_DLL_API
1155 Data
1156 rpowO(const boost::python::object& left) const;
1157
1158 /**
1159 \brief
1160 writes the object to a file in the DX file format
1161 */
1162 ESCRIPT_DLL_API
1163 void
1164 saveDX(std::string fileName) const;
1165
1166 /**
1167 \brief
1168 writes the object to a file in the VTK file format
1169 */
1170 ESCRIPT_DLL_API
1171 void
1172 saveVTK(std::string fileName) const;
1173
1174 /**
1175 \brief
1176 Overloaded operator +=
1177 \param right - Input - The right hand side.
1178 *
1179 */
1180 ESCRIPT_DLL_API
1181 Data& operator+=(const Data& right);
1182 ESCRIPT_DLL_API
1183 Data& operator+=(const boost::python::object& right);
1184
1185 ESCRIPT_DLL_API
1186 Data& operator=(const Data& other);
1187
1188 /**
1189 \brief
1190 Overloaded operator -=
1191 \param right - Input - The right hand side.
1192 *
1193 */
1194 ESCRIPT_DLL_API
1195 Data& operator-=(const Data& right);
1196 ESCRIPT_DLL_API
1197 Data& operator-=(const boost::python::object& right);
1198
1199 /**
1200 \brief
1201 Overloaded operator *=
1202 \param right - Input - The right hand side.
1203 *
1204 */
1205 ESCRIPT_DLL_API
1206 Data& operator*=(const Data& right);
1207 ESCRIPT_DLL_API
1208 Data& operator*=(const boost::python::object& right);
1209
1210 /**
1211 \brief
1212 Overloaded operator /=
1213 \param right - Input - The right hand side.
1214 *
1215 */
1216 ESCRIPT_DLL_API
1217 Data& operator/=(const Data& right);
1218 ESCRIPT_DLL_API
1219 Data& operator/=(const boost::python::object& right);
1220
1221 /**
1222 \brief
1223 Returns true if this can be interpolated to functionspace.
1224 */
1225 ESCRIPT_DLL_API
1226 bool
1227 probeInterpolation(const FunctionSpace& functionspace) const;
1228
1229 /**
1230 Data object slicing methods.
1231 */
1232
1233 /**
1234 \brief
1235 Returns a slice from this Data object.
1236
1237 /description
1238 Implements the [] get operator in python.
1239 Calls getSlice.
1240
1241 \param key - Input - python slice tuple specifying
1242 slice to return.
1243 */
1244 ESCRIPT_DLL_API
1245 Data
1246 getItem(const boost::python::object& key) const;
1247
1248 /**
1249 \brief
1250 Copies slice from value into this Data object.
1251
1252 Implements the [] set operator in python.
1253 Calls setSlice.
1254
1255 \param key - Input - python slice tuple specifying
1256 slice to copy from value.
1257 \param value - Input - Data object to copy from.
1258 */
1259 ESCRIPT_DLL_API
1260 void
1261 setItemD(const boost::python::object& key,
1262 const Data& value);
1263
1264 ESCRIPT_DLL_API
1265 void
1266 setItemO(const boost::python::object& key,
1267 const boost::python::object& value);
1268
1269 // These following public methods should be treated as private.
1270
1271 /**
1272 \brief
1273 Perform the given unary operation on every element of every data point in
1274 this Data object.
1275 */
1276 template <class UnaryFunction>
1277 ESCRIPT_DLL_API
1278 inline
1279 void
1280 unaryOp2(UnaryFunction operation);
1281
1282 /**
1283 \brief
1284 Return a Data object containing the specified slice of
1285 this Data object.
1286 \param region - Input - Region to copy.
1287 *
1288 */
1289 ESCRIPT_DLL_API
1290 Data
1291 getSlice(const DataTypes::RegionType& region) const;
1292
1293 /**
1294 \brief
1295 Copy the specified slice from the given value into this
1296 Data object.
1297 \param value - Input - Data to copy from.
1298 \param region - Input - Region to copy.
1299 *
1300 */
1301 ESCRIPT_DLL_API
1302 void
1303 setSlice(const Data& value,
1304 const DataTypes::RegionType& region);
1305
1306 /**
1307 \brief
1308 print the data values to stdout. Used for debugging
1309 */
1310 ESCRIPT_DLL_API
1311 void
1312 print(void);
1313
1314 /**
1315 \brief
1316 return the MPI rank number of the local data
1317 MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()
1318 is returned
1319 */
1320 ESCRIPT_DLL_API
1321 int
1322 get_MPIRank(void) const;
1323
1324 /**
1325 \brief
1326 return the MPI rank number of the local data
1327 MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()
1328 is returned
1329 */
1330 ESCRIPT_DLL_API
1331 int
1332 get_MPISize(void) const;
1333
1334 /**
1335 \brief
1336 return the MPI rank number of the local data
1337 MPI_COMM_WORLD is assumed and returned.
1338 */
1339 ESCRIPT_DLL_API
1340 MPI_Comm
1341 get_MPIComm(void) const;
1342
1343 /**
1344 \brief
1345 return the object produced by the factory, which is a DataConstant or DataExpanded
1346 TODO Ownership of this object should be explained in doco.
1347 */
1348 ESCRIPT_DLL_API
1349 DataAbstract*
1350 borrowData(void) const;
1351
1352
1353 /**
1354 \brief
1355 Return a pointer to the beginning of the datapoint at the specified offset.
1356 TODO Eventually these should be inlined.
1357 \param i - position(offset) in the underlying datastructure
1358 */
1359 ESCRIPT_DLL_API
1360 DataTypes::ValueType::const_reference
1361 getDataAtOffset(DataTypes::ValueType::size_type i) const;
1362
1363
1364 ESCRIPT_DLL_API
1365 DataTypes::ValueType::reference
1366 getDataAtOffset(DataTypes::ValueType::size_type i);
1367
1368 protected:
1369
1370 private:
1371
1372 /**
1373 \brief
1374 Check *this and the right operand are compatible. Throws
1375 an exception if they aren't.
1376 \param right - Input - The right hand side.
1377 */
1378 inline
1379 void
1380 operandCheck(const Data& right) const
1381 {
1382 return m_data->operandCheck(*(right.m_data.get()));
1383 }
1384
1385 /**
1386 \brief
1387 Perform the specified reduction algorithm on every element of every data point in
1388 this Data object according to the given function and return the single value result.
1389 */
1390 template <class BinaryFunction>
1391 inline
1392 double
1393 algorithm(BinaryFunction operation,
1394 double initial_value) const;
1395
1396 /**
1397 \brief
1398 Reduce each data-point in this Data object using the given operation. Return a Data
1399 object with the same number of data-points, but with each data-point containing only
1400 one value - the result of the reduction operation on the corresponding data-point in
1401 this Data object
1402 */
1403 template <class BinaryFunction>
1404 inline
1405 Data
1406 dp_algorithm(BinaryFunction operation,
1407 double initial_value) const;
1408
1409 /**
1410 \brief
1411 Perform the given binary operation on all of the data's elements.
1412 The underlying type of the right hand side (right) determines the final
1413 type of *this after the operation. For example if the right hand side
1414 is expanded *this will be expanded if necessary.
1415 RHS is a Data object.
1416 */
1417 template <class BinaryFunction>
1418 inline
1419 void
1420 binaryOp(const Data& right,
1421 BinaryFunction operation);
1422
1423 /**
1424 \brief
1425 Convert the data type of the RHS to match this.
1426 \param right - Input - data type to match.
1427 */
1428 void
1429 typeMatchLeft(Data& right) const;
1430
1431 /**
1432 \brief
1433 Convert the data type of this to match the RHS.
1434 \param right - Input - data type to match.
1435 */
1436 void
1437 typeMatchRight(const Data& right);
1438
1439 /**
1440 \brief
1441 Construct a Data object of the appropriate type.
1442 */
1443
1444 void
1445 initialise(const DataTypes::ValueType& value,
1446 const DataTypes::ShapeType& shape,
1447 const FunctionSpace& what,
1448 bool expanded);
1449
1450 void
1451 initialise(const boost::python::numeric::array& value,
1452 const FunctionSpace& what,
1453 bool expanded);
1454
1455 //
1456 // flag to protect the data object against any update
1457 bool m_protected;
1458
1459 //
1460 // pointer to the actual data object
1461 boost::shared_ptr<DataAbstract> m_data;
1462
1463 };
1464
1465
1466
1467 /**
1468 Modify a filename for MPI parallel output to multiple files
1469 */
1470 char *Escript_MPI_appendRankToFileName(const char *, int, int);
1471
1472 /**
1473 Binary Data object operators.
1474 */
1475 inline double rpow(double x,double y)
1476 {
1477 return pow(y,x);
1478 }
1479
1480 /**
1481 \brief
1482 Operator+
1483 Takes two Data objects.
1484 */
1485 ESCRIPT_DLL_API Data operator+(const Data& left, const Data& right);
1486
1487 /**
1488 \brief
1489 Operator-
1490 Takes two Data objects.
1491 */
1492 ESCRIPT_DLL_API Data operator-(const Data& left, const Data& right);
1493
1494 /**
1495 \brief
1496 Operator*
1497 Takes two Data objects.
1498 */
1499 ESCRIPT_DLL_API Data operator*(const Data& left, const Data& right);
1500
1501 /**
1502 \brief
1503 Operator/
1504 Takes two Data objects.
1505 */
1506 ESCRIPT_DLL_API Data operator/(const Data& left, const Data& right);
1507
1508 /**
1509 \brief
1510 Operator+
1511 Takes LHS Data object and RHS python::object.
1512 python::object must be convertable to Data type.
1513 */
1514 ESCRIPT_DLL_API Data operator+(const Data& left, const boost::python::object& right);
1515
1516 /**
1517 \brief
1518 Operator-
1519 Takes LHS Data object and RHS python::object.
1520 python::object must be convertable to Data type.
1521 */
1522 ESCRIPT_DLL_API Data operator-(const Data& left, const boost::python::object& right);
1523
1524 /**
1525 \brief
1526 Operator*
1527 Takes LHS Data object and RHS python::object.
1528 python::object must be convertable to Data type.
1529 */
1530 ESCRIPT_DLL_API Data operator*(const Data& left, const boost::python::object& right);
1531
1532 /**
1533 \brief
1534 Operator/
1535 Takes LHS Data object and RHS python::object.
1536 python::object must be convertable to Data type.
1537 */
1538 ESCRIPT_DLL_API Data operator/(const Data& left, const boost::python::object& right);
1539
1540 /**
1541 \brief
1542 Operator+
1543 Takes LHS python::object and RHS Data object.
1544 python::object must be convertable to Data type.
1545 */
1546 ESCRIPT_DLL_API Data operator+(const boost::python::object& left, const Data& right);
1547
1548 /**
1549 \brief
1550 Operator-
1551 Takes LHS python::object and RHS Data object.
1552 python::object must be convertable to Data type.
1553 */
1554 ESCRIPT_DLL_API Data operator-(const boost::python::object& left, const Data& right);
1555
1556 /**
1557 \brief
1558 Operator*
1559 Takes LHS python::object and RHS Data object.
1560 python::object must be convertable to Data type.
1561 */
1562 ESCRIPT_DLL_API Data operator*(const boost::python::object& left, const Data& right);
1563
1564 /**
1565 \brief
1566 Operator/
1567 Takes LHS python::object and RHS Data object.
1568 python::object must be convertable to Data type.
1569 */
1570 ESCRIPT_DLL_API Data operator/(const boost::python::object& left, const Data& right);
1571
1572
1573
1574 /**
1575 \brief
1576 Output operator
1577 */
1578 ESCRIPT_DLL_API std::ostream& operator<<(std::ostream& o, const Data& data);
1579
1580 /**
1581 \brief
1582 Compute a tensor product of two Data objects
1583 \param arg0 - Input - Data object
1584 \param arg1 - Input - Data object
1585 \param axis_offset - Input - axis offset
1586 \param transpose - Input - 0: transpose neither, 1: transpose arg0, 2: transpose arg1
1587 */
1588 ESCRIPT_DLL_API
1589 Data
1590 C_GeneralTensorProduct(Data& arg0,
1591 Data& arg1,
1592 int axis_offset=0,
1593 int transpose=0);
1594
1595
1596
1597 // /**
1598 /* \brief
1599 Return true if operands are equivalent, else return false.
1600 NB: this operator does very little at this point, and isn't to
1601 be relied on. Requires further implementation.*/
1602 //*/
1603 // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1604
1605 /**
1606 \brief
1607 Perform the given binary operation with this and right as operands.
1608 Right is a Data object.
1609 */
1610 template <class BinaryFunction>
1611 inline
1612 void
1613 Data::binaryOp(const Data& right,
1614 BinaryFunction operation)
1615 {
1616 //
1617 // if this has a rank of zero promote it to the rank of the RHS
1618 if (getDataPointRank()==0 && right.getDataPointRank()!=0) {
1619 throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1620 }
1621 //
1622 // initially make the temporary a shallow copy
1623 Data tempRight(right);
1624 if (getFunctionSpace()!=right.getFunctionSpace()) {
1625 if (right.probeInterpolation(getFunctionSpace())) {
1626 //
1627 // an interpolation is required so create a new Data
1628 tempRight=Data(right,this->getFunctionSpace());
1629 } else if (probeInterpolation(right.getFunctionSpace())) {
1630 //
1631 // interpolate onto the RHS function space
1632 Data tempLeft(*this,right.getFunctionSpace());
1633 m_data=tempLeft.m_data;
1634 }
1635 }
1636 operandCheck(tempRight);
1637 //
1638 // ensure this has the right type for the RHS
1639 typeMatchRight(tempRight);
1640 //
1641 // Need to cast to the concrete types so that the correct binaryOp
1642 // is called.
1643 if (isExpanded()) {
1644 //
1645 // Expanded data will be done in parallel, the right hand side can be
1646 // of any data type
1647 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1648 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1649 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1650 } else if (isTagged()) {
1651 //
1652 // Tagged data is operated on serially, the right hand side can be
1653 // either DataConstant or DataTagged
1654 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1655 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1656 if (right.isTagged()) {
1657 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1658 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1659 escript::binaryOp(*leftC,*rightC,operation);
1660 } else {
1661 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1662 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1663 escript::binaryOp(*leftC,*rightC,operation);
1664 }
1665 } else if (isConstant()) {
1666 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1667 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1668 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1669 escript::binaryOp(*leftC,*rightC,operation);
1670 }
1671 }
1672
1673 /**
1674 \brief
1675 Perform the given Data object reduction algorithm on this and return the result.
1676 Given operation combines each element of each data point, thus argument
1677 object (*this) is a rank n Data object, and returned object is a scalar.
1678 Calls escript::algorithm.
1679 */
1680 template <class BinaryFunction>
1681 inline
1682 double
1683 Data::algorithm(BinaryFunction operation, double initial_value) const
1684 {
1685 if (isExpanded()) {
1686 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1687 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1688 return escript::algorithm(*leftC,operation,initial_value);
1689 } else if (isTagged()) {
1690 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1691 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1692 return escript::algorithm(*leftC,operation,initial_value);
1693 } else if (isConstant()) {
1694 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1695 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1696 return escript::algorithm(*leftC,operation,initial_value);
1697 } else if (isEmpty()) {
1698 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1699 }
1700 return 0;
1701 }
1702
1703 /**
1704 \brief
1705 Perform the given data point reduction algorithm on data and return the result.
1706 Given operation combines each element within each data point into a scalar,
1707 thus argument object is a rank n Data object, and returned object is a
1708 rank 0 Data object.
1709 Calls escript::dp_algorithm.
1710 */
1711 template <class BinaryFunction>
1712 inline
1713 Data
1714 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1715 {
1716 if (isEmpty()) {
1717 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1718 }
1719 else if (isExpanded()) {
1720 Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1721 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1722 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1723 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1724 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1725 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1726 return result;
1727 }
1728 else if (isTagged()) {
1729 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1730 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1731 DataTypes::ValueType defval(1);
1732 defval[0]=0;
1733 DataTagged* resultT=new DataTagged(getFunctionSpace(), DataTypes::scalarShape, defval, dataT);
1734 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1735 return Data(resultT); // note: the Data object now owns the resultT pointer
1736 }
1737 else if (isConstant()) {
1738 Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1739 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1740 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1741 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1742 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1743 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1744 return result;
1745 }
1746 Data falseRetVal; // to keep compiler quiet
1747 return falseRetVal;
1748 }
1749
1750 /**
1751 \brief
1752 Compute a tensor operation with two Data objects
1753 \param arg0 - Input - Data object
1754 \param arg1 - Input - Data object
1755 \param operation - Input - Binary op functor
1756 */
1757 template <typename BinaryFunction>
1758 inline
1759 Data
1760 C_TensorBinaryOperation(Data const &arg_0,
1761 Data const &arg_1,
1762 BinaryFunction operation)
1763 {
1764 if (arg_0.isEmpty() || arg_1.isEmpty())
1765 {
1766 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1767 }
1768 // Interpolate if necessary and find an appropriate function space
1769 Data arg_0_Z, arg_1_Z;
1770 if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
1771 if (arg_0.probeInterpolation(arg_1.getFunctionSpace())) {
1772 arg_0_Z = arg_0.interpolate(arg_1.getFunctionSpace());
1773 arg_1_Z = Data(arg_1);
1774 }
1775 else if (arg_1.probeInterpolation(arg_0.getFunctionSpace())) {
1776 arg_1_Z=arg_1.interpolate(arg_0.getFunctionSpace());
1777 arg_0_Z =Data(arg_0);
1778 }
1779 else {
1780 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible function spaces.");
1781 }
1782 } else {
1783 arg_0_Z = Data(arg_0);
1784 arg_1_Z = Data(arg_1);
1785 }
1786 // Get rank and shape of inputs
1787 int rank0 = arg_0_Z.getDataPointRank();
1788 int rank1 = arg_1_Z.getDataPointRank();
1789 DataTypes::ShapeType shape0 = arg_0_Z.getDataPointShape();
1790 DataTypes::ShapeType shape1 = arg_1_Z.getDataPointShape();
1791 int size0 = arg_0_Z.getDataPointSize();
1792 int size1 = arg_1_Z.getDataPointSize();
1793
1794 // Declare output Data object
1795 Data res;
1796
1797 if (shape0 == shape1) {
1798
1799 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
1800 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
1801 /* double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1802 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1803 double *ptr_2 = &((res.getPointDataView().getData())[0]);*/
1804 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
1805 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
1806 double *ptr_2 = &(res.getDataAtOffset(0));
1807
1808 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1809 }
1810 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
1811
1812 // Prepare the DataConstant input
1813 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1814
1815 // Borrow DataTagged input from Data object
1816 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1817
1818 // Prepare a DataTagged output 2
1819 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
1820 res.tag();
1821 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1822
1823 // Prepare offset into DataConstant
1824 int offset_0 = tmp_0->getPointOffset(0,0);
1825 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1826 // Get the views
1827 // DataArrayView view_1 = tmp_1->getDefaultValue();
1828 // DataArrayView view_2 = tmp_2->getDefaultValue();
1829 // // Get the pointers to the actual data
1830 // double *ptr_1 = &((view_1.getData())[0]);
1831 // double *ptr_2 = &((view_2.getData())[0]);
1832
1833 // Get the pointers to the actual data
1834 double *ptr_1 = &(tmp_1->getDefaultValue(0));
1835 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1836
1837 // Compute a result for the default
1838 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1839 // Compute a result for each tag
1840 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1841 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1842 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1843 tmp_2->addTag(i->first);
1844 /* DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1845 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1846 double *ptr_1 = &view_1.getData(0);
1847 double *ptr_2 = &view_2.getData(0);*/
1848 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1849 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1850
1851 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1852 }
1853
1854 }
1855 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
1856
1857 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1858 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1859 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1860 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1861
1862 int sampleNo_1,dataPointNo_1;
1863 int numSamples_1 = arg_1_Z.getNumSamples();
1864 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
1865 int offset_0 = tmp_0->getPointOffset(0,0);
1866 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
1867 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
1868 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1869 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1870 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1871 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1872 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1873 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1874
1875 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1876 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1877 double *ptr_2 = &(res.getDataAtOffset(offset_2));
1878 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1879 }
1880 }
1881
1882 }
1883 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
1884
1885 // Borrow DataTagged input from Data object
1886 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1887
1888 // Prepare the DataConstant input
1889 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1890
1891 // Prepare a DataTagged output 2
1892 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
1893 res.tag();
1894 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1895
1896 // Prepare offset into DataConstant
1897 int offset_1 = tmp_1->getPointOffset(0,0);
1898 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1899 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1900 // Get the views
1901 // DataArrayView view_0 = tmp_0->getDefaultValue();
1902 // DataArrayView view_2 = tmp_2->getDefaultValue();
1903 // // Get the pointers to the actual data
1904 // double *ptr_0 = &((view_0.getData())[0]);
1905 // double *ptr_2 = &((view_2.getData())[0]);
1906 // Get the pointers to the actual data
1907 double *ptr_0 = &(tmp_0->getDefaultValue(0));
1908 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1909 // Compute a result for the default
1910 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1911 // Compute a result for each tag
1912 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1913 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1914 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1915 tmp_2->addTag(i->first);
1916 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1917 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1918 // double *ptr_0 = &view_0.getData(0);
1919 // double *ptr_2 = &view_2.getData(0);
1920 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1921 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1922 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1923 }
1924
1925 }
1926 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
1927
1928 // Borrow DataTagged input from Data object
1929 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1930
1931 // Borrow DataTagged input from Data object
1932 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1933
1934 // Prepare a DataTagged output 2
1935 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
1936 res.tag(); // DataTagged output
1937 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1938
1939 // // Get the views
1940 // DataArrayView view_0 = tmp_0->getDefaultValue();
1941 // DataArrayView view_1 = tmp_1->getDefaultValue();
1942 // DataArrayView view_2 = tmp_2->getDefaultValue();
1943 // // Get the pointers to the actual data
1944 // double *ptr_0 = &((view_0.getData())[0]);
1945 // double *ptr_1 = &((view_1.getData())[0]);
1946 // double *ptr_2 = &((view_2.getData())[0]);
1947
1948 // Get the pointers to the actual data
1949 double *ptr_0 = &(tmp_0->getDefaultValue(0));
1950 double *ptr_1 = &(tmp_1->getDefaultValue(0));
1951 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1952
1953 // Compute a result for the default
1954 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1955 // Merge the tags
1956 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1957 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1958 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1959 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1960 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
1961 }
1962 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1963 tmp_2->addTag(i->first);
1964 }
1965 // Compute a result for each tag
1966 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1967 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1968
1969 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1970 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1971 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1972 // double *ptr_0 = &view_0.getData(0);
1973 // double *ptr_1 = &view_1.getData(0);
1974 // double *ptr_2 = &view_2.getData(0);
1975
1976 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1977 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1978 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1979
1980 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1981 }
1982
1983 }
1984 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
1985
1986 // After finding a common function space above the two inputs have the same numSamples and num DPPS
1987 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1988 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1989 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1990 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1991
1992 int sampleNo_0,dataPointNo_0;
1993 int numSamples_0 = arg_0_Z.getNumSamples();
1994 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1995 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1996 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1997 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1998 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1999 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2000 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2001 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2002
2003 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2004 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2005 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2006 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2007
2008
2009 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2010 }
2011 }
2012
2013 }
2014 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2015
2016 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2017 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2018 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2019 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2020
2021 int sampleNo_0,dataPointNo_0;
2022 int numSamples_0 = arg_0_Z.getNumSamples();
2023 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2024 int offset_1 = tmp_1->getPointOffset(0,0);
2025 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2026 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2027 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2028 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2029 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2030
2031 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2032 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2033 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2034
2035 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2036 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2037 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2038
2039
2040 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2041 }
2042 }
2043
2044 }
2045 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2046
2047 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2048 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2049 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2050 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2051 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2052
2053 int sampleNo_0,dataPointNo_0;
2054 int numSamples_0 = arg_0_Z.getNumSamples();
2055 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2056 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2057 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2058 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2059 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2060 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2061 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2062 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2063 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2064 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2065 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2066 }
2067 }
2068
2069 }
2070 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2071
2072 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2073 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2074 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2075 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2076 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2077
2078 int sampleNo_0,dataPointNo_0;
2079 int numSamples_0 = arg_0_Z.getNumSamples();
2080 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2081 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2082 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2083 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2084 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2085 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2086 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2087 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2088 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2089 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2090 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2091 }
2092 }
2093
2094 }
2095 else {
2096 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2097 }
2098
2099 } else if (0 == rank0) {
2100
2101 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2102 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataConstant output
2103 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2104 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2105 double *ptr_2 = &(res.getDataAtOffset(0));
2106 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2107 }
2108 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2109
2110 // Prepare the DataConstant input
2111 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2112
2113 // Borrow DataTagged input from Data object
2114 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2115
2116 // Prepare a DataTagged output 2
2117 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataTagged output
2118 res.tag();
2119 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2120
2121 // Prepare offset into DataConstant
2122 int offset_0 = tmp_0->getPointOffset(0,0);
2123 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2124 // Get the views
2125 // DataArrayView view_1 = tmp_1->getDefaultValue();
2126 // DataArrayView view_2 = tmp_2->getDefaultValue();
2127 // // Get the pointers to the actual data
2128 // double *ptr_1 = &((view_1.getData())[0]);
2129 // double *ptr_2 = &((view_2.getData())[0]);
2130 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2131 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2132
2133 // Compute a result for the default
2134 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2135 // Compute a result for each tag
2136 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2137 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2138 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2139 tmp_2->addTag(i->first);
2140 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2141 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2142 // double *ptr_1 = &view_1.getData(0);
2143 // double *ptr_2 = &view_2.getData(0);
2144 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2145 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2146 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2147 }
2148
2149 }
2150 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2151
2152 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2153 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2154 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2155 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2156
2157 int sampleNo_1,dataPointNo_1;
2158 int numSamples_1 = arg_1_Z.getNumSamples();
2159 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2160 int offset_0 = tmp_0->getPointOffset(0,0);
2161 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2162 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2163 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2164 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2165 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2166 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2167 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2168 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2169 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2170
2171 }
2172 }
2173
2174 }
2175 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2176
2177 // Borrow DataTagged input from Data object
2178 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2179
2180 // Prepare the DataConstant input
2181 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2182
2183 // Prepare a DataTagged output 2
2184 res = Data(0.0, shape1, arg_0_Z.getFunctionSpace()); // DataTagged output
2185 res.tag();
2186 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2187
2188 // Prepare offset into DataConstant
2189 int offset_1 = tmp_1->getPointOffset(0,0);
2190 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2191 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2192 // Get the views
2193 /* DataArrayView view_0 = tmp_0->getDefaultValue();
2194 DataArrayView view_2 = tmp_2->getDefaultValue();
2195 // Get the pointers to the actual data
2196 double *ptr_0 = &((view_0.getData())[0]);
2197 double *ptr_2 = &((view_2.getData())[0]);*/
2198
2199 // Get the pointers to the actual data
2200 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2201 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2202
2203
2204 // Compute a result for the default
2205 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2206 // Compute a result for each tag
2207 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2208 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2209 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2210 tmp_2->addTag(i->first);
2211 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2212 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2213 double *ptr_0 = &view_0.getData(0);
2214 double *ptr_2 = &view_2.getData(0);*/
2215 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2216 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2217
2218 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2219 }
2220
2221 }
2222 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2223
2224 // Borrow DataTagged input from Data object
2225 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2226
2227 // Borrow DataTagged input from Data object
2228 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2229
2230 // Prepare a DataTagged output 2
2231 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());
2232 res.tag(); // DataTagged output
2233 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2234
2235 // Get the views
2236 /* DataArrayView view_0 = tmp_0->getDefaultValue();
2237 DataArrayView view_1 = tmp_1->getDefaultValue();
2238 DataArrayView view_2 = tmp_2->getDefaultValue();
2239 // Get the pointers to the actual data
2240 double *ptr_0 = &((view_0.getData())[0]);
2241 double *ptr_1 = &((view_1.getData())[0]);
2242 double *ptr_2 = &((view_2.getData())[0]);*/
2243
2244 // Get the pointers to the actual data
2245 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2246 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2247 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2248
2249
2250 // Compute a result for the default
2251 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2252 // Merge the tags
2253 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2254 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2255 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2256 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2257 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2258 }
2259 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2260 tmp_2->addTag(i->first);
2261 }
2262 // Compute a result for each tag
2263 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2264 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2265
2266 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2267 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2268 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2269 double *ptr_0 = &view_0.getData(0);
2270 double *ptr_1 = &view_1.getData(0);
2271 double *ptr_2 = &view_2.getData(0);*/
2272
2273 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2274 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2275 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2276
2277 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2278 }
2279
2280 }
2281 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2282
2283 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2284 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2285 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2286 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2287 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2288
2289 int sampleNo_0,dataPointNo_0;
2290 int numSamples_0 = arg_0_Z.getNumSamples();
2291 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2292 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2293 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2294 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2295 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2296 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2297 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2298 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2299 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2300 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2301 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2302 }
2303 }
2304
2305 }
2306 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2307
2308 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2309 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2310 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2311 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2312
2313 int sampleNo_0,dataPointNo_0;
2314 int numSamples_0 = arg_0_Z.getNumSamples();
2315 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2316 int offset_1 = tmp_1->getPointOffset(0,0);
2317 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2318 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2319 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2320 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2321 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2322 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2323 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2324 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2325 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2326 }
2327 }
2328
2329
2330 }
2331 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2332
2333 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2334 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2335 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2336 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2337 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2338
2339 int sampleNo_0,dataPointNo_0;
2340 int numSamples_0 = arg_0_Z.getNumSamples();
2341 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2342 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2343 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2344 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2345 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2346 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2347 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2348 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2349 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2350 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2351 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2352 }
2353 }
2354
2355 }
2356 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2357
2358 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2359 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2360 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2361 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2362 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2363
2364 int sampleNo_0,dataPointNo_0;
2365 int numSamples_0 = arg_0_Z.getNumSamples();
2366 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2367 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2368 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2369 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2370 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2371 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2372 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2373 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2374 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2375 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2376 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2377 }
2378 }
2379
2380 }
2381 else {
2382 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2383 }
2384
2385 } else if (0 == rank1) {
2386
2387 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2388 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
2389 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2390 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2391 double *ptr_2 = &(res.getDataAtOffset(0));
2392 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2393 }
2394 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2395
2396 // Prepare the DataConstant input
2397 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2398
2399 // Borrow DataTagged input from Data object
2400 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2401
2402 // Prepare a DataTagged output 2
2403 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
2404 res.tag();
2405 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2406
2407 // Prepare offset into DataConstant
2408 int offset_0 = tmp_0->getPointOffset(0,0);
2409 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2410 // Get the views
2411 /* DataArrayView view_1 = tmp_1->getDefaultValue();
2412 DataArrayView view_2 = tmp_2->getDefaultValue();
2413 // Get the pointers to the actual data
2414 double *ptr_1 = &((view_1.getData())[0]);
2415 double *ptr_2 = &((view_2.getData())[0]);*/
2416 //Get the pointers to the actual data
2417 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2418 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2419
2420 // Compute a result for the default
2421 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2422 // Compute a result for each tag
2423 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2424 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2425 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2426 tmp_2->addTag(i->first);
2427 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2428 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2429 // double *ptr_1 = &view_1.getData(0);
2430 // double *ptr_2 = &view_2.getData(0);
2431 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2432 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2433
2434
2435 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2436 }
2437
2438 }
2439 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2440
2441 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2442 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2443 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2444 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2445
2446 int sampleNo_1,dataPointNo_1;
2447 int numSamples_1 = arg_1_Z.getNumSamples();
2448 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2449 int offset_0 = tmp_0->getPointOffset(0,0);
2450 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2451 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2452 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2453 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2454 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2455 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2456 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2457 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2458 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2459 }
2460 }
2461
2462 }
2463 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2464
2465 // Borrow DataTagged input from Data object
2466 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2467
2468 // Prepare the DataConstant input
2469 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2470
2471 // Prepare a DataTagged output 2
2472 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
2473 res.tag();
2474 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2475
2476 // Prepare offset into DataConstant
2477 int offset_1 = tmp_1->getPointOffset(0,0);
2478 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2479 // Get the views
2480 // DataArrayView view_0 = tmp_0->getDefaultValue();
2481 // DataArrayView view_2 = tmp_2->getDefaultValue();
2482 // // Get the pointers to the actual data
2483 // double *ptr_0 = &((view_0.getData())[0]);
2484 // double *ptr_2 = &((view_2.getData())[0]);
2485 // Get the pointers to the actual data
2486 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2487 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2488 // Compute a result for the default
2489 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2490 // Compute a result for each tag
2491 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2492 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2493 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2494 tmp_2->addTag(i->first);
2495 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2496 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2497 double *ptr_0 = &view_0.getData(0);
2498 double *ptr_2 = &view_2.getData(0);*/
2499 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2500 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2501 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2502 }
2503
2504 }
2505 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2506
2507 // Borrow DataTagged input from Data object
2508 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2509
2510 // Borrow DataTagged input from Data object
2511 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2512
2513 // Prepare a DataTagged output 2
2514 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
2515 res.tag(); // DataTagged output
2516 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2517
2518 // Get the views
2519 // DataArrayView view_0 = tmp_0->getDefaultValue();
2520 // DataArrayView view_1 = tmp_1->getDefaultValue();
2521 // DataArrayView view_2 = tmp_2->getDefaultValue();
2522 // // Get the pointers to the actual data
2523 // double *ptr_0 = &((view_0.getData())[0]);
2524 // double *ptr_1 = &((view_1.getData())[0]);
2525 // double *ptr_2 = &((view_2.getData())[0]);
2526
2527 // Get the pointers to the actual data
2528 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2529 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2530 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2531
2532 // Compute a result for the default
2533 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2534 // Merge the tags
2535 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2536 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2537 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2538 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2539 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2540 }
2541 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2542 tmp_2->addTag(i->first);
2543 }
2544 // Compute a result for each tag
2545 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2546 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2547 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2548 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2549 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2550 // double *ptr_0 = &view_0.getData(0);
2551 // double *ptr_1 = &view_1.getData(0);
2552 // double *ptr_2 = &view_2.getData(0);
2553
2554 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2555 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2556 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2557 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2558 }
2559
2560 }
2561 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2562
2563 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2564 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2565 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2566 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2567 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2568
2569 int sampleNo_0,dataPointNo_0;
2570 int numSamples_0 = arg_0_Z.getNumSamples();
2571 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2572 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2573 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2574 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2575 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2576 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2577 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2578 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2579 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2580 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2581 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2582 }
2583 }
2584
2585 }
2586 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2587
2588 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2589 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2590 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2591 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2592
2593 int sampleNo_0,dataPointNo_0;
2594 int numSamples_0 = arg_0_Z.getNumSamples();
2595 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2596 int offset_1 = tmp_1->getPointOffset(0,0);
2597 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2598 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2599 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2600 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2601 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2602 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2603 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2604 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2605 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2606 }
2607 }
2608
2609
2610 }
2611 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2612
2613 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2614 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2615 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2616 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2617 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2618
2619 int sampleNo_0,dataPointNo_0;
2620 int numSamples_0 = arg_0_Z.getNumSamples();
2621 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2622 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2623 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2624 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2625 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2626 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2627 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2628 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2629 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2630 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2631 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2632 }
2633 }
2634
2635 }
2636 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2637
2638 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2639 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2640 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2641 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2642 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2643
2644 int sampleNo_0,dataPointNo_0;
2645 int numSamples_0 = arg_0_Z.getNumSamples();
2646 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2647 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2648 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2649 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2650 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2651 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2652 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2653 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2654 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2655 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2656 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2657 }
2658 }
2659
2660 }
2661 else {
2662 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2663 }
2664
2665 } else {
2666 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible shapes");
2667 }
2668
2669 return res;
2670 }
2671
2672 template <typename UnaryFunction>
2673 Data
2674 C_TensorUnaryOperation(Data const &arg_0,
2675 UnaryFunction operation)
2676 {
2677 if (arg_0.isEmpty()) // do this before we attempt to interpolate
2678 {
2679 throw DataException("Error - Operations not permitted on instances of DataEmpty.");
2680 }
2681
2682 // Interpolate if necessary and find an appropriate function space
2683 Data arg_0_Z = Data(arg_0);
2684
2685 // Get rank and shape of inputs
2686 int rank0 = arg_0_Z.getDataPointRank();
2687 const DataTypes::ShapeType& shape0 = arg_0_Z.getDataPointShape();
2688 int size0 = arg_0_Z.getDataPointSize();
2689
2690 // Declare output Data object
2691 Data res;
2692
2693 if (arg_0_Z.isConstant()) {
2694 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataConstant output
2695 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2696 // double *ptr_2 = &((res.getPointDataView().getData())[0]);
2697 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2698 double *ptr_2 = &(res.getDataAtOffset(0));
2699 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2700 }
2701 else if (arg_0_Z.isTagged()) {
2702
2703 // Borrow DataTagged input from Data object
2704 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2705
2706 // Prepare a DataTagged output 2
2707 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
2708 res.tag();
2709 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2710
2711 // // Get the views
2712 // DataArrayView view_0 = tmp_0->getDefaultValue();
2713 // DataArrayView view_2 = tmp_2->getDefaultValue();
2714 // // Get the pointers to the actual data
2715 // double *ptr_0 = &((view_0.getData())[0]);
2716 // double *ptr_2 = &((view_2.getData())[0]);
2717 // Get the pointers to the actual data
2718 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2719 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2720 // Compute a result for the default
2721 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2722 // Compute a result for each tag
2723 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2724 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2725 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2726 tmp_2->addTag(i->first);
2727 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2728 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2729 // double *ptr_0 = &view_0.getData(0);
2730 // double *ptr_2 = &view_2.getData(0);
2731 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2732 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2733 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2734 }
2735
2736 }
2737 else if (arg_0_Z.isExpanded()) {
2738
2739 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace(),true); // DataExpanded output
2740 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2741 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2742
2743 int sampleNo_0,dataPointNo_0;
2744 int numSamples_0 = arg_0_Z.getNumSamples();
2745 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2746 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2747 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2748 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2749 // int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2750 // int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2751 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2752 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2753 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2754 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2755 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2756 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2757 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2758 }
2759 }
2760 }
2761 else {
2762 throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");
2763 }
2764
2765 return res;
2766 }
2767
2768 }
2769 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26