Suppose you have a buffer named mtx stored in a shared buffer:
Its size is 10x6 and four kernels need to access it, two for writing and two for reading from it:
kernel k1, k2, k3, k4;
shared_buffer<int> mtx;
mygraph()
{
k1 = kernel::create(func1); k2 = kernel::create(func2);
k3 = kernel::create(func3); k4 = kernel::create(func4);
mtx = shared_buffer<int>::create({10, 6}, 2, 2); // Size:10x6, 2 write-inputs, 2 read-outputs
…
}
Kernel k1 writes to the buffer tile by tile. Each tile is size 3x2 and the read origin is (0,0):
The access scheme is as follows:
Dimension 0: two blocks, three samples apart
Dimension 1: three blocks, two samples apart.
write_access(mtx.in[0]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={3,2}, .offset={0,0}, .tile_traversal = {{.dimension=0, .stride=3, .wrap=2}, {.dimension=1, .stride=2, .wrap=3}}});
Kernel k2 writes to the buffer with different tile size and order:
The access scheme is as follows:
Dimension 1: two blocks, three samples apart
Dimension 0: two blocks, two samples apart
The subset origin is at position (6,0):
write_access(mtx.in[1]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={2,3}, .offset={6,0},
.tile_traversal = {{.dimension=1, .stride=3, .wrap=2},{.dimension=0, .stride=2, .wrap=2}}});
Kernels k3 and k4 read from the buffer differently than it was written:
These access schemes are defined in the graph with the following:
read_access(mtx.out[0]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={2,6}, .offset={0,0},
.tile_traversal = {{.dimension=0, .stride=2, .wrap=2}}});
read_access(mtx.out[1]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={3,6}, .offset={4,0}
.tile_traversal = {{.dimension=0, .stride=3, .wrap=2}}});
The overall C++ code, including the connections of the kernels to the shared_buffer looks like this:
class mygraph : public graph
{
kernel k1, k2, k3, k4;
shared_buffer<int> mtx;
mygraph()
{
k1 = kernel::create(func1); k2 = kernel::create(func2); k3 = kernel::create(func3); k4 = kernel::create(func4);
mtx = shared_buffer<int>::create({10, 6}, 2, 2); // 10x6, 2 write-inputs, 2 read-outputs
connect<> n1(k1.out[0], mtx.in[0]);
write_access(mtx.in[0]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={3,2}, .offset={0,0}, .tile_traversal = {{.order=0, .stride=3, .wrap=2}, {.order=1, .stride=2, .wrap=3}}});
connect<> n2(k2.out[0], mtx.in[1]);
write_access(mtx.in[1]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={2,3}, .offset={6,0},
.tile_traversal = {{.order=0, .stride=2, .wrap=2}, {.order=1, .stride=3, .wrap=2}}});
connect<> n3(mtx.out[0], k3.in[0]);
read_access(mtx.out[0]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={2,6}, .offset={0,0},
.tile_traversal = {{.order=0, .stride=2, .wrap=2}}});
connect<> n4(mtx.out[1], k4.in[0]);
read_access(mtx.out[1]) = tiling({
.buffer_dimension={10,6}, .tiling_dimension={3,6}, .offset={4,0},
.tile_traversal = {{.order=0, .stride=3, .wrap=2}}});
}
};