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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

temp/escript/src/Data.h revision 1387 by trankine, Fri Jan 11 07:45:26 2008 UTC trunk/escript/src/Data.h revision 1803 by jfenwick, Wed Sep 24 06:20:29 2008 UTC
# Line 25  Line 25 
25  #include "BinaryOp.h"  #include "BinaryOp.h"
26  #include "UnaryOp.h"  #include "UnaryOp.h"
27  #include "DataException.h"  #include "DataException.h"
28    #include "DataTypes.h"
29    
30  extern "C" {  extern "C" {
31  #include "DataC.h"  #include "DataC.h"
# Line 34  extern "C" { Line 35  extern "C" {
35  #include "esysmpi.h"  #include "esysmpi.h"
36  #include <string>  #include <string>
37  #include <algorithm>  #include <algorithm>
38    #include <sstream>
39    
40    
41  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
42  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
# Line 50  class DataExpanded; Line 53  class DataExpanded;
53    
54  /**  /**
55     \brief     \brief
56     Data creates the appropriate Data object for the given construction     Data represents a collection of datapoints.
    arguments.  
57    
58     Description:     Description:
59     Data is essentially a factory class which creates the appropriate Data     Internally, the datapoints are actually stored by a DataAbstract object.
60     object for the given construction arguments. It retains control over     The specific instance of DataAbstract used may vary over the lifetime
61     the object created for the lifetime of the object.     of the Data object.
62     The type of Data object referred to may change during the lifetime of     Some methods on this class return references (eg getShape()).
63     the Data object.     These references should not be used after an operation which changes the underlying DataAbstract object.
64       Doing so will lead to invalid memory access.
65       This should not affect any methods exposed via boost::python.
66  */  */
67  class Data {  class Data {
68    
# Line 101  class Data { Line 105  class Data {
105         const FunctionSpace& what);         const FunctionSpace& what);
106    
107    /**    /**
108       \brief      \brief Copy Data from an existing vector
109       Constructor which copies data from a DataArrayView.    */
110    
      \param value - Input - Data value for a single point.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the value. Otherwise a more efficient storage  
                        mechanism will be used.  
   */  
111    ESCRIPT_DLL_API    ESCRIPT_DLL_API
112    Data(const DataArrayView& value,    Data(const DataTypes::ValueType& value,
113         const FunctionSpace& what=FunctionSpace(),           const DataTypes::ShapeType& shape,
114         bool expanded=false);                   const FunctionSpace& what=FunctionSpace(),
115                     bool expanded=false);
116    
117    /**    /**
118       \brief       \brief
# Line 128  class Data { Line 127  class Data {
127    */    */
128    ESCRIPT_DLL_API    ESCRIPT_DLL_API
129    Data(double value,    Data(double value,
130         const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),         const DataTypes::ShapeType& dataPointShape=DataTypes::ShapeType(),
131         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
132         bool expanded=false);         bool expanded=false);
133    
# Line 141  class Data { Line 140  class Data {
140    */    */
141    ESCRIPT_DLL_API    ESCRIPT_DLL_API
142    Data(const Data& inData,    Data(const Data& inData,
143         const DataArrayView::RegionType& region);         const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Constructor which will create Tagged data if expanded is false.  
      No attempt is made to ensure the tag keys match the tag keys  
      within the function space.  
   
      \param tagKeys - Input - List of tag values.  
      \param values - Input - List of values, one for each tag.  
      \param defaultValue - Input - A default value, used if tag doesn't exist.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the appropriate values.  
     ==>*  
   */  
   ESCRIPT_DLL_API  
   Data(const DataTagged::TagListType& tagKeys,  
        const DataTagged::ValueListType& values,  
        const DataArrayView& defaultValue,  
        const FunctionSpace& what=FunctionSpace(),  
        bool expanded=false);  
144    
145    /**    /**
146       \brief       \brief
# Line 217  class Data { Line 195  class Data {
195         const boost::python::tuple& shape=boost::python::make_tuple(),         const boost::python::tuple& shape=boost::python::make_tuple(),
196         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
197         bool expanded=false);         bool expanded=false);
198    
199    
200    
201      /**
202        \brief Create a Data using an existing DataAbstract. Warning: The new object assumes ownership of the pointer!
203        Once you have passed the pointer, do not delete it.
204      */
205      ESCRIPT_DLL_API
206      Data(DataAbstract* underlyingdata);
207    
208    
209    /**    /**
210       \brief       \brief
211       Destructor       Destructor
# Line 225  class Data { Line 214  class Data {
214    ~Data();    ~Data();
215    
216    /**    /**
217       \brief       \brief Make this object a deep copy of "other".
      Perform a deep copy.  
218    */    */
219    ESCRIPT_DLL_API    ESCRIPT_DLL_API
220    void    void
221    copy(const Data& other);    copy(const Data& other);
222    
223    /**    /**
224         \brief Return a pointer to a deep copy of this object.
225      */
226      ESCRIPT_DLL_API
227      Data*
228      copySelf();
229    
230    
231    
232    
233      /**
234       Member access methods.       Member access methods.
235    */    */
236    
# Line 298  class Data { Line 296  class Data {
296       \brief       \brief
297       Return the tag number associated with the given data-point.       Return the tag number associated with the given data-point.
298    
      The data-point number here corresponds to the data-point number in the  
      numarray returned by convertToNumArray.  
299    */    */
300    ESCRIPT_DLL_API    ESCRIPT_DLL_API
301    int    int
# Line 313  class Data { Line 309  class Data {
309    escriptDataC    escriptDataC
310    getDataC();    getDataC();
311    
312    
313    
314    
315    
316    
317    // REMOVE ME
318    // ESCRIPT_DLL_API
319    // void
320    // CompareDebug(const Data& rd);
321    
322    
323    /**    /**
324       \brief       \brief
325       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
# Line 323  class Data { Line 330  class Data {
330    
331    /**    /**
332       \brief       \brief
333       Write the data as a string.       Write the data as a string. For large amounts of data, a summary is printed.
334    */    */
335    ESCRIPT_DLL_API    ESCRIPT_DLL_API
   inline  
336    std::string    std::string
337    toString() const    toString() const;
   {  
     return m_data->toString();  
   }  
338    
339    /**  
340       \brief  //  /**
341    /*     \brief
342       Return the DataArrayView of the point data. This essentially contains       Return the DataArrayView of the point data. This essentially contains
343       the shape information for each data point although it also may be used       the shape information for each data point although it also may be used
344       to manipulate the point data.       to manipulate the point data.*/
345    */  //  */
346    ESCRIPT_DLL_API  //   ESCRIPT_DLL_API
347    inline  //   inline
348    const DataArrayView&  //   const DataArrayView&
349    getPointDataView() const  //   getPointDataView() const
350    {  //   {
351       return m_data->getPointDataView();  //      return m_data->getPointDataView();
352    }  //   }
353    
354    /**    /**
355       \brief       \brief
# Line 392  class Data { Line 396  class Data {
396    
397    /**    /**
398       \brief       \brief
399       Return true if this Data is empty.       Return true if this Data holds an instance of DataEmpty. This is _not_ the same as asking if the object
400    contains datapoints.
401    */    */
402    ESCRIPT_DLL_API    ESCRIPT_DLL_API
403    bool    bool
# Line 447  class Data { Line 452  class Data {
452    int    int
453    getDataPointRank() const    getDataPointRank() const
454    {    {
455      return m_data->getPointDataView().getRank();  //    return m_data->getPointDataView().getRank();
456        return m_data->getRank();
457    }    }
458    
459    /**    /**
# Line 484  class Data { Line 490  class Data {
490    {    {
491      return m_data->getNumDPPSample();      return m_data->getNumDPPSample();
492    }    }
493    
494    
495      /**
496        \brief
497        Return the number of values in the shape for this object.
498      */
499      ESCRIPT_DLL_API
500      int
501      getNoValues() const
502      {
503        return m_data->getNoValues();
504      }
505    
506    
507    /**    /**
508       \brief       \brief
509       dumps the object into a netCDF file       dumps the object into a netCDF file
# Line 519  class Data { Line 539  class Data {
539      return m_data->getSampleDataByTag(tag);      return m_data->getSampleDataByTag(tag);
540    }    }
541    
542    //  /**
543    /*     \brief
544         Return a view into the data for the data point specified.
545         NOTE: Construction of the DataArrayView is a relatively expensive
546         operation.
547         \param sampleNo - Input -
548         \param dataPointNo - Input -*/
549    //  */
550    //   ESCRIPT_DLL_API
551    //   inline
552    //   DataArrayView
553    //   getDataPoint(int sampleNo,
554    //                int dataPointNo)
555    //   {
556    //                 return m_data->getDataPoint(sampleNo,dataPointNo);
557    //   }
558    
559    
560    /**    /**
561       \brief       \brief
562       Return a view into the data for the data point specified.       Return a view into the data for the data point specified.
# Line 528  class Data { Line 566  class Data {
566       \param dataPointNo - Input -       \param dataPointNo - Input -
567    */    */
568    ESCRIPT_DLL_API    ESCRIPT_DLL_API
569      DataTypes::ValueType::const_reference
570      getDataPoint(int sampleNo, int dataPointNo) const;
571    
572    
573      ESCRIPT_DLL_API
574      DataTypes::ValueType::reference
575      getDataPoint(int sampleNo, int dataPointNo);
576    
577    
578    
579      /**
580         \brief
581         Return the offset for the given sample and point within the sample
582      */
583      ESCRIPT_DLL_API
584    inline    inline
585    DataArrayView    DataTypes::ValueType::size_type
586    getDataPoint(int sampleNo,    getDataOffset(int sampleNo,
587                 int dataPointNo)                 int dataPointNo)
588    {    {
589                  return m_data->getDataPoint(sampleNo,dataPointNo);                  return m_data->getPointOffset(sampleNo,dataPointNo);
590    }    }
591    
592    /**    /**
# Line 541  class Data { Line 594  class Data {
594       Return a reference to the data point shape.       Return a reference to the data point shape.
595    */    */
596    ESCRIPT_DLL_API    ESCRIPT_DLL_API
597    const DataArrayView::ShapeType&    inline
598    getDataPointShape() const;    const DataTypes::ShapeType&
599      getDataPointShape() const
600      {
601        return m_data->getShape();
602      }
603    
604    /**    /**
605       \brief       \brief
# Line 566  class Data { Line 623  class Data {
623       Return the number of doubles stored for this Data.       Return the number of doubles stored for this Data.
624    */    */
625    ESCRIPT_DLL_API    ESCRIPT_DLL_API
626    DataArrayView::ValueType::size_type    DataTypes::ValueType::size_type
627    getLength() const;    getLength() const;
628    
629    
# Line 599  class Data { Line 656  class Data {
656    setTaggedValue(int tagKey,    setTaggedValue(int tagKey,
657                   const boost::python::object& value);                   const boost::python::object& value);
658    
659    
660    //  /**
661    //     \brief
662    //     Assign the given value to the tag. Implicitly converts this
663    //     object to type DataTagged if it is constant.
664    //
665    //     \param tagKey - Input - Integer key.
666    //     \param value - Input - Value to associate with given key.
667    //    ==>*
668    //  */
669    //   ESCRIPT_DLL_API
670    //   void
671    //   setTaggedValueFromCPP(int tagKey,
672    //                         const DataArrayView& value);
673    
674    /**    /**
675       \brief       \brief
676       Assign the given value to the tag. Implicitly converts this       Assign the given value to the tag. Implicitly converts this
677       object to type DataTagged if it is constant.       object to type DataTagged if it is constant.
678    
679       \param tagKey - Input - Integer key.       \param tagKey - Input - Integer key.
680         \param pointshape - Input - The shape of the value parameter
681       \param value - Input - Value to associate with given key.       \param value - Input - Value to associate with given key.
682      ==>*       \param dataOffset - Input - Offset of the begining of the point within the value parameter
683    */    */
684    ESCRIPT_DLL_API    ESCRIPT_DLL_API
685    void    void
686    setTaggedValueFromCPP(int tagKey,    setTaggedValueFromCPP(int tagKey,
687                          const DataArrayView& value);              const DataTypes::ShapeType& pointshape,
688                            const DataTypes::ValueType& value,
689                int dataOffset=0);
690    
691    
692    
693    /**    /**
694      \brief      \brief
# Line 1212  class Data { Line 1289  class Data {
1289    */    */
1290    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1291    Data    Data
1292    getSlice(const DataArrayView::RegionType& region) const;    getSlice(const DataTypes::RegionType& region) const;
1293    
1294    /**    /**
1295       \brief       \brief
# Line 1225  class Data { Line 1302  class Data {
1302    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1303    void    void
1304    setSlice(const Data& value,    setSlice(const Data& value,
1305             const DataArrayView::RegionType& region);             const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Archive the current Data object to the given file.  
      \param fileName - Input - file to archive to.  
   */  
   ESCRIPT_DLL_API  
   void  
   archiveData(const std::string fileName);  
   
   /**  
      \brief  
      Extract the Data object archived in the given file, overwriting  
      the current Data object.  
      Note - the current object must be of type DataEmpty.  
      \param fileName - Input - file to extract from.  
      \param fspace - Input - a suitable FunctionSpace descibing the data.  
   */  
   ESCRIPT_DLL_API  
   void  
   extractData(const std::string fileName,  
               const FunctionSpace& fspace);  
   
1306    
1307    /**    /**
1308       \brief       \brief
# Line 1290  class Data { Line 1344  class Data {
1344    /**    /**
1345       \brief       \brief
1346       return the object produced by the factory, which is a DataConstant or DataExpanded       return the object produced by the factory, which is a DataConstant or DataExpanded
1347        TODO Ownership of this object should be explained in doco.
1348    */    */
1349    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1350          DataAbstract*          DataAbstract*
1351          borrowData(void) const;          borrowData(void) const;
1352    
1353    
1354      /**
1355         \brief
1356         Return a pointer to the beginning of the datapoint at the specified offset.
1357         TODO Eventually these should be inlined.
1358         \param i - position(offset) in the underlying datastructure
1359      */
1360      ESCRIPT_DLL_API
1361            DataTypes::ValueType::const_reference
1362            getDataAtOffset(DataTypes::ValueType::size_type i) const;
1363    
1364    
1365      ESCRIPT_DLL_API
1366            DataTypes::ValueType::reference
1367            getDataAtOffset(DataTypes::ValueType::size_type i);
1368    
1369   protected:   protected:
1370    
1371   private:   private:
# Line 1370  class Data { Line 1441  class Data {
1441       \brief       \brief
1442       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1443    */    */
1444    template <class IValueType>  
1445    void    void
1446    initialise(const IValueType& value,    initialise(const DataTypes::ValueType& value,
1447             const DataTypes::ShapeType& shape,
1448               const FunctionSpace& what,               const FunctionSpace& what,
1449               bool expanded);               bool expanded);
1450    
1451      void
1452      initialise(const boost::python::numeric::array& value,
1453                     const FunctionSpace& what,
1454                     bool expanded);
1455    
1456    //    //
1457    // flag to protect the data object against any update    // flag to protect the data object against any update
1458    bool m_protected;    bool m_protected;
# Line 1386  class Data { Line 1463  class Data {
1463    
1464  };  };
1465    
1466  template <class IValueType>  
1467  void  
1468  Data::initialise(const IValueType& value,  /**
1469                   const FunctionSpace& what,     Modify a filename for MPI parallel output to multiple files
1470                   bool expanded)  */
1471  {  char *Escript_MPI_appendRankToFileName(const char *, int, int);
   //  
   // Construct a Data object of the appropriate type.  
   // Construct the object first as there seems to be a bug which causes  
   // undefined behaviour if an exception is thrown during construction  
   // within the shared_ptr constructor.  
   if (expanded) {  
     DataAbstract* temp=new DataExpanded(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   } else {  
     DataAbstract* temp=new DataConstant(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   }  
 }  
1472    
1473  /**  /**
1474     Binary Data object operators.     Binary Data object operators.
# Line 1532  C_GeneralTensorProduct(Data& arg0, Line 1594  C_GeneralTensorProduct(Data& arg0,
1594                       int transpose=0);                       int transpose=0);
1595    
1596    
 /**  
   \brief  
   Compute a tensor operation with two Data objects  
   \param arg0 - Input - Data object  
   \param arg1 - Input - Data object  
   \param operation - Input - Binary op functor  
 */  
 template <typename BinaryFunction>  
 ESCRIPT_DLL_API  
 Data  
 C_TensorBinaryOperation(Data const &arg0,  
                         Data const &arg1,  
                         BinaryFunction operation);  
1597    
1598  /**  // /**
1599    \brief  /*  \brief
1600    Return true if operands are equivalent, else return false.    Return true if operands are equivalent, else return false.
1601    NB: this operator does very little at this point, and isn't to    NB: this operator does very little at this point, and isn't to
1602    be relied on. Requires further implementation.    be relied on. Requires further implementation.*/
1603  */  //*/
1604  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1605    
1606  /**  /**
# Line 1567  Data::binaryOp(const Data& right, Line 1616  Data::binaryOp(const Data& right,
1616  {  {
1617     //     //
1618     // if this has a rank of zero promote it to the rank of the RHS     // if this has a rank of zero promote it to the rank of the RHS
1619     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {     if (getDataPointRank()==0 && right.getDataPointRank()!=0) {
1620       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1621     }     }
1622     //     //
# Line 1646  Data::algorithm(BinaryFunction operation Line 1695  Data::algorithm(BinaryFunction operation
1695      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1696      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1697      return escript::algorithm(*leftC,operation,initial_value);      return escript::algorithm(*leftC,operation,initial_value);
1698      } else if (isEmpty()) {
1699        throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1700    }    }
1701    return 0;    return 0;
1702  }  }
# Line 1663  inline Line 1714  inline
1714  Data  Data
1715  Data::dp_algorithm(BinaryFunction operation, double initial_value) const  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1716  {  {
1717    if (isExpanded()) {    if (isEmpty()) {
1718      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());      throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1719      }
1720      else if (isExpanded()) {
1721        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1722      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1723      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1724      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1725      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1726      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1727      return result;      return result;
1728    } else if (isTagged()) {    }
1729      else if (isTagged()) {
1730      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
     DataArrayView::ShapeType viewShape;  
     DataArrayView::ValueType viewData(1);  
     viewData[0]=0;  
     DataArrayView defaultValue(viewData,viewShape);  
     DataTagged::TagListType keys;  
     DataTagged::ValueListType values;  
     DataTagged::DataMapType::const_iterator i;  
     for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {  
       keys.push_back(i->first);  
       values.push_back(defaultValue);  
     }  
     Data result(keys,values,defaultValue,getFunctionSpace());  
     DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());  
1731      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1732      EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");      DataTypes::ValueType defval(1);
1733        defval[0]=0;
1734        DataTagged* resultT=new DataTagged(getFunctionSpace(), DataTypes::scalarShape, defval, dataT);
1735      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1736      return result;      return Data(resultT);   // note: the Data object now owns the resultT pointer
1737    } else if (isConstant()) {    }
1738      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());    else if (isConstant()) {
1739        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1740      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1741      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1742      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
# Line 1703  Data::dp_algorithm(BinaryFunction operat Line 1748  Data::dp_algorithm(BinaryFunction operat
1748    return falseRetVal;    return falseRetVal;
1749  }  }
1750    
1751    /**
1752      \brief
1753      Compute a tensor operation with two Data objects
1754      \param arg0 - Input - Data object
1755      \param arg1 - Input - Data object
1756      \param operation - Input - Binary op functor
1757    */
1758  template <typename BinaryFunction>  template <typename BinaryFunction>
1759    inline
1760  Data  Data
1761  C_TensorBinaryOperation(Data const &arg_0,  C_TensorBinaryOperation(Data const &arg_0,
1762                          Data const &arg_1,                          Data const &arg_1,
1763                          BinaryFunction operation)                          BinaryFunction operation)
1764  {  {
1765      if (arg_0.isEmpty() || arg_1.isEmpty())
1766      {
1767         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1768      }
1769    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
1770    Data arg_0_Z, arg_1_Z;    Data arg_0_Z, arg_1_Z;
1771    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
# Line 1730  C_TensorBinaryOperation(Data const &arg_ Line 1787  C_TensorBinaryOperation(Data const &arg_
1787    // Get rank and shape of inputs    // Get rank and shape of inputs
1788    int rank0 = arg_0_Z.getDataPointRank();    int rank0 = arg_0_Z.getDataPointRank();
1789    int rank1 = arg_1_Z.getDataPointRank();    int rank1 = arg_1_Z.getDataPointRank();
1790    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    DataTypes::ShapeType shape0 = arg_0_Z.getDataPointShape();
1791    DataArrayView::ShapeType shape1 = arg_1_Z.getDataPointShape();    DataTypes::ShapeType shape1 = arg_1_Z.getDataPointShape();
1792    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
1793    int size1 = arg_1_Z.getDataPointSize();    int size1 = arg_1_Z.getDataPointSize();
1794    
# Line 1742  C_TensorBinaryOperation(Data const &arg_ Line 1799  C_TensorBinaryOperation(Data const &arg_
1799    
1800      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1801        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
1802        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  /*      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1803        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1804        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);*/
1805          double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
1806          double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
1807          double *ptr_2 = &(res.getDataAtOffset(0));
1808    
1809        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1810      }      }
1811      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 1762  C_TensorBinaryOperation(Data const &arg_ Line 1823  C_TensorBinaryOperation(Data const &arg_
1823    
1824        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1825        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
1826        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1827        // Get the views        // Get the views
1828        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1829        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1830    //       // Get the pointers to the actual data
1831    //       double *ptr_1 = &((view_1.getData())[0]);
1832    //       double *ptr_2 = &((view_2.getData())[0]);
1833    
1834        // Get the pointers to the actual data        // Get the pointers to the actual data
1835        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1836        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1837    
1838        // Compute a result for the default        // Compute a result for the default
1839        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1840        // Compute a result for each tag        // Compute a result for each tag
1841        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1842        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1843        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1844          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1845          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  /*        DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1846          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1847          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
1848          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
1849            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1850            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1851    
1852          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1853        }        }
1854    
# Line 1800  C_TensorBinaryOperation(Data const &arg_ Line 1869  C_TensorBinaryOperation(Data const &arg_
1869          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1870            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1871            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1872            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1873            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1874            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1875    
1876              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1877              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1878              double *ptr_2 = &(res.getDataAtOffset(offset_2));
1879            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1880          }          }
1881        }        }
# Line 1823  C_TensorBinaryOperation(Data const &arg_ Line 1896  C_TensorBinaryOperation(Data const &arg_
1896    
1897        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1898        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
1899        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1900          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1901        // Get the views        // Get the views
1902        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1903        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1904    //       // Get the pointers to the actual data
1905    //       double *ptr_0 = &((view_0.getData())[0]);
1906    //       double *ptr_2 = &((view_2.getData())[0]);
1907        // Get the pointers to the actual data        // Get the pointers to the actual data
1908        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1909        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1910        // Compute a result for the default        // Compute a result for the default
1911        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1912        // Compute a result for each tag        // Compute a result for each tag
1913        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1914        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1915        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1916          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1917          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1918          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1919          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1920          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
1921            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1922            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1923          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1924        }        }
1925    
# Line 1858  C_TensorBinaryOperation(Data const &arg_ Line 1937  C_TensorBinaryOperation(Data const &arg_
1937        res.tag();        // DataTagged output        res.tag();        // DataTagged output
1938        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1939    
1940        // Get the views  //       // Get the views
1941        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1942        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1943        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1944    //       // Get the pointers to the actual data
1945    //       double *ptr_0 = &((view_0.getData())[0]);
1946    //       double *ptr_1 = &((view_1.getData())[0]);
1947    //       double *ptr_2 = &((view_2.getData())[0]);
1948    
1949        // Get the pointers to the actual data        // Get the pointers to the actual data
1950        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1951        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1952        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1953    
1954        // Compute a result for the default        // Compute a result for the default
1955        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1956        // Merge the tags        // Merge the tags
# Line 1873  C_TensorBinaryOperation(Data const &arg_ Line 1958  C_TensorBinaryOperation(Data const &arg_
1958        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1959        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1960        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1961          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
1962        }        }
1963        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1964          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1965        }        }
1966        // Compute a result for each tag        // Compute a result for each tag
1967        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1968        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1969          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
1970          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1971          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1972          double *ptr_0 = &view_0.getData(0);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1973          double *ptr_1 = &view_1.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1974          double *ptr_2 = &view_2.getData(0);  //         double *ptr_1 = &view_1.getData(0);
1975    //         double *ptr_2 = &view_2.getData(0);
1976    
1977            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1978            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1979            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1980    
1981          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1982        }        }
1983    
# Line 1905  C_TensorBinaryOperation(Data const &arg_ Line 1996  C_TensorBinaryOperation(Data const &arg_
1996        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1997        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1998          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1999          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2000          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2001            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2002            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2003            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  
2004            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2005    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2006              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2007              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2008    
2009    
2010            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2011          }          }
2012        }        }
# Line 1932  C_TensorBinaryOperation(Data const &arg_ Line 2028  C_TensorBinaryOperation(Data const &arg_
2028          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2029            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2030            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2031            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  
2032            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2033            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2034    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2035    
2036              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2037              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2038              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2039    
2040    
2041            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2042          }          }
2043        }        }
# Line 1954  C_TensorBinaryOperation(Data const &arg_ Line 2057  C_TensorBinaryOperation(Data const &arg_
2057        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2058        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2059          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2060          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2061          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2062            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2063            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2064            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2065            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2066            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2067          }          }
2068        }        }
# Line 1982  C_TensorBinaryOperation(Data const &arg_ Line 2085  C_TensorBinaryOperation(Data const &arg_
2085            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2086            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2087            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2088            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2089            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2090            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2091            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2092          }          }
2093        }        }
# Line 1998  C_TensorBinaryOperation(Data const &arg_ Line 2101  C_TensorBinaryOperation(Data const &arg_
2101    
2102      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2103        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output
2104        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2105        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2106        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2107        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2108      }      }
2109      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2018  C_TensorBinaryOperation(Data const &arg_ Line 2121  C_TensorBinaryOperation(Data const &arg_
2121    
2122        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2123        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2124        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2125        // Get the views        // Get the views
2126        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2127        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2128        // Get the pointers to the actual data  //       // Get the pointers to the actual data
2129        double *ptr_1 = &((view_1.getData())[0]);  //       double *ptr_1 = &((view_1.getData())[0]);
2130        double *ptr_2 = &((view_2.getData())[0]);  //       double *ptr_2 = &((view_2.getData())[0]);
2131           double *ptr_1 = &(tmp_1->getDefaultValue(0));
2132           double *ptr_2 = &(tmp_2->getDefaultValue(0));
2133    
2134        // Compute a result for the default        // Compute a result for the default
2135        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2136        // Compute a result for each tag        // Compute a result for each tag
2137        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2138        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2139        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2140          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2141          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2142          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2143          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2144          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2145            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2146            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2147          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2148        }        }
2149    
# Line 2056  C_TensorBinaryOperation(Data const &arg_ Line 2164  C_TensorBinaryOperation(Data const &arg_
2164          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2165            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2166            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2167            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2168            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2169            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2170            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2171    
2172          }          }
# Line 2080  C_TensorBinaryOperation(Data const &arg_ Line 2188  C_TensorBinaryOperation(Data const &arg_
2188    
2189        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2190        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2191        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2192          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2193        // Get the views        // Get the views
2194        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2195        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2196        // Get the pointers to the actual data        // Get the pointers to the actual data
2197        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2198        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2199    
2200          // Get the pointers to the actual data
2201          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2202          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2203    
2204    
2205        // Compute a result for the default        // Compute a result for the default
2206        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2207        // Compute a result for each tag        // Compute a result for each tag
2208        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2209        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2210        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2211          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2212          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2213          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2214          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2215          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2216            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2217            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2218    
2219          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2220        }        }
2221    
# Line 2116  C_TensorBinaryOperation(Data const &arg_ Line 2234  C_TensorBinaryOperation(Data const &arg_
2234        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2235    
2236        // Get the views        // Get the views
2237        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2238        DataArrayView view_1 = tmp_1->getDefaultValue();        DataArrayView view_1 = tmp_1->getDefaultValue();
2239        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2240        // Get the pointers to the actual data        // Get the pointers to the actual data
2241        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2242        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2243        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2244    
2245          // Get the pointers to the actual data
2246          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2247          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2248          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2249    
2250    
2251        // Compute a result for the default        // Compute a result for the default
2252        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2253        // Merge the tags        // Merge the tags
# Line 2130  C_TensorBinaryOperation(Data const &arg_ Line 2255  C_TensorBinaryOperation(Data const &arg_
2255        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2256        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2257        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2258          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2259        }        }
2260        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2261          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2262        }        }
2263        // Compute a result for each tag        // Compute a result for each tag
2264        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2265        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2266          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
2267    /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2268          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2269          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2270          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2271          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2272          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2273    
2274            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2275            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2276            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2277    
2278          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2279        }        }
2280    
# Line 2162  C_TensorBinaryOperation(Data const &arg_ Line 2293  C_TensorBinaryOperation(Data const &arg_
2293        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2294        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2295          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2296          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2297          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2298            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2299            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2300            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2301            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2302            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2303          }          }
2304        }        }
# Line 2189  C_TensorBinaryOperation(Data const &arg_ Line 2320  C_TensorBinaryOperation(Data const &arg_
2320          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2321            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2322            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2323            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2324            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2325            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2326            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2327          }          }
2328        }        }
# Line 2212  C_TensorBinaryOperation(Data const &arg_ Line 2343  C_TensorBinaryOperation(Data const &arg_
2343        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2344        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2345          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2346          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2347          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2348            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2349            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2350            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2351            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2352            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2353          }          }
2354        }        }
# Line 2240  C_TensorBinaryOperation(Data const &arg_ Line 2371  C_TensorBinaryOperation(Data const &arg_
2371            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2372            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2373            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2374            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2375            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2376            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2377            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2378          }          }
2379        }        }
# Line 2256  C_TensorBinaryOperation(Data const &arg_ Line 2387  C_TensorBinaryOperation(Data const &arg_
2387    
2388      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2389        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
2390        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2391        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2392        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2393        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2394      }      }
2395      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2276  C_TensorBinaryOperation(Data const &arg_ Line 2407  C_TensorBinaryOperation(Data const &arg_
2407    
2408        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2409        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2410        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2411        // Get the views        // Get the views
2412        DataArrayView view_1 = tmp_1->getDefaultValue();  /*      DataArrayView view_1 = tmp_1->getDefaultValue();
2413        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2414        // Get the pointers to the actual data        // Get the pointers to the actual data
2415        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2416        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2417          //Get the pointers to the actual data
2418          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2419          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2420    
2421        // Compute a result for the default        // Compute a result for the default
2422        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2423        // Compute a result for each tag        // Compute a result for each tag
2424        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2425        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2426        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2427          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2428          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2429          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2430          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2431          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2432            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2433            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2434    
2435    
2436          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2437        }        }
2438    
# Line 2314  C_TensorBinaryOperation(Data const &arg_ Line 2453  C_TensorBinaryOperation(Data const &arg_
2453          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2454            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2455            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2456            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2457            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2458            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2459            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2460          }          }
2461        }        }
# Line 2337  C_TensorBinaryOperation(Data const &arg_ Line 2476  C_TensorBinaryOperation(Data const &arg_
2476    
2477        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2478        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2479        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2480        // Get the views        // Get the views
2481        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2482        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2483    //       // Get the pointers to the actual data
2484    //       double *ptr_0 = &((view_0.getData())[0]);
2485    //       double *ptr_2 = &((view_2.getData())[0]);
2486        // Get the pointers to the actual data        // Get the pointers to the actual data
2487        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2488        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2489        // Compute a result for the default        // Compute a result for the default
2490        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2491        // Compute a result for each tag        // Compute a result for each tag
2492        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2493        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2494        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2495          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2496          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2497          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2498          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2499          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2500            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2501            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2502          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2503        }        }
2504    
# Line 2373  C_TensorBinaryOperation(Data const &arg_ Line 2517  C_TensorBinaryOperation(Data const &arg_
2517        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2518    
2519        // Get the views        // Get the views
2520        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2521        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2522        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2523    //       // Get the pointers to the actual data
2524    //       double *ptr_0 = &((view_0.getData())[0]);
2525    //       double *ptr_1 = &((view_1.getData())[0]);
2526    //       double *ptr_2 = &((view_2.getData())[0]);
2527    
2528        // Get the pointers to the actual data        // Get the pointers to the actual data
2529        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2530        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
2531        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2532    
2533        // Compute a result for the default        // Compute a result for the default
2534        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2535        // Merge the tags        // Merge the tags
# Line 2387  C_TensorBinaryOperation(Data const &arg_ Line 2537  C_TensorBinaryOperation(Data const &arg_
2537        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2538        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2539        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2540          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2541        }        }
2542        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2543          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2544        }        }
2545        // Compute a result for each tag        // Compute a result for each tag
2546        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2547        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2548          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2549          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2550          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2551          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
2552          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2553          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2554    
2555            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2556            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2557            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2558          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2559        }        }
2560    
# Line 2419  C_TensorBinaryOperation(Data const &arg_ Line 2573  C_TensorBinaryOperation(Data const &arg_
2573        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2574        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2575          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2576          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2577          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2578            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2579            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2580            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2581            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2582            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2583          }          }
2584        }        }
# Line 2446  C_TensorBinaryOperation(Data const &arg_ Line 2600  C_TensorBinaryOperation(Data const &arg_
2600          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2601            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2602            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2603            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2604            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2605            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2606            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2607          }          }
2608        }        }
# Line 2469  C_TensorBinaryOperation(Data const &arg_ Line 2623  C_TensorBinaryOperation(Data const &arg_
2623        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2624        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2625          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2626          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2627          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2628            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2629            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2630            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2631            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2632            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2633          }          }
2634        }        }
# Line 2497  C_TensorBinaryOperation(Data const &arg_ Line 2651  C_TensorBinaryOperation(Data const &arg_
2651            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2652            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2653            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2654            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2655            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2656            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2657            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2658          }          }
2659        }        }
# Line 2521  Data Line 2675  Data
2675  C_TensorUnaryOperation(Data const &arg_0,  C_TensorUnaryOperation(Data const &arg_0,
2676                         UnaryFunction operation)                         UnaryFunction operation)
2677  {  {
2678      if (arg_0.isEmpty())  // do this before we attempt to interpolate
2679      {
2680         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
2681      }
2682    
2683    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
2684    Data arg_0_Z = Data(arg_0);    Data arg_0_Z = Data(arg_0);
2685    
2686    // Get rank and shape of inputs    // Get rank and shape of inputs
2687    int rank0 = arg_0_Z.getDataPointRank();    int rank0 = arg_0_Z.getDataPointRank();
2688    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    const DataTypes::ShapeType& shape0 = arg_0_Z.getDataPointShape();
2689    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
2690    
2691    // Declare output Data object    // Declare output Data object
# Line 2534  C_TensorUnaryOperation(Data const &arg_0 Line 2693  C_TensorUnaryOperation(Data const &arg_0
2693    
2694    if (arg_0_Z.isConstant()) {    if (arg_0_Z.isConstant()) {
2695      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output
2696      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  //     double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2697      double *ptr_2 = &((res.getPointDataView().getData())[0]);  //     double *ptr_2 = &((res.getPointDataView().getData())[0]);
2698        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2699        double *ptr_2 = &(res.getDataAtOffset(0));
2700      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2701    }    }
2702    else if (arg_0_Z.isTagged()) {    else if (arg_0_Z.isTagged()) {
# Line 2548  C_TensorUnaryOperation(Data const &arg_0 Line 2709  C_TensorUnaryOperation(Data const &arg_0
2709      res.tag();      res.tag();
2710      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2711    
2712      // Get the views  //     // Get the views
2713      DataArrayView view_0 = tmp_0->getDefaultValue();  //     DataArrayView view_0 = tmp_0->getDefaultValue();
2714      DataArrayView view_2 = tmp_2->getDefaultValue();  //     DataArrayView view_2 = tmp_2->getDefaultValue();
2715    //     // Get the pointers to the actual data
2716    //     double *ptr_0 = &((view_0.getData())[0]);
2717    //     double *ptr_2 = &((view_2.getData())[0]);
2718      // Get the pointers to the actual data      // Get the pointers to the actual data
2719      double *ptr_0 = &((view_0.getData())[0]);      double *ptr_0 = &(tmp_0->getDefaultValue(0));
2720      double *ptr_2 = &((view_2.getData())[0]);      double *ptr_2 = &(tmp_2->getDefaultValue(0));
2721      // Compute a result for the default      // Compute a result for the default
2722      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2723      // Compute a result for each tag      // Compute a result for each tag
2724      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2725      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2726      for (i=lookup_0.begin();i!=lookup_0.end();i++) {      for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2727        tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());        tmp_2->addTag(i->first);
2728        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //       DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2729        DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //       DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2730        double *ptr_0 = &view_0.getData(0);  //       double *ptr_0 = &view_0.getData(0);
2731        double *ptr_2 = &view_2.getData(0);  //       double *ptr_2 = &view_2.getData(0);
2732          double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2733          double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2734        tensor_unary_operation(size0, ptr_0, ptr_2, operation);        tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2735      }      }
2736    
# Line 2581  C_TensorUnaryOperation(Data const &arg_0 Line 2747  C_TensorUnaryOperation(Data const &arg_0
2747      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2748      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2749        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2750    //         int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2751    //         int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2752    //         double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2753    //         double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2754          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2755          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2756          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2757          double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);          double *ptr_2 = &(res.getDataAtOffset(offset_2));
2758          tensor_unary_operation(size0, ptr_0, ptr_2, operation);          tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2759        }        }
2760      }      }
   
2761    }    }
2762    else {    else {
2763      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");

Legend:
Removed from v.1387  
changed lines
  Added in v.1803

  ViewVC Help
Powered by ViewVC 1.1.26