Reproducible Global Sums

Open
#604 4 comments 0 reactions 2 assignees View on GitHub

@TeranIvy is already working on this.

Since Nov 28, 2019.

Assessment

This issue has not been assessed yet.

Description

LFRic

Reproducible global sums are more expensive and potentially unaffordable for production running. However, they can be useful for debugging purposes so that different processor decompositions don't change the answer.

This can be implemented by adding a new builtin for the reproducible global sums, and simply copying the UM version.
Ben Shipway has started to add a PSyclone builtin to his local copy. It looks like this ...
The generated code looks OK!

class DynXKahanproductYKern(DynBuiltIn):
''' Calculates the inner product of two fields, using Kahan's method
to retain precision in the sum
innprod = SUM( X(:)*Y(:) ) '''

def __str__(self):
    return "Built-in: X_kahanproduct_Y"

def gen_code(self, parent):
    '''
    Generates Dynamo0.3 API specific PSy code for a call to the
    X_kahanproduct_Y Built-in.

    :param parent: Node in f2pygen tree to which to add call
    :type parent: :py:class:`psyclone.f2pygen.BaseGen`
    '''
    from psyclone.f2pygen import AssignGen, DeclGen
    # We sum the DoF-wise product of the supplied fields. The variable
    # holding the sum is initialised to zero in the psy layer.
    # This uses Kahan's method which requires additional local
    # variables
    parent.add(DeclGen(parent, datatype="real", kind="r_def",
                       entity_decls=["local_sum", "corr"],
                       initial_values=["0.0_r_def", "0.0_r_def"]))
    parent.add(DeclGen(parent, datatype="real", kind="r_def",
                       entity_decls=["new_sum", "corr_next"]))
    innprod_name = self._reduction_ref(self._arguments.args[0].name)
    field_name1 = self.array_ref(self._arguments.args[1].proxy_name)
    field_name2 = self.array_ref(self._arguments.args[2].proxy_name)
    # Kahan's method
    rhs_expr =  "corr +" + field_name1 + "*" + field_name2
    parent.add(AssignGen(parent, lhs="corr_next", rhs=rhs_expr))
    parent.add(AssignGen(parent, lhs="new_sum", rhs="local_sum + corr"))
    parent.add(AssignGen(parent, lhs="corr", rhs="corr_next - (new_sum - local_sum)"))
    parent.add(AssignGen(parent, lhs="local_sum", rhs="new_sum"))
    rhs_expr = "local_sum + corr"
    parent.parent.add(AssignGen(parent.parent, lhs=innprod_name, rhs=rhs_expr))
Dominant language
Python
Stars
137
Forks
36
Avg merge
6d 16h
Merged PRs (30d)
18

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stfc/PSyclone

All issues in stfc/PSyclone

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.