MeteoSwiss-APN / dawn

Compiler toolchain to enable generation of high-level DSLs for geophysical fluid dynamics models
MIT License
28 stars 30 forks source link

Fix field versioning for solvers #474

Open jdahm opened 5 years ago

jdahm commented 5 years ago

Dawn can currently generate incorrect code for solvers when a field has been versioned. Specifically, this occurs, when there are vertical dependencies in a versioned field. This happens for example with:

#include "gridtools/clang_dsl.hpp"
using namespace gridtools::clang;

stencil test{
        storage in, out;
        Do {
                vertical_region(k_start+1, k_end){
                        in = out[k-1];
                        out = in + 1;
                }
        }
};

The stencil instantiation for this is

  Stencil_0 {
    MultiStage_0 [parallel] {
      Stage_0 {
        Do_0 { Start+1 : End } {
          in[<no_horizontal_offset>,0] = out_0[<no_horizontal_offset>,-1];
            Write Accesses:
              in : [<no_horizontal_extent>,(0,0)]
            Read Accesses:
              out_0 : [<no_horizontal_extent>,(-1,-1)]

          out[<no_horizontal_offset>,0] = (in[<no_horizontal_offset>,0] + 1);
            Write Accesses:
              out : [<no_horizontal_extent>,(0,0)]
            Read Accesses:
              1 : [<no_horizontal_extent>,(0,0)]
              in : [<no_horizontal_extent>,(0,0)]
        }
        Extents: [<no_horizontal_extent>,(0,0)]
      }}}

Notice that this reads from an uninitialized field out_0. PassFixVersionedInputFields, which adds multistages to initialize versioned fields warns the user when it sees this pattern, but it cannot currently fix it. Adding a multistage to initialize out_0 in this case generates invalid code, so we need another approach to address these cases.

dominichofer commented 4 years ago

This might be the same bug we hit with:

stencil vertical_loop_1 {
  storage a;
  var b;
  Do {
    vertical_region(k_start+1, k_end) {
      b = a[k-1];
      a += b;
    }
  }
};
stencil vertical_loop_2 {
  storage a;
  Do {
    vertical_region(k_start+1, k_end) {
      double b = a[k-1];
      a += b;
    }
  }
};

We expect the same output as with this code:

stencil vertical_loop_3 {
  storage a;
  Do {
    vertical_region(k_start+1, k_end) {
      a += a[k-1];
    }
  }
};