Commit ff3cd379 authored by Swann Perarnau's avatar Swann Perarnau
Browse files

Merge branch 'no_sparse_layout' into 'staging'

[cleanup] Sparse layouts

See merge request !168
parents 59070b5e b32bbdc2
Pipeline #12135 passed with stages
in 6 minutes and 48 seconds
......@@ -11,7 +11,6 @@ include_aml_layout_HEADERS = \
aml/layout/native.h \
aml/layout/dense.h \
aml/layout/pad.h \
aml/layout/sparse.h \
aml/layout/reshape.h
include_aml_dmadir=$(includedir)/aml/dma
......
/*******************************************************************************
* 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_AREA_LAYOUT_SPARSE_H
#define AML_AREA_LAYOUT_SPARSE_H
#include <aml.h>
/**
* @defgroup aml_layout_sparse "AML Layout Sparse"
* @brief Default aml layout.
*
* Sparse layouts describe storage of a set of pointers.
* This layout has only one dimension of n pointers.
* Therefore, layout order does not matter. It is set to
* AML_LAYOUT_ORDER_ROW_MAJOR. Each element have a different size but
* aml_layout_element_size() will always return the size of a pointer. rawptr()
* is not implemented since the layout contains several raw pointers. slice()
*and reshape() functions are not implemented for this type of layout.
*
* @code
* #include <aml/layout/sparse.h>
* @endcode
* @see aml_layout
* @{
**/
/**
* The plain sparse layout structure.
* Unlike dense layout, it does not have cartesian coordinates.
* This layout is only a flat array of pointers.
* It always has 1 dimension in row major order.
* Its element size is the size of a pointer
* It can be extended with a coordinate system (weather a dense layout
* over pointers or a sparse ndimensional space associating a set of
* coordinates to each pointer.
* This is the minimal layout for performing dmas from/to set
* of plain pointers.
**/
struct aml_layout_sparse {
/**
* Additional metadata for customizing this layout.
* Needed by cuda to add device number used by dma
* to target the right devices.
**/
void *metadata;
/**
* Size of metadata field used to duplicate this layout.
*/
size_t metadata_size;
/** Number of pointers in the layout **/
size_t nptr;
/**
* Pointers of the layout (nptr elements)
**/
void **ptrs;
/**
* Pointers size (nptr elements)
* Pointers may hold data of different size.
* We need this information for dmas.
**/
size_t *sizes;
};
/**
* Sparse layout constructor.
* Destroy with aml_layout_destroy() or free.
* @param[out] layout: A pointer where to store a newly allocated layout.
* @param[in] nptr: The number of pointers in the layout.
* @param[in] ptrs: The pointer to the data structure described by this layout.
* dimension. If NULL, pitch is set to the number of elements in each dimension.
* @param[in] sizes: The size of memory area pointed to by each pointer.
* @param[in] metadata: Extra data to embed in the layout.
* If not NULL, it will be copied with memcpy.
* @param[in] metadata_size: The size of metadata.
* Must be 0 if no metadata is provided.
* @return -AML_ENOMEM if layout allocation failed.
* @return -AML_EINVAL if layout is NULL.
* @return AML_SUCCESS if creation succeeded.
* @see aml_layout_sparse
**/
int aml_layout_sparse_create(struct aml_layout **layout,
const size_t nptr,
void **ptrs,
const size_t *sizes,
void *metadata,
const size_t metadata_size);
/**
* Deref operator for sparse layout.
* @param[in] data: Sparse layout structure.
* @param[in] coords: An array of one coordinate. This coordinate is
* the index in pointer array where to pick the element to return.
* @see aml_layout_deref()
* @see aml_layout_deref_native()
**/
void *aml_layout_sparse_deref(const struct aml_layout_data *data,
const size_t *coords);
/**
* @param[in] data: Sparse layout structure.
* @return always AML_LAYOUT_ORDER_ROW_MAJOR.
* @see aml_layout_order()
**/
int aml_layout_sparse_order(const struct aml_layout_data *data);
/**
* @param[in] data: Sparse layout structure.
* @return always 1.
* @see aml_layout_ndims()
**/
size_t aml_layout_sparse_ndims(const struct aml_layout_data *data);
/**
* @param[in] data: Sparse layout structure.
* @return always sizeof(void*).
* @see aml_layout_element_size()
**/
size_t aml_layout_sparse_element_size(const struct aml_layout_data *data);
/**
* Duplicate operator.
* @param[in] layout: The input sparse layout.
* @param[out] dest: A pointer where layout duplicate will be
* allocated.
* @param[in] ptr: If not NULL use these pointers as the new layout raw pointer.
* ptr is casted to (void**) and shall contain one new pointer per rawptr of
* this layout.
* @return same as aml_layout_sparse_create().
*/
int aml_layout_sparse_duplicate(const struct aml_layout *layout,
struct aml_layout **dest,
void *ptr);
/**
* Pre-existing operators for sparse layout.
* slice() and reshape() functions are not implemented for this type of layout.
* rawptr() is not implemented since the layout contains several raw pointers.
**/
extern struct aml_layout_ops aml_layout_sparse_ops;
/**
* @}
**/
#endif
......@@ -17,7 +17,6 @@ AREA_SOURCES = \
LAYOUT_SOURCES = \
layout/layout.c \
layout/dense.c \
layout/sparse.c \
layout/pad.c \
layout/reshape.c
......
/*******************************************************************************
* 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/layout/sparse.h"
int aml_layout_sparse_create(struct aml_layout **layout,
const size_t nptr,
void **ptrs,
const size_t *sizes,
void *metadata,
const size_t metadata_size)
{
struct aml_layout *ret;
struct aml_layout_sparse *data;
ret = AML_INNER_MALLOC_EXTRA(nptr, void *,
nptr * sizeof(size_t) + metadata_size,
struct aml_layout,
struct aml_layout_sparse);
if (ret == NULL)
return -AML_ENOMEM;
data = AML_INNER_MALLOC_GET_FIELD(ret, 2, struct aml_layout,
struct aml_layout_sparse);
data->ptrs = AML_INNER_MALLOC_GET_ARRAY(ret, void *, struct aml_layout,
struct aml_layout_sparse);
data->sizes = AML_INNER_MALLOC_GET_EXTRA(
ret, nptr, void *, struct aml_layout, struct aml_layout_sparse);
data->metadata_size = metadata_size;
memcpy(data->ptrs, ptrs, nptr * sizeof(*ptrs));
memcpy(data->sizes, sizes, nptr * sizeof(*sizes));
if (metadata_size > 0) {
data->metadata =
data->sizes + nptr * sizeof(size_t) + sizeof(size_t);
memcpy(data->metadata, metadata, metadata_size);
} else
data->metadata = NULL;
data->nptr = nptr;
ret->data = (struct aml_layout_data *)data;
ret->ops = &aml_layout_sparse_ops;
*layout = ret;
return AML_SUCCESS;
}
int aml_layout_sparse_duplicate(const struct aml_layout *layout,
struct aml_layout **dest,
void *ptr)
{
struct aml_layout_sparse *src =
(struct aml_layout_sparse *)layout->data;
return aml_layout_sparse_create(dest, src->nptr,
ptr ? (void **)ptr : src->ptrs,
src->sizes, src->metadata,
src->metadata_size);
}
void *aml_layout_sparse_deref(const struct aml_layout_data *data,
const size_t *coords)
{
struct aml_layout_sparse *layout = (struct aml_layout_sparse *)data;
return layout->ptrs[*coords];
}
int aml_layout_sparse_order(const struct aml_layout_data *data)
{
(void)data;
return AML_LAYOUT_ORDER_ROW_MAJOR;
}
size_t aml_layout_sparse_ndims(const struct aml_layout_data *data)
{
(void)data;
return 1;
}
int aml_layout_sparse_dims(const struct aml_layout_data *data, size_t *dims)
{
struct aml_layout_sparse *layout = (struct aml_layout_sparse *)data;
*dims = layout->nptr;
return AML_SUCCESS;
}
size_t aml_layout_sparse_element_size(const struct aml_layout_data *data)
{
(void)data;
return sizeof(void *);
}
int aml_layout_sparse_fprintf(const struct aml_layout_data *data,
FILE *stream,
const char *prefix)
{
struct aml_layout_sparse *layout = (struct aml_layout_sparse *)data;
fprintf(stream, "%s[", prefix);
for (size_t i = 0; i < layout->nptr - 1; i++)
fprintf(stream, "%p, ", layout->ptrs[i]);
fprintf(stream, "%p]\n", layout->ptrs[layout->nptr - 1]);
return AML_SUCCESS;
}
struct aml_layout_ops aml_layout_sparse_ops = {
.deref = aml_layout_sparse_deref,
.deref_native = aml_layout_sparse_deref,
.rawptr = NULL,
.order = aml_layout_sparse_order,
.dims = aml_layout_sparse_dims,
.dims_native = aml_layout_sparse_dims,
.ndims = aml_layout_sparse_ndims,
.element_size = aml_layout_sparse_element_size,
.reshape = NULL,
.slice = NULL,
.slice_native = NULL,
.fprintf = aml_layout_sparse_fprintf,
.duplicate = aml_layout_sparse_duplicate,
.destroy = NULL,
};
......@@ -53,7 +53,6 @@ LDADD = liblayout_test.la libreplicaset_test.la
LAYOUT_TESTS = \
layout/test_coords \
layout/test_dense \
layout/test_sparse \
layout/test_reshape \
layout/test_pad
......
/*******************************************************************************
* 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/layout/sparse.h"
void test_common(struct aml_layout *layout, size_t nptr, size_t *data)
{
size_t dims;
assert(aml_layout_order(layout) == AML_LAYOUT_ORDER_ROW_MAJOR);
assert(aml_layout_ndims(layout) == 1);
assert(aml_layout_element_size(layout) == sizeof(void *));
assert(aml_layout_dims(layout, &dims) == AML_SUCCESS);
assert(dims == nptr);
for (size_t coords = 0; coords < nptr; coords++)
assert(aml_layout_deref(layout, &coords) == data + coords);
}
void test_functional()
{
// Data initialization
const size_t nptr = 16;
size_t data[nptr];
void *ptrs[nptr];
size_t sizes[nptr];
for (size_t i = 0; i < nptr; i++) {
data[i] = i;
sizes[i] = sizeof(*sizes);
ptrs[i] = data + i;
}
// Create layout
struct aml_layout *layout;
assert(aml_layout_sparse_create(&layout, nptr, ptrs, sizes, NULL, 0) ==
AML_SUCCESS);
test_common(layout, nptr, data);
// Duplicate
struct aml_layout *dup;
assert(aml_layout_duplicate(layout, &dup, NULL) == AML_SUCCESS);
test_common(dup, nptr, data);
// Cleanup
aml_layout_destroy(&layout);
aml_layout_destroy(&dup);
}
int main()
{
test_functional();
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