/[escript]/branches/schroedinger/escript/src/DataLazy.cpp
ViewVC logotype

Diff of /branches/schroedinger/escript/src/DataLazy.cpp

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

revision 1885 by jfenwick, Tue Oct 14 05:51:59 2008 UTC revision 1886 by jfenwick, Wed Oct 15 01:34:18 2008 UTC
# Line 25  Line 25 
25  #include "FunctionSpace.h"  #include "FunctionSpace.h"
26  #include "DataTypes.h"  #include "DataTypes.h"
27  #include "Data.h"  #include "Data.h"
28    #include "UnaryFuncs.h"     // for escript::fsign
29    
30  using namespace std;  using namespace std;
31  using namespace boost;  using namespace boost;
# Line 38  opToString(ES_optype op); Line 39  opToString(ES_optype op);
39  namespace  namespace
40  {  {
41    
42    
43    
44    enum ES_opgroup
45    {
46       G_UNKNOWN,
47       G_IDENTITY,
48       G_BINARY,
49       G_UNARY
50    };
51    
52    
53    
54    
55    string ES_opstrings[]={"UNKNOWN","IDENTITY","+","-","*","/","sin","cos","tan",
56                "asin","acos","atan","sinh","cosh","tanh","erf",
57                "asinh","acosh","atanh",
58                "log10","log","sign","abs","neg","pos"};
59    int ES_opcount=25;
60    ES_opgroup opgroups[]={G_UNKNOWN,G_IDENTITY,G_BINARY,G_BINARY,G_BINARY,G_BINARY,G_UNARY,G_UNARY,G_UNARY, //9
61                G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,    // 16
62                G_UNARY,G_UNARY,G_UNARY,                    // 19
63                G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY,G_UNARY};       // 25
64    
65    inline
66    ES_opgroup
67    getOpgroup(ES_optype op)
68    {
69      return opgroups[op];
70    }
71    
72  // return the FunctionSpace of the result of "left op right"  // return the FunctionSpace of the result of "left op right"
73  FunctionSpace  FunctionSpace
74  resultFS(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)  resultFS(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
# Line 69  resultShape(DataAbstract_ptr left, DataA Line 100  resultShape(DataAbstract_ptr left, DataA
100  size_t  size_t
101  resultLength(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)  resultLength(DataAbstract_ptr left, DataAbstract_ptr right, ES_optype op)
102  {  {
103     switch(op)     switch (getOpgroup(op))
104     {     {
105  //   case IDENTITY: return left->getLength();     case G_BINARY: return left->getLength();
106     case ADD:    // the length is preserved in these ops     case G_UNARY: return left->getLength();
    case SUB:  
    case MUL:  
    case DIV: return left->getLength();  
107     default:     default:
108      throw DataException("Programmer Error - attempt to getLength() for operator "+opToString(op)+".");      throw DataException("Programmer Error - attempt to getLength() for operator "+opToString(op)+".");
   
109     }     }
110  }  }
111    
112  int  int
113  calcBuffs(const DataLazy_ptr& left, const DataLazy_ptr& right, ES_optype op)  calcBuffs(const DataLazy_ptr& left, const DataLazy_ptr& right, ES_optype op)
114  {  {
115     switch(op)     switch(getOpgroup(op))
116     {     {
117     case IDENTITY: return 0;     case G_IDENTITY: return 1;
118     case ADD:    // the length is preserved in these ops     case G_BINARY: return max(left->getBuffsRequired(),right->getBuffsRequired()+1);
119     case SUB:     case G_UNARY: return max(left->getBuffsRequired(),1);
    case MUL:  
    case DIV: return max(left->getBuffsRequired(),right->getBuffsRequired());  
120     default:     default:
121      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");      throw DataException("Programmer Error - attempt to calcBuffs() for operator "+opToString(op)+".");
122     }     }
123  }  }
124    
 string ES_opstrings[]={"UNKNOWN","IDENTITY","+","-","*","/"};  
 int ES_opcount=5;  
125    
 // void performOp(ValueType& v, int startOffset, ES_optype op, int m_samplesize)  
 // {  
 //    switch(op)  
 //    {  
 //    case ADD:  DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),  
 //      startOffset+m_samplesize,plus<double>());  
 //        break;      
 //    case SUB:  DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),  
 //      startOffset+m_samplesize,minus<double>());  
 //        break;  
 //    case MUL:  DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),  
 //      startOffset+m_samplesize,multiplies<double>());  
 //        break;  
 //    case DIV:  DataMaths::binaryOp(v,getShape(),startOffset,v,getShape(),  
 //      startOffset+m_samplesize,divides<double>());  
 //        break;  
 //    default:  
 //  throw DataException("Programmer Error - attempt to performOp() for operator "+opToString(op)+".");  
 //    }  
 //  
 // }  
126    
127  }   // end anonymous namespace  }   // end anonymous namespace
128    
# Line 153  DataLazy::DataLazy(DataAbstract_ptr p) Line 155  DataLazy::DataLazy(DataAbstract_ptr p)
155      m_id=dynamic_pointer_cast<DataReady>(p);      m_id=dynamic_pointer_cast<DataReady>(p);
156     }     }
157     m_length=p->getLength();     m_length=p->getLength();
158     m_buffsRequired=0;     m_buffsRequired=1;
159     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
160  cout << "(1)Lazy created with " << m_samplesize << endl;  cout << "(1)Lazy created with " << m_samplesize << endl;
161  }  }
162    
163    DataLazy::DataLazy(DataAbstract_ptr left, ES_optype op)
164        : parent(left->getFunctionSpace(),left->getShape()),
165        m_op(op)
166    {
167       if (getOpgroup(op)!=G_UNARY)
168       {
169        throw DataException("Programmer error - constructor DataLazy(left, op) will only process UNARY operations.");
170       }
171       DataLazy_ptr lleft;
172       if (!left->isLazy())
173       {
174        lleft=DataLazy_ptr(new DataLazy(left));
175       }
176       else
177       {
178        lleft=dynamic_pointer_cast<DataLazy>(left);
179       }
180       m_length=left->getLength();
181       m_left=lleft;
182       m_buffsRequired=1;
183       m_samplesize=getNumDPPSample()*getNoValues();
184    }
185    
186    
187  DataLazy::DataLazy(DataLazy_ptr left, DataLazy_ptr right, ES_optype op)  DataLazy::DataLazy(DataLazy_ptr left, DataLazy_ptr right, ES_optype op)
188      : parent(resultFS(left,right,op), resultShape(left,right,op)),      : parent(resultFS(left,right,op), resultShape(left,right,op)),
189      m_left(left),      m_left(left),
190      m_right(right),      m_right(right),
191      m_op(op)      m_op(op)
192  {  {
193       if (getOpgroup(op)!=G_BINARY)
194       {
195        throw DataException("Programmer error - constructor DataLazy(left, right, op) will only process BINARY operations.");
196       }
197     m_length=resultLength(m_left,m_right,m_op);     m_length=resultLength(m_left,m_right,m_op);
198     m_samplesize=getNumDPPSample()*getNoValues();     m_samplesize=getNumDPPSample()*getNoValues();
199     m_buffsRequired=calcBuffs(m_left, m_right, m_op);     m_buffsRequired=calcBuffs(m_left, m_right, m_op);
# Line 174  DataLazy::DataLazy(DataAbstract_ptr left Line 204  DataLazy::DataLazy(DataAbstract_ptr left
204      : parent(resultFS(left,right,op), resultShape(left,right,op)),      : parent(resultFS(left,right,op), resultShape(left,right,op)),
205      m_op(op)      m_op(op)
206  {  {
207       if (getOpgroup(op)!=G_BINARY)
208       {
209        throw DataException("Programmer error - constructor DataLazy(left, op) will only process BINARY operations.");
210       }
211     if (left->isLazy())     if (left->isLazy())
212     {     {
213      m_left=dynamic_pointer_cast<DataLazy>(left);      m_left=dynamic_pointer_cast<DataLazy>(left);
# Line 224  DataLazy::resolveSample(ValueType& v,int Line 258  DataLazy::resolveSample(ValueType& v,int
258    }    }
259    size_t rightoffset=offset+m_samplesize;    size_t rightoffset=offset+m_samplesize;
260    const double* left=m_left->resolveSample(v,sampleNo,offset);    const double* left=m_left->resolveSample(v,sampleNo,offset);
261    const double* right=m_right->resolveSample(v,sampleNo,rightoffset);    const double* right=0;
262      if (getOpgroup(m_op)==G_BINARY)
263      {
264        right=m_right->resolveSample(v,sampleNo,rightoffset);
265      }
266    double* result=&(v[offset]);    double* result=&(v[offset]);
267    {    {
268      switch(m_op)      switch(m_op)
# Line 241  DataLazy::resolveSample(ValueType& v,int Line 279  DataLazy::resolveSample(ValueType& v,int
279      case DIV:            case DIV:      
280      tensor_binary_operation(m_samplesize, left, right, result, divides<double>());      tensor_binary_operation(m_samplesize, left, right, result, divides<double>());
281      break;      break;
282    // unary ops
283        case SIN:
284        tensor_unary_operation(m_samplesize, left, result, ::sin);
285        break;
286        case COS:
287        tensor_unary_operation(m_samplesize, left, result, ::cos);
288        break;
289        case TAN:
290        tensor_unary_operation(m_samplesize, left, result, ::tan);
291        break;
292        case ASIN:
293        tensor_unary_operation(m_samplesize, left, result, ::asin);
294        break;
295        case ACOS:
296        tensor_unary_operation(m_samplesize, left, result, ::acos);
297        break;
298        case ATAN:
299        tensor_unary_operation(m_samplesize, left, result, ::atan);
300        break;
301        case SINH:
302        tensor_unary_operation(m_samplesize, left, result, ::sinh);
303        break;
304        case COSH:
305        tensor_unary_operation(m_samplesize, left, result, ::cosh);
306        break;
307        case TANH:
308        tensor_unary_operation(m_samplesize, left, result, ::tanh);
309        break;
310        case ERF:
311    #ifdef _WIN32
312        throw DataException("Error - Data:: erf function is not supported on _WIN32 platforms.");
313    #else
314        tensor_unary_operation(m_samplesize, left, result, ::erf);
315        break;
316    #endif
317       case ASINH:
318    #ifdef _WIN32
319        tensor_unary_operation(m_samplesize, left, result, escript::asinh_substitute);
320    #else
321        tensor_unary_operation(m_samplesize, left, result, ::asinh);
322    #endif  
323        break;
324       case ACOSH:
325    #ifdef _WIN32
326        tensor_unary_operation(m_samplesize, left, result, escript::acosh_substitute);
327    #else
328        tensor_unary_operation(m_samplesize, left, result, ::acosh);
329    #endif  
330        break;
331       case ATANH:
332    #ifdef _WIN32
333        tensor_unary_operation(m_samplesize, left, result, escript::atanh_substitute);
334    #else
335        tensor_unary_operation(m_samplesize, left, result, ::atanh);
336    #endif  
337        break;
338        case LOG10:
339        tensor_unary_operation(m_samplesize, left, result, ::log10);
340        break;
341        case LOG:
342        tensor_unary_operation(m_samplesize, left, result, ::log);
343        break;
344        case SIGN:
345        tensor_unary_operation(m_samplesize, left, result, escript::fsign);
346        break;
347        case ABS:
348        tensor_unary_operation(m_samplesize, left, result, ::fabs);
349        break;
350        case NEG:
351        tensor_unary_operation(m_samplesize, left, result, negate<double>());
352        break;
353        case POS:
354        // it doesn't mean anything for delayed.
355        // it will just trigger a deep copy of the lazy object
356        throw DataException("Programmer error - POS not supported for lazy data.");
357        break;
358      default:      default:
359      throw DataException("Programmer error - do not know how to resolve operator "+opToString(m_op)+".");      throw DataException("Programmer error - do not know how to resolve operator "+opToString(m_op)+".");
360      }      }
# Line 263  cout << "Buffers=" << m_buffsRequired << Line 377  cout << "Buffers=" << m_buffsRequired <<
377    numthreads=omp_get_max_threads();    numthreads=omp_get_max_threads();
378    int threadnum=0;    int threadnum=0;
379  #endif  #endif
380    ValueType v(numthreads*threadbuffersize); // the +1 comes from the fact that I want to have a safe    ValueType v(numthreads*threadbuffersize);
                             // space for the RHS of ops to write to even if they don't  
                             // need it.  
381  cout << "Buffer created with size=" << v.size() << endl;  cout << "Buffer created with size=" << v.size() << endl;
382    ValueType dummy(getNoValues());    ValueType dummy(getNoValues());
383    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),dummy);    DataExpanded* result=new DataExpanded(getFunctionSpace(),getShape(),dummy);
# Line 294  cout << "Buffer created with size=" << v Line 406  cout << "Buffer created with size=" << v
406  std::string  std::string
407  DataLazy::toString() const  DataLazy::toString() const
408  {  {
409    return "Lazy evaluation object. No details available.";    ostringstream oss;
410      oss << "Lazy Data:";
411      intoString(oss);
412      return oss.str();
413    }
414    
415    void
416    DataLazy::intoString(ostringstream& oss) const
417    {
418      switch (getOpgroup(m_op))
419      {
420      case G_IDENTITY:
421        oss << '@' << m_id.get();
422        break;
423      case G_BINARY:
424        oss << '(';
425        m_left->intoString(oss);
426        oss << ' ' << opToString(m_op) << ' ';
427        m_right->intoString(oss);
428        oss << ')';
429        break;
430      case G_UNARY:
431        oss << opToString(m_op) << '(';
432        m_left->intoString(oss);
433        oss << ')';
434        break;
435      default:
436        oss << "UNKNOWN";
437      }
438  }  }
439    
440  // Note that in this case, deepCopy does not make copies of the leaves.  // Note that in this case, deepCopy does not make copies of the leaves.

Legend:
Removed from v.1885  
changed lines
  Added in v.1886

  ViewVC Help
Powered by ViewVC 1.1.26