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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1781 - (show annotations)
Thu Sep 11 05:03:14 2008 UTC (10 years, 11 months ago) by jfenwick
File MIME type: text/plain
File size: 88376 byte(s)
Branch commit

Merged changes from trunk version 1695 up to and including version 1779.


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26