Commit ed30f0ab authored by Swann Perarnau's avatar Swann Perarnau

[feature/refactor] second version of tilings

Refactor the tilings to become generic to N dimensions, and interfacing
with the newly added layouts.

The main idea for this version of tilings is to provide an index into a
partitioning of a source layout into sub-layouts of smaller sizes.
parent eed9ce2c
......@@ -23,8 +23,8 @@ include_aml_scratch_HEADERS = \
include_aml_tilingdir=$(includedir)/aml/tiling
include_aml_tiling_HEADERS = \
aml/tiling/1d.h \
aml/tiling/2d.h
aml/tiling/native.h \
aml/tiling/resize.h
include_amlutilsdir=$(includedir)/aml/utils
......
This diff is collapsed.
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#ifndef AML_TILING_1D_H
#define AML_TILING_1D_H 1
/**
* @defgroup aml_tiling_1d "AML 1D Tiling"
* @brief 1 dimension tiling implementation.
*
* Implementation of 1D tilings.
* @{
**/
/** Initialized structure containing operations on 1D tiling. **/
extern struct aml_tiling_ops aml_tiling_1d_ops;
/** Initialized structure containing operations on 1D tiling. **/
extern struct aml_tiling_iterator_ops aml_tiling_iterator_1d_ops;
/**
* Data of 1 dimension tiling. 1D tiling consists in a set of
* contiguous data blocks.
**/
struct aml_tiling_1d_data {
/** The size of a data block in tiling **/
size_t blocksize;
/** The toal size of the tiling **/
size_t totalsize;
};
/** Data of 1 dimension tiling iterator. **/
struct aml_tiling_iterator_1d_data {
/** Index of the current iteration **/
size_t i;
/** Tiling beeing iterated **/
struct aml_tiling_1d_data *tiling;
};
/**
* Allocates and initializes a new 1D tiling.
*
* @param tiling an address where the pointer to the newly allocated tiling
* structure will be stored.
* @param tilesize provides the size of each tile.
* @param totalsize provides the size of the complete user data structure to be
* tiled.
* @return 0 if successful; an error code otherwise.
**/
int aml_tiling_1d_create(struct aml_tiling **tiling,
size_t tilesize, size_t totalsize);
/**
* Tears down an initialized tiling.
*
* @param tiling a tiling created with aml_tiling_1d_create. NULL after return.
**/
void aml_tiling_1d_destroy(struct aml_tiling **tiling);
/**
* @}
**/
#endif /* AML_TILING_1D_H */
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#ifndef AML_TILING_2D_H
#define AML_TILING_2D_H 1
/**
* @defgroup aml_tiling_2d "AML 2D Tiling"
* @brief 2 dimensions tiling implementation.
*
* Implementation of 2D tilings, i.e a contiguous memory area composed
* of contiguous tiles arranged in 2D grid.
* @{
**/
/**
* Initialized structure containing operations
* on 2D tiling aranged in row major order.
**/
extern struct aml_tiling_ops aml_tiling_2d_rowmajor_ops;
/**
* Initialized structure containing operations
* on 2D tiling aranged in column major order.
**/
extern struct aml_tiling_ops aml_tiling_2d_colmajor_ops;
/**
* Initialized structure containing operations
* on 2D tiling aranged.
**/
extern struct aml_tiling_iterator_ops aml_tiling_iterator_2d_ops;
/**
* Data of 2 dimensions tiling. 2D tiling consists in a set of
* contiguous data blocks with information to iterate on it as a
* 2D structure.
**/
struct aml_tiling_2d_data {
/** The size of a data block in tiling **/
size_t blocksize;
/** The toal size of the tiling **/
size_t totalsize;
/* # number of rows, # number of columns (in tiles) */
size_t ndims[2];
};
/** Data of 2 dimensions tiling iterator. **/
struct aml_tiling_iterator_2d_data {
/** Index of the current iteration **/
size_t i;
/** Tiling beeing iterated **/
struct aml_tiling_2d_data *tiling;
};
/**
* Allocates and initializes a new 2D tiling.
*
* @param tiling an address where the pointer to the newly allocated tiling
* structure will be stored.
* @param type a type of 2D tiling
* @param tilesize provides the size of each tile.
* @param totalsize provides the size of the complete user data structure to be
* tiled.
* @param rowsize the number of tiles in a row
* @param colsize the number of tiles in a column
* @return 0 if successful; an error code otherwise.
**/
int aml_tiling_2d_create(struct aml_tiling **tiling, int type,
size_t tilesize, size_t totalsize,
size_t rowsize, size_t colsize);
/**
* Tears down an initialized tiling.
*
* @param tiling a tiling created with aml_tiling_1d_create. NULL after return.
**/
void aml_tiling_2d_destroy(struct aml_tiling **tiling);
/**
* @}
**/
#endif /* AML_TILING_2D_H */
/*************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
**************************************************************************/
#ifndef AML_TILING_NATIVE_H
#define AML_TILING_NATIVE_H
/**
* @defgroup aml_tiling_native "AML Tiling Internal API"
* @brief API for internal management of tilings.
*
* #include <aml/tiling/native.h>
* @{
**/
struct aml_layout *aml_tiling_index_native(const struct aml_tiling *tiling,
const size_t *coords);
int aml_tiling_dims_native(const struct aml_tiling *tiling, size_t *dims);
/**
* @}
**/
#endif // AML_TILING_NATIVE_H
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#ifndef AML_TILING_RESIZE_H
#define AML_TILING_RESIZE_H 1
/**
* @defgroup aml_tiling_1d "AML Resizable Tiling"
* @brief tiling with not homogeneous tiles
*
* Implementation of a tiling for which the border tiles have the exact size of
* the underlying layout (not smaller, not larger).
* @{
**/
/** Initialized structure containing operations for a tiling in column order.
**/
extern struct aml_tiling_ops aml_tiling_resize_column_ops;
/** Initialized structure containing operations for a tiling in row order. **/
extern struct aml_tiling_ops aml_tiling_resize_row_ops;
struct aml_tiling_resize {
int tags;
const struct aml_layout *layout;
size_t ndims;
size_t *tile_dims;
size_t *dims;
size_t *border_tile_dims;
};
int aml_tiling_resize_create(struct aml_tiling **t, int tags,
const struct aml_layout *l,
size_t ndims, const size_t *tile_dims);
void aml_tiling_resize_destroy(struct aml_tiling **t);
/**
* @}
**/
#endif /* AML_TILING_RESIZE_H */
......@@ -28,8 +28,7 @@ SCRATCH_SOURCES = \
TILING_SOURCES = \
tiling/tiling.c \
tiling/tiling_1d.c \
tiling/tiling_2d.c
tiling/tiling_resize.c
UTILS_SOURCES = \
utils/bitmap.c \
......
......@@ -9,101 +9,96 @@
*******************************************************************************/
#include "aml.h"
#include "aml/tiling/1d.h"
#include "aml/tiling/2d.h"
#include "aml/tiling/native.h"
#include <assert.h>
/*******************************************************************************
* Tiling functions
******************************************************************************/
int aml_tiling_tileid(const struct aml_tiling *t, ...)
int aml_tiling_order(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;
if (t == NULL || t->ops == NULL)
return -AML_EINVAL;
return t->ops->order(t->data);
}
size_t aml_tiling_tilesize(const struct aml_tiling *t, int tileid)
int aml_tiling_tile_dims(const struct aml_tiling *t, size_t *dims)
{
assert(t != NULL);
return t->ops->tilesize(t->data, tileid);
if (t == NULL || t->ops == NULL || dims == NULL)
return -AML_EINVAL;
return t->ops->tile_dims(t->data, dims);
}
void *aml_tiling_tilestart(const struct aml_tiling *t, const void *ptr,
int tileid)
int aml_tiling_dims(const struct aml_tiling *t, size_t *dims)
{
assert(t != NULL);
return t->ops->tilestart(t->data, ptr, tileid);
if (t == NULL || t->ops == NULL || dims == NULL)
return -AML_EINVAL;
return t->ops->dims(t->data, dims);
}
int aml_tiling_ndims(const struct aml_tiling *t, ...)
int aml_tiling_dims_native(const struct aml_tiling *t, size_t *dims)
{
assert(t != NULL);
va_list ap;
int err;
va_start(ap, t);
err = t->ops->ndims(t->data, ap);
va_end(ap);
return err;
}
if (t == NULL || t->ops == NULL || dims == NULL)
return -AML_EINVAL;
/*******************************************************************************
* Tiling Iterator functions
******************************************************************************/
return t->ops->dims_native(t->data, dims);
}
int aml_tiling_iterator_reset(struct aml_tiling_iterator *it)
size_t aml_tiling_ndims(const struct aml_tiling *t)
{
assert(it != NULL);
return it->ops->reset(it->data);
assert(t != NULL && t->ops != NULL);
return t->ops->ndims(t->data);
}
int aml_tiling_iterator_next(struct aml_tiling_iterator *it)
size_t aml_tiling_ntiles(const struct aml_tiling *t)
{
assert(it != NULL);
return it->ops->next(it->data);
assert(t != NULL && t->ops != NULL);
return t->ops->ntiles(t->data);
}
int aml_tiling_iterator_end(const struct aml_tiling_iterator *it)
struct aml_layout *aml_tiling_index(const struct aml_tiling *t,
const size_t *coords)
{
assert(it != NULL);
return it->ops->end(it->data);
if (t == NULL || t->ops == NULL || coords == NULL)
return NULL;
return t->ops->index(t->data, coords);
}
int aml_tiling_iterator_get(const struct aml_tiling_iterator *it, ...)
int aml_tiling_tileid(const struct aml_tiling *t,
const size_t *coords)
{
assert(it != NULL);
va_list ap;
if (t == NULL || t->ops == NULL || coords == NULL)
return -AML_EINVAL;
va_start(ap, it);
it->ops->get(it->data, ap);
va_end(ap);
return 0;
return t->ops->tileid(t->data, coords);
}
/*******************************************************************************
* Iterator Init
* We can't do the allocation ourselves here, as we don't have the type of the
* tiling.
******************************************************************************/
int aml_tiling_create_iterator(struct aml_tiling *t,
struct aml_tiling_iterator **it, int flags)
struct aml_layout *aml_tiling_index_native(const struct aml_tiling *t,
const size_t *coords)
{
assert(t != NULL);
assert(it != NULL);
return t->ops->create_iterator(t->data, it, flags);
if (t == NULL || t->ops == NULL || coords == NULL)
return NULL;
return t->ops->index_native(t->data, coords);
}
void aml_tiling_destroy_iterator(struct aml_tiling *t,
struct aml_tiling_iterator **it)
struct aml_layout *aml_tiling_index_byid(const struct aml_tiling *t,
int uuid)
{
assert(t != NULL);
assert(it != NULL);
t->ops->destroy_iterator(t->data, it);
if (t == NULL || t->ops == NULL || uuid < 0)
return NULL;
size_t ndims = aml_tiling_ndims(t);
size_t coords[ndims];
size_t dims[ndims];
aml_tiling_dims_native(t, dims);
for (size_t i = 0; i < ndims; i++) {
coords[i] = uuid % dims[i];
uuid /= dims[i];
}
return aml_tiling_index_native(t, coords);
}
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include "aml/tiling/1d.h"
#include <assert.h>
/*******************************************************************************
* 1D Iterator
******************************************************************************/
int aml_tiling_iterator_1d_reset(struct aml_tiling_iterator_data *data)
{
struct aml_tiling_iterator_1d_data *it =
(struct aml_tiling_iterator_1d_data *)data;
it->i = 0;
return 0;
}
int aml_tiling_iterator_1d_end(const struct aml_tiling_iterator_data *data)
{
const struct aml_tiling_iterator_1d_data *it =
(const struct aml_tiling_iterator_1d_data *)data;
return it->i * it->tiling->blocksize >= it->tiling->totalsize;
}
int aml_tiling_iterator_1d_next(struct aml_tiling_iterator_data *data)
{
struct aml_tiling_iterator_1d_data *it =
(struct aml_tiling_iterator_1d_data *)data;
it->i++;
return 0;
}
int aml_tiling_iterator_1d_get(const struct aml_tiling_iterator_data *data,
va_list args)
{
const struct aml_tiling_iterator_1d_data *it =
(const struct aml_tiling_iterator_1d_data *)data;
unsigned long *x = va_arg(args, unsigned long *);
*x = it->i;
return 0;
}
struct aml_tiling_iterator_ops aml_tiling_iterator_1d_ops = {
aml_tiling_iterator_1d_reset,
aml_tiling_iterator_1d_next,
aml_tiling_iterator_1d_end,
aml_tiling_iterator_1d_get,
};
/*******************************************************************************
* 1D ops
******************************************************************************/
int aml_tiling_1d_tileid(const struct aml_tiling_data *t, va_list ap)
{
(void)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;
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)
{
const struct aml_tiling_1d_data *data =
(const struct aml_tiling_1d_data *)t;
intptr_t p = (intptr_t)ptr;
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)
{
const struct aml_tiling_1d_data *data =
(const struct aml_tiling_1d_data *)t;
size_t *x = va_arg(ap, size_t *);
*x = data->totalsize/data->blocksize;
if (data->totalsize % data->blocksize != 0)
*x += 1;
return 0;
}
int aml_tiling_1d_init_iterator(struct aml_tiling_data *t,
struct aml_tiling_iterator *it, int flags)
{
assert(it->data != NULL);
(void)flags;
struct aml_tiling_iterator_1d_data *data =
(struct aml_tiling_iterator_1d_data *)it->data;
it->ops = &aml_tiling_iterator_1d_ops;
data->i = 0;
data->tiling = (struct aml_tiling_1d_data *)t;
return 0;
}
int aml_tiling_1d_create_iterator(struct aml_tiling_data *tiling,
struct aml_tiling_iterator **it, int flags)
{
struct aml_tiling_iterator *ret;
struct aml_tiling_iterator_1d_data *data;
(void)flags;
if (it == NULL)
return -AML_EINVAL;
*it = NULL;
ret = AML_INNER_MALLOC_2(struct aml_tiling_iterator,
struct aml_tiling_iterator_1d_data);
if (ret == NULL)
return -AML_ENOMEM;
ret->ops = &aml_tiling_iterator_1d_ops;
ret->data = AML_INNER_MALLOC_NEXTPTR(ret, struct aml_tiling_iterator,
struct aml_tiling_iterator_1d_data);
data = (struct aml_tiling_iterator_1d_data *)ret->data;
data->i = 0;
data->tiling = (struct aml_tiling_1d_data *)tiling;
*it = ret;
return AML_SUCCESS;
}
int aml_tiling_1d_destroy_iterator(struct aml_tiling_data *t,
struct aml_tiling_iterator **iter)
{
struct aml_tiling_iterator *it;
(void)t;
if (iter == NULL)
return -AML_EINVAL;
it = *iter;
if (it == NULL)
return -AML_EINVAL;
free(it);
*iter = NULL;
return AML_SUCCESS;
}
struct aml_tiling_ops aml_tiling_1d_ops = {
aml_tiling_1d_create_iterator,
aml_tiling_1d_destroy_iterator,
aml_tiling_1d_tileid,
aml_tiling_1d_tilesize,
aml_tiling_1d_tilestart,
aml_tiling_1d_ndims,
};
/*******************************************************************************
* 1D create/destroy
******************************************************************************/
int aml_tiling_1d_create(struct aml_tiling **tiling,
size_t tilesize, size_t totalsize)
{
struct aml_tiling *ret = NULL;
struct aml_tiling_1d_data *t;
if (tiling == NULL || tilesize > totalsize)
return -AML_EINVAL;
*tiling = NULL;
ret = AML_INNER_MALLOC_2(struct aml_tiling, struct aml_tiling_1d_data);
if (ret == NULL)
return -AML_ENOMEM;
ret->ops = &aml_tiling_1d_ops;
ret->data = AML_INNER_MALLOC_NEXTPTR(ret, struct aml_tiling,
struct aml_tiling_1d_data);
t = (struct aml_tiling_1d_data *) ret->data;
t->blocksize = tilesize;
t->totalsize = totalsize;
*tiling = ret;
return AML_SUCCESS;
}
void aml_tiling_1d_destroy(struct aml_tiling **tiling)
{
struct aml_tiling *t;
if (tiling == NULL)
return;
t = *tiling;
if (t == NULL)
return;
free(t);
*tiling = NULL;
}
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include "aml/tiling/2d.h"
#include <assert.h>
/*******************************************************************************
* 2D Iterator
******************************************************************************/
int aml_tiling_iterator_2d_reset(struct aml_tiling_iterator_data *data)
{
struct aml_tiling_iterator_2d_data *it =
(struct aml_tiling_iterator_2d_data *)data;
it->i = 0;
return 0;
}
int aml_tiling_iterator_2d_end(const struct aml_tiling_iterator_data *data)
{
const struct aml_tiling_iterator_2d_data *it =
(const struct aml_tiling_iterator_2d_data *)data;
return it->i * it->tiling->blocksize >= it->tiling->totalsize;
}
int aml_tiling_iterator_2d_next(struct aml_tiling_iterator_data *data)
{
struct aml_tiling_iterator_2d_data *it =
(struct aml_tiling_iterator_2d_data *)data;
it->i++;
return 0;
}
int aml_tiling_iterator_2d_get(const struct aml_tiling_iterator_data *data,
va_list args)
{
const struct aml_tiling_iterator_2d_data *it =
(const struct aml_tiling_iterator_2d_data *)data;
unsigned long *x = va_arg(args, unsigned long *);
*x = it->i;
return 0;
}
struct aml_tiling_iterator_ops aml_tiling_iterator_2d_ops = {
aml_tiling_iterator_2d_reset,
aml_tiling_iterator_2d_next,
aml_tiling_iterator_2d_end,
aml_tiling_iterator_2d_get,
};
/*******************************************************************************
* 2D ops
* Tileids are the order in memory of the tiles.
******************************************************************************/
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;
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;
}
int aml_tiling_2d_colmajor_tileid(const struct aml_tiling_data *t, va_list ap)
{
const struct aml_tiling_2d_data *data =