Commit ac8d9bb3 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 5ce0914f
......@@ -23,8 +23,7 @@ include_aml_scratch_HEADERS = \
include_aml_tilingdir=$(includedir)/aml/tiling
include_aml_tiling_HEADERS = \
aml/tiling/1d.h \
aml/tiling/2d.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_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);
int 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,59 @@
*******************************************************************************/
#include "aml.h"
#include "aml/tiling/1d.h"
#include "aml/tiling/2d.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;
if (t == NULL || t->ops == NULL)
return -AML_EINVAL;
va_start(ap, t);
ret = t->ops->tileid(t->data, ap);
va_end(ap);
return ret;
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;
void *aml_tiling_tilestart(const struct aml_tiling *t, const void *ptr,
int tileid)
{
assert(t != NULL);
return t->ops->tilestart(t->data, ptr, tileid);
return t->ops->tile_dims(t->data, dims);
}
int aml_tiling_ndims(const struct aml_tiling *t, ...)
int aml_tiling_dims(const struct aml_tiling *t, size_t *dims)
{
assert(t != NULL);
va_list ap;
int err;
if (t == NULL || t->ops == NULL || dims == NULL)
return -AML_EINVAL;
va_start(ap, t);
err = t->ops->ndims(t->data, ap);
va_end(ap);
return err;
return t->ops->dims(t->data, dims);
}
/*******************************************************************************
* Tiling Iterator functions
******************************************************************************/
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;
int aml_tiling_iterator_get(const struct aml_tiling_iterator *it, ...)
{
assert(it != NULL);
va_list ap;
va_start(ap, it);
it->ops->get(it->data, ap);
va_end(ap);
return 0;
return t->ops->index(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_linear(const struct aml_tiling *t,
size_t uuid)
{
assert(t != NULL);
assert(it != NULL);
return t->ops->create_iterator(t->data, it, flags);
}
if (t == NULL || t->ops == NULL)
return NULL;
void aml_tiling_destroy_iterator(struct aml_tiling *t,
struct aml_tiling_iterator **it)
{
assert(t != NULL);
assert(it != NULL);
t->ops->destroy_iterator(t->data, it);
return t->ops->index_linear(t->data, uuid);
}
/*******************************************************************************
* 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 =
(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 (col*data->ndims[0]) + row;
}
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 >= (int)(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;
if (tileid < 0 || tileid >= (int)(data->ndims[0]*data->ndims[1]))
return NULL;
else
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 *nrows = va_arg(ap, size_t *);
size_t *ncols = va_arg(ap, size_t *);
/* looks totally wrong */
*nrows = data->ndims[0];
*ncols = data->ndims[1];
return 0;
}
int aml_tiling_2d_create_iterator(struct aml_tiling_data *tiling,
struct aml_tiling_iterator **it, int flags)
{
struct aml_tiling_iterator *ret;
struct aml_tiling_iterator_2d_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_2d_data);
if (ret == NULL)
return -AML_ENOMEM;
ret->ops = &aml_tiling_iterator_2d_ops;
ret->data = AML_INNER_MALLOC_NEXTPTR(ret, struct aml_tiling_iterator,
struct aml_tiling_iterator_2d_data);
data = (struct aml_tiling_iterator_2d_data *)ret->data;
data->i = 0;
data->tiling = (struct aml_tiling_2d_data *)tiling;
*it = ret;
return AML_SUCCESS;
}
int aml_tiling_2d_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_2d_rowmajor_ops = {
aml_tiling_2d_create_iterator,
aml_tiling_2d_destroy_iterator,
aml_tiling_2d_rowmajor_tileid,
aml_tiling_2d_tilesize,
aml_tiling_2d_tilestart,
aml_tiling_2d_ndims,
};
struct aml_tiling_ops aml_tiling_2d_colmajor_ops = {
aml_tiling_2d_create_iterator,
aml_tiling_2d_destroy_iterator,
aml_tiling_2d_colmajor_tileid,
aml_tiling_2d_tilesize,
aml_tiling_2d_tilestart,
aml_tiling_2d_ndims,
};
/*******************************************************************************
* 2d create/destroy
******************************************************************************/
int aml_tiling_2d_create(struct aml_tiling **tiling, int type,
size_t tilesize, size_t totalsize,
size_t rowsize, size_t colsize)
{
struct aml_tiling *ret = NULL;
struct aml_tiling_2d_data *data;
if (tiling == NULL)
return -AML_EINVAL;
if (type != AML_TILING_TYPE_2D_ROWMAJOR &&
type != AML_TILING_TYPE_2D_COLMAJOR)
return -AML_EINVAL;
if (tilesize > totalsize)
return -AML_EINVAL;
*tiling = NULL;
ret = AML_INNER_MALLOC_2(struct aml_tiling, struct aml_tiling_2d_data);
if (ret == NULL)
return -AML_ENOMEM;
if (type == AML_TILING_TYPE_2D_ROWMAJOR)
ret->ops = &aml_tiling_2d_rowmajor_ops;
else
ret->ops = &aml_tiling_2d_colmajor_ops;
ret->data = AML_INNER_MALLOC_NEXTPTR(ret, struct aml_tiling,
struct aml_tiling_2d_data);
data = (struct aml_tiling_2d_data *)ret->data;
data->blocksize = tilesize;
data->totalsize = totalsize;
data->ndims[0] = rowsize;
data->ndims[1] = colsize;
*tiling = ret;
return AML_SUCCESS;
}
void aml_tiling_2d_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)
*