Commit 55500ab0 authored by Swann Perarnau's avatar Swann Perarnau

[feature/refactor] add tileid function

Instead of asking the user to provide the offsets into a tiling, add a
function providing a tileid. This tileid corresponds to the in-memory
order of tiles, making the tilestart functions a lot simpler.

We still need to split the tileid for tilestart because scratchpads
create requests based on tileids.

Also add a unit test for tiling_2d, to make sure we're not doing
anything crazy.
parent d4fa5289
......@@ -780,6 +780,7 @@ struct aml_tiling_ops {
struct aml_tiling_iterator *iterator, int flags);
int (*destroy_iterator)(struct aml_tiling_data *tiling,
struct aml_tiling_iterator *iterator);
int (*tileid)(const struct aml_tiling_data *tiling, va_list);
size_t (*tilesize)(const struct aml_tiling_data *tiling, int tileid);
void* (*tilestart)(const struct aml_tiling_data *tiling,
const void *ptr, int tileid);
......@@ -791,6 +792,17 @@ struct aml_tiling {
struct aml_tiling_data *data;
};
/*
* Provides the tile id of a tile.
* "tiling": an initialized tiling structure.
* Variadic arguments:
* - a list of size_t coordinates, one per dimension of the tiling.
* Returns the id of the tile (that is, its order in memory), to use with other
* functions.
* Returns -1 in case of invalid coordinates.
*/
int aml_tiling_tileid(const struct aml_tiling *tiling, ...);
/*
* Provides the information on the size of a tile.
* "tiling": an initialized tiling structure.
......
......@@ -4,6 +4,17 @@
/*******************************************************************************
* Tiling functions
******************************************************************************/
int aml_tiling_tileid(const struct aml_tiling *t, ...)
{
assert(t != NULL);
va_list ap;
int ret;
va_start(ap, t);
ret = t->ops->tileid(t->data, ap);
va_end(ap);
return ret;
}
size_t aml_tiling_tilesize(const struct aml_tiling *t, int tileid)
{
assert(t != NULL);
......
......@@ -49,11 +49,22 @@ struct aml_tiling_iterator_ops aml_tiling_iterator_1d_ops = {
* 1D ops
******************************************************************************/
int aml_tiling_1d_tileid(const struct aml_tiling_data *t, va_list ap)
{
const struct aml_tiling_1d_data *data =
(const struct aml_tiling_1d_data *)t;
size_t x = va_arg(ap, size_t);
return x;
}
size_t aml_tiling_1d_tilesize(const struct aml_tiling_data *t, int tileid)
{
const struct aml_tiling_1d_data *data =
(const struct aml_tiling_1d_data *)t;
return data->blocksize;
if(tileid < 0)
return 0;
else
return data->blocksize;
}
void* aml_tiling_1d_tilestart(const struct aml_tiling_data *t, const void *ptr, int tileid)
......@@ -61,7 +72,10 @@ void* aml_tiling_1d_tilestart(const struct aml_tiling_data *t, const void *ptr,
const struct aml_tiling_1d_data *data =
(const struct aml_tiling_1d_data *)t;
intptr_t p = (intptr_t)ptr;
return (void *)(p + tileid*data->blocksize);
if(tileid < 0)
return NULL;
else
return (void *)(p + tileid*data->blocksize);
}
int aml_tiling_1d_ndims(const struct aml_tiling_data *t, va_list ap)
......@@ -113,6 +127,7 @@ struct aml_tiling_ops aml_tiling_1d_ops = {
aml_tiling_1d_create_iterator,
aml_tiling_1d_init_iterator,
aml_tiling_1d_destroy_iterator,
aml_tiling_1d_tileid,
aml_tiling_1d_tilesize,
aml_tiling_1d_tilestart,
aml_tiling_1d_ndims,
......
......@@ -47,54 +47,64 @@ struct aml_tiling_iterator_ops aml_tiling_iterator_2d_ops = {
/*******************************************************************************
* 2D ops
* Tileids are always in rowmajor: for NM matrix[i][j], tileid = i*M + j
* Tileids are the order in memory of the tiles.
******************************************************************************/
size_t aml_tiling_2d_tilesize(const struct aml_tiling_data *t, int tileid)
int aml_tiling_2d_rowmajor_tileid(const struct aml_tiling_data *t, va_list ap)
{
const struct aml_tiling_2d_data *data =
(const struct aml_tiling_2d_data *)t;
return data->blocksize;
size_t row = va_arg(ap, size_t);
size_t col = va_arg(ap, size_t);
if(row >= data->ndims[0] || col >= data->ndims[1])
return -1;
else
return (row*data->ndims[1]) + col;
}
void* aml_tiling_2d_rowmajor_tilestart(const struct aml_tiling_data *t,
const void *ptr, int tileid)
int aml_tiling_2d_colmajor_tileid(const struct aml_tiling_data *t, va_list ap)
{
const struct aml_tiling_2d_data *data =
(const struct aml_tiling_2d_data *)t;
intptr_t p = (intptr_t)ptr;
size_t i = tileid/data->ndims[1];
size_t j = tileid % data->ndims[1];
if(i >= data->ndims[0] || j >= data->ndims[1])
return NULL;
size_t row = va_arg(ap, size_t);
size_t col = va_arg(ap, size_t);
if(row >= data->ndims[0] || col >= data->ndims[1])
return -1;
else
return (void *)(p + tileid*data->blocksize);
return (col*data->ndims[0]) + row;
}
void* aml_tiling_2d_colmajor_tilestart(const struct aml_tiling_data *t,
const void *ptr, int tileid)
size_t aml_tiling_2d_tilesize(const struct aml_tiling_data *t, int tileid)
{
const struct aml_tiling_2d_data *data =
(const struct aml_tiling_2d_data *)t;
if(tileid < 0 || tileid >= data->ndims[0]*data->ndims[1])
return 0;
else
return data->blocksize;
}
void* aml_tiling_2d_tilestart(const struct aml_tiling_data *t,
const void *ptr, int tileid)
{
const struct aml_tiling_2d_data *data =
(const struct aml_tiling_2d_data *)t;
intptr_t p = (intptr_t)ptr;
size_t i = tileid/data->ndims[1];
size_t j = tileid % data->ndims[1];
size_t offset = j*data->ndims[0] + i;
if(i >= data->ndims[0] || j >= data->ndims[1])
if(tileid < 0 || tileid >= data->ndims[0]*data->ndims[1])
return NULL;
else
return (void *)(p + offset*data->blocksize);
return (void *)(p + tileid*data->blocksize);
}
int aml_tiling_2d_ndims(const struct aml_tiling_data *t, va_list ap)
{
const struct aml_tiling_2d_data *data =
(const struct aml_tiling_2d_data *)t;
size_t *x = va_arg(ap, size_t *);
size_t *y = va_arg(ap, size_t *);
size_t *nrows = va_arg(ap, size_t *);
size_t *ncols = va_arg(ap, size_t *);
/* looks totally wrong */
*x = data->ndims[0];
*y = data->ndims[1];
*nrows = data->ndims[0];
*ncols = data->ndims[1];
return 0;
}
......@@ -138,8 +148,9 @@ struct aml_tiling_ops aml_tiling_2d_rowmajor_ops = {
aml_tiling_2d_create_iterator,
aml_tiling_2d_init_iterator,
aml_tiling_2d_destroy_iterator,
aml_tiling_2d_rowmajor_tileid,
aml_tiling_2d_tilesize,
aml_tiling_2d_rowmajor_tilestart,
aml_tiling_2d_tilestart,
aml_tiling_2d_ndims,
};
......@@ -147,7 +158,8 @@ struct aml_tiling_ops aml_tiling_2d_colmajor_ops = {
aml_tiling_2d_create_iterator,
aml_tiling_2d_init_iterator,
aml_tiling_2d_destroy_iterator,
aml_tiling_2d_colmajor_tileid,
aml_tiling_2d_tilesize,
aml_tiling_2d_colmajor_tilestart,
aml_tiling_2d_tilestart,
aml_tiling_2d_ndims,
};
......@@ -20,7 +20,8 @@ AREA_LINUX_TESTS = linux_mbind \
AREA_POSIX_TESTS = area_posix
TILING_TESTS = tiling
TILING_TESTS = tiling \
tiling_2d
BINDING_TESTS = binding
......
#include <aml.h>
#include <assert.h>
#define N 2
#define M 3
int main(int argc, char *argv[])
{
AML_TILING_2D_ROWMAJOR_DECL(trm);
AML_TILING_2D_ROWMAJOR_DECL(trt);
AML_TILING_2D_COLMAJOR_DECL(tcm);
AML_TILING_2D_ROWMAJOR_DECL(tct);
/* Matrices used for checks:
* - rowm: stored in row-major, numbered in memory order
* - rowt: stored in row-major, transposition of rowm
* - colm: stored in col-major, number in memory order
* - colt: stored in col-major, transposition of colt
*
* Matrices shapes:
*
* rowm/colt rowt/colm
* +---+---+---+ +---+---+
* | 0 | 1 | 2 | | 0 | 3 |
* +---+---+---+ +---+---+
* | 3 | 4 | 5 | | 1 | 4 |
* +---+---+---+ +---+---+
* | 2 | 5 |
* +---+---+
* Matrices in memory:
*
* rowm/colm rowt/colt
* +---+---+---+---+---+ +---+---+---+---+---+---+
* | 0 | 1 | 2 | 4 | 5 | | 0 | 3 | 1 | 4 | 2 | 5 |
* +---+---+---+---+---+ +---+---+---+---+---+---+
*/
int num;
int rowm[N][M];
int rowt[M][N];
int colm[M][N];
int colt[N][M];
/* library initialization */
aml_init(&argc, &argv);
/* init matrices */
for(int i = 0; i < N*M; i++)
((int*)rowm)[i] = i;
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
rowt[i][j] = rowm[j][i];
memcpy(colm, rowm, N*M*sizeof(int));
memcpy(colt, rowt, N*M*sizeof(int));
/* initialize the tilings */
aml_tiling_init(&trm, AML_TILING_TYPE_2D_ROWMAJOR,
sizeof(int), N*M*sizeof(int), N, M);
aml_tiling_init(&trt, AML_TILING_TYPE_2D_ROWMAJOR,
sizeof(int), N*M*sizeof(int), M, N);
aml_tiling_init(&tcm, AML_TILING_TYPE_2D_COLMAJOR,
sizeof(int), N*M*sizeof(int), M, N);
aml_tiling_init(&tct, AML_TILING_TYPE_2D_COLMAJOR,
sizeof(int), N*M*sizeof(int), N, M);
size_t ndims[2];
aml_tiling_ndims(&trm, &ndims[0], &ndims[1]);
assert(ndims[0] == N && ndims[1] == M);
aml_tiling_ndims(&tcm, &ndims[0], &ndims[1]);
assert(ndims[0] == M && ndims[1] == N);
/* check that the tilings gives me the right ids */
num = 0;
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
{
int irow = aml_tiling_tileid(&trm, i, j);
int icol = aml_tiling_tileid(&tcm, j, i);
assert(irow == icol && irow == num);
num++;
}
/* check that the tiling gives the right starts */
num = 0;
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
{
int irow = aml_tiling_tileid(&trm, i, j);
int icol = aml_tiling_tileid(&tcm, j, i);
int *rm = aml_tiling_tilestart(&trm, &rowm, irow);
int *cm = aml_tiling_tilestart(&tcm, &colm, icol);
assert(*rm == num && *cm == num);
num++;
}
/* check that applying a column-major tiling on a row-major matrix gives
* us its transposition. */
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
{
int icm = aml_tiling_tileid(&tcm, j, i);
int *cm = aml_tiling_tilestart(&tcm, &rowm, icm);
int irt = aml_tiling_tileid(&trt, j, i);
int *rt = aml_tiling_tilestart(&trt, &rowt, irt);
assert(*cm == *rt);
}
/* check that applying a row-major tiling on a col-major matrix gives
* us its transposition. */
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
int irm = aml_tiling_tileid(&trm, j, i);
int *rm = aml_tiling_tilestart(&trm, &colm, irm);
int ict = aml_tiling_tileid(&tct, j, i);
int *ct = aml_tiling_tilestart(&tct, &rowt, ict);
assert(*rm == *ct);
}
/* delete the tilings */
aml_tiling_destroy(&trm, AML_TILING_TYPE_2D_ROWMAJOR);
aml_tiling_destroy(&trt, AML_TILING_TYPE_2D_ROWMAJOR);
aml_tiling_destroy(&tcm, AML_TILING_TYPE_2D_COLMAJOR);
aml_tiling_destroy(&tct, AML_TILING_TYPE_2D_COLMAJOR);
aml_finalize();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment