dense.h 8.03 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
/*******************************************************************************
 * 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_DENSE_H
#define AML_AREA_LAYOUT_DENSE_H

/**
 * @defgroup aml_layout_dense "AML Layout Dense"
 * @brief Default aml layout.
 *
 * Dense layouts describe how a multi-dimensional dense data structure
 * is collapsed into a linear (and contiguous) virtual address range.
 * Dimensions of a layout may contain a stride (space between elements)
 * on the virtual address space, and a pitch (distance between contiguous
 * elements of the same dimension).
 *
 * #include <aml/layout/dense.h>
 * @see aml_layout
 * @{
 **/

/**
 * Structure of a dense layout.
 **/
struct aml_layout_dense {
	/**
	 * dimensions, in element size, of the data structure,
	 * by order of appearance in memory.
	 **/
	size_t *dims;
	/**
	 * Offset between elements of the same dimension.
	 * Offset in number of elements.
	 **/
	size_t *stride;
	/**
	 * distances between two elements of the next dimension
	 * (or total dimension of the layout in this dimension).
	 **/
	size_t *pitch;
	/**
	 * cumulative distances between two elements in the same
	 * dimension (pitch[0] is the element size in bytes).
	 **/
	size_t *cpitch;
	/** base pointer of the address range **/
	void *ptr;
	/** number of dimensions **/
	size_t ndims;
};

/**
 * Dense layout constructor.
 * @param layout[out]: A pointer where to store a newly allocated layout.
 * @param ptr[in]: The pointer to the data structure described by this layout.
 * @param order[in]: The order in which dimensions are organized.
 * Can be AML_LAYOUT_ORDER_COLUMN_MAJOR or AML_LAYOUT_ORDER_ROW_MAJOR.
 * @param element_size[in]: The size of each element in layout.
 * @param ndims[in]: The number of dimensions of the layout.
 * @param dims[in]: The number of elements along each dimension of the layout.
 * @param stride[in]: The space between elements (in number of elements),
 * along each dimension. If NULL then the stride is set to one for each
 * dimension.
 * @param pitch[in]: The space between consecutive elements of the same
 * dimension. If NULL, pitch is set to the number of elements in each dimension.
 * @return -AML_ENOMEM if layout allocation failed.
 * @return -AML_EINVAL if layout is NULL.
 * @return AML_SUCCESS if creation succeeded.
 * @see aml_layout_dense
 **/
int aml_layout_dense_create(struct aml_layout **layout,
			    void *ptr,
			    const int order,
			    const size_t element_size,
			    const size_t ndims,
			    const size_t *dims,
			    const size_t *stride,
			    const size_t *pitch);

/**
 * Function to free a dense layout.
 * @param layout[inout]: The layout to deallocate. NULL on return.
 **/
void aml_layout_dense_destroy(struct aml_layout **layout);

/**
 * Deref operator for dense layout in AML_ORDER_COLUMN_MAJOR.
 * Also used as the deref operator for this type of layout.
 * Does not check its argument. If data is NULL, or coords are out
 * of bounds, the behaviour of aml_layout_column_deref() is undefined.
 * @see aml_layout_deref()
 * @see aml_layout_deref_native()
 **/
void *aml_layout_column_deref(const struct aml_layout_data *data,
			      const size_t *coords);

/**
 * Layout operator for retrieving order of dimension storage.
 * This function shall not fail.
 * @see aml_layout_order()
 **/
int aml_layout_column_order(const struct aml_layout_data *data);

/**
 * Operator for retrieving the number of dimensions in the layout.
 * Does not check data is not NULL. If data is NULL or not the good
 * pointer type, the behaviour is undefined.
 * @see aml_layout_ndims()
 **/
size_t aml_layout_dense_ndims(const struct aml_layout_data *data);

/**
 * Layout operator for retrieving layout elements size.
 * Does not check data is not NULL. If data is NULL or not the good
 * @see aml_layout_element_size()
 **/
size_t aml_layout_dense_element_size(const struct aml_layout_data *data);

/**
 * Operator for reshaping dense layouts with column major order.
 * Does not check if the number of elements match.
 * This should be done in aml_layout_reshape().
 * @return -AML_EINVAL if merge then split of dimensions
 * cannot be done appropriatly.
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful reshape.
 * @see aml_layout_reshape()
 **/
int aml_layout_column_reshape(const struct aml_layout_data *data,
			      struct aml_layout **output,
			      size_t ndims,
			      const size_t *dims);

/**
 * Operator for slicing dense layouts with column major order.
 * Does not check if slice elements are out of bound.
 * This should be done in aml_layout_slice().
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful slicing.
 * @see aml_layout_slice()
 **/
int aml_layout_column_slice(const struct aml_layout_data *data,
			    struct aml_layout **output,
			    const size_t *offsets,
			    const size_t *dims,
			    const size_t *strides);

/**
 * Operator for slicing dense layouts with column major order.
 * Does not check if slice elements are out of bound.
 * This should be done in aml_layout_slice().
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful slicing.
 * @see aml_layout_deref()
 **/
void *aml_layout_row_deref(const struct aml_layout_data *data,
			   const size_t *coords);

/**
 * Operator for retrieving layout order of a row major layout.
 * This function shall not fail.
 * @see aml_layout_order()
 **/
int aml_layout_row_order(const struct aml_layout_data *data);

/**
 * Operator for retrieving dimensions size of a layout with row major order.
 * Does not check data is not NULL. If data is NULL or not the good
 * pointer type, the behaviour is undefined.
 * Arguments are supposed to be checked in aml_layout_dims().
 * @see aml_layout_dims()
 **/
int aml_layout_row_dims(const struct aml_layout_data *data, size_t *dims);

/**
 * Operator for reshaping dense layouts with row major order.
 * Does not check if the number of elements match.
 * This should be done in aml_layout_reshape().
 * @return -AML_EINVAL if merge then split of dimensions
 * cannot be done appropriatly.
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful reshape.
 * @see aml_layout_reshape()
 **/
int aml_layout_row_reshape(const struct aml_layout_data *data,
			   struct aml_layout **output,
			   const size_t ndims,
			   const size_t *dims);

/**
 * Operator for slicing dense layouts with row major order.
 * Does not check if slice elements are out of bound.
 * This should be done in aml_layout_slice().
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful slicing.
 * @see aml_layout_slice()
 **/
int aml_layout_row_slice(const struct aml_layout_data *data,
			 struct aml_layout **output,
			 const size_t *offsets,
			 const size_t *dims,
			 const size_t *strides);

/**
 * Operator for slicing dense layouts with row major order,
 * without the overhead of user defined order, i.e using the internal
 * library order.
 * Does not check if slice elements are out of bound.
 * This should be done in aml_layout_slice().
 * @return -AML_ENOMEM if the resulting layout cannot be allocated.
 * @return AML_SUCCESS on successful slicing.
 * @see aml_layout_slice()
 **/
int aml_layout_row_slice_native(const struct aml_layout_data *data,
				struct aml_layout **output,
				const size_t *offsets,
				const size_t *dims,
				const size_t *strides);

Swann Perarnau's avatar
Swann Perarnau committed
227 228
void aml_layout_dense_print(FILE *stream, char *prefix,
			    const struct aml_layout_dense *);
229 230 231 232 233 234 235 236 237 238 239 240 241
/**
 * Pre-existing operators for dense layout
 * with AML_LAYOUT_ORDER_COLUMN_MAJOR order.
 **/
extern struct aml_layout_ops aml_layout_column_ops;

/**
 * Pre-existing operators for dense layout
 * with AML_LAYOUT_ORDER_ROW_MAJOR order.
 **/
extern struct aml_layout_ops aml_layout_row_ops;

#endif