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);
// }
}
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: