Skip to content

stencil_copy test fails after adding an additional elementwise function into the pipeline. #759

Description

@vksnk

This is basically a stencil::2d test, but I added an elementwise op right before stencil copy. It's possible I messed something up, but it does pass some of the tests, but for some it produces incorrect results or crashes altogether.

To reproduce insert the test below and run:

bazel run -c dbg //slinky/builder/test:stencil_pipeline --test_filter=*2d_interm*
TEST_P(stencil, 2d_interm) {
  const bool no_alias_buffers = std::get<0>(GetParam());
  const int S = std::get<1>(GetParam());
  const int D = std::get<2>(GetParam());
  const int K = std::get<3>(GetParam());
  const int split = std::get<4>(GetParam());

  // Make the pipeline
  node_context ctx;

  auto in = buffer_expr::make(ctx, "in", 2, sizeof(short));
  auto intm = buffer_expr::make(ctx, "intm", 2, sizeof(short));
  auto out = buffer_expr::make(ctx, "out", 2, sizeof(short));

  in->dim(0).fold_factor = dim::unfolded;
  in->dim(1).fold_factor = dim::unfolded;

  auto stencil = buffer_expr::make(ctx, "stencil", 4, sizeof(short));

  var x(ctx, "x");
  var y(ctx, "y");
  var dx(ctx, "dx");
  var dy(ctx, "dy");

  func mul1 = func::make(multiply_2<int>, {{in, {point(x), point(y)}}}, {{intm, {x, y}}});

  // See the 1d version for a 1D description of what this is doing in 2D.
  func stencil_copy = func::make_copy({intm, {point(x * S + dx * D), point(y * S + dy * D)}}, {stencil, {x, y, dx, dy}});
  auto sum_23 = [K](const buffer<const short>& in, const buffer<short>& out) {
    return sum(in, out, /*dims=*/{{2, 0, K - 1}, {3, 0, K - 1}});
  };
  func reduce = func::make(
      std::move(sum_23), {{stencil, {point(x), point(y), min_extent(0, K), min_extent(0, K)}}}, {{{out, {x, y}}}});

  if (split > 0) {
    reduce.loops({{x, split}, {y, split}});
  }

  pipeline p = build_pipeline(ctx, {in}, {out}, build_options{.no_alias_buffers = no_alias_buffers});

  // Run the pipeline.
  const int W = 10;
  const int H = 5;

  buffer<short, 2> out_buf({W, H});
  out_buf.allocate();

  buffer<short, 2> in_buf({(W - 1) * S + (K - 1) * D + 1, (H - 1) * S + (K - 1) * D + 1});
  init_random(in_buf);

  // Not having span(std::initializer_list<T>) is unfortunate.
  const raw_buffer* inputs[] = {&in_buf};
  const raw_buffer* outputs[] = {&out_buf};
  test_context eval_ctx;
  p.evaluate(inputs, outputs, eval_ctx);

  for (int y = 0; y < H; ++y) {
    for (int x = 0; x < W; ++x) {
      int expected = 0;
      for (int dy = 0; dy < K; ++dy) {
        for (int dx = 0; dx < K; ++dx) {
          expected += 2 * in_buf(x * S + dx * D, y * S + dy * D);
        }
      }
      ASSERT_EQ(expected, out_buf(x, y));
    }
  }

  // if (!no_alias_buffers) {
  //   ASSERT_EQ(eval_ctx.heap.allocs.size(), 1);
  //   ASSERT_EQ(eval_ctx.copy_calls, 0);
  // } else {
  //   ASSERT_EQ(eval_ctx.heap.allocs.size(), 2);
  // }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions