/[escript]/trunk/escript/src/DataLazy.cpp
ViewVC logotype

Diff of /trunk/escript/src/DataLazy.cpp

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

revision 2157 by jfenwick, Mon Dec 15 06:05:58 2008 UTC revision 2497 by jfenwick, Mon Jun 29 00:04:45 2009 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    #include "EscriptParams.h"
32    
33    #include <iomanip>      // for some fancy formatting in debug
34    
35  // #define LAZYDEBUG(X) if (privdebug){X;}  // #define LAZYDEBUG(X) if (privdebug){X;}
36  #define LAZYDEBUG(X)  #define LAZYDEBUG(X)
37  namespace  namespace
# Line 38  bool privdebug=false; Line 42  bool privdebug=false;
42  #define DISABLEDEBUG privdebug=false;  #define DISABLEDEBUG privdebug=false;
43  }  }
44    
45    // #define SIZELIMIT
46    // #define SIZELIMIT if ((m_height>7) || (m_children>127)) {cerr << "\n!!!!!!! SIZE LIMIT EXCEEDED " << m_children << ";" << m_height << endl << toString() << endl; resolveToIdentity();}
47    //#define SIZELIMIT if ((m_height>7) || (m_children>127)) {resolveToIdentity();}
48    
49    #define SIZELIMIT if ((m_height>escript::escriptParams.getTOO_MANY_LEVELS()) || (m_children>escript::escriptParams.getTOO_MANY_NODES())) {resolveToIdentity();}
50    
51  /*  /*
52  How does DataLazy work?  How does DataLazy work?
53  ~~~~~~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~
# Line 109  enum ES_opgroup Line 119  enum ES_opgroup
119     G_UNARY_P,       // pointwise operations with one argument, requiring a parameter     G_UNARY_P,       // pointwise operations with one argument, requiring a parameter
120     G_NP1OUT,        // non-pointwise op with one output     G_NP1OUT,        // non-pointwise op with one output
121     G_NP1OUT_P,      // non-pointwise op with one output requiring a parameter     G_NP1OUT_P,      // non-pointwise op with one output requiring a parameter
122     G_TENSORPROD     // general tensor product     G_TENSORPROD,    // general tensor product
123       G_NP1OUT_2P      // non-pointwise op with one output requiring two params
124  };  };
125    
126    
# Line 123  string ES_opstrings[]={"UNKNOWN","IDENTI Line 134  string ES_opstrings[]={"UNKNOWN","IDENTI
134              "1/","where>0","where<0","where>=0","where<=0", "where<>0","where=0",              "1/","where>0","where<0","where>=0","where<=0", "where<>0","where=0",
135              "symmetric","nonsymmetric",              "symmetric","nonsymmetric",
136              "prod",              "prod",
137              "transpose", "trace"};              "transpose", "trace",
138  int ES_opcount=40;              "swapaxes"};
139    int ES_opcount=41;
140  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,
141              G_UNARY,G_UNARY,G_UNARY, //10              G_UNARY,G_UNARY,G_UNARY, //10
142              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 133  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENT Line 145  ES_opgroup opgroups[]={G_UNKNOWN,G_IDENT
145              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY, G_UNARY_P, G_UNARY_P,      // 35              G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY, G_UNARY_P, G_UNARY_P,      // 35
146              G_NP1OUT,G_NP1OUT,              G_NP1OUT,G_NP1OUT,
147              G_TENSORPROD,              G_TENSORPROD,
148              G_NP1OUT_P, G_NP1OUT_P};              G_NP1OUT_P, G_NP1OUT_P,
149                G_NP1OUT_2P};
150  inline  inline
151  ES_opgroup  ES_opgroup
152  getOpgroup(ES_optype op)  getOpgroup(ES_optype op)
# Line 194  resultShape(DataAbstract_ptr left, DataA Line 207  resultShape(DataAbstract_ptr left, DataA
207  // return the shape for "op left"  // return the shape for "op left"
208    
209  DataTypes::ShapeType  DataTypes::ShapeType
210  resultShape(DataAbstract_ptr left, ES_optype op)  resultShape(DataAbstract_ptr left, ES_optype op, int axis_offset)
211  {  {
212      switch(op)      switch(op)
213      {      {
214          case TRANS:          case TRANS:
215          return left->getShape();         {            // for the scoping of variables
216            const DataTypes::ShapeType& s=left->getShape();
217            DataTypes::ShapeType sh;
218            int rank=left->getRank();
219            if (axis_offset<0 || axis_offset>rank)
220            {
221                   throw DataException("Error - Data::transpose must have 0 <= axis_offset <= rank=" + rank);
222                }
223                for (int i=0; i<rank; i++)
224            {
225               int index = (axis_offset+i)%rank;
226                   sh.push_back(s[index]); // Append to new shape
227                }
228            return sh;
229           }
230      break;      break;
231      case TRACE:      case TRACE:
232          return DataTypes::scalarShape;         {
233            int rank=left->getRank();
234            if (rank<2)
235            {
236               throw DataException("Trace can only be computed for objects with rank 2 or greater.");
237            }
238            if ((axis_offset>rank-2) || (axis_offset<0))
239            {
240               throw DataException("Trace: axis offset must lie between 0 and rank-2 inclusive.");
241            }
242            if (rank==2)
243            {
244               return DataTypes::scalarShape;
245            }
246            else if (rank==3)
247            {
248               DataTypes::ShapeType sh;
249                   if (axis_offset==0)
250               {
251                    sh.push_back(left->getShape()[2]);
252                   }
253                   else     // offset==1
254               {
255                sh.push_back(left->getShape()[0]);
256                   }
257               return sh;
258            }
259            else if (rank==4)
260            {
261               DataTypes::ShapeType sh;
262               const DataTypes::ShapeType& s=left->getShape();
263                   if (axis_offset==0)
264               {
265                    sh.push_back(s[2]);
266                    sh.push_back(s[3]);
267                   }
268                   else if (axis_offset==1)
269               {
270                    sh.push_back(s[0]);
271                    sh.push_back(s[3]);
272                   }
273               else     // offset==2
274               {
275                sh.push_back(s[0]);
276                sh.push_back(s[1]);
277               }
278               return sh;
279            }
280            else        // unknown rank
281            {
282               throw DataException("Error - Data::trace can only be calculated for rank 2, 3 or 4 object.");
283            }
284           }
285      break;      break;
286          default:          default:
287      throw DataException("Programmer error - resultShape(left,op) can't compute shapes for operator "+opToString(op)+".");      throw DataException("Programmer error - resultShape(left,op) can't compute shapes for operator "+opToString(op)+".");
288      }      }
289  }  }
290    
291    DataTypes::ShapeType
292    SwapShape(DataAbstract_ptr left, const int axis0, const int axis1)
293    {
294         // This code taken from the Data.cpp swapaxes() method
295         // Some of the checks are probably redundant here
296         int axis0_tmp,axis1_tmp;
297         const DataTypes::ShapeType& s=left->getShape();
298         DataTypes::ShapeType out_shape;
299         // Here's the equivalent of python s_out=s[axis_offset:]+s[:axis_offset]
300         // which goes thru all shape vector elements starting with axis_offset (at index=rank wrap around to 0)
301         int rank=left->getRank();
302         if (rank<2) {
303            throw DataException("Error - Data::swapaxes argument must have at least rank 2.");
304         }
305         if (axis0<0 || axis0>rank-1) {
306            throw DataException("Error - Data::swapaxes: axis0 must be between 0 and rank-1=" + rank-1);
307         }
308         if (axis1<0 || axis1>rank-1) {
309             throw DataException("Error - Data::swapaxes: axis1 must be between 0 and rank-1=" + rank-1);
310         }
311         if (axis0 == axis1) {
312             throw DataException("Error - Data::swapaxes: axis indices must be different.");
313         }
314         if (axis0 > axis1) {
315             axis0_tmp=axis1;
316             axis1_tmp=axis0;
317         } else {
318             axis0_tmp=axis0;
319             axis1_tmp=axis1;
320         }
321         for (int i=0; i<rank; i++) {
322           if (i == axis0_tmp) {
323              out_shape.push_back(s[axis1_tmp]);
324           } else if (i == axis1_tmp) {
325              out_shape.push_back(s[axis0_tmp]);
326           } else {
327              out_shape.push_back(s[i]);
328           }
329         }
330        return out_shape;
331    }
332    
333    
334  // determine the output shape for the general tensor product operation  // determine the output shape for the general tensor product operation
335  // the additional parameters return information required later for the product  // the additional parameters return information required later for the product
336  // 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 273  GTPShape(DataAbstract_ptr left, DataAbst Line 395  GTPShape(DataAbstract_ptr left, DataAbst
395    return shape2;    return shape2;
396  }  }
397    
   
 // determine the number of points in the result of "left op right"  
 // note that determining the resultLength for G_TENSORPROD is more complex and will not be processed here  
 // size_t  
 // resultLength(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)  
 // {  
 //    switch (getOpgroup(op))  
 //    {  
 //    case G_BINARY: return left->getLength();  
 //    case G_UNARY: return left->getLength();  
 //    case G_NP1OUT: return left->getLength();  
 //    default:  
 //  throw DataException("Programmer Error - attempt to getLength() for operator "+opToString(op)+".");  
 //    }  
 // }  
   
398  // determine the number of samples requires to evaluate an expression combining left and right  // determine the number of samples requires to evaluate an expression combining left and right
399  // NP1OUT needs an extra buffer because we can't write the answers over the top of the input.  // NP1OUT needs an extra buffer because we can't write the answers over the top of the input.
400  // The same goes for G_TENSORPROD  // The same goes for G_TENSORPROD
401  // It might seem that pointwise binary ops (G_BINARY) could be written over the top of the lefths.  // It might seem that pointwise binary ops (G_BINARY) could be written over the top of the lefts.
402  // This would be true were it not for the possibility that the LHS could be a scalar which needs to be examined  // This would be true were it not for the possibility that the LHS could be a scalar which needs to be examined
403  // multiple times  // multiple times
404  int  int
# Line 307  calcBuffs(const DataLazy_ptr& left, cons Line 413  calcBuffs(const DataLazy_ptr& left, cons
413     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);     case G_NP1OUT: return 1+max(left->getBuffsRequired(),1);
414     case G_NP1OUT_P: return 1+max(left->getBuffsRequired(),1);     case G_NP1OUT_P: return 1+max(left->getBuffsRequired(),1);
415     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);     case G_TENSORPROD: return 1+max(left->getBuffsRequired(),right->getBuffsRequired()+1);
416       case G_NP1OUT_2P: return 1+max(left->getBuffsRequired(),1);
417     default:     default:
418      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");
419     }     }
# Line 330  opToString(ES_optype op) Line 437  opToString(ES_optype op)
437    
438    
439  DataLazy::DataLazy(DataAbstract_ptr p)  DataLazy::DataLazy(DataAbstract_ptr p)
440      : parent(p->getFunctionSpace(),p->getShape()),      : parent(p->getFunctionSpace(),p->getShape())
     m_op(IDENTITY),  
     m_axis_offset(0),  
     m_transpose(0),  
     m_SL(0), m_SM(0), m_SR(0)  
441  {  {
442     if (p->isLazy())     if (p->isLazy())
443     {     {
# Line 345  DataLazy::DataLazy(DataAbstract_ptr p) Line 448  DataLazy::DataLazy(DataAbstract_ptr p)
448     }     }
449     else     else
450     {     {
451      m_id=dynamic_pointer_cast<DataReady>(p);      p->makeLazyShared();
452      if(p->isConstant()) {m_readytype='C';}      DataReady_ptr dr=dynamic_pointer_cast<DataReady>(p);
453      else if(p->isExpanded()) {m_readytype='E';}      makeIdentity(dr);
454      else if (p->isTagged()) {m_readytype='T';}  LAZYDEBUG(cout << "Wrapping " << dr.get() << " id=" << m_id.get() << endl;)
     else {throw DataException("Unknown DataReady instance in DataLazy constructor.");}  
455     }     }
    m_buffsRequired=1;  
    m_samplesize=getNumDPPSample()*getNoValues();  
    m_maxsamplesize=m_samplesize;  
456  LAZYDEBUG(cout << "(1)Lazy created with " << m_samplesize << endl;)  LAZYDEBUG(cout << "(1)Lazy created with " << m_samplesize << endl;)
457  }  }
458    
# Line 386  DataLazy::DataLazy(DataAbstract_ptr left Line 485  DataLazy::DataLazy(DataAbstract_ptr left
485     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
486     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
487     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
488       m_children=m_left->m_children+1;
489       m_height=m_left->m_height+1;
490       SIZELIMIT
491  }  }
492    
493    
# Line 395  DataLazy::DataLazy(DataAbstract_ptr left Line 497  DataLazy::DataLazy(DataAbstract_ptr left
497      m_op(op),      m_op(op),
498      m_SL(0), m_SM(0), m_SR(0)      m_SL(0), m_SM(0), m_SR(0)
499  {  {
500    LAZYDEBUG(cout << "Forming operator with " << left.get() << " " << right.get() << endl;)
501     if ((getOpgroup(op)!=G_BINARY))     if ((getOpgroup(op)!=G_BINARY))
502     {     {
503      throw DataException("Programmer error - constructor DataLazy(left, right, op) will only process BINARY operations.");      throw DataException("Programmer error - constructor DataLazy(left, right, op) will only process BINARY operations.");
# Line 411  DataLazy::DataLazy(DataAbstract_ptr left Line 514  DataLazy::DataLazy(DataAbstract_ptr left
514     {     {
515      Data tmp(Data(right),getFunctionSpace());      Data tmp(Data(right),getFunctionSpace());
516      right=tmp.borrowDataPtr();      right=tmp.borrowDataPtr();
517    LAZYDEBUG(cout << "Right interpolation required " << right.get() << endl;)
518     }     }
519     left->operandCheck(*right);     left->operandCheck(*right);
520    
521     if (left->isLazy())          // the children need to be DataLazy. Wrap them in IDENTITY if required     if (left->isLazy())          // the children need to be DataLazy. Wrap them in IDENTITY if required
522     {     {
523      m_left=dynamic_pointer_cast<DataLazy>(left);      m_left=dynamic_pointer_cast<DataLazy>(left);
524    LAZYDEBUG(cout << "Left is " << m_left->toString() << endl;)
525     }     }
526     else     else
527     {     {
528      m_left=DataLazy_ptr(new DataLazy(left));      m_left=DataLazy_ptr(new DataLazy(left));
529    LAZYDEBUG(cout << "Left " << left.get() << " wrapped " << m_left->m_id.get() << endl;)
530     }     }
531     if (right->isLazy())     if (right->isLazy())
532     {     {
533      m_right=dynamic_pointer_cast<DataLazy>(right);      m_right=dynamic_pointer_cast<DataLazy>(right);
534    LAZYDEBUG(cout << "Right is " << m_right->toString() << endl;)
535     }     }
536     else     else
537     {     {
538      m_right=DataLazy_ptr(new DataLazy(right));      m_right=DataLazy_ptr(new DataLazy(right));
539    LAZYDEBUG(cout << "Right " << right.get() << " wrapped " << m_right->m_id.get() << endl;)
540     }     }
541     char lt=m_left->m_readytype;     char lt=m_left->m_readytype;
542     char rt=m_right->m_readytype;     char rt=m_right->m_readytype;
# Line 447  DataLazy::DataLazy(DataAbstract_ptr left Line 555  DataLazy::DataLazy(DataAbstract_ptr left
555     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
556     m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());       m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());  
557     m_buffsRequired=calcBuffs(m_left, m_right,m_op);     m_buffsRequired=calcBuffs(m_left, m_right,m_op);
558       m_children=m_left->m_children+m_right->m_children+2;
559       m_height=max(m_left->m_height,m_right->m_height)+1;
560       SIZELIMIT
561  LAZYDEBUG(cout << "(3)Lazy created with " << m_samplesize << endl;)  LAZYDEBUG(cout << "(3)Lazy created with " << m_samplesize << endl;)
562  }  }
563    
# Line 476  DataLazy::DataLazy(DataAbstract_ptr left Line 587  DataLazy::DataLazy(DataAbstract_ptr left
587      Data tmp(Data(right),getFunctionSpace());      Data tmp(Data(right),getFunctionSpace());
588      right=tmp.borrowDataPtr();      right=tmp.borrowDataPtr();
589     }     }
590     left->operandCheck(*right);  //    left->operandCheck(*right);
591    
592     if (left->isLazy())          // the children need to be DataLazy. Wrap them in IDENTITY if required     if (left->isLazy())          // the children need to be DataLazy. Wrap them in IDENTITY if required
593     {     {
# Line 511  DataLazy::DataLazy(DataAbstract_ptr left Line 622  DataLazy::DataLazy(DataAbstract_ptr left
622     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
623     m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());       m_maxsamplesize=max(max(m_samplesize,m_right->getMaxSampleSize()),m_left->getMaxSampleSize());  
624     m_buffsRequired=calcBuffs(m_left, m_right,m_op);     m_buffsRequired=calcBuffs(m_left, m_right,m_op);
625       m_children=m_left->m_children+m_right->m_children+2;
626       m_height=max(m_left->m_height,m_right->m_height)+1;
627       SIZELIMIT
628  LAZYDEBUG(cout << "(4)Lazy created with " << m_samplesize << endl;)  LAZYDEBUG(cout << "(4)Lazy created with " << m_samplesize << endl;)
629  }  }
630    
631    
632  DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op, int axis_offset)  DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op, int axis_offset)
633      : parent(left->getFunctionSpace(), resultShape(left,op)),      : parent(left->getFunctionSpace(), resultShape(left,op, axis_offset)),
634      m_op(op),      m_op(op),
635      m_axis_offset(axis_offset),      m_axis_offset(axis_offset),
636      m_transpose(0),      m_transpose(0),
# Line 540  DataLazy::DataLazy(DataAbstract_ptr left Line 654  DataLazy::DataLazy(DataAbstract_ptr left
654     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
655     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
656     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
657       m_children=m_left->m_children+1;
658       m_height=m_left->m_height+1;
659       SIZELIMIT
660  LAZYDEBUG(cout << "(5)Lazy created with " << m_samplesize << endl;)  LAZYDEBUG(cout << "(5)Lazy created with " << m_samplesize << endl;)
661  }  }
662    
# Line 568  DataLazy::DataLazy(DataAbstract_ptr left Line 685  DataLazy::DataLazy(DataAbstract_ptr left
685     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
686     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
687     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());     m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
688       m_children=m_left->m_children+1;
689       m_height=m_left->m_height+1;
690       SIZELIMIT
691  LAZYDEBUG(cout << "(6)Lazy created with " << m_samplesize << endl;)  LAZYDEBUG(cout << "(6)Lazy created with " << m_samplesize << endl;)
692  }  }
693    
694    
695    DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op, const int axis0, const int axis1)
696        : parent(left->getFunctionSpace(), SwapShape(left,axis0,axis1)),
697        m_op(op),
698        m_axis_offset(axis0),
699        m_transpose(axis1),
700        m_tol(0)
701    {
702       if ((getOpgroup(op)!=G_NP1OUT_2P))
703       {
704        throw DataException("Programmer error - constructor DataLazy(left, op, tol) will only process UNARY operations which require two integer parameters.");
705       }
706       DataLazy_ptr lleft;
707       if (!left->isLazy())
708       {
709        lleft=DataLazy_ptr(new DataLazy(left));
710       }
711       else
712       {
713        lleft=dynamic_pointer_cast<DataLazy>(left);
714       }
715       m_readytype=lleft->m_readytype;
716       m_left=lleft;
717       m_buffsRequired=calcBuffs(m_left, m_right,m_op); // yeah m_right will be null at this point
718       m_samplesize=getNumDPPSample()*getNoValues();
719       m_maxsamplesize=max(m_samplesize,m_left->getMaxSampleSize());
720       m_children=m_left->m_children+1;
721       m_height=m_left->m_height+1;
722       SIZELIMIT
723    LAZYDEBUG(cout << "(7)Lazy created with " << m_samplesize << endl;)
724    }
725    
726  DataLazy::~DataLazy()  DataLazy::~DataLazy()
727  {  {
728  }  }
# Line 589  DataLazy::getMaxSampleSize() const Line 741  DataLazy::getMaxSampleSize() const
741      return m_maxsamplesize;      return m_maxsamplesize;
742  }  }
743    
744    
745    
746    size_t
747    DataLazy::getSampleBufferSize() const
748    {
749        return m_maxsamplesize*(max(1,m_buffsRequired));
750    }
751    
752  /*  /*
753    \brief Evaluates the expression using methods on Data.    \brief Evaluates the expression using methods on Data.
754    This does the work for the collapse method.    This does the work for the collapse method.
# Line 728  DataLazy::collapseToReady() Line 888  DataLazy::collapseToReady()
888      case TRACE:      case TRACE:
889      result=left.trace(m_axis_offset);      result=left.trace(m_axis_offset);
890      break;      break;
891        case SWAP:
892        result=left.swapaxes(m_axis_offset, m_transpose);
893        break;
894      default:      default:
895      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)+".");
896    }    }
# Line 977  DataLazy::resolveNP1OUT_P(ValueType& v, Line 1140  DataLazy::resolveNP1OUT_P(ValueType& v,
1140      // since we can't write the result over the input, we need a result offset further along      // since we can't write the result over the input, we need a result offset further along
1141    size_t subroffset;    size_t subroffset;
1142    const ValueType* vleft=m_left->resolveSample(v,offset+m_left->m_samplesize,sampleNo,subroffset);    const ValueType* vleft=m_left->resolveSample(v,offset+m_left->m_samplesize,sampleNo,subroffset);
1143  LAZYDEBUG(cerr << "from=" << offset+m_left->m_samplesize << " to=" << subroffset << " ret=" << roffset << endl;)  LAZYDEBUG(cerr << "srcsamplesize=" << offset+m_left->m_samplesize << " beg=" << subroffset << endl;)
1144    LAZYDEBUG(cerr << "Offset for 5800=" << getPointOffset(5800/getNumDPPSample(),5800%getNumDPPSample()) << endl;)
1145    roffset=offset;    roffset=offset;
1146    size_t loop=0;    size_t loop=0;
1147    size_t numsteps=(m_readytype=='E')?getNumDPPSample():1;    size_t numsteps=(m_readytype=='E')?getNumDPPSample():1;
1148    size_t step=getNoValues();    size_t outstep=getNoValues();
1149      size_t instep=m_left->getNoValues();
1150    LAZYDEBUG(cerr << "instep=" << instep << " outstep=" << outstep<< " numsteps=" << numsteps << endl;)
1151    switch (m_op)    switch (m_op)
1152    {    {
1153      case TRACE:      case TRACE:
1154      for (loop=0;loop<numsteps;++loop)      for (loop=0;loop<numsteps;++loop)
1155      {      {
1156              DataMaths::trace(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset);  size_t zz=sampleNo*getNumDPPSample()+loop;
1157          subroffset+=step;  if (zz==5800)
1158          offset+=step;  {
1159    LAZYDEBUG(cerr << "point=" <<  zz<< endl;)
1160    LAZYDEBUG(cerr << "Input to  trace=" << DataTypes::pointToString(*vleft,m_left->getShape(),subroffset,"") << endl;)
1161    LAZYDEBUG(cerr << "Offset for point=" << getPointOffset(5800/getNumDPPSample(),5800%getNumDPPSample()) << " vs ";)
1162    LAZYDEBUG(cerr << subroffset << endl;)
1163    LAZYDEBUG(cerr << "output=" << offset << endl;)
1164    }
1165                DataMaths::trace(*vleft,m_left->getShape(),subroffset, v ,getShape(),offset,m_axis_offset);
1166    if (zz==5800)
1167    {
1168    LAZYDEBUG(cerr << "Result of trace=" << DataTypes::pointToString(v,getShape(),offset,"") << endl;)
1169    }
1170            subroffset+=instep;
1171            offset+=outstep;
1172      }      }
1173      break;      break;
1174      case TRANS:      case TRANS:
1175      for (loop=0;loop<numsteps;++loop)      for (loop=0;loop<numsteps;++loop)
1176      {      {
1177              DataMaths::transpose(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset);              DataMaths::transpose(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset);
1178          subroffset+=step;          subroffset+=instep;
1179          offset+=step;          offset+=outstep;
1180      }      }
1181      break;      break;
1182      default:      default:
# Line 1007  LAZYDEBUG(cerr << "from=" << offset+m_le Line 1186  LAZYDEBUG(cerr << "from=" << offset+m_le
1186  }  }
1187    
1188    
1189    /*
1190      \brief Compute the value of the expression (unary operation with int params) for the given sample.
1191      \return Vector which stores the value of the subexpression for the given sample.
1192      \param v A vector to store intermediate results.
1193      \param offset Index in v to begin storing results.
1194      \param sampleNo Sample number to evaluate.
1195      \param roffset (output parameter) the offset in the return vector where the result begins.
1196    
1197      The return value will be an existing vector so do not deallocate it.
1198      If the result is stored in v it should be stored at the offset given.
1199      Everything from offset to the end of v should be considered available for this method to use.
1200    */
1201    DataTypes::ValueType*
1202    DataLazy::resolveNP1OUT_2P(ValueType& v, size_t offset, int sampleNo, size_t& roffset) const
1203    {
1204        // we assume that any collapsing has been done before we get here
1205        // since we only have one argument we don't need to think about only
1206        // processing single points.
1207      if (m_readytype!='E')
1208      {
1209        throw DataException("Programmer error - resolveNP1OUT_2P should only be called on expanded Data.");
1210      }
1211        // since we can't write the result over the input, we need a result offset further along
1212      size_t subroffset;
1213      const ValueType* vleft=m_left->resolveSample(v,offset+m_left->m_samplesize,sampleNo,subroffset);
1214    LAZYDEBUG(cerr << "srcsamplesize=" << offset+m_left->m_samplesize << " beg=" << subroffset << endl;)
1215    LAZYDEBUG(cerr << "Offset for 5800=" << getPointOffset(5800/getNumDPPSample(),5800%getNumDPPSample()) << endl;)
1216      roffset=offset;
1217      size_t loop=0;
1218      size_t numsteps=(m_readytype=='E')?getNumDPPSample():1;
1219      size_t outstep=getNoValues();
1220      size_t instep=m_left->getNoValues();
1221    LAZYDEBUG(cerr << "instep=" << instep << " outstep=" << outstep<< " numsteps=" << numsteps << endl;)
1222      switch (m_op)
1223      {
1224        case SWAP:
1225        for (loop=0;loop<numsteps;++loop)
1226        {
1227                DataMaths::swapaxes(*vleft,m_left->getShape(),subroffset, v,getShape(),offset,m_axis_offset, m_transpose);
1228            subroffset+=instep;
1229            offset+=outstep;
1230        }
1231        break;
1232        default:
1233        throw DataException("Programmer error - resolveNP1OUT2P can not resolve operator "+opToString(m_op)+".");
1234      }
1235      return &v;
1236    }
1237    
1238    
1239    
1240  #define PROC_OP(TYPE,X)                               \  #define PROC_OP(TYPE,X)                               \
1241      for (int j=0;j<onumsteps;++j)\      for (int j=0;j<onumsteps;++j)\
1242      {\      {\
# Line 1105  LAZYDEBUG(cout << "Resolve binary: " << Line 1335  LAZYDEBUG(cout << "Resolve binary: " <<
1335             leftstep=0;             leftstep=0;
1336             oleftstep=1;             oleftstep=1;
1337             rightstep=1;             rightstep=1;
1338             orightstep=(RN?-rightsize:0);             orightstep=(RN ? -(int)rightsize : 0);
1339             numsteps=rightsize;             numsteps=rightsize;
1340             onumsteps=m_left->getNumDPPSample();             onumsteps=m_left->getNumDPPSample();
1341          }          }
# Line 1123  LAZYDEBUG(cout << "Resolve binary: " << Line 1353  LAZYDEBUG(cout << "Resolve binary: " <<
1353             rightstep=0;             rightstep=0;
1354             orightstep=1;             orightstep=1;
1355             leftstep=1;             leftstep=1;
1356             oleftstep=(LN?-leftsize:0);             oleftstep=(LN ? -(int)leftsize : 0);
1357             numsteps=leftsize;             numsteps=leftsize;
1358             onumsteps=m_right->getNumDPPSample();             onumsteps=m_right->getNumDPPSample();
1359          }          }
# Line 1168  LAZYDEBUG(cout << " numsteps=" << numste Line 1398  LAZYDEBUG(cout << " numsteps=" << numste
1398  LAZYDEBUG(cout << "onumsteps=" << onumsteps << endl;)  LAZYDEBUG(cout << "onumsteps=" << onumsteps << endl;)
1399  LAZYDEBUG(cout << " DPPS=" << m_left->getNumDPPSample() << "," <<m_right->getNumDPPSample() << endl;)  LAZYDEBUG(cout << " DPPS=" << m_left->getNumDPPSample() << "," <<m_right->getNumDPPSample() << endl;)
1400  LAZYDEBUG(cout << "" << LS << RS << LN << RN << LES << RES <<LEN << REN <<   endl;)  LAZYDEBUG(cout << "" << LS << RS << LN << RN << LES << RES <<LEN << REN <<   endl;)
1401    
1402    
1403    double* resultp=&(v[offset]);     // results are stored at the vector offset we recieved    double* resultp=&(v[offset]);     // results are stored at the vector offset we recieved
1404    switch(m_op)    switch(m_op)
1405    {    {
# Line 1189  LAZYDEBUG(cout << "" << LS << RS << LN < Line 1421  LAZYDEBUG(cout << "" << LS << RS << LN <
1421      default:      default:
1422      throw DataException("Programmer error - resolveBinary can not resolve operator "+opToString(m_op)+".");      throw DataException("Programmer error - resolveBinary can not resolve operator "+opToString(m_op)+".");
1423    }    }
1424    roffset=offset;      roffset=offset;
1425    return &v;    return &v;
1426  }  }
1427    
# Line 1213  LAZYDEBUG(cout << "" << LS << RS << LN < Line 1445  LAZYDEBUG(cout << "" << LS << RS << LN <
1445  DataTypes::ValueType*  DataTypes::ValueType*
1446  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
1447  {  {
1448  LAZYDEBUG(cout << "Resolve TensorProduct: " << toString() << endl;)  LAZYDEBUG(cout << "Resolve TensorProduct: " << toString()  << " to offset " << offset<< endl;)
1449    
1450    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
1451      // first work out which of the children are expanded      // first work out which of the children are expanded
1452    bool leftExp=(m_left->m_readytype=='E');    bool leftExp=(m_left->m_readytype=='E');
1453    bool rightExp=(m_right->m_readytype=='E');    bool rightExp=(m_right->m_readytype=='E');
1454    int steps=getNumDPPSample();    int steps=getNumDPPSample();
1455    int leftStep=((leftExp && !rightExp)? m_right->getNoValues() : 0);  /*  int leftStep=((leftExp && !rightExp)? m_right->getNoValues() : 0);
1456    int rightStep=((rightExp && !leftExp)? m_left->getNoValues() : 0);    int rightStep=((rightExp && !leftExp)? m_left->getNoValues() : 0);*/
1457    int resultStep=max(leftStep,rightStep);   // only one (at most) should be !=0    int leftStep=(leftExp? m_left->getNoValues() : 0);        // do not have scalars as input to this method
1458      int rightStep=(rightExp?m_right->getNoValues() : 0);
1459    
1460      int resultStep=getNoValues();
1461      // Get the values of sub-expressions (leave a gap of one sample for the result).      // Get the values of sub-expressions (leave a gap of one sample for the result).
1462    int gap=offset+m_left->getMaxSampleSize();    // actually only needs to be m_left->m_samplesize    int gap=offset+m_samplesize;  
1463    
1464    LAZYDEBUG(cout << "Query left with offset=" << gap << endl;)
1465    
1466    const ValueType* left=m_left->resolveSample(v,gap,sampleNo,lroffset);    const ValueType* left=m_left->resolveSample(v,gap,sampleNo,lroffset);
1467    gap+=m_right->getMaxSampleSize();    gap+=m_left->getMaxSampleSize();
1468    const ValueType* right=m_right->resolveSample(v,gap,sampleNo,rroffset);  
1469  LAZYDEBUG(cout << "Post sub calls: " << toString() << endl;)  
1470    LAZYDEBUG(cout << "Query right with offset=" << gap << endl;)
1471    
1472    
1473      const ValueType* right=m_right->resolveSample(v,gap,sampleNo,rroffset);
1474    
1475    LAZYDEBUG(cerr << "[Left shape]=" << DataTypes::shapeToString(m_left->getShape()) << "\n[Right shape]=" << DataTypes::shapeToString(m_right->getShape()) << " result=" <<DataTypes::shapeToString(getShape()) <<  endl;
1476    cout << getNoValues() << endl;)
1477    LAZYDEBUG(cerr << "Result of left=";)
1478    LAZYDEBUG(cerr << "[" << lroffset << " .. " << lroffset+m_left->getNoValues() << "]" << endl;
1479    
1480    for (int i=lroffset, limit=lroffset+(leftExp?m_left->getNoValues()*m_left->getNumDPPSample():m_left->getNoValues());i<limit;++i)
1481    {
1482    cout << "[" << setw(2) << i-lroffset << "] " << setw(10) << (*left)[i] << " ";
1483    if (i%4==0) cout << endl;
1484    })
1485    LAZYDEBUG(cerr << "\nResult of right=" << endl;)
1486    LAZYDEBUG(
1487    for (int i=rroffset, limit=rroffset+(rightExp?m_right->getNoValues()*m_right->getNumDPPSample():m_right->getNoValues());i<limit;++i)
1488    {
1489    cerr << "[" <<  setw(2)<< i-rroffset << "] " << setw(10) << (*right)[i] << " ";
1490    if (i%4==0) cout << endl;
1491    }
1492    cerr << endl;
1493    )
1494    LAZYDEBUG(cerr << "Post sub calls: " << toString() << endl;)
1495  LAZYDEBUG(cout << "LeftExp=" << leftExp << " rightExp=" << rightExp << endl;)  LAZYDEBUG(cout << "LeftExp=" << leftExp << " rightExp=" << rightExp << endl;)
1496  LAZYDEBUG(cout << "LeftR=" << m_left->getRank() << " rightExp=" << m_right->getRank() << endl;)  LAZYDEBUG(cout << "LeftR=" << m_left->getRank() << " rightExp=" << m_right->getRank() << endl;)
1497  LAZYDEBUG(cout << "LeftSize=" << m_left->getNoValues() << " RightSize=" << m_right->getNoValues() << endl;)  LAZYDEBUG(cout << "LeftSize=" << m_left->getNoValues() << " RightSize=" << m_right->getNoValues() << endl;)
1498  LAZYDEBUG(cout << "m_samplesize=" << m_samplesize << endl;)  LAZYDEBUG(cout << "m_samplesize=" << m_samplesize << endl;)
1499  LAZYDEBUG(cout << "outputshape=" << DataTypes::shapeToString(getShape()) << endl;)  LAZYDEBUG(cout << "outputshape=" << DataTypes::shapeToString(getShape()) << endl;)
1500    LAZYDEBUG(cout << "DPPS=" << m_right->getNumDPPSample() <<"."<<endl;)
1501    
1502    double* resultp=&(v[offset]);     // results are stored at the vector offset we recieved    double* resultp=&(v[offset]);     // results are stored at the vector offset we recieved
1503    switch(m_op)    switch(m_op)
1504    {    {
1505      case PROD:      case PROD:
1506      for (int i=0;i<steps;++i,resultp+=resultStep)      for (int i=0;i<steps;++i,resultp+=resultStep)
1507      {      {
1508    
1509  LAZYDEBUG(cout << "lroffset=" << lroffset << "rroffset=" << rroffset << endl;)  LAZYDEBUG(cout << "lroffset=" << lroffset << "rroffset=" << rroffset << endl;)
1510  LAZYDEBUG(cout << "l*=" << left << " r*=" << right << endl;)  LAZYDEBUG(cout << "l*=" << left << " r*=" << right << endl;)
1511  LAZYDEBUG(cout << "m_SL=" << m_SL << " m_SM=" << m_SM << " m_SR=" << m_SR << endl;)  LAZYDEBUG(cout << "m_SL=" << m_SL << " m_SM=" << m_SM << " m_SR=" << m_SR << endl;)
1512    
1513            const double *ptr_0 = &((*left)[lroffset]);            const double *ptr_0 = &((*left)[lroffset]);
1514            const double *ptr_1 = &((*right)[rroffset]);            const double *ptr_1 = &((*right)[rroffset]);
1515    
1516  LAZYDEBUG(cout << DataTypes::pointToString(*left, m_left->getShape(),lroffset,"LEFT") << endl;)  LAZYDEBUG(cout << DataTypes::pointToString(*left, m_left->getShape(),lroffset,"LEFT") << endl;)
1517  LAZYDEBUG(cout << DataTypes::pointToString(*right,m_right->getShape(),rroffset, "RIGHT") << endl;)  LAZYDEBUG(cout << DataTypes::pointToString(*right,m_right->getShape(),rroffset, "RIGHT") << endl;)
1518    
1519            matrix_matrix_product(m_SL, m_SM, m_SR, ptr_0, ptr_1, resultp, m_transpose);            matrix_matrix_product(m_SL, m_SM, m_SR, ptr_0, ptr_1, resultp, m_transpose);
1520    
1521    LAZYDEBUG(cout << "Results--\n";
1522    {
1523      DataVector dv(getNoValues());
1524    for (int z=0;z<getNoValues();++z)
1525    {
1526      cout << "[" << setw(2) << z<< "] " << setw(10) << resultp[z] << " ";
1527      if (z%4==0) cout << endl;
1528      dv[z]=resultp[z];
1529    }
1530    cout << endl << DataTypes::pointToString(dv,getShape(),0,"RESLT");
1531    cout << "\nWritten to: " << resultp << " resultStep=" << resultStep << endl;
1532    }
1533    )
1534        lroffset+=leftStep;        lroffset+=leftStep;
1535        rroffset+=rightStep;        rroffset+=rightStep;
1536      }      }
# Line 1288  LAZYDEBUG(cout << "Resolve sample " << t Line 1571  LAZYDEBUG(cout << "Resolve sample " << t
1571    }    }
1572    if (m_op==IDENTITY)      if (m_op==IDENTITY)  
1573    {    {
1574      const ValueType& vec=m_id->getVector();      const ValueType& vec=m_id->getVectorRO();
1575      if (m_readytype=='C')      if (m_readytype=='C')
1576      {      {
1577      roffset=0;      roffset=0;
# Line 1311  LAZYDEBUG(cout << "Finish  sample " << t Line 1594  LAZYDEBUG(cout << "Finish  sample " << t
1594    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);    case G_NP1OUT: return resolveNP1OUT(v, offset, sampleNo,roffset);
1595    case G_NP1OUT_P: return resolveNP1OUT_P(v, offset, sampleNo,roffset);    case G_NP1OUT_P: return resolveNP1OUT_P(v, offset, sampleNo,roffset);
1596    case G_TENSORPROD: return resolveTProd(v,offset, sampleNo,roffset);    case G_TENSORPROD: return resolveTProd(v,offset, sampleNo,roffset);
1597      case G_NP1OUT_2P: return resolveNP1OUT_2P(v, offset, sampleNo, roffset);
1598    default:    default:
1599      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)+".");
1600    }    }
1601    
1602  }  }
1603    
1604    const DataTypes::ValueType*
1605    DataLazy::resolveSample(BufferGroup& bg, int sampleNo, size_t& roffset)
1606    {
1607    #ifdef _OPENMP
1608        int tid=omp_get_thread_num();
1609    #else
1610        int tid=0;
1611    #endif
1612        return resolveSample(bg.getBuffer(tid),bg.getOffset(tid),sampleNo,roffset);
1613    }
1614    
1615    
1616    // This needs to do the work of the identity constructor
1617    void
1618    DataLazy::resolveToIdentity()
1619    {
1620       if (m_op==IDENTITY)
1621        return;
1622       DataReady_ptr p=resolveVectorWorker();
1623       makeIdentity(p);
1624    }
1625    
1626    void DataLazy::makeIdentity(const DataReady_ptr& p)
1627    {
1628       m_op=IDENTITY;
1629       m_axis_offset=0;
1630       m_transpose=0;
1631       m_SL=m_SM=m_SR=0;
1632       m_children=m_height=0;
1633       m_id=p;
1634       if(p->isConstant()) {m_readytype='C';}
1635       else if(p->isExpanded()) {m_readytype='E';}
1636       else if (p->isTagged()) {m_readytype='T';}
1637       else {throw DataException("Unknown DataReady instance in convertToIdentity constructor.");}
1638       m_buffsRequired=1;
1639       m_samplesize=p->getNumDPPSample()*p->getNoValues();
1640       m_maxsamplesize=m_samplesize;
1641       m_left.reset();
1642       m_right.reset();
1643    }
1644    
1645    
1646    DataReady_ptr
1647    DataLazy::resolve()
1648    {
1649        resolveToIdentity();
1650        return m_id;
1651    }
1652    
1653  // To simplify the memory management, all threads operate on one large vector, rather than one each.  // To simplify the memory management, all threads operate on one large vector, rather than one each.
1654  // Each sample is evaluated independently and copied into the result DataExpanded.  // Each sample is evaluated independently and copied into the result DataExpanded.
1655  DataReady_ptr  DataReady_ptr
1656  DataLazy::resolve()  DataLazy::resolveVectorWorker()
1657  {  {
1658    
1659  LAZYDEBUG(cout << "Sample size=" << m_samplesize << endl;)  LAZYDEBUG(cout << "Sample size=" << m_samplesize << endl;)
1660  LAZYDEBUG(cout << "Buffers=" << m_buffsRequired << endl;)  LAZYDEBUG(cout << "Buffers=" << m_buffsRequired << endl;)
   
1661    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
1662    {    {
1663      collapse();      collapse();
# Line 1340  LAZYDEBUG(cout << "Buffers=" << m_buffsR Line 1671  LAZYDEBUG(cout << "Buffers=" << m_buffsR
1671      // storage to evaluate its expression      // storage to evaluate its expression
1672    int numthreads=1;    int numthreads=1;
1673  #ifdef _OPENMP  #ifdef _OPENMP
1674    numthreads=getNumberOfThreads();    numthreads=omp_get_max_threads();
1675  #endif  #endif
1676    ValueType v(numthreads*threadbuffersize);    ValueType v(numthreads*threadbuffersize);
1677  LAZYDEBUG(cout << "Buffer created with size=" << v.size() << endl;)  LAZYDEBUG(cout << "Buffer created with size=" << v.size() << endl;)
1678    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),  ValueType(getNoValues()));    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),  ValueType(getNoValues()));
1679    ValueType& resvec=result->getVector();    ValueType& resvec=result->getVectorRW();
1680    DataReady_ptr resptr=DataReady_ptr(result);    DataReady_ptr resptr=DataReady_ptr(result);
1681    int sample;    int sample;
1682    size_t outoffset;     // offset in the output data    size_t outoffset;     // offset in the output data
# Line 1357  LAZYDEBUG(cout << "Total number of sampl Line 1688  LAZYDEBUG(cout << "Total number of sampl
1688    for (sample=0;sample<totalsamples;++sample)    for (sample=0;sample<totalsamples;++sample)
1689    {    {
1690        if (sample==0)  {ENABLEDEBUG}        if (sample==0)  {ENABLEDEBUG}
1691    
1692  LAZYDEBUG(cout << "################################# " << sample << endl;)  LAZYDEBUG(cout << "################################# " << sample << endl;)
1693  #ifdef _OPENMP  #ifdef _OPENMP
1694      res=resolveSample(v,threadbuffersize*omp_get_thread_num(),sample,resoffset);      res=resolveSample(v,threadbuffersize*omp_get_thread_num(),sample,resoffset);
# Line 1369  LAZYDEBUG(cerr<< "Copying sample#" << sa Line 1701  LAZYDEBUG(cerr<< "Copying sample#" << sa
1701  LAZYDEBUG(cerr << "offset=" << outoffset << " from offset=" << resoffset << " " << m_samplesize << " doubles" << endl;)  LAZYDEBUG(cerr << "offset=" << outoffset << " from offset=" << resoffset << " " << m_samplesize << " doubles" << endl;)
1702      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
1703      {      {
1704  // LAZYDEBUG(cerr << "outoffset=" << outoffset << " resoffset=" << resoffset << endl;)  LAZYDEBUG(cerr << "outoffset=" << outoffset << " resoffset=" << resoffset << " " << (*res)[resoffset]<< endl;)
1705      resvec[outoffset]=(*res)[resoffset];      resvec[outoffset]=(*res)[resoffset];
1706      }      }
1707  LAZYDEBUG(cerr << DataTypes::pointToString(resvec,getShape(),outoffset-m_samplesize+DataTypes::noValues(getShape()),"Final result:") << endl;)  LAZYDEBUG(cerr << DataTypes::pointToString(resvec,getShape(),outoffset-m_samplesize+DataTypes::noValues(getShape()),"Final result:") << endl;)
# Line 1392  DataLazy::toString() const Line 1724  DataLazy::toString() const
1724  void  void
1725  DataLazy::intoString(ostringstream& oss) const  DataLazy::intoString(ostringstream& oss) const
1726  {  {
1727    //    oss << "[" << m_children <<";"<<m_height <<"]";
1728    switch (getOpgroup(m_op))    switch (getOpgroup(m_op))
1729    {    {
1730    case G_IDENTITY:    case G_IDENTITY:
# Line 1435  DataLazy::intoString(ostringstream& oss) Line 1768  DataLazy::intoString(ostringstream& oss)
1768      m_right->intoString(oss);      m_right->intoString(oss);
1769      oss << ')';      oss << ')';
1770      break;      break;
1771      case G_NP1OUT_2P:
1772        oss << opToString(m_op) << '(';
1773        m_left->intoString(oss);
1774        oss << ", " << m_axis_offset << ", " << m_transpose;
1775        oss << ')';
1776        break;
1777    default:    default:
1778      oss << "UNKNOWN";      oss << "UNKNOWN";
1779    }    }
# Line 1531  DataLazy::getPointOffset(int sampleNo, Line 1870  DataLazy::getPointOffset(int sampleNo,
1870    throw DataException("Programmer error - getPointOffset on lazy data may require collapsing (but this object is marked const).");    throw DataException("Programmer error - getPointOffset on lazy data may require collapsing (but this object is marked const).");
1871  }  }
1872    
1873  // It would seem that DataTagged will need to be treated differently since even after setting all tags  
1874  // to zero, all the tags from all the DataTags would be in the result.  // I have decided to let Data:: handle this issue.
 // However since they all have the same value (0) whether they are there or not should not matter.  
 // So I have decided that for all types this method will create a constant 0.  
 // It can be promoted up as required.  
 // A possible efficiency concern might be expanded->constant->expanded which has an extra memory management  
 // but we can deal with that if it arrises.  
1875  void  void
1876  DataLazy::setToZero()  DataLazy::setToZero()
1877  {  {
1878    DataTypes::ValueType v(getNoValues(),0);  //   DataTypes::ValueType v(getNoValues(),0);
1879    m_id=DataReady_ptr(new DataConstant(getFunctionSpace(),getShape(),v));  //   m_id=DataReady_ptr(new DataConstant(getFunctionSpace(),getShape(),v));
1880    m_op=IDENTITY;  //   m_op=IDENTITY;
1881    m_right.reset();    //   m_right.reset();  
1882    m_left.reset();  //   m_left.reset();
1883    m_readytype='C';  //   m_readytype='C';
1884    m_buffsRequired=1;  //   m_buffsRequired=1;
1885    
1886      throw DataException("Programmer error - setToZero not supported for DataLazy (DataLazy objects should be read only).");
1887    
1888    }
1889    
1890    bool
1891    DataLazy::actsExpanded() const
1892    {
1893        return (m_readytype=='E');
1894  }  }
1895    
1896  }   // end namespace  }   // end namespace

Legend:
Removed from v.2157  
changed lines
  Added in v.2497

  ViewVC Help
Powered by ViewVC 1.1.26