/[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 2082 by caltinay, Fri Nov 21 01:46:05 2008 UTC revision 2086 by jfenwick, Mon Nov 24 02:38:50 2008 UTC
# Line 97  enum ES_opgroup Line 97  enum ES_opgroup
97     G_BINARY,        // pointwise operations with two arguments     G_BINARY,        // pointwise operations with two arguments
98     G_UNARY,     // pointwise operations with one argument     G_UNARY,     // pointwise operations with one argument
99     G_NP1OUT,        // non-pointwise op with one output     G_NP1OUT,        // non-pointwise op with one output
100       G_NP1OUT_P,      // non-pointwise op with one output requiring a parameter
101     G_TENSORPROD     // general tensor product     G_TENSORPROD     // general tensor product
102  };  };
103    
# Line 110  string ES_opstrings[]={"UNKNOWN","IDENTI Line 111  string ES_opstrings[]={"UNKNOWN","IDENTI
111              "log10","log","sign","abs","neg","pos","exp","sqrt",              "log10","log","sign","abs","neg","pos","exp","sqrt",
112              "1/","where>0","where<0","where>=0","where<=0",              "1/","where>0","where<0","where>=0","where<=0",
113              "symmetric","nonsymmetric",              "symmetric","nonsymmetric",
114              "prod"};              "prod",
115  int ES_opcount=36;              "transpose",
116                "trace"};
117    int ES_opcount=38;
118  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,
119              G_UNARY,G_UNARY,G_UNARY, //10              G_UNARY,G_UNARY,G_UNARY, //10
120              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
# Line 119  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENT Line 122  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENT
122              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
123              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,            // 33              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,            // 33
124              G_NP1OUT,G_NP1OUT,              G_NP1OUT,G_NP1OUT,
125              G_TENSORPROD};              G_TENSORPROD,
126                G_NP1OUT_P, G_NP1OUT_P};
127  inline  inline
128  ES_opgroup  ES_opgroup
129  getOpgroup(ES_optype op)  getOpgroup(ES_optype op)
# Line 177  resultShape(DataAbstract_ptr left, DataA Line 181  resultShape(DataAbstract_ptr left, DataA
181      return left->getShape();      return left->getShape();
182  }  }
183    
184    // return the shape for "op left"
185    
186    DataTypes::ShapeType
187    resultShape(DataAbstract_ptr left, ES_optype op)
188    {
189        switch(op)
190        {
191            case TRANS:
192            return left->getShape();
193        break;
194        case TRACE:
195            return DataTypes::scalarShape;
196        break;
197            default:
198        throw DataException("Programmer error - resultShape(left,op) can't compute shapes for operator "+opToString(op)+".");
199        }
200    }
201    
202  // determine the output shape for the general tensor product operation  // determine the output shape for the general tensor product operation
203  // the additional parameters return information required later for the product  // the additional parameters return information required later for the product
204  // the majority of this code is copy pasted from C_General_Tensor_Product  // the majority of this code is copy pasted from C_General_Tensor_Product
# Line 197  GTPShape(DataAbstract_ptr left, DataAbst Line 219  GTPShape(DataAbstract_ptr left, DataAbst
219    else if (transpose == 2)  { start1 = rank1-axis_offset; }    else if (transpose == 2)  { start1 = rank1-axis_offset; }
220    else              { throw DataException("DataLazy GeneralTensorProduct Constructor: Error - transpose should be 0, 1 or 2"); }    else              { throw DataException("DataLazy GeneralTensorProduct Constructor: Error - transpose should be 0, 1 or 2"); }
221    
222      if (rank0<axis_offset)
223      {
224        throw DataException("DataLazy GeneralTensorProduct Constructor: Error - rank of left < axisoffset");
225      }
226    
227    // Adjust the shapes for transpose    // Adjust the shapes for transpose
228    DataTypes::ShapeType tmpShape0(rank0);    // pre-sizing the vectors rather    DataTypes::ShapeType tmpShape0(rank0);    // pre-sizing the vectors rather
# Line 226  GTPShape(DataAbstract_ptr left, DataAbst Line 252  GTPShape(DataAbstract_ptr left, DataAbst
252       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
253       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
254    }    }
255    
256      if (shape2.size()>ESCRIPT_MAX_DATA_RANK)
257      {
258         ostringstream os;
259         os << "C_GeneralTensorProduct: Error - Attempt to create a rank " << shape2.size() << " object. The maximum rank is " << ESCRIPT_MAX_DATA_RANK << ".";
260         throw DataException(os.str());
261      }
262    
263    return shape2;    return shape2;
264  }  }
265    
# Line 257  calcBuffs(const DataLazy_ptr& left, cons Line 291  calcBuffs(const DataLazy_ptr& left, cons
291     case G_BINARY: return max(left->getBuffsRequired(),right->getBuffsRequired()+1);     case G_BINARY: return max(left->getBuffsRequired(),right->getBuffsRequired()+1);
292     case G_UNARY: return max(left->getBuffsRequired(),1);     case G_UNARY: return max(left->getBuffsRequired(),1);
293     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);
294       case G_NP1OUT_P: return 1+max(left->getBuffsRequired(),1);
295     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);
296     default:     default:
297      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");
# Line 466  cout << "(4)Lazy created with " << m_sam Line 501  cout << "(4)Lazy created with " << m_sam
501  }  }
502    
503    
504    DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op, int axis_offset)
505        : parent(left->getFunctionSpace(), resultShape(left,op)),
506        m_op(op),
507        m_axis_offset(axis_offset),
508        m_transpose(0)
509    {
510       if ((getOpgroup(op)!=G_NP1OUT_P))
511       {
512        throw DataException("Programmer error - constructor DataLazy(left, op, ax) will only process UNARY operations which require parameters.");
513       }
514       DataLazy_ptr lleft;
515       if (!left->isLazy())
516       {
517        lleft=DataLazy_ptr(new DataLazy(left));
518       }
519       else
520       {
521        lleft=dynamic_pointer_cast<DataLazy>(left);
522       }
523       m_readytype=lleft->m_readytype;
524       m_left=lleft;
525       m_buffsRequired=calcBuffs(m_left, m_right,m_op); // yeah m_right will be null at this point
526       m_samplesize=getNumDPPSample()*getNoValues();
527       m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
528    cout << "(5)Lazy created with " << m_samplesize << endl;
529    }
530    
531    
532  DataLazy::~DataLazy()  DataLazy::~DataLazy()
533  {  {
534  }  }
# Line 611  DataLazy::collapseToReady() Line 674  DataLazy::collapseToReady()
674      case PROD:      case PROD:
675      result=C_GeneralTensorProduct(left,right,m_axis_offset, m_transpose);      result=C_GeneralTensorProduct(left,right,m_axis_offset, m_transpose);
676      break;      break;
677        case TRANS:
678        result=left.transpose(m_axis_offset);
679        break;
680        case TRACE:
681        result=left.trace(m_axis_offset);
682        break;
683      default:      default:
684      throw DataException("Programmer error - collapseToReady does not know how to resolve operator "+opToString(m_op)+".");      throw DataException("Programmer error - collapseToReady does not know how to resolve operator "+opToString(m_op)+".");
685    }    }
# Line 810  DataLazy::resolveNP1OUT(ValueType& v, si Line 879  DataLazy::resolveNP1OUT(ValueType& v, si
879    return &v;    return &v;
880  }  }
881    
882    /*
883      \brief Compute the value of the expression (unary operation) for the given sample.
884      \return Vector which stores the value of the subexpression for the given sample.
885      \param v A vector to store intermediate results.
886      \param offset Index in v to begin storing results.
887      \param sampleNo Sample number to evaluate.
888      \param roffset (output parameter) the offset in the return vector where the result begins.
889    
890      The return value will be an existing vector so do not deallocate it.
891      If the result is stored in v it should be stored at the offset given.
892      Everything from offset to the end of v should be considered available for this method to use.
893    */
894    DataTypes::ValueType*
895    DataLazy::resolveNP1OUT_P(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const
896    {
897        // we assume that any collapsing has been done before we get here
898        // since we only have one argument we don't need to think about only
899        // processing single points.
900      if (m_readytype!='E')
901      {
902        throw DataException("Programmer error - resolveNP1OUT_P should only be called on expanded Data.");
903      }
904        // since we can't write the result over the input, we need a result offset further along
905      size_t subroffset=roffset+m_samplesize;
906      const ValueType* vleft=m_left->resolveSample(v,offset,sampleNo,subroffset);
907      roffset=offset;
908      switch (m_op)
909      {
910        case TRACE:
911             DataMaths::trace(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset);
912        break;
913        case TRANS:
914             DataMaths::transpose(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset);
915        break;
916        default:
917        throw DataException("Programmer error - resolveNP1OUTP can not resolve operator "+opToString(m_op)+".");
918      }
919      return &v;
920    }
921    
922    
923  #define PROC_OP(TYPE,X)                               \  #define PROC_OP(TYPE,X)                               \
# Line 851  cout << "Resolve binary: " << toString() Line 958  cout << "Resolve binary: " << toString()
958      // first work out which of the children are expanded      // first work out which of the children are expanded
959    bool leftExp=(m_left->m_readytype=='E');    bool leftExp=(m_left->m_readytype=='E');
960    bool rightExp=(m_right->m_readytype=='E');    bool rightExp=(m_right->m_readytype=='E');
961      if (!leftExp && !rightExp)
962      {
963        throw DataException("Programmer Error - please use collapse if neither argument has type 'E'.");
964      }
965      bool leftScalar=(m_left->getRank()==0);
966      bool rightScalar=(m_right->getRank()==0);
967    bool bigloops=((leftExp && rightExp) || (!leftExp && !rightExp)); // is processing in single step?    bool bigloops=((leftExp && rightExp) || (!leftExp && !rightExp)); // is processing in single step?
968    int steps=(bigloops?1:getNumDPPSample());    int steps=(bigloops?1:getNumDPPSample());
969    size_t chunksize=(bigloops? m_samplesize : getNoValues());    // if bigloops, pretend the whole sample is a datapoint    size_t chunksize=(bigloops? m_samplesize : getNoValues());    // if bigloops, pretend the whole sample is a datapoint
970    if (m_left->getRank()!=m_right->getRank())    // need to deal with scalar * ? ops    if (m_left->getRank()!=m_right->getRank())    // need to deal with scalar * ? ops
971    {    {
972      EsysAssert((m_left->getRank()==0) || (m_right->getRank()==0), "Error - Ranks must match unless one is 0.");      if (!leftScalar && !rightScalar)
973        {
974           throw DataException("resolveBinary - ranks of arguments must match unless one of them is scalar.");
975        }
976      steps=getNumDPPSample()*max(m_left->getNoValues(),m_right->getNoValues());      steps=getNumDPPSample()*max(m_left->getNoValues(),m_right->getNoValues());
977      chunksize=1;    // for scalar      chunksize=1;    // for scalar
978    }        }    
979    int leftStep=((leftExp && !rightExp)? m_right->getNoValues() : 0);    int leftStep=((leftExp && (!rightExp || rightScalar))? m_right->getNoValues() : 0);
980    int rightStep=((rightExp && !leftExp)? m_left->getNoValues() : 0);    int rightStep=((rightExp && (!leftExp || leftScalar))? m_left->getNoValues() : 0);
981    int resultStep=max(leftStep,rightStep);   // only one (at most) should be !=0    int resultStep=max(leftStep,rightStep);   // only one (at most) should be !=0
982      // Get the values of sub-expressions      // Get the values of sub-expressions
983    const ValueType* left=m_left->resolveSample(v,offset,sampleNo,lroffset);    const ValueType* left=m_left->resolveSample(v,offset,sampleNo,lroffset);
# Line 991  cout << "Resolve sample " << toString() Line 1107  cout << "Resolve sample " << toString()
1107    case G_UNARY: return resolveUnary(v, offset,sampleNo,roffset);    case G_UNARY: return resolveUnary(v, offset,sampleNo,roffset);
1108    case G_BINARY: return resolveBinary(v, offset,sampleNo,roffset);    case G_BINARY: return resolveBinary(v, offset,sampleNo,roffset);
1109    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);
1110      case G_NP1OUT_P: return resolveNP1OUT_P(v, offset, sampleNo,roffset);
1111    case G_TENSORPROD: return resolveTProd(v,offset, sampleNo,roffset);    case G_TENSORPROD: return resolveTProd(v,offset, sampleNo,roffset);
1112    default:    default:
1113      throw DataException("Programmer Error - resolveSample does not know how to process "+opToString(m_op)+".");      throw DataException("Programmer Error - resolveSample does not know how to process "+opToString(m_op)+".");
# Line 1096  DataLazy::intoString(ostringstream& oss) Line 1213  DataLazy::intoString(ostringstream& oss)
1213      break;      break;
1214    case G_UNARY:    case G_UNARY:
1215    case G_NP1OUT:    case G_NP1OUT:
1216      case G_NP1OUT_P:
1217      oss << opToString(m_op) << '(';      oss << opToString(m_op) << '(';
1218      m_left->intoString(oss);      m_left->intoString(oss);
1219      oss << ')';      oss << ')';

Legend:
Removed from v.2082  
changed lines
  Added in v.2086

  ViewVC Help
Powered by ViewVC 1.1.26