23
Tutorial Part 6

Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

Tutorial  Part  6  

Page 2: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

Mo-va-on  and  Requirements  

2  

Page 3: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Consider  horizontal  deriva-ve  

}  Fortran  implementa-on  

3  

z  

x  

Page 4: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Stencil  func-on  advantages  ◦  Closer  to  mathema-cs  ◦  Decompose  complex  update  func-ons  ◦  Reduce  code  duplica-on  /  increased  code  reuse  

}  Stencil  func-on  piDalls  ◦  Run-me  overheads  

4  

Page 5: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Stencil  func-ons  should  be  run-me  overhead  free  

}  Transparently  support  different  parameter  types  ◦  Data  field  parameters  ◦  Scalar  parameters  ◦  Func-on  parameters  

5  

Page 6: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Func-ons  are  of  key  importance  for  code  maintainability  

6  

Page 7: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

Defini-on  and  Implementa-on  

7  

Page 8: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Similar  to  a  Stencil  Stage  ◦  Structure  with  a  single  template  parameter  TEnv  ◦  A  sta-c  Do  method  implemen-ng  the  func-on  

}  Note  that  parameters  are  not  addressed  using  an  enum  ◦  Func-ons  are  used  by  different  stencils  with  different  parameter  enums  ◦  Parameters  are  numbered  instead  

8  

template<typename  TEnv>    struct  MyFunction  {      STENCIL_FUNCTION(TEnv)        FUNCTION_PARAMETER(0,  param0)      FUNCTION_PARAMETER(1,  param1)            static  T  Do(Context  ctx)        {            return  ctx[param0::Center()]  +  ctx[param1::Center()];          }  };  

Page 9: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Macros  support  the  StencilFunc-on  defini-on  ◦  STENCIL_FUNCTION(TEnv)  à  Define  environment  types  T  and  Context      ◦  FUNCTION_PARAMETER(number,  param)  à  Declare  a  parameter  param  and  assign  it  a  number  

}  Parameters  have  to  be  numbered  con-nuously  star-ng  with  0  

9  

template<typename  TEnv>    struct  MyFunction  {      STENCIL_FUNCTION(TEnv)            FUNCTION_PARAMETER(0,  param0)      FUNCTION_PARAMETER(1,  param1)      FUNCTION_PARAMETER(2,  param2)      FUNCTION_PARAMETER(3,  param3)            static  T  Do(Context  ctx)    {  /*…*/  }  };  

An  explicit  numbering  is  necessary  as  the  framework  cannot  determine  the  order  

of  the  defini-ons  

Page 10: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  The  sta-c  Do  method  implements  the  update-­‐func-on  ◦  It  may  return  a  value  of  type  T  or  void  ◦  An  op-onal  domain  parameter  allows  to  provide  domain  specific  Do  implementa-ons  

10  

template<typename  TEnv>    struct  ReturnValue  {      //  do  method  returning  a  value      static  T  Do(Context  ctx)  {  return  (T)0.0;  }  };    template<typename  TEnv>    struct  NoReturnValue  {      //  do  method  without  return  value      static  void  Do(Context  ctx)  {  ctx[param0::Center()]  =  (T)0.0;  }  };    template<typename  TEnv>    struct  OptionalDomainParameter  {      //  domain  specific  do  methods      static  void  Do(Context  ctx,  TerrainCoordinates)  {  ctx[param0::Center()]  =  (T)1.0;  }      static  void  Do(Context  ctx,  FlatCoordinates)  {  ctx[param0::Center()]  =  (T)0.0;  }  };  

Simplified  stencil  func-ons  illustra-ng  the  different  Do  signatures  

Page 11: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Func-ons  are  evaluated  using  the  Context  bracket  operator  ◦  Analog  to  the  parameter  evalua-on  

}  A  Call  structure  wraps  the  StencilFunc-on  ◦  It  provides  a  sta-c  With  method  for  passing  parameters    ◦  Op-onally  a  domain  can  be  passed  à  call  domain  specific  Do  method  

11  

static  void  Do(Context  ctx,  TerrainCoordinates)    {            //  call  a  function  returning  a  value      T  result  =  ctx[Call<ReturnValue>::With(param0::Center(),  param1::At(iplus1))];            //  call  a  function  not  returning  a  value      ctx[Call<NoReturnValue>::With(param0::Center(),  param1::Center())];            //  call  a  function  with  a  TerrainCoordinates  specific  Do  method      ctx[Call<OptionalDomainParameter,  TerrainCoordinates>::With(param0::Center())];  }    static  void  Do(Context  ctx,  FlatCoordinates)    {      //  call  a  function  with  a  FlatCoordinates  specific  Do  method      ctx[Call<OptionalDomainParameter,  FlatCoordinates>::With(param0::Center())];  }  

Shi_  param1  to  i+1  

Page 12: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Some-mes  not  all  func-on  parameters  are  used  ◦  E.g.  the  a  correc-on  factor  might  be  needed  in  J  but  not  in  I  direc-on  

}  Therefore  there  is  a  DummyParameter  ◦  If  the  stencil  func-on  accesses  the  DummyParameter  you  get  an  error  

12  

static  void  Do(Context  ctx,  TerrainCoordinates)  {      ctx[ppgradu::Center()]  =  ctx[Call<Gradient,  TerrainCoordinates>::With(iplus1,            ppuv::Center(),            ppgradcor::Center(),            hhl::Center()      )];  }    //  pass  dummy  parameters  in  the  flat  coordinate  domain  static  void  Do(Context  ctx,  FlatCoordinates)  {      ctx[ppgradu::Center()]  =  ctx[Call<Gradient,  FlatCoordinates>::With(iplus1,            ppuv::Center(),            DummyParameter(),            DummyParameter()      )];  }  

ppgradcor  and  hhl  are  not  used  in  the  FlatCoordinates  domain  

Page 13: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  It  is  o_en  useful  to  pass  a  offset  /  direc-on  argument  ◦  E.g.  one  func-on  can  implement  advec-on  in  I  and  J  direc-on  

}  Func-on  parameters  can  have  an  arbitrary  type  e.g.  an  Offset  

13  

//  define  an  average  method  taking  an  offset  parameter  template<typename  TEnv>  struct  Average  {              STENCIL_FUNCTION(TEnv)            FUNCTION_PARAMETER(0,  offset)          FUNCTION_PARAMETER(1,  data)                    static  T  Do(Context  ctx)          {                  return  (T)0.5  *  (ctx[data::Center()]  +  ctx[data::At(offset())]);          }  };    //  usage  of  the  average  method  static  void  Do(Context  ctx,  FullDomain)    {      T  dataAvgIPlus1  =  ctx[Call<Average>::With(iplus1,  data::Center())];      T  dataAvgJPlus1  =  ctx[Call<Average>::With(jplus1,  data::Center())];    }  

Instan-ate  the  offset  parameter  in  order  to  access  data  at  offset  

data  

data  

x  

y  

Page 14: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Func-ons  accept  other  func-ons  as  parameters  ◦  Combine  simple  building  block  to  define  more  complex  calcula-ons  

14  

static  void  Do(Context  ctx,  FullDomain)    {      T  dataAvgIJ  =  ctx[Call<Delta>::With(iplus1,  Call<Average>::With(jplus1,  data::Center()))];  }  

ctx[Call<Average>::With(jplus1,  data::Center())::At(iplus1)]  -­‐  ctx[Call<Average>::With(jplus1,  data::Center())::Center()]      

((T)0.5  *  (ctx[data::At(iplus1)]  +  ctx[data::At(iplus1)::At(jplus1)]))  -­‐  ((T)0.5  *  (ctx[data::Center()]  +  ctx[data::At(jplus1)]))    

Expand  Delta  

Expand  Average  

=  

=  

data  δx( )y  

Page 15: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  It  is  not  possible  to  pass  temporary  variables  directly  }  Values  passed  to  the  Context  bracket  operator  are  discarded  ◦  In  order  to  keep  the  Context  bracket  operator  run-me  overhead  free  ◦  Sta-c  stencil  accesses  usually  do  not  require  run-me  informa-on  

}  Instead  we  can  pass  temporary  variables  using  a  scalar  buffer  

15  

static  void  Do(Context  ctx,  FullDomain)    {      T  val  =  (T)0.0;      ctx[Call<SomeFunction>::With(val)];  }  

Only  the  type  info  T  but  not  the  value  0.0  is  passed  to  SomeFunc-on  

Page 16: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  The  HP2C  dycore  provides  a  number  of  predefined  func-ons  ◦  Delta,  SymmetricDelta  a(i+1)  –  a(i)  a(i+1)  –  a(i-­‐1)  

◦  Sum,  SymmetricSum  a(i+1)  +  a(i)  a(i+1)  +  a(i-­‐1)  

◦  Average,  SymmetricAverage  0.5*(a(i+1)  +  a(i))  0.5*(a(i+1)  +  a(i-­‐1))  

◦  Delta2K  w*a(k)  +  (1-­‐w)*a(k-­‐1)  ◦  DeltaZ  …      ◦  Gradient  

}  Many  operators  (advec-on,  diffusion,  …)  implemented  as  func-ons  

16  

Page 17: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Many  computa-ons  are  expressed  as  nested  func-on  calls  ◦  Closer  to  the  math  than  a  fully  expanded  formula  and  index  arithme-c's  

17  

ctx[utens::Center()]  +=            ctx[Call<Average>::With(                  jminus1,                    Call<CoriolisForce>::With(                          fc::Center(),                            Call<Average>::With(iplus1,  v::Center())                  )        )];  

z_fv_north  =  fc(i,j)      *  (  v(i,j    ,k,nn)  +  v(i+1,j    ,k,nn)  )  z_fv_south  =  fc(i,j-­‐1)  *  (  v(i,j-­‐1,k,nn)  +  v(i+1,j-­‐1,k,nn)  )  zfq  =  0.25_ireals  *  (  z_fv_north  +  z_fv_south  )  utens(i,j,k)  =  utens(i,j,k)  +  zfq  

ctx[utens::Center()]  +=            ctx[Call<Average>::With(                  mass2u,                    Call<CoriolisForce>::With(                          fc::Center(),                            Call<Average>::With(v2mass,  v::Center())                  )        )];  staggered  grid  

offsets  increase  readability  

Fortran  equivalent  using  “formula  expansion”  and  

absolute  indexing  

Page 18: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Stencil  Func-ons  are  similar  to  Stencil  Stages  ◦  Parameters  are  addressed  by  order  rather  than  via  enum  ◦  Do  methods  can  op-onally  return  a  value  ◦  Do  methods  can  op-onally  take  a  domain  parameter  

}  Stencil  Func-ons  are  powerful  concept  for  structuring  code  ◦  Code  duplica-on  is  reduced  ◦  Code  complexity  is  reduced  

18  

Page 19: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

Review  FastWavesUV  Update  

19  

Page 20: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Frequent  use  of  finite  difference  func-ons  }  Gradient  func-on  working  for  terrain  and  flat  coordinates  }  Bovom  boundary  condi-on  

20  

Page 21: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

Tutorial  6  assignments  

21  

Page 22: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Implement  a  func-on  compu-ng  the  deriva-ve  for  a  given  direc-on  ◦  𝑑𝑑𝑎𝑡𝑎/𝑑𝑑𝑖𝑟 =   𝑑𝑎𝑡𝑎(𝑑𝑖𝑟+1)–  𝑑𝑎𝑡𝑎(𝑑𝑖𝑟−1)/2  ∗  𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒   

}  Compute  the  IJ-­‐deriva-ve  in  2  steps  (2  stencil  stages)  1.  Compute  the  deriva-ve  in  I  and  store  the  result  to  a  buffer  2.  Compute  the  deriva-ve  in  J  given  the  buffer  as  input  

}  Pass  the  distance  as  scalar  parameter    Note  the  framework  provides  a  meta  func-on  which  scales  an  offset:  typedef  typename  scale_offset<dir,  2>::type  DirTimesTwo;  

Your  Tasks:  }  Implement  the  stencil  func-on  }  Implement  the  two  stencil  stages  }  Complete  the  Init  method  }  Verify  correctness   22  

Page 23: Tutorial)Part6) - ETH Z · Stencil)func-ons)should)be)run-me)overhead)free)! Transparently)supportdifferentparameter)types) Datafield)parameters) Scalar)parameters)

}  Reuse  the  func-on  compu-ng  the  deriva-ve  for  a  given  direc-on    ◦  𝑑𝑑𝑎𝑡𝑎/𝑑𝑑𝑖𝑟 =   𝑑𝑎𝑡𝑎(𝑑𝑖𝑟+1)–  𝑑𝑎𝑡𝑎(𝑑𝑖𝑟−1)/2  ∗  𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒   

}  Compute  the  IJ-­‐deriva-ve  in  1  step  (only  1  stencil  stage)  ◦  Compute  the  deriva-ve  on  the  fly  ◦  Pass  the  computa-on  of  the  I-­‐deriva-ve  as  func-on  parameter  

}  Pass  the  distance  as  scalar  parameter  

Your  Tasks:  }  Implement  the  stencil  stage  }  Complete  the  Init  method  }  Verify  correctness  

23