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

Diff of /branches/more_shared_ptrs_from_1812/escript/src/Data.h

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

revision 1327 by matt, Fri Oct 12 07:10:40 2007 UTC revision 1748 by ksteube, Wed Sep 3 06:10:39 2008 UTC
# Line 34  extern "C" { Line 34  extern "C" {
34  #include "esysmpi.h"  #include "esysmpi.h"
35  #include <string>  #include <string>
36  #include <algorithm>  #include <algorithm>
37    #include <sstream>
38    
39    
40  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
41  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
# Line 298  class Data { Line 300  class Data {
300       \brief       \brief
301       Return the tag number associated with the given data-point.       Return the tag number associated with the given data-point.
302    
      The data-point number here corresponds to the data-point number in the  
      numarray returned by convertToNumArray.  
303    */    */
304    ESCRIPT_DLL_API    ESCRIPT_DLL_API
305    int    int
# Line 323  class Data { Line 323  class Data {
323    
324    /**    /**
325       \brief       \brief
326       Write the data as a string.       Write the data as a string. For large amounts of data, a summary is printed.
327    */    */
328    ESCRIPT_DLL_API    ESCRIPT_DLL_API
   inline  
329    std::string    std::string
330    toString() const    toString() const;
331    {  
     return m_data->toString();  
   }  
332    
333    /**    /**
334       \brief       \brief
# Line 533  class Data { Line 530  class Data {
530    getDataPoint(int sampleNo,    getDataPoint(int sampleNo,
531                 int dataPointNo)                 int dataPointNo)
532    {    {
533          return m_data->getDataPoint(sampleNo,dataPointNo);                  return m_data->getDataPoint(sampleNo,dataPointNo);
534    }    }
535    
536    /**    /**
# Line 588  class Data { Line 585  class Data {
585    /**    /**
586       \brief       \brief
587       Assign the given value to the tag. Implicitly converts this       Assign the given value to the tag. Implicitly converts this
588       object to type DataTagged. Throws an exception if this object       object to type DataTagged if it is constant.
589       cannot be converted to a DataTagged object.  
590       \param tagKey - Input - Integer key.       \param tagKey - Input - Integer key.
591       \param value - Input - Value to associate with given key.       \param value - Input - Value to associate with given key.
592      ==>*      ==>*
# Line 602  class Data { Line 599  class Data {
599    /**    /**
600       \brief       \brief
601       Assign the given value to the tag. Implicitly converts this       Assign the given value to the tag. Implicitly converts this
602       object to type DataTagged. Throws an exception if this object       object to type DataTagged if it is constant.
603       cannot be converted to a DataTagged object.  
604       \param tagKey - Input - Integer key.       \param tagKey - Input - Integer key.
605       \param value - Input - Value to associate with given key.       \param value - Input - Value to associate with given key.
606      ==>*      ==>*
# Line 1201  class Data { Line 1198  class Data {
1198    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1199    inline    inline
1200    void    void
1201    unaryOp(UnaryFunction operation);    unaryOp2(UnaryFunction operation);
1202    
1203    /**    /**
1204       \brief       \brief
# Line 1256  class Data { Line 1253  class Data {
1253    */    */
1254    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1255    void    void
1256      print(void);          print(void);
1257    
1258    /**    /**
1259       \brief       \brief
1260       return the MPI rank number of the local data       return the MPI rank number of the local data
1261           MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()                   MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()
1262           is returned                   is returned
1263    */    */
1264    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1265      int          int
1266      get_MPIRank(void) const;          get_MPIRank(void) const;
1267    
1268    /**    /**
1269       \brief       \brief
1270       return the MPI rank number of the local data       return the MPI rank number of the local data
1271           MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()                   MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()
1272           is returned                   is returned
1273    */    */
1274    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1275      int          int
1276      get_MPISize(void) const;          get_MPISize(void) const;
1277    
1278    /**    /**
1279       \brief       \brief
1280       return the MPI rank number of the local data       return the MPI rank number of the local data
1281           MPI_COMM_WORLD is assumed and returned.                   MPI_COMM_WORLD is assumed and returned.
1282    */    */
1283    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1284      MPI_Comm          MPI_Comm
1285      get_MPIComm(void) const;          get_MPIComm(void) const;
1286    
1287    /**    /**
1288       \brief       \brief
1289       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
1290    */    */
1291    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1292      DataAbstract*          DataAbstract*
1293      borrowData(void) const;          borrowData(void) const;
1294    
1295   protected:   protected:
1296    
# Line 1409  Data::initialise(const IValueType& value Line 1406  Data::initialise(const IValueType& value
1406  }  }
1407    
1408  /**  /**
1409       Modify a filename for MPI parallel output to multiple files
1410    */
1411    char *Escript_MPI_appendRankToFileName(const char *, int, int);
1412    
1413    /**
1414     Binary Data object operators.     Binary Data object operators.
1415  */  */
1416  inline double rpow(double x,double y)  inline double rpow(double x,double y)
# Line 1532  C_GeneralTensorProduct(Data& arg0, Line 1534  C_GeneralTensorProduct(Data& arg0,
1534                       int transpose=0);                       int transpose=0);
1535    
1536    
 /**  
   \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);  
1537    
1538  /**  /**
1539    \brief    \brief
# Line 1624  Data::binaryOp(const Data& right, Line 1613  Data::binaryOp(const Data& right,
1613    
1614  /**  /**
1615    \brief    \brief
   Perform the given unary operation on other and return the result.  
   Given operation is performed on each element of each data point, thus  
   argument object is a rank n Data object, and returned object is a rank n  
   Data object.  
   Calls Data::unaryOp.  
 */  
 template <class UnaryFunction>  
 inline  
 Data  
 unaryOp(const Data& other,  
         UnaryFunction operation)  
 {  
   Data result;  
   result.copy(other);  
   result.unaryOp(operation);  
   return result;  
 }  
   
 /**  
   \brief  
   Perform the given unary operation on this.  
   Given operation is performed on each element of each data point.  
   Calls escript::unaryOp.  
 */  
 template <class UnaryFunction>  
 inline  
 void  
 Data::unaryOp(UnaryFunction operation)  
 {  
   if (isExpanded()) {  
     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());  
     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");  
     escript::unaryOp(*leftC,operation);  
   } else if (isTagged()) {  
     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());  
     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");  
     escript::unaryOp(*leftC,operation);  
   } else if (isConstant()) {  
     DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());  
     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");  
     escript::unaryOp(*leftC,operation);  
   }  
 }  
   
 /**  
   \brief  
1616    Perform the given Data object reduction algorithm on this and return the result.    Perform the given Data object reduction algorithm on this and return the result.
1617    Given operation combines each element of each data point, thus argument    Given operation combines each element of each data point, thus argument
1618    object (*this) is a rank n Data object, and returned object is a scalar.    object (*this) is a rank n Data object, and returned object is a scalar.
# Line 1749  Data::dp_algorithm(BinaryFunction operat Line 1692  Data::dp_algorithm(BinaryFunction operat
1692    return falseRetVal;    return falseRetVal;
1693  }  }
1694    
1695    /**
1696      \brief
1697      Compute a tensor operation with two Data objects
1698      \param arg0 - Input - Data object
1699      \param arg1 - Input - Data object
1700      \param operation - Input - Binary op functor
1701    */
1702  template <typename BinaryFunction>  template <typename BinaryFunction>
1703    inline
1704  Data  Data
1705  C_TensorBinaryOperation(Data const &arg_0,  C_TensorBinaryOperation(Data const &arg_0,
1706              Data const &arg_1,                          Data const &arg_1,
1707              BinaryFunction operation)                          BinaryFunction operation)
1708  {  {
1709    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
1710    Data arg_0_Z, arg_1_Z;    Data arg_0_Z, arg_1_Z;
# Line 1787  C_TensorBinaryOperation(Data const &arg_ Line 1738  C_TensorBinaryOperation(Data const &arg_
1738    if (shape0 == shape1) {    if (shape0 == shape1) {
1739    
1740      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1741        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());  // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
1742        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1743        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1744        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);
# Line 1802  C_TensorBinaryOperation(Data const &arg_ Line 1753  C_TensorBinaryOperation(Data const &arg_
1753        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1754    
1755        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
1756        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataTagged output
1757        res.tag();        res.tag();
1758        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1759    
# Line 1821  C_TensorBinaryOperation(Data const &arg_ Line 1772  C_TensorBinaryOperation(Data const &arg_
1772        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1773        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
1774        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1775      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1776      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1777      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1778      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
1779      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
1780      tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1781        }        }
1782    
1783      }      }
# Line 1843  C_TensorBinaryOperation(Data const &arg_ Line 1794  C_TensorBinaryOperation(Data const &arg_
1794        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
1795        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
1796        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
1797      for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1798        int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1799        int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1800        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1801        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1802        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1803        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1804      }          }
1805        }        }
1806    
1807      }      }
# Line 1863  C_TensorBinaryOperation(Data const &arg_ Line 1814  C_TensorBinaryOperation(Data const &arg_
1814        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1815    
1816        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
1817        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataTagged output
1818        res.tag();        res.tag();
1819        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1820    
# Line 1882  C_TensorBinaryOperation(Data const &arg_ Line 1833  C_TensorBinaryOperation(Data const &arg_
1833        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1834        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
1835        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1836      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1837      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1838      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1839      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
1840      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
1841      tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1842        }        }
1843    
1844      }      }
# Line 1901  C_TensorBinaryOperation(Data const &arg_ Line 1852  C_TensorBinaryOperation(Data const &arg_
1852    
1853        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
1854        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
1855        res.tag();    // DataTagged output        res.tag();        // DataTagged output
1856        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1857    
1858        // Get the views        // Get the views
# Line 1919  C_TensorBinaryOperation(Data const &arg_ Line 1870  C_TensorBinaryOperation(Data const &arg_
1870        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1871        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1872        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1873      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
1874        }        }
1875        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1876      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1877        }        }
1878        // Compute a result for each tag        // Compute a result for each tag
1879        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1880        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1881      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1882      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1883      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1884      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
1885      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
1886      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
1887      tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1888        }        }
1889    
1890      }      }
# Line 1950  C_TensorBinaryOperation(Data const &arg_ Line 1901  C_TensorBinaryOperation(Data const &arg_
1901        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1902        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1903        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1904      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
1905      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1906      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1907        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
1908        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1909        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1910        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1911        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1912      }          }
1913        }        }
1914    
1915      }      }
# Line 1975  C_TensorBinaryOperation(Data const &arg_ Line 1926  C_TensorBinaryOperation(Data const &arg_
1926        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
1927        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1928        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1929      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1930        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
1931        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1932        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1933        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1934        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1935        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1936      }          }
1937        }        }
1938    
1939      }      }
# Line 1999  C_TensorBinaryOperation(Data const &arg_ Line 1950  C_TensorBinaryOperation(Data const &arg_
1950        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1951        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1952        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1953      int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
1954      double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1955      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1956        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
1957        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1958        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1959        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1960        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1961      }          }
1962        }        }
1963    
1964      }      }
# Line 2024  C_TensorBinaryOperation(Data const &arg_ Line 1975  C_TensorBinaryOperation(Data const &arg_
1975        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1976        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1977        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1978      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1979        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
1980        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
1981        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1982        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1983        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1984        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1985        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1986      }          }
1987        }        }
1988    
1989      }      }
# Line 2043  C_TensorBinaryOperation(Data const &arg_ Line 1994  C_TensorBinaryOperation(Data const &arg_
1994    } else if (0 == rank0) {    } else if (0 == rank0) {
1995    
1996      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1997        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());  // DataConstant output        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output
1998        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1999        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2000        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);
# Line 2058  C_TensorBinaryOperation(Data const &arg_ Line 2009  C_TensorBinaryOperation(Data const &arg_
2009        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2010    
2011        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2012        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataTagged output
2013        res.tag();        res.tag();
2014        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2015    
# Line 2077  C_TensorBinaryOperation(Data const &arg_ Line 2028  C_TensorBinaryOperation(Data const &arg_
2028        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2029        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
2030        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2031      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2032      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2033      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2034      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2035      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2036      tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2037        }        }
2038    
2039      }      }
# Line 2099  C_TensorBinaryOperation(Data const &arg_ Line 2050  C_TensorBinaryOperation(Data const &arg_
2050        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2051        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2052        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2053      for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2054        int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2055        int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2056        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2057        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2058        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2059        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2060    
2061      }          }
2062        }        }
2063    
2064      }      }
# Line 2120  C_TensorBinaryOperation(Data const &arg_ Line 2071  C_TensorBinaryOperation(Data const &arg_
2071        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2072    
2073        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2074        res = Data(0.0, shape1, arg_0_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape1, arg_0_Z.getFunctionSpace());      // DataTagged output
2075        res.tag();        res.tag();
2076        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2077    
# Line 2139  C_TensorBinaryOperation(Data const &arg_ Line 2090  C_TensorBinaryOperation(Data const &arg_
2090        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2091        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
2092        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2093      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2094      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2095      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2096      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2097      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2098      tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2099        }        }
2100    
2101      }      }
# Line 2158  C_TensorBinaryOperation(Data const &arg_ Line 2109  C_TensorBinaryOperation(Data const &arg_
2109    
2110        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2111        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());
2112        res.tag();    // DataTagged output        res.tag();        // DataTagged output
2113        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2114    
2115        // Get the views        // Get the views
# Line 2176  C_TensorBinaryOperation(Data const &arg_ Line 2127  C_TensorBinaryOperation(Data const &arg_
2127        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2128        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2129        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2130      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2131        }        }
2132        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2133      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2134        }        }
2135        // Compute a result for each tag        // Compute a result for each tag
2136        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2137        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2138      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2139      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2140      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2141      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2142      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2143      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2144      tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2145        }        }
2146    
2147      }      }
# Line 2207  C_TensorBinaryOperation(Data const &arg_ Line 2158  C_TensorBinaryOperation(Data const &arg_
2158        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2159        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2160        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2161      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
2162      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2163      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2164        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2165        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2166        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2167        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2168        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2169      }          }
2170        }        }
2171    
2172      }      }
# Line 2232  C_TensorBinaryOperation(Data const &arg_ Line 2183  C_TensorBinaryOperation(Data const &arg_
2183        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2184        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2185        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2186      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2187        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2188        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2189        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2190        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2191        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2192        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2193      }          }
2194        }        }
2195    
2196    
# Line 2257  C_TensorBinaryOperation(Data const &arg_ Line 2208  C_TensorBinaryOperation(Data const &arg_
2208        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2209        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2210        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2211      int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2212      double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2213      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2214        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2215        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2216        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2217        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2218        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2219      }          }
2220        }        }
2221    
2222      }      }
# Line 2282  C_TensorBinaryOperation(Data const &arg_ Line 2233  C_TensorBinaryOperation(Data const &arg_
2233        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2234        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2235        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2236      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2237        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2238        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2239        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2240        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2241        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2242        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2243        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2244      }          }
2245        }        }
2246    
2247      }      }
# Line 2301  C_TensorBinaryOperation(Data const &arg_ Line 2252  C_TensorBinaryOperation(Data const &arg_
2252    } else if (0 == rank1) {    } else if (0 == rank1) {
2253    
2254      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2255        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());  // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
2256        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2257        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2258        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);
# Line 2316  C_TensorBinaryOperation(Data const &arg_ Line 2267  C_TensorBinaryOperation(Data const &arg_
2267        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());        DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2268    
2269        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2270        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataTagged output
2271        res.tag();        res.tag();
2272        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2273    
# Line 2335  C_TensorBinaryOperation(Data const &arg_ Line 2286  C_TensorBinaryOperation(Data const &arg_
2286        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2287        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
2288        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2289      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2290      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2291      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2292      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2293      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2294      tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2295        }        }
2296    
2297      }      }
# Line 2357  C_TensorBinaryOperation(Data const &arg_ Line 2308  C_TensorBinaryOperation(Data const &arg_
2308        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2309        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)        #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2310        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {        for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2311      for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2312        int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2313        int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2314        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2315        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2316        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2317        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2318      }          }
2319        }        }
2320    
2321      }      }
# Line 2377  C_TensorBinaryOperation(Data const &arg_ Line 2328  C_TensorBinaryOperation(Data const &arg_
2328        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());        DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2329    
2330        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2331        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());  // DataTagged output        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataTagged output
2332        res.tag();        res.tag();
2333        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2334    
# Line 2396  C_TensorBinaryOperation(Data const &arg_ Line 2347  C_TensorBinaryOperation(Data const &arg_
2347        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2348        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
2349        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2350      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2351      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2352      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2353      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2354      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2355      tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2356        }        }
2357    
2358      }      }
# Line 2415  C_TensorBinaryOperation(Data const &arg_ Line 2366  C_TensorBinaryOperation(Data const &arg_
2366    
2367        // Prepare a DataTagged output 2        // Prepare a DataTagged output 2
2368        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
2369        res.tag();    // DataTagged output        res.tag();        // DataTagged output
2370        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2371    
2372        // Get the views        // Get the views
# Line 2433  C_TensorBinaryOperation(Data const &arg_ Line 2384  C_TensorBinaryOperation(Data const &arg_
2384        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2385        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2386        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2387      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2388        }        }
2389        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2390      tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2391        }        }
2392        // Compute a result for each tag        // Compute a result for each tag
2393        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2394        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2395      DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2396      DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2397      DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2398      double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2399      double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2400      double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);
2401      tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2402        }        }
2403    
2404      }      }
# Line 2464  C_TensorBinaryOperation(Data const &arg_ Line 2415  C_TensorBinaryOperation(Data const &arg_
2415        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2416        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2417        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2418      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
2419      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2420      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2421        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2422        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2423        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2424        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2425        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2426      }          }
2427        }        }
2428    
2429      }      }
# Line 2489  C_TensorBinaryOperation(Data const &arg_ Line 2440  C_TensorBinaryOperation(Data const &arg_
2440        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2441        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2442        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2443      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2444        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2445        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2446        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2447        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2448        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2449        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2450      }          }
2451        }        }
2452    
2453    
# Line 2514  C_TensorBinaryOperation(Data const &arg_ Line 2465  C_TensorBinaryOperation(Data const &arg_
2465        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2466        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2467        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2468      int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2469      double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2470      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2471        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2472        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2473        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2474        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2475        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2476      }          }
2477        }        }
2478    
2479      }      }
# Line 2539  C_TensorBinaryOperation(Data const &arg_ Line 2490  C_TensorBinaryOperation(Data const &arg_
2490        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2491        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2492        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2493      for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2494        int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2495        int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2496        int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2497        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2498        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2499        double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2500        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2501      }          }
2502        }        }
2503    
2504      }      }
# Line 2560  C_TensorBinaryOperation(Data const &arg_ Line 2511  C_TensorBinaryOperation(Data const &arg_
2511    }    }
2512    
2513    return res;    return res;
2514    }
2515    
2516    template <typename UnaryFunction>
2517    Data
2518    C_TensorUnaryOperation(Data const &arg_0,
2519                           UnaryFunction operation)
2520    {
2521      // Interpolate if necessary and find an appropriate function space
2522      Data arg_0_Z = Data(arg_0);
2523    
2524      // Get rank and shape of inputs
2525      int rank0 = arg_0_Z.getDataPointRank();
2526      DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();
2527      int size0 = arg_0_Z.getDataPointSize();
2528    
2529      // Declare output Data object
2530      Data res;
2531    
2532      if (arg_0_Z.isConstant()) {
2533        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output
2534        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2535        double *ptr_2 = &((res.getPointDataView().getData())[0]);
2536        tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2537      }
2538      else if (arg_0_Z.isTagged()) {
2539    
2540        // Borrow DataTagged input from Data object
2541        DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2542    
2543        // Prepare a DataTagged output 2
2544        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());   // DataTagged output
2545        res.tag();
2546        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2547    
2548        // Get the views
2549        DataArrayView view_0 = tmp_0->getDefaultValue();
2550        DataArrayView view_2 = tmp_2->getDefaultValue();
2551        // Get the pointers to the actual data
2552        double *ptr_0 = &((view_0.getData())[0]);
2553        double *ptr_2 = &((view_2.getData())[0]);
2554        // Compute a result for the default
2555        tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2556        // Compute a result for each tag
2557        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2558        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2559        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2560          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2561          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2562          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2563          double *ptr_0 = &view_0.getData(0);
2564          double *ptr_2 = &view_2.getData(0);
2565          tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2566        }
2567    
2568      }
2569      else if (arg_0_Z.isExpanded()) {
2570    
2571        res = Data(0.0, shape0, arg_0_Z.getFunctionSpace(),true); // DataExpanded output
2572        DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2573        DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2574    
2575        int sampleNo_0,dataPointNo_0;
2576        int numSamples_0 = arg_0_Z.getNumSamples();
2577        int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2578        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2579        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2580          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2581            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2582            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2583            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2584            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2585            tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2586          }
2587        }
2588    
2589      }
2590      else {
2591        throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");
2592      }
2593    
2594      return res;
2595  }  }
2596    
2597  }  }

Legend:
Removed from v.1327  
changed lines
  Added in v.1748

  ViewVC Help
Powered by ViewVC 1.1.26