Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Tutorial Part 6
Mo-va-on and Requirements
2
} Consider horizontal deriva-ve
} Fortran implementa-on
3
z
x
} 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
} Stencil func-ons should be run-me overhead free
} Transparently support different parameter types ◦ Data field parameters ◦ Scalar parameters ◦ Func-on parameters
5
} Func-ons are of key importance for code maintainability
6
Defini-on and Implementa-on
7
} 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()]; } };
} 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
} 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
} 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
} 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
} 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
} 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
} 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
} 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
} 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
} 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
Review FastWavesUV Update
19
} Frequent use of finite difference func-ons } Gradient func-on working for terrain and flat coordinates } Bovom boundary condi-on
20
Tutorial 6 assignments
21
} 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
} 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