/[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

revision 2085 by jfenwick, Mon Nov 24 00:45:48 2008 UTC revision 2147 by jfenwick, Wed Dec 10 04:41:26 2008 UTC
# Line 28  Line 28 
28  #include "UnaryFuncs.h"     // for escript::fsign  #include "UnaryFuncs.h"     // for escript::fsign
29  #include "Utils.h"  #include "Utils.h"
30    
31    // #define LAZYDEBUG(X) X;
32    #define LAZYDEBUG(X)
33    
34  /*  /*
35  How does DataLazy work?  How does DataLazy work?
36  ~~~~~~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~
# Line 70  The convention that I use, is that the r Line 73  The convention that I use, is that the r
73  For expressions which evaluate to Constant or Tagged, there is a different evaluation method.  For expressions which evaluate to Constant or Tagged, there is a different evaluation method.
74  The collapse method invokes the (non-lazy) operations on the Data class to evaluate the expression.  The collapse method invokes the (non-lazy) operations on the Data class to evaluate the expression.
75    
76  To add a new operator you need to do the following (plus anything I might have forgotten):  To add a new operator you need to do the following (plus anything I might have forgotten - adding a new group for example):
77  1) Add to the ES_optype.  1) Add to the ES_optype.
78  2) determine what opgroup your operation belongs to (X)  2) determine what opgroup your operation belongs to (X)
79  3) add a string for the op to the end of ES_opstrings  3) add a string for the op to the end of ES_opstrings
# Line 96  enum ES_opgroup Line 99  enum ES_opgroup
99     G_IDENTITY,     G_IDENTITY,
100     G_BINARY,        // pointwise operations with two arguments     G_BINARY,        // pointwise operations with two arguments
101     G_UNARY,     // pointwise operations with one argument     G_UNARY,     // pointwise operations with one argument
102       G_UNARY_P,       // pointwise operations with one argument, requiring a parameter
103     G_NP1OUT,        // non-pointwise op with one output     G_NP1OUT,        // non-pointwise op with one output
104     G_NP1OUT_P,      // non-pointwise op with one output requiring a parameter     G_NP1OUT_P,      // non-pointwise op with one output requiring a parameter
105     G_TENSORPROD     // general tensor product     G_TENSORPROD     // general tensor product
# Line 109  string ES_opstrings[]={"UNKNOWN","IDENTI Line 113  string ES_opstrings[]={"UNKNOWN","IDENTI
113              "asin","acos","atan","sinh","cosh","tanh","erf",              "asin","acos","atan","sinh","cosh","tanh","erf",
114              "asinh","acosh","atanh",              "asinh","acosh","atanh",
115              "log10","log","sign","abs","neg","pos","exp","sqrt",              "log10","log","sign","abs","neg","pos","exp","sqrt",
116              "1/","where>0","where<0","where>=0","where<=0",              "1/","where>0","where<0","where>=0","where<=0", "where<>0","where=0",
117              "symmetric","nonsymmetric",              "symmetric","nonsymmetric",
118              "prod",              "prod",
119              "transpose",              "transpose", "trace"};
120              "trace"};  int ES_opcount=40;
 int ES_opcount=38;  
121  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENTITY,G_BINARY,G_BINARY,G_BINARY,G_BINARY, G_BINARY,  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENTITY,G_BINARY,G_BINARY,G_BINARY,G_BINARY, G_BINARY,
122              G_UNARY,G_UNARY,G_UNARY, //10              G_UNARY,G_UNARY,G_UNARY, //10
123              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,    // 17              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,    // 17
124              G_UNARY,G_UNARY,G_UNARY,                    // 20              G_UNARY,G_UNARY,G_UNARY,                    // 20
125              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,        // 28              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,    // 28
126              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,            // 33              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY, G_UNARY_P, G_UNARY_P,      // 35
127              G_NP1OUT,G_NP1OUT,              G_NP1OUT,G_NP1OUT,
128              G_TENSORPROD,              G_TENSORPROD,
129              G_NP1OUT_P, G_NP1OUT_P};              G_NP1OUT_P, G_NP1OUT_P};
# Line 252  GTPShape(DataAbstract_ptr left, DataAbst Line 255  GTPShape(DataAbstract_ptr left, DataAbst
255       for (int i=0; i<rank0-axis_offset; i++, ++out_index) { shape2[out_index]=tmpShape0[i]; } // First part of arg_0_Z       for (int i=0; i<rank0-axis_offset; i++, ++out_index) { shape2[out_index]=tmpShape0[i]; } // First part of arg_0_Z
256       for (int i=axis_offset; i<rank1; i++, ++out_index)   { shape2[out_index]=tmpShape1[i]; } // Last part of arg_1_Z       for (int i=axis_offset; i<rank1; i++, ++out_index)   { shape2[out_index]=tmpShape1[i]; } // Last part of arg_1_Z
257    }    }
258    
259      if (shape2.size()>ESCRIPT_MAX_DATA_RANK)
260      {
261         ostringstream os;
262         os << "C_GeneralTensorProduct: Error - Attempt to create a rank " << shape2.size() << " object. The maximum rank is " << ESCRIPT_MAX_DATA_RANK << ".";
263         throw DataException(os.str());
264      }
265    
266    return shape2;    return shape2;
267  }  }
268    
# Line 281  calcBuffs(const DataLazy_ptr& left, cons Line 292  calcBuffs(const DataLazy_ptr& left, cons
292     {     {
293     case G_IDENTITY: return 1;     case G_IDENTITY: return 1;
294     case G_BINARY: return max(left->getBuffsRequired(),right->getBuffsRequired()+1);     case G_BINARY: return max(left->getBuffsRequired(),right->getBuffsRequired()+1);
295     case G_UNARY: return max(left->getBuffsRequired(),1);     case G_UNARY:
296       case G_UNARY_P: return max(left->getBuffsRequired(),1);
297     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);
298     case G_NP1OUT_P: return 1+max(left->getBuffsRequired(),1);     case G_NP1OUT_P: return 1+max(left->getBuffsRequired(),1);
299     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);
# Line 332  DataLazy::DataLazy(DataAbstract_ptr p) Line 344  DataLazy::DataLazy(DataAbstract_ptr p)
344     m_buffsRequired=1;     m_buffsRequired=1;
345     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
346     m_maxsamplesize=m_samplesize;     m_maxsamplesize=m_samplesize;
347  cout << "(1)Lazy created with " << m_samplesize << endl;  LAZYDEBUG(cout << "(1)Lazy created with " << m_samplesize << endl;)
348  }  }
349    
350    
# Line 425  DataLazy::DataLazy(DataAbstract_ptr left Line 437  DataLazy::DataLazy(DataAbstract_ptr left
437     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
438     m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());       m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());  
439     m_buffsRequired=calcBuffs(m_left, m_right,m_op);     m_buffsRequired=calcBuffs(m_left, m_right,m_op);
440  cout << "(3)Lazy created with " << m_samplesize << endl;  LAZYDEBUG(cout << "(3)Lazy created with " << m_samplesize << endl;)
441  }  }
442    
443  DataLazy::DataLazy(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op, int axis_offset, int transpose)  DataLazy::DataLazy(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op, int axis_offset, int transpose)
# Line 489  DataLazy::DataLazy(DataAbstract_ptr left Line 501  DataLazy::DataLazy(DataAbstract_ptr left
501     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
502     m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());       m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());  
503     m_buffsRequired=calcBuffs(m_left, m_right,m_op);     m_buffsRequired=calcBuffs(m_left, m_right,m_op);
504  cout << "(4)Lazy created with " << m_samplesize << endl;  LAZYDEBUG(cout << "(4)Lazy created with " << m_samplesize << endl;)
505  }  }
506    
507    
# Line 497  DataLazy::DataLazy(DataAbstract_ptr left Line 509  DataLazy::DataLazy(DataAbstract_ptr left
509      : parent(left->getFunctionSpace(), resultShape(left,op)),      : parent(left->getFunctionSpace(), resultShape(left,op)),
510      m_op(op),      m_op(op),
511      m_axis_offset(axis_offset),      m_axis_offset(axis_offset),
512      m_transpose(0)      m_transpose(0),
513        m_tol(0)
514  {  {
515     if ((getOpgroup(op)!=G_NP1OUT_P))     if ((getOpgroup(op)!=G_NP1OUT_P))
516     {     {
# Line 517  DataLazy::DataLazy(DataAbstract_ptr left Line 530  DataLazy::DataLazy(DataAbstract_ptr left
530     m_buffsRequired=calcBuffs(m_left, m_right,m_op); // yeah m_right will be null at this point     m_buffsRequired=calcBuffs(m_left, m_right,m_op); // yeah m_right will be null at this point
531     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
532     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
533  cout << "(5)Lazy created with " << m_samplesize << endl;  LAZYDEBUG(cout << "(5)Lazy created with " << m_samplesize << endl;)
534  }  }
535    
536    DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op, double tol)
537        : parent(left->getFunctionSpace(), left->getShape()),
538        m_op(op),
539        m_axis_offset(0),
540        m_transpose(0),
541        m_tol(tol)
542    {
543       if ((getOpgroup(op)!=G_UNARY_P))
544       {
545        throw DataException("Programmer error - constructor DataLazy(left, op, tol) will only process UNARY operations which require parameters.");
546       }
547       DataLazy_ptr lleft;
548       if (!left->isLazy())
549       {
550        lleft=DataLazy_ptr(new DataLazy(left));
551       }
552       else
553       {
554        lleft=dynamic_pointer_cast<DataLazy>(left);
555       }
556       m_readytype=lleft->m_readytype;
557       m_left=lleft;
558       m_buffsRequired=calcBuffs(m_left, m_right,m_op); // yeah m_right will be null at this point
559       m_samplesize=getNumDPPSample()*getNoValues();
560       m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
561    LAZYDEBUG(cout << "(6)Lazy created with " << m_samplesize << endl;)
562    }
563    
564  DataLazy::~DataLazy()  DataLazy::~DataLazy()
565  {  {
# Line 657  DataLazy::collapseToReady() Line 697  DataLazy::collapseToReady()
697      case LEZ:      case LEZ:
698      result=left.whereNonPositive();      result=left.whereNonPositive();
699      break;      break;
700        case NEZ:
701        result=left.whereNonZero(m_tol);
702        break;
703        case EZ:
704        result=left.whereZero(m_tol);
705        break;
706      case SYM:      case SYM:
707      result=left.symmetric();      result=left.symmetric();
708      break;      break;
# Line 823  DataLazy::resolveUnary(ValueType& v, siz Line 869  DataLazy::resolveUnary(ValueType& v, siz
869      case LEZ:      case LEZ:
870      tensor_unary_operation(m_samplesize, left, result, bind2nd(less_equal<double>(),0.0));      tensor_unary_operation(m_samplesize, left, result, bind2nd(less_equal<double>(),0.0));
871      break;      break;
872    // There are actually G_UNARY_P but I don't see a compelling reason to treat them differently
873        case NEZ:
874        tensor_unary_operation(m_samplesize, left, result, bind2nd(AbsGT(),m_tol));
875        break;
876        case EZ:
877        tensor_unary_operation(m_samplesize, left, result, bind2nd(AbsLTE(),m_tol));
878        break;
879    
880      default:      default:
881      throw DataException("Programmer error - resolveUnary can not resolve operator "+opToString(m_op)+".");      throw DataException("Programmer error - resolveUnary can not resolve operator "+opToString(m_op)+".");
# Line 831  DataLazy::resolveUnary(ValueType& v, siz Line 884  DataLazy::resolveUnary(ValueType& v, siz
884  }  }
885    
886    
887    
888    
889    
890    
891  /*  /*
892    \brief Compute the value of the expression (unary operation) for the given sample.    \brief Compute the value of the expression (unary operation) for the given sample.
893    \return Vector which stores the value of the subexpression for the given sample.    \return Vector which stores the value of the subexpression for the given sample.
# Line 944  DataLazy::resolveNP1OUT_P(ValueType& v, Line 1001  DataLazy::resolveNP1OUT_P(ValueType& v,
1001  DataTypes::ValueType*  DataTypes::ValueType*
1002  DataLazy::resolveBinary(ValueType& v,  size_t offset, int sampleNo, size_t& roffset) const  DataLazy::resolveBinary(ValueType& v,  size_t offset, int sampleNo, size_t& roffset) const
1003  {  {
1004  cout << "Resolve binary: " << toString() << endl;  LAZYDEBUG(cout << "Resolve binary: " << toString() << endl;)
1005    
1006    size_t lroffset=0, rroffset=0;    // offsets in the left and right result vectors    size_t lroffset=0, rroffset=0;    // offsets in the left and right result vectors
1007      // first work out which of the children are expanded      // first work out which of the children are expanded
# Line 1019  cout << "Resolve binary: " << toString() Line 1076  cout << "Resolve binary: " << toString()
1076  DataTypes::ValueType*  DataTypes::ValueType*
1077  DataLazy::resolveTProd(ValueType& v,  size_t offset, int sampleNo, size_t& roffset) const  DataLazy::resolveTProd(ValueType& v,  size_t offset, int sampleNo, size_t& roffset) const
1078  {  {
1079  cout << "Resolve TensorProduct: " << toString() << endl;  LAZYDEBUG(cout << "Resolve TensorProduct: " << toString() << endl;)
1080    
1081    size_t lroffset=0, rroffset=0;    // offsets in the left and right result vectors    size_t lroffset=0, rroffset=0;    // offsets in the left and right result vectors
1082      // first work out which of the children are expanded      // first work out which of the children are expanded
# Line 1073  cout << "Resolve TensorProduct: " << toS Line 1130  cout << "Resolve TensorProduct: " << toS
1130  const DataTypes::ValueType*  const DataTypes::ValueType*
1131  DataLazy::resolveSample(ValueType& v, size_t offset, int sampleNo, size_t& roffset)  DataLazy::resolveSample(ValueType& v, size_t offset, int sampleNo, size_t& roffset)
1132  {  {
1133  cout << "Resolve sample " << toString() << endl;  LAZYDEBUG(cout << "Resolve sample " << toString() << endl;)
1134      // 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
1135    if (m_readytype!='E' && m_op!=IDENTITY)    if (m_readytype!='E' && m_op!=IDENTITY)
1136    {    {
# Line 1096  cout << "Resolve sample " << toString() Line 1153  cout << "Resolve sample " << toString()
1153    }    }
1154    switch (getOpgroup(m_op))    switch (getOpgroup(m_op))
1155    {    {
1156    case G_UNARY: return resolveUnary(v, offset,sampleNo,roffset);    case G_UNARY:
1157      case G_UNARY_P: return resolveUnary(v, offset,sampleNo,roffset);
1158    case G_BINARY: return resolveBinary(v, offset,sampleNo,roffset);    case G_BINARY: return resolveBinary(v, offset,sampleNo,roffset);
1159    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);
1160    case G_NP1OUT_P: return resolveNP1OUT_P(v, offset, sampleNo,roffset);    case G_NP1OUT_P: return resolveNP1OUT_P(v, offset, sampleNo,roffset);
# Line 1113  DataReady_ptr Line 1171  DataReady_ptr
1171  DataLazy::resolve()  DataLazy::resolve()
1172  {  {
1173    
1174  cout << "Sample size=" << m_samplesize << endl;  LAZYDEBUG(cout << "Sample size=" << m_samplesize << endl;)
1175  cout << "Buffers=" << m_buffsRequired << endl;  LAZYDEBUG(cout << "Buffers=" << m_buffsRequired << endl;)
1176    
1177    if (m_readytype!='E')     // if the whole sub-expression is Constant or Tagged, then evaluate it normally    if (m_readytype!='E')     // if the whole sub-expression is Constant or Tagged, then evaluate it normally
1178    {    {
# Line 1132  cout << "Buffers=" << m_buffsRequired << Line 1190  cout << "Buffers=" << m_buffsRequired <<
1190    numthreads=getNumberOfThreads();    numthreads=getNumberOfThreads();
1191  #endif  #endif
1192    ValueType v(numthreads*threadbuffersize);    ValueType v(numthreads*threadbuffersize);
1193  cout << "Buffer created with size=" << v.size() << endl;  LAZYDEBUG(cout << "Buffer created with size=" << v.size() << endl;)
1194    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),  ValueType(getNoValues()));    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),  ValueType(getNoValues()));
1195    ValueType& resvec=result->getVector();    ValueType& resvec=result->getVector();
1196    DataReady_ptr resptr=DataReady_ptr(result);    DataReady_ptr resptr=DataReady_ptr(result);
# Line 1144  cout << "Buffer created with size=" << v Line 1202  cout << "Buffer created with size=" << v
1202    #pragma omp parallel for private(sample,resoffset,outoffset,res) schedule(static)    #pragma omp parallel for private(sample,resoffset,outoffset,res) schedule(static)
1203    for (sample=0;sample<totalsamples;++sample)    for (sample=0;sample<totalsamples;++sample)
1204    {    {
1205  cout << "################################# " << sample << endl;  LAZYDEBUG(cout << "################################# " << sample << endl;)
1206  #ifdef _OPENMP  #ifdef _OPENMP
1207      res=resolveSample(v,threadbuffersize*omp_get_thread_num(),sample,resoffset);      res=resolveSample(v,threadbuffersize*omp_get_thread_num(),sample,resoffset);
1208  #else  #else
1209      res=resolveSample(v,0,sample,resoffset);   // res would normally be v, but not if its a single IDENTITY op.      res=resolveSample(v,0,sample,resoffset);   // res would normally be v, but not if its a single IDENTITY op.
1210  #endif  #endif
1211  cerr << "-------------------------------- " << endl;  LAZYDEBUG(cerr << "-------------------------------- " << endl;)
1212      outoffset=result->getPointOffset(sample,0);      outoffset=result->getPointOffset(sample,0);
1213  cerr << "offset=" << outoffset << endl;  LAZYDEBUG(cerr << "offset=" << outoffset << endl;)
1214      for (unsigned int i=0;i<m_samplesize;++i,++outoffset,++resoffset)   // copy values into the output vector      for (unsigned int i=0;i<m_samplesize;++i,++outoffset,++resoffset)   // copy values into the output vector
1215      {      {
1216      resvec[outoffset]=(*res)[resoffset];      resvec[outoffset]=(*res)[resoffset];
1217      }      }
1218  cerr << "*********************************" << endl;  LAZYDEBUG(cerr << "*********************************" << endl;)
1219    }    }
1220    return resptr;    return resptr;
1221  }  }
# Line 1204  DataLazy::intoString(ostringstream& oss) Line 1262  DataLazy::intoString(ostringstream& oss)
1262      oss << ')';      oss << ')';
1263      break;      break;
1264    case G_UNARY:    case G_UNARY:
1265      case G_UNARY_P:
1266    case G_NP1OUT:    case G_NP1OUT:
1267    case G_NP1OUT_P:    case G_NP1OUT_P:
1268      oss << opToString(m_op) << '(';      oss << opToString(m_op) << '(';

Legend:
Removed from v.2085  
changed lines
  Added in v.2147

  ViewVC Help
Powered by ViewVC 1.1.26