[RFC] Merge some ScalarCode improvements
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] Merge some ScalarCode improvements



Hi!

I have some improvements to ScalarCode which enhance its usability and
performance.  Unfortunately these patches depend on changes to
ScalarCodeInfo which in turn change user-visible API.  Patch to
ScalarCodeInfo appended below for reference.  The main change is
templating ScalarCodeInfo on dimension and number of MultiArg arguments.

Are you interested in having such changes merged?  Part of the changes
would be bugfixes to allow arbitrary expressions as ScalarCode arguments
(it doesnt handle updating guards correctly for shifted arguments at the
moment).

Richard.

--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/
*** pooma-bk/r2/src/Evaluator/ScalarCodeInfo.h	Thu Oct 23 14:39:32 2003
--- pooma-bib/r2/src/Evaluator/ScalarCodeInfo.h	Thu Jul 15 11:31:53 2004
***************
*** 56,61 ****
--- 56,62 ----
  //-----------------------------------------------------------------------------
  
  #include "Layout/INode.h"
+ #include "Layout/GuardLayers.h"
  
  //-----------------------------------------------------------------------------
  // Forward Declarations:
***************
*** 67,143 ****
  //
  //-----------------------------------------------------------------------------
  
  class ScalarCodeInfo
  {
  public:
!   typedef std::vector<int>  Extents_t;
    typedef std::vector<bool> BoolVector_t;
  
    ScalarCodeInfo()
    {
-     arguments_m = 0;
-     dimensions_m = 0;
-   }
- 
-   /// The number of arguments of the ScalarCode functor. This needs to be
-   /// called before any of write() and useGuards().
-   void arguments(int n)
-   {
-     PAssert(n > 0);
- 
-     arguments_m = n;
-     writers_m.resize(n);
-     readers_m.resize(n);
-     useGuards_m.resize(n);
- 
-     int i;
-     for (i = 0; i < n; ++i)
-     {
-       writers_m[i]   = false;
-       readers_m[i]   = true;
-       useGuards_m[i] = true;
-     }
      writers_m[0] = true;
      readers_m[0] = false;
    }
  
!   /// The number of dimensions the arguments to the ScalarCode functor
!   /// span. This needs to be specified before any of the lowerExtent()
!   /// and upperExtent().
!   void dimensions(int n)
!   {
!     PAssert(n > 0);
! 
!     dimensions_m = n;
!     lower_m.resize(n);
!     upper_m.resize(n);
  
!     int i;
!     for (i = 0; i < n; ++i)
!     {
!       lower_m[i] = 0;
!       upper_m[i] = 0;
!     }
    }
  
!   /// Lower extent for dimension i. This specifies the (maximum) stencil size.
!   /// Note that you need to make sure a view extending the physical domain by
!   /// this amount can be taken of every argument to the functor.
! 
!   int &lowerExtent(int i)
    {
!     return lower_m[i];
    }
  
!   /// Upper extent for dimension i. This specifies the (maximum) stencil size.
!   /// Note that you need to make sure a view extending the physical domain by
!   /// this amount can be taken of every argument to the functor.
! 
!   int &upperExtent(int i)
    {
!     return upper_m[i];
    }
!  
    /// Specify whether argument i is written to, writing allows reading. This
    /// triggers notifying the engine after writing and possibly dirtying
    /// relations attached to a written field.
--- 68,111 ----
  //
  //-----------------------------------------------------------------------------
  
+ template <int Dim, int size>
  class ScalarCodeInfo
  {
  public:
!   enum { dimensions = Dim };
!   enum { arguments = size };
! 
    typedef std::vector<bool> BoolVector_t;
  
    ScalarCodeInfo()
+     : extent_m(GuardLayers<Dim>(0)),
+       useGuards_m(arguments, true),
+       writers_m(arguments, false),
+       readers_m(arguments, true)
    {
      writers_m[0] = true;
      readers_m[0] = false;
    }
  
!   /// Specify the shape of the guard layers used. This is used for taking
!   /// views of the arguments.
  
!   void extent(const GuardLayers<Dim> &g)
!   {
!     extent_m = g;
    }
  
!   GuardLayers<Dim>& extent()
    {
!     return extent_m;
    }
  
!   const GuardLayers<Dim>& extent() const
    {
!     return extent_m;
    }
! 
! 
    /// Specify whether argument i is written to, writing allows reading. This
    /// triggers notifying the engine after writing and possibly dirtying
    /// relations attached to a written field.
***************
*** 170,220 ****
  
    /// The domain we take the view of before passing it to the functors
    /// operator() method.
!   template<int D>
!   inline Interval<D> extendDomain(const Interval<D> &domain)
    {
!     Interval<D> ret;
!     int d;
!     for (d = 0; d < D; ++d)
!     {
!       ret[d] =
! 	        Interval<1>(
!     		    domain[d].first() - lower_m[d],
!     		    domain[d].last() + upper_m[d]
! 		    );
!     }
!     return ret;
    }
  
    /// The domain evaluation takes place on the viewed (zero-based!) engine.
!   template<int D>
!   inline Interval<D> evaluationDomain(const Interval<D> &domain)
    {
!     Interval<D> ret;
!     int d;
!     for (d = 0; d < D; ++d)
      {
!       ret[d] =
! 	Interval<1>(
! 		    lower_m[d],
! 		    domain[d].last() - domain[d].first()  + lower_m[d]
! 		    );
      }
      return ret;
    }
  
!   template<int D>
!   inline INode<D> extendDomain(const INode<D> &inode)
    {
!     return INode<D>(inode, extendDomain(inode.domain()));
    }
  
  private:
  
!   int       arguments_m;
!   int       dimensions_m;
!   Extents_t upper_m;
!   Extents_t lower_m;
    BoolVector_t useGuards_m;
    BoolVector_t writers_m;
    BoolVector_t readers_m;
--- 138,169 ----
  
    /// The domain we take the view of before passing it to the functors
    /// operator() method.
!   inline Interval<Dim> extendDomain(const Interval<Dim> &domain) const
    {
!     return grow(domain, extent_m);
    }
  
    /// The domain evaluation takes place on the viewed (zero-based!) engine.
!   inline Interval<Dim> evaluationDomain(const Interval<Dim> &domain) const
    {
!     Interval<Dim> ret;
!     for (int d = 0; d < Dim; ++d)
      {
!       ret[d] = Interval<1>(extent_m.lower(d),
! 			   domain[d].last() - domain[d].first()
! 			   + extent_m.lower(d));
      }
      return ret;
    }
  
!   inline INode<Dim> extendDomain(const INode<Dim> &inode) const
    {
!     return INode<Dim>(inode, extendDomain(inode.domain()));
    }
  
  private:
  
!   GuardLayers<Dim> extent_m;
    BoolVector_t useGuards_m;
    BoolVector_t writers_m;
    BoolVector_t readers_m;