contentpackage.hh

Go to the documentation of this file.
00001 /************************************************************************
00002 
00003 Copyright Rice University, 2006
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
00030 
00031 **************************************************************************/
00032 
00033 #ifndef __RVL_TOOLS_NEW_CONTENT_PACKAGE_
00034 #define __RVL_TOOLS_NEW_CONTENT_PACKAGE_
00035 
00036 #include "local.hh"
00037 #include "dejavu.hh"
00038 
00039 namespace RVL {
00040 
00041   // forward declaration
00042   template<typename T, typename M>
00043   class ContentPackage;
00044 
00045   // rewrite of ADP's ContentPackage - now stores only a single 
00046   // metadata object, which is supposed to be collective
00047   
00055   template<typename MetaType>
00056   size_t getDataSize(MetaType const & md) {
00057     size_t t = md;
00058     return t;
00059   }
00060 
00066   template<class MetaType>
00067   size_t getMetaSize(MetaType const & md) {
00068     return sizeof(MetaType);
00069   }
00070 
00073   template<typename MetaType>
00074   char * serialize(MetaType const & mt, size_t & len) {
00075     len = getMetaSize<MetaType>(mt);
00076     char * cbuf = new char[len];
00077     memcpy(cbuf, (char *)(&mt), len);
00078     return cbuf;
00079   }
00080 
00084   template<typename MetaType>
00085   MetaType * deserialize(char * cbuf, size_t len) {
00086     // functional only for data of fixed size and 
00087     // default construction - test this first
00088     MetaType * mt = new MetaType;
00089     if (len < getMetaSize<MetaType>(*mt)) {
00090       RVLException e;
00091       e<<"ERROR: deserialize[ContentPackage MetaType]\n";
00092       e<<"  asserted size of char buf too small to hold\n";
00093       e<<"  metadata object of this type\n";
00094       throw e;
00095     }
00096     memcpy((char *)mt,cbuf,getMetaSize<MetaType>(*mt));
00097     return mt;
00098   }
00099 
00103   template<typename DataType, typename MetaType>
00104   char * serialize(ContentPackage<DataType,MetaType> const & cp, size_t & len) {
00105     size_t mlen = 0;
00106     char * mbuf = serialize<MetaType>(cp.getMetadata(), mlen);
00107     size_t dlen = getDataSize<MetaType>(cp.getMetadata())*sizeof(DataType);
00108     len = mlen + dlen;
00109     char * cbuf = new char[len];
00110     memcpy(cbuf,mbuf,mlen);
00111     memcpy(&(cbuf[mlen]),(char *)(cp.getData()),dlen);
00112     delete [] mbuf;
00113     return cbuf;
00114   }
00115 
00119   template<typename DataType, typename MetaType>
00120   ContentPackage<DataType,MetaType> * deserialize(char * cbuf, size_t len) {
00121     try {
00122       MetaType * mt = deserialize<MetaType>(cbuf,len);
00123       int clen = getMetaSize<MetaType>(*mt) + getDataSize<MetaType>(*mt)*sizeof(DataType);
00124       if (len != clen) {
00125     RVLException e;
00126     e<<"ERROR: deserialize[ContentPackage]\n";
00127     e<<"  asserted size of char buffer appears to differ from that needed\n";
00128     e<<"  to store CP object of given type\n";
00129     e<<"  asserted size of char buffer = "<<len<<"\n";
00130     e<<"  require buffer size for CP   = "<<clen<<"\n";
00131     throw e;
00132       }
00133       ContentPackage<DataType,MetaType> * cp = new ContentPackage<DataType,MetaType>;
00134       cp->initialize(*mt);
00135       delete mt;
00136       memcpy((char *)(cp->getData()), &(cbuf[getMetaSize<MetaType>(*mt)]),getDataSize<MetaType>(*mt)*sizeof(DataType) );
00137       return cp;
00138     }
00139     catch (RVLException & e) {
00140       e<<"\ncalled from deserialize[ContentPackage]\n";
00141       throw e;
00142     }
00143   }
00144 
00147   template<class MetaType>
00148   ostream & writeMeta(MetaType const & md, ostream & e) { 
00149     e<<md<<"\n"; return e; }
00150 
00153   template<typename DataType,typename MetaType>
00154   DataType * newData(MetaType & md) {
00155     return new DataType[getDataSize<MetaType>(md)];
00156   }
00157 
00160   template<typename DataType,typename MetaType>
00161   void deleteData(DataType ** d, MetaType ** md) {
00162     delete [] *d; *d=NULL;
00163   }
00164 
00201   template<class DataType, class MetaType >
00202   class ContentPackage: public LocalDataContainer<DataType> {
00203     
00204   private:
00205     
00206     mutable MetaType * md;
00207     mutable DataType * d;
00208     bool own;
00209 
00210   public:    
00211 
00214     ContentPackage(const ContentPackage<DataType,MetaType> & bin)
00215       : md(NULL), d(NULL), own(bin.own) {
00216       if (bin.md) {
00217     md = new MetaType(*(bin.md));
00218     if (own) {
00219       //      d = new DataType[getDataSize<MetaType>(*md)];
00220       d=newData<DataType,MetaType>(*md);
00221       memcpy(d,bin.d,getDataSize<MetaType>(*md)*sizeof(DataType));
00222     }
00223     else {
00224       d = bin.d;
00225     }
00226       }
00227       //cerr<<"CP copy constr: md = "<<md<<" d = "<<d<<" own = "<<own<<" this = "<<this<<endl;
00228       //cerr<<"*** metadata:"<<endl;
00229       //      writeMeta<MetaType>(*md,cerr);
00230     } 
00231 
00233     ContentPackage() 
00234       :md(NULL), d(NULL), own(true) {
00235       //cerr<<"CP main constr: md = "<<md<<" d = "<<d<<" this = "<<this<<endl;
00236     }
00237 
00238     virtual ~ContentPackage() {
00239       //cerr<<"CP destr begin, this = "<<this<<"\n";
00240       //cerr<<"   d = "<<d<<" own = "<<own<<endl;
00241       //if (d && own) delete [] d; d = NULL;
00242       if (d && own) deleteData<DataType,MetaType>(&d,&md);
00243       //cerr<<"  d = "<<d<<endl;
00244       //cerr<<"*** metadata: md="<<md<<endl;
00245       //writeMeta<MetaType>(*md,cerr);
00246       if (md) {
00247     //cerr<<"  delete md\n";
00248     delete md; md = NULL;
00249     //cerr<<"  md = "<<md<<endl;
00250       }
00251       //cerr<<"CP destr finish\n";
00252     }
00253         
00258     bool initialize(MetaType const & _md, 
00259             LocalDataContainer<DataType> * p = NULL,
00260             size_t start = 0) {
00261       if (md) return false;
00262       md = new MetaType(_md);
00263       //cerr<<"CP::initialize - md = "<<md<<" this = "<<this<<endl;
00264       //cerr<<"*** metadata:"<<endl;
00265       //writeMeta<MetaType>(*md,cerr);
00266       if (p) {
00267     if (getDataSize<MetaType>(*md) <= p->getSize()-start) {
00268       d = &((p->getData())[start]);
00269       own = false;
00270       return true;
00271     }
00272     else {
00273       //cerr<<"warning: ContentPackage::initialize\n";
00274       //      cerr<<"attempted to build view of external LDC\n";
00275       //      cerr<<"of length "<<getDataSize<MetaType>(*md)<<" starting at word "
00276       //       <<start<<" of LDC of length "<<p->getSize()<<"\n";
00277       delete md;
00278       md=NULL;
00279       return false;
00280     }
00281       }
00282       else {
00283     //  d = new DataType[getDataSize<MetaType>(*md)];
00284     d=newData<DataType,MetaType>(*md);
00285     return true;
00286       }
00287     }
00288 
00290     bool isInitialized() const { if (md) return true; return false; }
00291 
00293     ContentPackage<DataType,MetaType> & 
00294     operator=(ContentPackage<DataType,MetaType> const & src) { 
00295       if (this != &src) {
00296     if (*md != *(src.md)) {
00297       RVLException e;
00298       e<<"Error: ContentPackage assignment op\n";
00299       e<<"metadata of this differs from metadata of source\n";
00300       throw e;
00301     }
00302     size_t n = getDataSize<MetaType>(*md);
00303     if (!d) d = new DataType[n];
00304     memcpy(d,src.d,n*sizeof(DataType));
00305       }
00306       return *this;
00307     }
00309     bool operator==(ContentPackage<DataType,MetaType> const & a) const {
00310       if (this == &a) return true;
00311       if (*md != *(a.md)) return false;
00312       if (getSize() != a.getSize()) return false;
00313       for (size_t i=0;i<getSize();i++) {
00314     if (getData()[i] != a.getData()[i]) return false;
00315       }
00316       return true;
00317     }
00318     bool operator!=(ContentPackage<DataType,MetaType> const & a) const { 
00319       return !operator==(a); 
00320     }
00321 
00322     bool isCompatible(ContentPackage<DataType,MetaType> const & a) const {
00323       return (this->getMetadata() == a.getMetadata());
00324     }
00325 
00327     MetaType & getMetadata() { 
00328       if (!md) {
00329     RVLException e;
00330     e<<"Error: ContentPackage::getMetaData\n";
00331     e<<"metadata not initialized yet\n";
00332     throw e;
00333       }
00334       return *md;
00335     }
00336 
00338     MetaType const & getMetadata() const { 
00339       if (!md) {
00340     RVLException e;
00341     e<<"Error: ContentPackage::getMetaData\n";
00342     e<<"metadata not initialized yet\n";
00343     throw e;
00344       }
00345       return *md;
00346     }
00347 
00349     size_t getSize() const { 
00350       if (md) return getDataSize<MetaType>(*md); 
00351       return 0;
00352     }
00353 
00355     DataType * getData() {
00356       if (!d) {
00357     RVLException e;
00358     e<<"Error: ContentPackage::getData\n";
00359     e<<"data not initialized yet\n";
00360     throw e;
00361       }
00362       return d;
00363     } 
00365     DataType const * getData() const {
00366       if (!d) {
00367     RVLException e;
00368     e<<"Error: ContentPackage::getData\n";
00369     e<<"data not initialized yet\n";
00370     throw e;
00371       }
00372       return d;
00373     } 
00374 
00375     ostream & write(ostream & str) const {
00376       str<<"ContentPackage LDC, MetaData = \n";
00377       if (md) {
00378     writeMeta<MetaType>(*md,str);
00379       }
00380       else {
00381     str<<"(not initialized)\n";
00382       }
00383       str<<"  and data array\n";
00384       for (size_t i=0;i<this->getSize(); i++) {
00385     str<<"  "<<i<<". ";
00386     writeMeta<DataType>(d[i],str);
00387       }
00388       return str;
00389     }
00390   };
00391 
00392 
00396   template<typename Source, typename Target>
00397   void copyCP(Source const & in, Target & out) {
00398     try {
00399       size_t n = min(in.getSize(),out.getSize());
00400       for (size_t i=0;i<n;i++) out.getData()[i]=in.getData()[i];
00401     }
00402     catch (RVLException & e) {
00403       e<<"\ncalled from copyCP\n";
00404       throw e;
00405     }
00406   }
00407 
00458   template<typename DataType, typename MetaType>
00459   class PackageContainer: 
00460     public DataContainer {
00461 
00462   protected:
00463 
00483     virtual ContentPackage<DataType,MetaType> 
00484     & get(bool & more) = 0;
00485     virtual ContentPackage<DataType,MetaType> const 
00486     & get(bool & more) const = 0;
00487 
00492     virtual void put() const = 0;
00493 
00496     virtual void reset() const = 0;
00497 
00498   public:
00499 
00500     PackageContainer() {}
00501     PackageContainer(PackageContainer<DataType,MetaType> const &) {}
00502     virtual ~PackageContainer() {}
00503     
00505     virtual void eval(FunctionObject & f, 
00506                       std::vector<DataContainer const *> & x) {
00507       try {
00508     //  cerr<<"pc: before reset\n";
00509     //  this->write(cerr);
00510     this->reset();
00511     //  cerr<<"pc: after reset\n";
00512     //  this->write(cerr);
00513     std::vector<PackageContainer<DataType,MetaType> const *> pcx(x.size());
00514     for (size_t i=0;i<x.size();i++) {
00515       if (!(pcx[i] = dynamic_cast<PackageContainer<DataType,MetaType> 
00516         const *>(x[i]))) {
00517         RVLException e;
00518         e<<"Error: PackageContainer::eval(FO)\n";
00519         e<<"at least one other arg is not a package container.\n";
00520         for (size_t j=0;j<x.size();j++) {
00521           e<<"*** arg "<<j<<":\n";
00522           x[j]->write(e);
00523         }
00524         throw e;
00525       }
00526       // cannot alias input with output
00527       if (this == pcx[i]) {
00528         RVLException e;
00529         e<<"Error: PackageContainer::eval(FO)\n";
00530         e<<"input argument "<<i<<" aliased with output\n";
00531         throw e;
00532       }
00533       pcx[i]->reset();
00534     }
00535     
00536     bool more = true;
00537     std::vector<DataContainer const *> cpx(x.size());
00538 
00539     //  cerr<<"cp: size="<<x.size()<<endl;
00540     //  cerr<<"cp: more="<<more<<endl;
00541     while (more) {
00542       for (size_t i=0;i<x.size();i++) {
00543         // check for alias
00544         size_t j=i;
00545         dejavu<PackageContainer<DataType,MetaType> const>(&j,pcx);
00546         // if j has not changed value, then this is a non-aliased arg
00547         if (j==i) { cpx[i]=&(pcx[i]->get(more)); }
00548         // otherwise we've already seen it
00549         else { cpx[i] = cpx[j]; }
00550       }
00551       //      cerr<<"cp->get\n";
00552       //      this->write(cerr);
00553       ContentPackage<DataType,MetaType> & cp = this->get(more);
00554       //      cerr<<"cp->eval\n";
00555       cp.eval(f,cpx);
00556       //      cerr<<"this->put\n";
00557       this->put();
00558     }
00559       }
00560       catch (RVLException & e) {
00561     e<<"\ncalled from PackageContainer::eval(FO)\n";
00562     throw e;
00563       }
00564     }
00565               
00567     virtual void eval(FunctionObjectConstEval & f, 
00568                       vector<DataContainer const *> & x) const {
00569       try {
00570     this->reset();
00571     std::vector<PackageContainer<DataType,MetaType> const *> pcx(x.size());
00572     for (size_t i=0;i<x.size();i++) {
00573       if (!(pcx[i] = 
00574         dynamic_cast<PackageContainer<DataType,MetaType> 
00575         const *>(x[i]))) {
00576         RVLException e;
00577         e<<"Error: PackageContainer::eval(FOR)\n";
00578         e<<"at least one other arg is not a package container.\n";
00579         throw e;
00580       }
00581       pcx[i]->reset();
00582     }
00583     bool more = true;
00584     std::vector<DataContainer const *> cpx(x.size());
00585 
00586     while (more) {
00587       ContentPackage<DataType,MetaType> const & cp = this->get(more);
00588       for (size_t i=0;i<x.size();i++) {
00589         // check for alias with target
00590         if (this == pcx[i]) {
00591           cpx[i] = &cp;
00592         }
00593         else {
00594           // check for alias
00595           size_t j=i;
00596           dejavu<PackageContainer<DataType,MetaType> const>(&j,pcx);
00597           // if j has not changed value, then this is a non-aliased arg
00598           if (j==i) { 
00599         cpx[i]=&(pcx[i]->get(more)); }
00600           // otherwise we've already seen it
00601           else { 
00602         cpx[i] = cpx[j]; 
00603           }
00604         }
00605       }
00606       cp.eval(f,cpx);
00607     }
00608       }
00609       catch (RVLException & e) {
00610     e<<"\ncalled from PackageContainer::eval(FOR)\n";
00611     throw e;
00612       }
00613     }
00614 
00615   };
00616 
00626   template<typename DataType,typename MetaType>
00627   class PackageContainerFactory: public DataContainerFactory {
00628   protected:
00629 
00630     virtual PackageContainer<DataType,MetaType> * buildPC() const = 0;
00631     
00632   public:
00633 
00635     virtual PackageContainerFactory<DataType,MetaType> * clone() const = 0;
00636 
00637     DataContainer * build() const { return buildPC(); }
00638 
00639     virtual bool compare( DataContainerFactory const & dcf) const {
00640       PackageContainerFactory<DataType,MetaType> const * ptr = NULL;
00641       if ((ptr = 
00642        dynamic_cast< PackageContainerFactory<DataType,MetaType> const * >(&dcf)))
00643     return true;
00644       return false;
00645     }
00646 
00647     virtual bool isCompatible(DataContainer const & dc) const {
00648       PackageContainer<DataType,MetaType> const * ptr = NULL;
00649       if ((ptr = 
00650        dynamic_cast< PackageContainer<DataType,MetaType> const * >(&dc)))
00651     return true;
00652       return false;
00653     }
00654       
00655     virtual ostream & write(ostream & str) const {
00656       str<<"PackageContainerFactory\n";
00657       return str;
00658     }    
00659   };
00660     
00669   template<typename Datatype, typename Metatype>
00670   class SingleDataContainer: public PackageContainer<Datatype,Metatype> {
00671     
00672   private:
00673     
00674     ContentPackage<Datatype,Metatype> gd;
00675     mutable int nrep;
00676     int nrep0;
00677 
00678   protected:
00679 
00680     ContentPackage<Datatype,Metatype> & get(bool & more) {
00681       nrep--;
00682       if (nrep<1) more = false; 
00683       return gd;
00684     }
00685     
00686     ContentPackage<Datatype,Metatype> const & get(bool & more) const {
00687       nrep--;
00688       if (nrep<1) more = false; 
00689       return gd;
00690     }
00691 
00692     void put() const {}
00693 
00694     void reset() const { nrep=nrep0; }
00695 
00696   public:
00697     
00698     SingleDataContainer(int _nrep = 1)
00699       : PackageContainer<Datatype,Metatype>(), 
00700     gd(), nrep(_nrep), nrep0(nrep) {}
00701     
00702     SingleDataContainer(SingleDataContainer<Datatype,Metatype> const & g)
00703       : PackageContainer<Datatype,Metatype>(g), gd(g.gd), 
00704     nrep(g.nrep), nrep0(g.nrep0) {}
00705     ~SingleDataContainer() {}
00706     
00707     void initialize(Metatype const & g) { gd.initialize(g); }
00708     Metatype const & getMetadata() const {
00709       if (gd.isInitialized()) return gd.getMetadata();
00710       RVLException e;
00711       e<<"Error: SingleDataContainer::getMetadata\n";
00712       e<<"cannot return reference to internal Metadata, as\n";
00713       e<<"this is not initialized yet.\n";
00714       throw e;
00715     }
00716     
00717     ostream & write(ostream & e) const {
00718       e<<"SingleDataContainer encapsulating ContentPackage object:\n";
00719       gd.write(e);
00720       return e;
00721     }
00722     
00723   };  
00724 
00726   template<typename Datatype, typename Metatype>
00727   class SingleDataContainerFactory: 
00728     public PackageContainerFactory<Datatype,Metatype> {
00729   private:
00730     int nrep;
00731     Metatype * g;
00732 
00733   protected:
00734     PackageContainer<Datatype,Metatype> * buildPC() const {
00735       SingleDataContainer<Datatype,Metatype> * gdc 
00736     = new SingleDataContainer<Datatype,Metatype>(nrep);
00737       if (g) {
00738     gdc->initialize(*g);
00739     return gdc;
00740       }
00741       else {
00742     RVLException e;
00743     e<<"Error: SingleDataContainerFactory::buildPC\n";
00744     e<<"internal Metadata not initialized\n";
00745     throw e;
00746       }
00747     }
00748     
00749   public:
00750     SingleDataContainerFactory(int _nrep=1): nrep(_nrep), g(NULL) {}
00751     SingleDataContainerFactory
00752     (SingleDataContainerFactory<Datatype,Metatype> const & f)
00753       : nrep(f.nrep), g(NULL) { 
00754       if (f.g) g=new Metatype(*(f.g)); }
00755     ~SingleDataContainerFactory() { if (g) delete g; }
00756   
00757     PackageContainerFactory<Datatype,Metatype> * clone() const {
00758       if (g) {
00759     SingleDataContainerFactory<Datatype,Metatype> * f 
00760       = new SingleDataContainerFactory<Datatype,Metatype>;
00761     f->initialize(*g);
00762     return f;
00763       }
00764       RVLException e;
00765       e<<"Error: SingleDataContainerFactory::clone\n";
00766       e<<"cannot construct copy because not initialized\n";
00767       throw e;
00768     }
00769     void initialize(Metatype const & _g) { g = new Metatype(_g); } 
00770 
00771     bool compare( DataContainerFactory const & dcf) const {
00772       try {
00773     if (!g) {
00774       cerr<<"Warning: SingleDataContainerFactory::compare\n";
00775       cerr<<"cannot compare uninitialized factory to others\n";
00776       return false;
00777     }
00778     SingleDataContainerFactory<Datatype,Metatype> const * dcfptr = NULL;
00779     if ((dcfptr = dynamic_cast<SingleDataContainerFactory<Datatype,Metatype> const *>(dcfptr))) {
00780       if (!(dcfptr->g)) {
00781         cerr<<"Warning: GridDataContainerFactory::compare\n";
00782         cerr<<"cannot compare this to uninitialized factory\n";
00783         return false;
00784       }
00785       if ( *g == *(dcfptr->g)) return true;
00786     }
00787       }
00788       catch (RVLException & e) {
00789     e<<"\ncalled from SingleDataContainerFactory::compare\n";
00790     throw e;
00791       }
00792     }     
00793 
00794     bool isCompatible(DataContainer const & dc) const {
00795       try {
00796     if (!g) {
00797       cerr<<"Warning: SingleDataContainerFactory::isCompatible\n";
00798       cerr<<"cannot decide compatibility for uninitialized factory\n";
00799       return false;
00800     }
00801     SingleDataContainer<Datatype,Metatype> const * dcptr = NULL;
00802     if ((dcptr = dynamic_cast<SingleDataContainer<Datatype,Metatype> const *>(&dc))) 
00803     if (*g == dcptr->getMetadata()) return true;
00804     return false;
00805       }
00806       catch (RVLException & e) {
00807     e<<"\ncalled from GridDataContainerFactory::isCompatible\n";
00808     throw e;
00809       }
00810     }   
00811     
00812     ostream & write(ostream & str) const {
00813       str<<"SingleDataContainerFactory";
00814       if (g) {
00815     str<<" using Metadata:\n";
00816     g->write(str);
00817       }
00818       else {
00819     str<<" (uninitialized)\n";
00820       }
00821       return str;
00822     }      
00823   
00824   };
00825 
00826 }
00827 
00828 #endif

Generated on 5 Jan 2017 for LocalRVL by  doxygen 1.4.7