// -*- C++ -*- // ACL:license // ---------------------------------------------------------------------- // This software and ancillary information (herein called "SOFTWARE") // called POOMA (Parallel Object-Oriented Methods and Applications) is // made available under the terms described here. The SOFTWARE has been // approved for release with associated LA-CC Number LA-CC-98-65. // // Unless otherwise indicated, this SOFTWARE has been authored by an // employee or employees of the University of California, operator of the // Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with // the U.S. Department of Energy. The U.S. Government has rights to use, // reproduce, and distribute this SOFTWARE. The public may copy, distribute, // prepare derivative works and publicly display this SOFTWARE without // charge, provided that this Notice and any statement of authorship are // reproduced on all copies. Neither the Government nor the University // makes any warranty, express or implied, or assumes any liability or // responsibility for the use of this SOFTWARE. // // If SOFTWARE is modified to produce derivative works, such modified // SOFTWARE should be clearly marked, so as not to confuse it with the // version available from LANL. // // For more information about POOMA, send e-mail to address@hidden, // or visit the POOMA web page at http://www.acl.lanl.gov/pooma/. // ---------------------------------------------------------------------- // ACL:license #ifndef POOMA_DOMAIN_GRID_H #define POOMA_DOMAIN_GRID_H //----------------------------------------------------------------------------- // Class: // Grid //----------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // Overview: // Grid is a general type of integer domain, which refers to a set of points // a0, a1, ... aN for each dimension. The points can be any ascending or // descending sequence, there is no fixed stride. This is basically a set // of Dim IndirectionList's, one for each dimension; the total domain // is the tensor product of these lists. Grid is basically an array // of Grid<1> objects. // // Grid defers most of its implementation to the Domain> // base class. //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Typedefs: //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Includes: //----------------------------------------------------------------------------- #include "Domain/Domain.h" #include "Domain/DomainTraits.Grid.h" #include "Domain/NewDomain.h" #include "Domain/Loc.h" // needed for use of operator<< #include //----------------------------------------------------------------------------- // Forward Declarations: //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // // Full Description of Grid: // // Grid is a domain representing a set of N numeric sequences, one // for each dimension N. The sequences are lists of ascending or descending // numbers, but without any fixed stride - the list for each dimension is // an IndirectionList. It does not have any concept of loop variables, // however, like Index does, so it cannot be used in any kind of tensor-like // expression. // // You can construct a Grid object using other domain objects. // The constructors accept up to 7 domain objects of various types. // Domain types are, for example, Loc, Grid, Interval. int may also be used // in the constructor for Grid; it acts like a Loc<1> object // in that context. The domain arguments for the Grid // constructors are combined together to form a single domain object with // a dimension equal to the sum of the arguments dimensions; for example, // if you try to create a Grid<3> from a Loc<2> and an Interval<1>, e.g. // Grid<3> a(Loc<2>(1,2), Interval<1>(3,5)); // the Loc<2> and Interval arguments are combined into a (2+1=3) dimensional // domain object, used to initialize the Grid<3>. The number of dimensions // for the arguments must be <= number of dimensions of the newly constructed // Grid. // // Grid, unlike other domain objects, can also be constructed with // IndirectionList objects. IndirectionList's look like 1D domain objects // to the constructor of Grid, so multiple lists can be used. Grid's can // also be used in this same way to construct other Grid's. // // For Grid<1>, the list of constructors includes the following: // Grid<1> a() - default constructor, which creates an EMPTY Grid // Grid<1> a(n) - sets the Grid to the sequence [0 ... (n-1)], stride 1 // Grid<1> a(m,n) - sets the Grid to the sequence [m ... n], stride 1 or -1 // Grid<1> a(m,n,s) - sets the Grid to the sequence [m ... n], stride s // // The default Grid<1> constructor initializes the Grid to be empty, // that is, to have a length() of zero. In that case, the endpoints are // undefined, as is any operation involving the Grid. // // In addition to the constructors, Grid has the following public // interface, similar to all domain objects. There are two classes of // interface methods, one class which includes methods which any Grid // object has, regardless of dimensions, the other class which includes extra // interface methods that are available for just Grid<1> objects. // // Grid interface: // ------------------- // long size() - return the 'volume' of the domain, which is the product // of the lenghts of the N 1D Grids // bool empty() - return if any of the Grid<1> objects have length == 0 // Grid<1> operator[](int N) - return the Nth Grid<1> in a // multidimensional Grid. For Grid<1> objects, this just // returns the object back. // comparison operators: <, >, !=, ==, <=, >= : compare a Grid to // another domain object. The compared domains must have the same // number of dimensions. // arithmetic accumulation operators +=, -=, *=, /= : add or substract in a // given domain. The added domain must have the same number of // dimensions, or a dimension of 1 (in which case, the same value // is used for all dimensions), and be known to be single-valued (which // is true for Loc and int's). Note that for Grid, *= and /= ARE // allowed, since Grid can have its stride changed at run time. *= // and /= result in scaling of the endpoints and stride, which leaves // the length (and size) the same. += and -= shift the beginning // endpoints by the given values, also leaving the length and size the // same. Negation of a Grid negates the endpoints and stride. // binary arithmethic operators +, -, *, / : for + and -, adding a Grid // to another Loc or int returns a new Grid. For * and /, scaling // by a Loc or int also returns a Grid object, since the stride may // change. // increment/decrement operator ++, -- : only prefix versions of ++ and -- // are provided; they act just like += 1 and -= 1 operations. // // Grid<1> interface: // ------------------- // all of the methods for Grid are also available for Grid<1>. Plus: // int length() - number of elements (including endpoints) of the domain. // for a non-unit-stride Grid, the length refers to the number of // strided points (including the endpoints), NOT the difference between // the first and last endpoint. That is, length = (end-beg)/stride + 1, // NOT (end-beg) + 1. // int first() - the beginning endpoint. // int last() - the ending endpoint. // int min(), int max() - min or max of the endpoints. // Interval<1>::iterator begin() and end() - return iterators for the 1D // domain. These act like (at least) bidirectional iterators. // // For the special case of Grid<1>, there is a specialization given // after the general case that has different constructors. // // Grid inherits much of its activity from Domain> // //----------------------------------------------------------------------------- template class Grid : public Domain > > { // convenience typedefs typedef DomainTraits< Grid > DT_t; typedef Domain Base_t; public: // Typedefs from parent class and DomainTraits typedef typename Base_t::iterator iterator; typedef typename Base_t::const_iterator const_iterator; typedef typename Base_t::blockIterator blockIterator; typedef typename Base_t::const_blockIterator const_blockIterator; typedef typename DT_t::Element_t Element_t; typedef typename DT_t::Domain_t Domain_t; typedef typename DT_t::OneDomain_t OneDomain_t; typedef typename DT_t::BlockDomain_t BlockDomain_t; typedef typename DT_t::AskDomain_t AskDomain_t; typedef typename DT_t::AddResult_t AddResult_t; typedef typename DT_t::MultResult_t MultResult_t; typedef typename DT_t::Storage_t Storage_t; // duplicate static data from traits class static const bool domain = DT_t::domain; static const int dimensions = DT_t::dimensions; static const int sliceDimensions = DT_t::sliceDimensions; static const bool loopAware = DT_t::loopAware; static const bool singleValued = DT_t::singleValued; static const bool unitStride = DT_t::unitStride; static const bool wildcard = DT_t::wildcard; // // Constructors. // // default constructor : initialize to an empty domain Grid() { } // copy constructor Grid(const Grid &a) { NewDomain1 >::fill(*this, a); } // templated constructors, taking from 1 to 7 different domain objects // (or integers). template explicit Grid(const T1 &a) { NewDomain1::fill(*this, a); } template Grid(const T1 &a, const T2 &b) { NewDomain2::fill(*this, a, b); } template Grid(const T1 &a, const T2 &b, const T3 &c) { NewDomain3::fill(*this, a, b, c); } template Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d) { NewDomain4::fill(*this, a, b, c, d); } template Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e) { NewDomain5::fill(*this, a, b, c, d, e); } template Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e, const T6 &f) { NewDomain6::fill(*this, a, b, c, d, e, f); } template Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e, const T6 &f, const T7 &g) { NewDomain7::fill(*this, a, b, c, d, e, f, g); } // // Destructor. For this class there is nothing to do. // ~Grid() { for (int i=0;i Grid &operator=(const T &newdom) { return NewDomain1::fill(*this, newdom); } Grid &operator=(const Grid &newdom) { return NewDomain1 >::fill(*this, newdom); } // // I/O/ // // print a Grid to a stream, in the format // "[" value1,value2,...,valueN "]" template void print(Out &o) const { iterator p = begin(); iterator pend = end(); o << "["; while (p != pend) { o << *p; ++p; if (p != pend) o << ","; } o << "]"; } protected: private: }; //----------------------------------------------------------------------------- // // Full Description of Grid<1>: // // Grid<1> is a 1D specialization of Grid; for the 1D case, // there are only a restricted set of constructors available. // For the special case of Grid<1>, the following constructors // are defined: // Grid<1> a() - default constructor, which creates an EMPTY Grid // Grid<1> a(n) - sets the Grid to the sequence [0 ... (n-1)], stride 1 // Grid<1> a(m,n) - sets the Grid to the sequence [m ... n], stride 1 or -1 // Grid<1> a(m,n,s) - sets the Grid to the sequence [m ... n], stride s // Grid<1> a(Domain d) : a Grid copied from d, which must be a // 1D domain object. // //----------------------------------------------------------------------------- template<> class Grid<1> : public Domain<1, DomainTraits > > { // convenience typedef typedef DomainTraits< Grid<1> > DT_t; public: // typedefs from DomainTraits typedef DT_t::Element_t Element_t; typedef DT_t::Domain_t Domain_t; typedef DT_t::OneDomain_t OneDomain_t; typedef DT_t::BlockDomain_t BlockDomain_t; typedef DT_t::AskDomain_t AskDomain_t; typedef DT_t::AddResult_t AddResult_t; typedef DT_t::MultResult_t MultResult_t; typedef DT_t::Storage_t Storage_t; // duplicate static data from traits class static const bool domain = DT_t::domain; static const int dimensions = DT_t::dimensions; static const int sliceDimensions = DT_t::sliceDimensions; static const bool loopAware = DT_t::loopAware; static const bool singleValued = DT_t::singleValued; static const bool unitStride = DT_t::unitStride; static const bool wildcard = DT_t::wildcard; // // Constructors. // // default constructor Grid() { } // copy constructor Grid(const Grid<1> &a) { NewDomain1 >::fill(*this, a); } // general argument constructor, to copy from a different domain type template explicit Grid(const T1 &a) { NewDomain1::fill(*this, a); } // initialize from a single scalar. must specialize to all scalars. Grid(char a) { PAssert(a != 0); DomainTraits >::setDomain(domain_m, 0, a - 1); } Grid(unsigned char a) { PAssert(a != 0); DomainTraits >::setDomain(domain_m, 0, a - 1); } Grid(short a) { PAssert(a != 0); short s = (a < 0 ? -1 : 1); DomainTraits >::setDomain(domain_m, 0, a - s); } Grid(unsigned short a) { PAssert(a != 0); DomainTraits >::setDomain(domain_m, 0, a - 1); } Grid(int a) { PAssert(a != 0); int s = (a < 0 ? -1 : 1); DomainTraits >::setDomain(domain_m, 0, a - s); } Grid(unsigned int a) { PAssert(a != 0); DomainTraits >::setDomain(domain_m, 0, a - 1); } Grid(long a) { PAssert(a != 0); long s = (a < 0 ? -1 : 1); DomainTraits >::setDomain(domain_m, 0, a - s); } Grid(unsigned long a) { PAssert(a != 0); DomainTraits >::setDomain(domain_m, 0, a - 1); } // initialize from a set of endpoints: sets range to [m ..n]. // domain_m is the domain information storage kept in the base class. template Grid(const T1 &m, const T2 &n) { DomainTraits >::setDomain(domain_m, m, n); } // initialize from a set of endpoints and with a given stride. // domain_m is the domain information storage kept in the base class. template Grid(const T1 &m, const T2 &n, const T3 &s) { DomainTraits >::setDomain(domain_m, m, n, s); } // // Destructor. For this class there is nothing to do. // ~Grid() { } // // operator=, templated to allow assignment from other domain objects // this uses the same mechanism as the constructors to fill in to this // object the data from the given object. If the new object has too // few dimensions, this will only change the first M dimensions of this // object, where M is the number of dimensions for newdom // template Grid<1> &operator=(const T &newdom) { return NewDomain1::fill(*this, newdom); } Grid<1> &operator=(const Grid<1> &newdom) { return NewDomain1 >::fill(*this, newdom); } // // A special function used to initialize one Grid from another. For // this, we need non-modifiable access to the storage. // const Storage_t &storage() const { return domain_m; } // // I/O/ // // print a Grid to a stream, in the format // "[" value1,value2,...,valueN "]" template void print(Out &o) const { iterator p = begin(); iterator pend = end(); o << "["; while (p != pend) { o << *p; ++p; if (p != pend) o << ","; } o << "]"; } }; ////////////////////////////////////////////////////////////////////// // // print a Grid to a stream, in the format // "[" value1,value2,...,valueN "]" // ////////////////////////////////////////////////////////////////////// template std::ostream& operator<<(std::ostream &o, const Grid &grid) { grid.print(o); return o; } ////////////////////////////////////////////////////////////////////// // // Specialization of the CHEETAH Serialize class for Grid<1>. // ////////////////////////////////////////////////////////////////////// #if POOMA_CHEETAH #include "Cheetah/Cheetah.h" namespace Cheetah { template<> class Serialize > { public: typedef Grid<1> Grid_t; typedef Grid_t::Element_t Element_t; typedef IndirectionList List_t; static inline long size(const Grid_t &a) { return sizeof(int) + a.length() * sizeof(Element_t); } static inline int pack(const Grid_t &a, char *buffer) { *reinterpret_cast(buffer) = a.length(); long length = a.length() * sizeof(Element_t); memcpy(buffer + sizeof(int), &a.storage()(0), length); return sizeof(int) + length; } static inline int unpack(Grid_t* &a, char *buffer) { int length = *reinterpret_cast(buffer); List_t list(length); length *= sizeof(Element_t); memcpy(&list(0), buffer + sizeof(int), length); a = new Grid_t(list); return sizeof(int) + length; } static inline void cleanup(Grid_t* a) { delete a; } }; } // namespace Cheetah #endif // POOMA_CHEETAH #endif // POOMA_DOMAIN_GRID_H // ACL:rcsinfo // ---------------------------------------------------------------------- // $RCSfile: Grid.h,v $ $Author: cummings $ // $Revision: 1.11 $ $Date: 2001/04/13 02:12:59 $ // ---------------------------------------------------------------------- // ACL:rcsinfo