/[escript]/branches/clazy/escriptcore/src/DataLazy.cpp
ViewVC logotype

Diff of /branches/clazy/escriptcore/src/DataLazy.cpp

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

trunk/escript/src/DataLazy.cpp revision 4264 by jfenwick, Thu Feb 28 11:32:57 2013 UTC trunk/escriptcore/src/DataLazy.cpp revision 5938 by jfenwick, Thu Feb 18 06:30:35 2016 UTC
# Line 1  Line 1 
1    
2  /*****************************************************************************  /*****************************************************************************
3  *  *
4  * Copyright (c) 2003-2013 by University of Queensland  * Copyright (c) 2003-2016 by The University of Queensland
5  * http://www.uq.edu.au  * http://www.uq.edu.au
6  *  *
7  * Primary Business: Queensland, Australia  * Primary Business: Queensland, Australia
# Line 9  Line 9 
9  * http://www.opensource.org/licenses/osl-3.0.php  * http://www.opensource.org/licenses/osl-3.0.php
10  *  *
11  * Development until 2012 by Earth Systems Science Computational Center (ESSCC)  * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12  * Development since 2012 by School of Earth Sciences  * Development 2012-2013 by School of Earth Sciences
13    * Development from 2014 by Centre for Geoscience Computing (GeoComp)
14  *  *
15  *****************************************************************************/  *****************************************************************************/
16    
17    #define ESNEEDPYTHON
18    #include "esysUtils/first.h"
19    
20  #include "DataLazy.h"  #include "DataLazy.h"
21  #include "esysUtils/Esys_MPI.h"  #include "esysUtils/Esys_MPI.h"
# Line 33  Line 36 
36    
37  #include <iomanip>      // for some fancy formatting in debug  #include <iomanip>      // for some fancy formatting in debug
38    
39    using namespace escript::DataTypes;
40    
41  // #define LAZYDEBUG(X) if (privdebug){X;}  // #define LAZYDEBUG(X) if (privdebug){X;}
42  #define LAZYDEBUG(X)  #define LAZYDEBUG(X)
43  namespace  namespace
# Line 61  A special operation, IDENTITY, stores an Line 66  A special operation, IDENTITY, stores an
66  This means that all "internal" nodes in the structure are instances of DataLazy.  This means that all "internal" nodes in the structure are instances of DataLazy.
67    
68  Each operation has a string representation as well as an opgroup - eg G_IDENTITY, G_BINARY, ...  Each operation has a string representation as well as an opgroup - eg G_IDENTITY, G_BINARY, ...
69  Note that IDENITY is not considered a unary operation.  Note that IDENTITY is not considered a unary operation.
70    
71  I am avoiding calling the structure formed a tree because it is not guaranteed to be one (eg c=a+a).  I am avoiding calling the structure formed a tree because it is not guaranteed to be one (eg c=a+a).
72  It must however form a DAG (directed acyclic graph).  It must however form a DAG (directed acyclic graph).
# Line 70  I will refer to individual DataLazy obje Line 75  I will refer to individual DataLazy obje
75  Each node also stores:  Each node also stores:
76  - m_readytype \in {'E','T','C','?'} ~ indicates what sort of DataReady would be produced if the expression was  - m_readytype \in {'E','T','C','?'} ~ indicates what sort of DataReady would be produced if the expression was
77      evaluated.      evaluated.
78  - m_buffsrequired ~ the larged number of samples which would need to be kept simultaneously in order to  - m_buffsrequired ~ the large number of samples which would need to be kept simultaneously in order to
79      evaluate the expression.      evaluate the expression.
80  - m_samplesize ~ the number of doubles stored in a sample.  - m_samplesize ~ the number of doubles stored in a sample.
81    
# Line 822  DataLazy::~DataLazy() Line 827  DataLazy::~DataLazy()
827    For reasons of efficiency do not call this method on DataExpanded nodes.    For reasons of efficiency do not call this method on DataExpanded nodes.
828  */  */
829  DataReady_ptr  DataReady_ptr
830  DataLazy::collapseToReady()  DataLazy::collapseToReady() const
831  {  {
832    if (m_readytype=='E')    if (m_readytype=='E')
833    { // this is more an efficiency concern than anything else    { // this is more an efficiency concern than anything else
# Line 977  DataLazy::collapseToReady() Line 982  DataLazy::collapseToReady()
982     the purpose of using DataLazy in the first place).     the purpose of using DataLazy in the first place).
983  */  */
984  void  void
985  DataLazy::collapse()  DataLazy::collapse() const
986  {  {
987    if (m_op==IDENTITY)    if (m_op==IDENTITY)
988    {    {
# Line 1015  LAZYDEBUG(cout << " result=      " << re Line 1020  LAZYDEBUG(cout << " result=      " << re
1020    
1021  // The result will be stored in m_samples  // The result will be stored in m_samples
1022  // The return value is a pointer to the DataVector, offset is the offset within the return value  // The return value is a pointer to the DataVector, offset is the offset within the return value
1023  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1024  DataLazy::resolveNodeSample(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeSample(int tid, int sampleNo, size_t& roffset) const
1025  {  {
1026  LAZYDEBUG(cout << "Resolve sample " << toString() << endl;)  LAZYDEBUG(cout << "Resolve sample " << toString() << endl;)
1027      // collapse so we have a 'E' node or an IDENTITY for some other type      // collapse so we have a 'E' node or an IDENTITY for some other type
# Line 1064  if (&x<stackend[omp_get_thread_num()]) Line 1069  if (&x<stackend[omp_get_thread_num()])
1069    }    }
1070  }  }
1071    
1072  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1073  DataLazy::resolveNodeUnary(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeUnary(int tid, int sampleNo, size_t& roffset) const
1074  {  {
1075      // we assume that any collapsing has been done before we get here      // we assume that any collapsing has been done before we get here
1076      // since we only have one argument we don't need to think about only      // since we only have one argument we don't need to think about only
# Line 1079  DataLazy::resolveNodeUnary(int tid, int Line 1084  DataLazy::resolveNodeUnary(int tid, int
1084    {    {
1085      throw DataException("Programmer error - resolveNodeUnary should not be called on identity nodes.");      throw DataException("Programmer error - resolveNodeUnary should not be called on identity nodes.");
1086    }    }
1087    const DataTypes::ValueType* leftres=m_left->resolveNodeSample(tid, sampleNo, roffset);    const DataTypes::RealVectorType* leftres=m_left->resolveNodeSample(tid, sampleNo, roffset);
1088    const double* left=&((*leftres)[roffset]);    const double* left=&((*leftres)[roffset]);
1089    roffset=m_samplesize*tid;    roffset=m_samplesize*tid;
1090    double* result=&(m_samples[roffset]);    double* result=&(m_samples[roffset]);
# Line 1196  DataLazy::resolveNodeUnary(int tid, int Line 1201  DataLazy::resolveNodeUnary(int tid, int
1201  }  }
1202    
1203    
1204  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1205  DataLazy::resolveNodeReduction(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeReduction(int tid, int sampleNo, size_t& roffset) const
1206  {  {
1207      // we assume that any collapsing has been done before we get here      // we assume that any collapsing has been done before we get here
1208      // since we only have one argument we don't need to think about only      // since we only have one argument we don't need to think about only
# Line 1212  DataLazy::resolveNodeReduction(int tid, Line 1217  DataLazy::resolveNodeReduction(int tid,
1217      throw DataException("Programmer error - resolveNodeUnary should not be called on identity nodes.");      throw DataException("Programmer error - resolveNodeUnary should not be called on identity nodes.");
1218    }    }
1219    size_t loffset=0;    size_t loffset=0;
1220    const DataTypes::ValueType* leftres=m_left->resolveNodeSample(tid, sampleNo, loffset);    const DataTypes::RealVectorType* leftres=m_left->resolveNodeSample(tid, sampleNo, loffset);
1221    
1222    roffset=m_samplesize*tid;    roffset=m_samplesize*tid;
1223    unsigned int ndpps=getNumDPPSample();    unsigned int ndpps=getNumDPPSample();
# Line 1248  DataLazy::resolveNodeReduction(int tid, Line 1253  DataLazy::resolveNodeReduction(int tid,
1253    return &(m_samples);    return &(m_samples);
1254  }  }
1255    
1256  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1257  DataLazy::resolveNodeNP1OUT(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeNP1OUT(int tid, int sampleNo, size_t& roffset) const
1258  {  {
1259      // we assume that any collapsing has been done before we get here      // we assume that any collapsing has been done before we get here
1260      // since we only have one argument we don't need to think about only      // since we only have one argument we don't need to think about only
# Line 1293  DataLazy::resolveNodeNP1OUT(int tid, int Line 1298  DataLazy::resolveNodeNP1OUT(int tid, int
1298    return &m_samples;    return &m_samples;
1299  }  }
1300    
1301  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1302  DataLazy::resolveNodeNP1OUT_P(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeNP1OUT_P(int tid, int sampleNo, size_t& roffset) const
1303  {  {
1304      // we assume that any collapsing has been done before we get here      // we assume that any collapsing has been done before we get here
1305      // since we only have one argument we don't need to think about only      // since we only have one argument we don't need to think about only
# Line 1341  DataLazy::resolveNodeNP1OUT_P(int tid, i Line 1346  DataLazy::resolveNodeNP1OUT_P(int tid, i
1346  }  }
1347    
1348    
1349  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1350  DataLazy::resolveNodeNP1OUT_2P(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeNP1OUT_2P(int tid, int sampleNo, size_t& roffset) const
1351  {  {
1352    if (m_readytype!='E')    if (m_readytype!='E')
1353    {    {
# Line 1377  DataLazy::resolveNodeNP1OUT_2P(int tid, Line 1382  DataLazy::resolveNodeNP1OUT_2P(int tid,
1382    return &m_samples;    return &m_samples;
1383  }  }
1384    
1385  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1386  DataLazy::resolveNodeCondEval(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeCondEval(int tid, int sampleNo, size_t& roffset) const
1387  {  {
1388    if (m_readytype!='E')    if (m_readytype!='E')
1389    {    {
# Line 1421  DataLazy::resolveNodeCondEval(int tid, i Line 1426  DataLazy::resolveNodeCondEval(int tid, i
1426  // There is an additional complication when scalar operations are considered.  // There is an additional complication when scalar operations are considered.
1427  // For example, 2+Vector.  // For example, 2+Vector.
1428  // In this case each double within the point is treated individually  // In this case each double within the point is treated individually
1429  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1430  DataLazy::resolveNodeBinary(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeBinary(int tid, int sampleNo, size_t& roffset) const
1431  {  {
1432  LAZYDEBUG(cout << "Resolve binary: " << toString() << endl;)  LAZYDEBUG(cout << "Resolve binary: " << toString() << endl;)
1433    
# Line 1549  LAZYDEBUG(cout << "Right res["<< rroffse Line 1554  LAZYDEBUG(cout << "Right res["<< rroffse
1554    
1555    
1556    roffset=m_samplesize*tid;    roffset=m_samplesize*tid;
1557    double* resultp=&(m_samples[roffset]);        // results are stored at the vector offset we recieved    double* resultp=&(m_samples[roffset]);        // results are stored at the vector offset we received
1558    switch(m_op)    switch(m_op)
1559    {    {
1560      case ADD:      case ADD:
# Line 1578  LAZYDEBUG(cout << "Result res[" << roffs Line 1583  LAZYDEBUG(cout << "Result res[" << roffs
1583  // This method assumes that any subexpressions which evaluate to Constant or Tagged Data  // This method assumes that any subexpressions which evaluate to Constant or Tagged Data
1584  // have already been collapsed to IDENTITY. So we must have at least one expanded child.  // have already been collapsed to IDENTITY. So we must have at least one expanded child.
1585  // unlike the other resolve helpers, we must treat these datapoints separately.  // unlike the other resolve helpers, we must treat these datapoints separately.
1586  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1587  DataLazy::resolveNodeTProd(int tid, int sampleNo, size_t& roffset)  DataLazy::resolveNodeTProd(int tid, int sampleNo, size_t& roffset) const
1588  {  {
1589  LAZYDEBUG(cout << "Resolve TensorProduct: " << toString() << endl;)  LAZYDEBUG(cout << "Resolve TensorProduct: " << toString() << endl;)
1590    
# Line 1611  LAZYDEBUG(cout << "m_samplesize=" << m_s Line 1616  LAZYDEBUG(cout << "m_samplesize=" << m_s
1616  LAZYDEBUG(cout << "outputshape=" << DataTypes::shapeToString(getShape()) << endl;)  LAZYDEBUG(cout << "outputshape=" << DataTypes::shapeToString(getShape()) << endl;)
1617  LAZYDEBUG(cout << "DPPS=" << m_right->getNumDPPSample() <<"."<<endl;)  LAZYDEBUG(cout << "DPPS=" << m_right->getNumDPPSample() <<"."<<endl;)
1618    
1619    double* resultp=&(m_samples[offset]);     // results are stored at the vector offset we recieved    double* resultp=&(m_samples[offset]);     // results are stored at the vector offset we received
1620    switch(m_op)    switch(m_op)
1621    {    {
1622      case PROD:      case PROD:
# Line 1637  LAZYDEBUG(cout << DataTypes::pointToStri Line 1642  LAZYDEBUG(cout << DataTypes::pointToStri
1642  }  }
1643    
1644    
1645  const DataTypes::ValueType*  const DataTypes::RealVectorType*
1646  DataLazy::resolveSample(int sampleNo, size_t& roffset)  DataLazy::resolveSample(int sampleNo, size_t& roffset) const
1647  {  {
1648  #ifdef _OPENMP  #ifdef _OPENMP
1649      int tid=omp_get_thread_num();      int tid=omp_get_thread_num();
# Line 1649  DataLazy::resolveSample(int sampleNo, si Line 1654  DataLazy::resolveSample(int sampleNo, si
1654  #ifdef LAZY_STACK_PROF  #ifdef LAZY_STACK_PROF
1655      stackstart[tid]=&tid;      stackstart[tid]=&tid;
1656      stackend[tid]=&tid;      stackend[tid]=&tid;
1657      const DataTypes::ValueType* r=resolveNodeSample(tid, sampleNo, roffset);      const DataTypes::RealVectorType* r=resolveNodeSample(tid, sampleNo, roffset);
1658      size_t d=(size_t)stackstart[tid]-(size_t)stackend[tid];      size_t d=(size_t)stackstart[tid]-(size_t)stackend[tid];
1659      #pragma omp critical      #pragma omp critical
1660      if (d>maxstackuse)      if (d>maxstackuse)
# Line 1758  DataLazy::resolveGroupWorker(std::vector Line 1763  DataLazy::resolveGroupWorker(std::vector
1763  #else  #else
1764                  res=work[j]->resolveNodeSample(0,sample,roffset);                  res=work[j]->resolveNodeSample(0,sample,roffset);
1765  #endif  #endif
1766                  DataVector::size_type outoffset=dep[j]->getPointOffset(sample,0);                  RealVectorType::size_type outoffset=dep[j]->getPointOffset(sample,0);
1767                  memcpy(&((*vecs[j])[outoffset]),&((*res)[roffset]),work[j]->m_samplesize*sizeof(DataVector::ElementType));                  memcpy(&((*vecs[j])[outoffset]),&((*res)[roffset]),work[j]->m_samplesize*sizeof(RealVectorType::ElementType));
1768          }          }
1769          }          }
1770      }      }
# Line 1819  LAZYDEBUG(cout << "Total number of sampl Line 1824  LAZYDEBUG(cout << "Total number of sampl
1824  #endif  #endif
1825  LAZYDEBUG(cout << "Sample #" << sample << endl;)  LAZYDEBUG(cout << "Sample #" << sample << endl;)
1826  LAZYDEBUG(cout << "Final res[" << roffset<< "]=" << (*res)[roffset] << (*res)[roffset]<< endl; )  LAZYDEBUG(cout << "Final res[" << roffset<< "]=" << (*res)[roffset] << (*res)[roffset]<< endl; )
1827              DataVector::size_type outoffset=result->getPointOffset(sample,0);              RealVectorType::size_type outoffset=result->getPointOffset(sample,0);
1828              memcpy(&(resvec[outoffset]),&((*res)[roffset]),m_samplesize*sizeof(DataVector::ElementType));              memcpy(&(resvec[outoffset]),&((*res)[roffset]),m_samplesize*sizeof(RealVectorType::ElementType));
1829      }      }
1830    }    }
1831  #ifdef LAZY_STACK_PROF  #ifdef LAZY_STACK_PROF
# Line 1986  DataLazy::intoTreeString(ostringstream& Line 1991  DataLazy::intoTreeString(ostringstream&
1991    
1992    
1993  DataAbstract*  DataAbstract*
1994  DataLazy::deepCopy()  DataLazy::deepCopy() const
1995  {  {
1996    switch (getOpgroup(m_op))    switch (getOpgroup(m_op))
1997    {    {
# Line 2012  DataLazy::deepCopy() Line 2017  DataLazy::deepCopy()
2017  // or it could be some function of the lengths of the DataReady instances which  // or it could be some function of the lengths of the DataReady instances which
2018  // form part of the expression.  // form part of the expression.
2019  // Rather than have people making assumptions, I have disabled the method.  // Rather than have people making assumptions, I have disabled the method.
2020  DataTypes::ValueType::size_type  DataTypes::RealVectorType::size_type
2021  DataLazy::getLength() const  DataLazy::getLength() const
2022  {  {
2023    throw DataException("getLength() does not make sense for lazy data.");    throw DataException("getLength() does not make sense for lazy data.");
# Line 2027  DataLazy::getSlice(const DataTypes::Regi Line 2032  DataLazy::getSlice(const DataTypes::Regi
2032    
2033    
2034  // To do this we need to rely on our child nodes  // To do this we need to rely on our child nodes
2035  DataTypes::ValueType::size_type  DataTypes::RealVectorType::size_type
2036  DataLazy::getPointOffset(int sampleNo,  DataLazy::getPointOffset(int sampleNo,
2037                   int dataPointNo)                   int dataPointNo)
2038  {  {
# Line 2053  DataLazy::getPointOffset(int sampleNo, Line 2058  DataLazy::getPointOffset(int sampleNo,
2058  }  }
2059    
2060  // To do this we need to rely on our child nodes  // To do this we need to rely on our child nodes
2061  DataTypes::ValueType::size_type  DataTypes::RealVectorType::size_type
2062  DataLazy::getPointOffset(int sampleNo,  DataLazy::getPointOffset(int sampleNo,
2063                   int dataPointNo) const                   int dataPointNo) const
2064  {  {
# Line 2086  DataLazy::getPointOffset(int sampleNo, Line 2091  DataLazy::getPointOffset(int sampleNo,
2091  void  void
2092  DataLazy::setToZero()  DataLazy::setToZero()
2093  {  {
2094  //   DataTypes::ValueType v(getNoValues(),0);  //   DataTypes::RealVectorType v(getNoValues(),0);
2095  //   m_id=DataReady_ptr(new DataConstant(getFunctionSpace(),getShape(),v));  //   m_id=DataReady_ptr(new DataConstant(getFunctionSpace(),getShape(),v));
2096  //   m_op=IDENTITY;  //   m_op=IDENTITY;
2097  //   m_right.reset();    //   m_right.reset();  
# Line 2094  DataLazy::setToZero() Line 2099  DataLazy::setToZero()
2099  //   m_readytype='C';  //   m_readytype='C';
2100  //   m_buffsRequired=1;  //   m_buffsRequired=1;
2101    
2102    privdebug=privdebug;  // to stop the compiler complaining about unused privdebug    (void)privdebug;  // to stop the compiler complaining about unused privdebug
2103    throw DataException("Programmer error - setToZero not supported for DataLazy (DataLazy objects should be read only).");    throw DataException("Programmer error - setToZero not supported for DataLazy (DataLazy objects should be read only).");
2104  }  }
2105    

Legend:
Removed from v.4264  
changed lines
  Added in v.5938

  ViewVC Help
Powered by ViewVC 1.1.26