/[escript]/branches/schroedinger/escript/src/Data.h
ViewVC logotype

Contents of /branches/schroedinger/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1799 - (show annotations)
Wed Sep 17 06:33:18 2008 UTC (11 years ago) by jfenwick
Original Path: trunk/escript/src/Data.h
File MIME type: text/plain
File size: 87887 byte(s)
Added Data::copySelf() [Note: this is exposed as copy() in python].
This method returns a pointer to a deep copy of the target.
There are c++ tests but no python tests for this yet.

All DataAbstracts now have a deepCopy() which simplifies the 
implementation of the compy methods.


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26