Skip to content

WIP: Lazy stencil expressions for kernel fusion#3401

Open
bendudson wants to merge 3 commits into
nextfrom
lazy-stencil-operators
Open

WIP: Lazy stencil expressions for kernel fusion#3401
bendudson wants to merge 3 commits into
nextfrom
lazy-stencil-operators

Conversation

@bendudson

Copy link
Copy Markdown
Contributor

Operators return BinaryExpr types that perform derivatives 'lazily'. Like the single index operators they capture a CoordinatesAccessor to provide access to metrics etc. The difference is that the user code doesn't need to create field accessors or explicitly write the loop, capture variables etc. All that is done automatically if the compiler is smart/sufficiently aggressively optimizing.

Implemented DDZ_C2 and DDZ_C4 operators for Z derivatives. These appear to inline as expected in the Hasegawa-Wakatani example.

Return BinaryExpr types, perform derivatives in Z
using CoordinateAccessor to get dz.

Appear to inline in Hasegawa-Wakatani example.
@bendudson bendudson added the work in progress Not ready for merging label Jun 21, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread examples/hasegawa-wakatani/hw.cxx Outdated

ddt(n) =
-bracket(phi, n, bm) + alpha * (nonzonal_phi - nonzonal_n) - kappa * DDZ(phi);
-bracket(phi, n, bm) + alpha * (nonzonal_phi - nonzonal_n) - kappa * DDZ_C2(phi);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "bracket" is directly included [misc-include-cleaner]

        -bracket(phi, n, bm) + alpha * (nonzonal_phi - nonzonal_n) - kappa * DDZ_C2(phi);
         ^

int nz{0};

template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "BOUT_FORCEINLINE" is directly included [misc-include-cleaner]

  BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,
                   ^

int nz{0};

template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "BOUT_HOST_DEVICE" is directly included [misc-include-cleaner]

include/bout/stencil_expr.hxx:1:

- #ifndef BOUT_STENCIL_EXPR_HXX
+ #include "bout/build_config.hxx"
+ #ifndef BOUT_STENCIL_EXPR_HXX

int nz{0};

template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "BoutReal" is directly included [misc-include-cleaner]

include/bout/stencil_expr.hxx:1:

- #ifndef BOUT_STENCIL_EXPR_HXX
+ #include "bout/bout_types.hxx"
+ #ifndef BOUT_STENCIL_EXPR_HXX


template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,
const RView&) const {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: all parameters should be named in a function [readability-named-parameter]

Suggested change
const RView&) const {
const RView& /*unused*/) const {


template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,
const RView&) const {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: all parameters should be named in a function [readability-named-parameter]

Suggested change
const RView&) const {
const RView& /*unused*/) const {

inline bout::stencil::DDZExprC2 DDZ_C2(const Field3D& f) {
checkData(f);

const auto region_id = f.getMesh()->getRegionID("RGN_NOBNDRY");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member access into incomplete type 'Mesh' [clang-diagnostic-error]

  const auto region_id = f.getMesh()->getRegionID("RGN_NOBNDRY");
                                    ^
Additional context

include/bout/field_data.hxx:47: forward declaration of 'Mesh'

class Mesh;
      ^

f.getLocation(),
f.getDirections(),
region_id,
f.getMesh()->getRegion("RGN_NOBNDRY")};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member access into incomplete type 'Mesh' [clang-diagnostic-error]

      f.getMesh()->getRegion("RGN_NOBNDRY")};
                 ^
Additional context

include/bout/field_data.hxx:47: forward declaration of 'Mesh'

class Mesh;
      ^

inline bout::stencil::DDZExprC4 DDZ_C4(const Field3D& f) {
checkData(f);

const auto region_id = f.getMesh()->getRegionID("RGN_NOBNDRY");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member access into incomplete type 'Mesh' [clang-diagnostic-error]

  const auto region_id = f.getMesh()->getRegionID("RGN_NOBNDRY");
                                    ^
Additional context

include/bout/field_data.hxx:47: forward declaration of 'Mesh'

class Mesh;
      ^

f.getLocation(),
f.getDirections(),
region_id,
f.getMesh()->getRegion("RGN_NOBNDRY")};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member access into incomplete type 'Mesh' [clang-diagnostic-error]

      f.getMesh()->getRegion("RGN_NOBNDRY")};
                 ^
Additional context

include/bout/field_data.hxx:47: forward declaration of 'Mesh'

class Mesh;
      ^

Implements Arakawa bracket in X-Z as a BinaryExpr.
Testing the performance impact of runtime dispatch. The hope is to
preserve the ability to switch method at runtime.  The conditional
that selects the method is the same for all iterations, so hopefully
good branch prediction and no warp divergence.

DDZ_Dispatch(f, method) selects between DDZ_C2 and DDZ_C4 at runtime.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions


ddt(n) =
-bracket(phi, n, bm) + alpha * (nonzonal_phi - nonzonal_n) - kappa * DDZ(phi);
ddt(n) = -bracket_arakawa(phi, n) + alpha * (nonzonal_phi - nonzonal_n)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "ddt" is directly included [misc-include-cleaner]

    ddt(n) = -bracket_arakawa(phi, n) + alpha * (nonzonal_phi - nonzonal_n)
    ^

ddt(n) =
-bracket(phi, n, bm) + alpha * (nonzonal_phi - nonzonal_n) - kappa * DDZ(phi);
ddt(n) = -bracket_arakawa(phi, n) + alpha * (nonzonal_phi - nonzonal_n)
- kappa * DDZ_Dispatch(phi, DIFF_C2);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "DIFF_C2" is directly included [misc-include-cleaner]

             - kappa * DDZ_Dispatch(phi, DIFF_C2);
                                         ^

struct DDZ_Dispatch_Op {
CoordinatesAccessor coords;
int nz{0};
DIFF_METHOD method{DIFF_DEFAULT};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "DIFF_DEFAULT" is directly included [misc-include-cleaner]

  DIFF_METHOD method{DIFF_DEFAULT};
                     ^

struct DDZ_Dispatch_Op {
CoordinatesAccessor coords;
int nz{0};
DIFF_METHOD method{DIFF_DEFAULT};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "DIFF_METHOD" is directly included [misc-include-cleaner]

  DIFF_METHOD method{DIFF_DEFAULT};
  ^


template <typename LView, typename RView>
BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,
const RView&) const {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: all parameters should be named in a function [readability-named-parameter]

Suggested change
const RView&) const {
const RView& /*unused*/) const {

BOUT_HOST_DEVICE BOUT_FORCEINLINE BoutReal operator()(int idx, const LView& lhs,
const RView&) const {
switch (method) {
case DIFF_C2:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "DIFF_C2" is directly included [misc-include-cleaner]

    case DIFF_C2:
         ^

switch (method) {
case DIFF_C2:
return apply_c2(idx, lhs);
case DIFF_C4:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "DIFF_C4" is directly included [misc-include-cleaner]

    case DIFF_C4:
         ^


if ((method != DIFF_C2) && (method != DIFF_C4)) {
throw BoutException("DDZ_Dispatch only supports DIFF_C2 and DIFF_C4, got {:s}",
toString(method));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "toString" is directly included [misc-include-cleaner]

                        toString(method));
                        ^

const Field3D& g) {
checkData(f);
checkData(g);
ASSERT1_FIELDS_COMPATIBLE(f, g);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "ASSERT1_FIELDS_COMPATIBLE" is directly included [misc-include-cleaner]

include/bout/stencil_expr.hxx:1:

- #ifndef BOUT_STENCIL_EXPR_HXX
+ #include "bout/field2d.hxx"
+ #ifndef BOUT_STENCIL_EXPR_HXX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

work in progress Not ready for merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant