27#include <Padico/Puk.h>
74#define _NM_DATA_CONTENT_SIZE 64
76#define _NM_DATA_GENERATOR_SIZE 64
80#define NM_DATA_USE_UCONTEXT_SLICER
83#define NM_DATA_USE_COROUTINE_GENERATOR
85#define NM_DATA_USE_COROUTINE_SLICER
92#define NM_DATA_USE_UCONTEXT_GENERATOR
125#define NM_DATA_CHUNK_NULL ((struct nm_data_chunk_s){ .ptr = NULL, .len = 0 })
128 return (p_chunk->
ptr == NULL);
152#ifdef NM_DATA_USE_COROUTINE_GENERATOR
153#define nm_data_generator_default_init &nm_data_generator_coroutine_init
154#define nm_data_generator_default_next &nm_data_generator_coroutine_next
155#define nm_data_generator_default_destroy &nm_data_generator_coroutine_destroy
157#define nm_data_generator_default_init &nm_data_generator_generic_init
158#define nm_data_generator_default_next &nm_data_generator_generic_next
159#define nm_data_generator_default_destroy NULL
207 p_props->is_cuda = -1;
210 p_props->is_hip = -1;
220 if(p_props->is_cuda == -1)
222 NM_FATAL(
"incorrect data properties: is_cuda = %d (should be either 0 or 1)\n", p_props->is_cuda);
226 if(p_props->is_hip == -1)
228 NM_FATAL(
"incorrect data properties: is_hip = %d (should be either 0 or 1)\n", p_props->is_hip);
240#define NM_DATA_TYPE(ENAME, CONTENT_TYPE, OPS) \
241 static inline void nm_data_##ENAME##_set(struct nm_data_s*p_data, CONTENT_TYPE value) \
243 p_data->ops = *(OPS); \
244 assert(p_data->ops.p_traversal != NULL); \
245 if(p_data->ops.p_properties_compute == NULL) \
247 p_data->ops.p_properties_compute = nm_data_default_properties_compute; \
249 assert(sizeof(CONTENT_TYPE) <= _NM_DATA_CONTENT_SIZE); \
250 CONTENT_TYPE*p_content = (CONTENT_TYPE*)&p_data->_content[0]; \
251 *p_content = value; \
252 p_data->props.blocks = -1; \
253 nm_data_propertie_gpu_preinit(&p_data->props); \
254 (*p_data->ops.p_properties_compute)(p_data); \
255 nm_data_propertie_gpu_postinit(&p_data->props); \
256 if(p_data->ops.p_generator_init == NULL) \
258 if(p_data->props.is_contig) \
261 p_data->ops.p_generator_init = &nm_data_generator_generic_init; \
262 p_data->ops.p_generator_next = &nm_data_generator_generic_next; \
263 p_data->ops.p_generator_destroy = NULL; \
267 p_data->ops.p_generator_init = nm_data_generator_default_init; \
268 p_data->ops.p_generator_next = nm_data_generator_default_next; \
269 p_data->ops.p_generator_destroy = nm_data_generator_default_destroy; \
273 static inline CONTENT_TYPE*nm_data_##ENAME##_content(const struct nm_data_s*p_data) \
275 return (CONTENT_TYPE*)p_data->_content; \
282#define NM_DATAV_INIT_SIZE 4
368 const struct iovec*
v;
459 assert(p_generator->p_data->ops.p_generator_next != NULL);
460 const struct nm_data_chunk_s chunk = (*p_generator->p_data->ops.p_generator_next)(p_generator->p_data, &p_generator->_bytes);
479 return &p_data->
props;
486 return p_props->
size;
562#define NM_DATA_SLICER_NULL ((struct nm_data_slicer_s){ .kind = NM_DATA_SLICER_NONE })
607 assert(p_datav->
p_data != NULL);
610 padico_free(p_datav->
p_data);
647 for(i = 0; i < p_datav->
n_data; i++)
#define _NM_DATA_CONTENT_SIZE
maximum size of content descriptor for nm_data
struct nm_data_chunk_s nm_data_generator_generic_next(const struct nm_data_s *p_data, void *_generator)
void nm_data_generator_generic_init(const struct nm_data_s *p_data, void *_generator)
static void nm_datav_uncommit(struct nm_datav_s *p_datav)
'uncommit' a datav: explicitely declare that nm_data pointing to this datav has been destroyed.
struct nm_data_chunk_s(* nm_data_generator_next_t)(const struct nm_data_s *p_data, void *_generator)
returns next data chunk for the given generator.
#define NM_DATAV_INIT_SIZE
initial size of an nm_datav
static void nm_data_propertie_gpu_preinit(struct nm_data_properties_s *p_props)
pre-init GPU part of data properties
void(* nm_data_generator_destroy_t)(const struct nm_data_s *p_data, void *_generator)
destroys resources allocated by generator
struct nm_data_chunk_s nm_data_generator_coroutine_next(const struct nm_data_s *p_data, void *_generator)
static nm_len_t nm_datav_size(struct nm_datav_s *p_datav)
get the size (number of bytes) of data contained in the datav
static int nm_data_chunk_isnull(const struct nm_data_chunk_s *p_chunk)
void(* nm_data_generator_init_t)(const struct nm_data_s *p_data, void *_generator)
initializes a generator (i.e.
static void nm_datav_add_chunk(struct nm_datav_s *p_datav, const void *ptr, nm_len_t len)
add a chunk of contiguous data to a datav
void nm_data_generator_coroutine_init(const struct nm_data_s *p_data, void *_generator)
void(* nm_data_traversal_t)(const void *_content, const nm_data_apply_t apply, void *_context)
funtion to traverse data with app layout, i.e.
void(* nm_data_apply_t)(void *ptr, nm_len_t len, void *_context)
function to apply to each data chunk upon traversal
void(* nm_data_properties_compute_t)(struct nm_data_s *p_data)
function to compute data properties
#define NM_DATA_TYPE(ENAME, CONTENT_TYPE, OPS)
macro to generate typed functions to init/access data fields.
static void nm_datav_init(struct nm_datav_s *p_datav)
initialize a datav
void nm_data_default_properties_compute(struct nm_data_s *p_data)
#define _NM_DATA_GENERATOR_SIZE
maximum content size for generators
void nm_data_generator_coroutine_destroy(const struct nm_data_s *p_data, void *_generator)
static void nm_data_propertie_gpu_postinit(const struct nm_data_properties_s *p_props)
post-init GPU part of data properties: check that p_properties_compute function actually filled the G...
static void nm_datav_destroy(struct nm_datav_s *p_datav)
destroys a datav
static void nm_datav_add_chunk_data(struct nm_datav_s *p_datav, const struct nm_data_s *p_data)
add a chunk of data to datav; given p_data content is copied.
static void nm_data_generator_destroy(struct nm_data_generator_s *p_generator)
destroy the generator after use
static nm_len_t nm_data_size(const struct nm_data_s *p_data)
returns the amount of data contained in the descriptor
static void nm_data_generator_init(const struct nm_data_s *p_data, struct nm_data_generator_s *p_generator)
build a new generator for the given data type
void nm_data_chunk_extractor_traversal(const struct nm_data_s *p_data, nm_len_t chunk_offset, nm_len_t chunk_len, nm_data_apply_t apply, void *_context)
void nm_data_aggregator_traversal(const struct nm_data_s *p_data, nm_data_apply_t apply, void *_context)
void nm_data_copy(struct nm_data_s *p_dest, struct nm_data_s *p_from)
copy from nm_data to another nm_data
void nm_data_chunk_properties_compute(const struct nm_data_s *p_data, nm_len_t chunk_offset, nm_len_t chunk_len, struct nm_data_properties_s *p_props)
compute properties of the given chunk inside the data
static void nm_data_traversal_apply(const struct nm_data_s *p_data, nm_data_apply_t apply, void *_context)
helper function to apply iterator to data
static struct nm_data_chunk_s nm_data_generator_next(struct nm_data_generator_s *p_generator)
get the next chunk of data
void nm_data_copy_to(const struct nm_data_s *p_data, nm_len_t offset, nm_len_t len, const void *srcbuf)
copy chunk of data from contiguous buffer to user layout
void * nm_data_baseptr_get(const struct nm_data_s *p_data)
find base pointer for a data known to be contiguous
void nm_data_copy_from(const struct nm_data_s *p_data, nm_len_t offset, nm_len_t len, void *destbuf)
copy chunk of data from user layout to contiguous buffer
static const struct nm_data_properties_s * nm_data_properties_get(const struct nm_data_s *p_data)
returns the properties block for the data
uint32_t nm_data_checksum(const struct nm_data_s *p_data)
checksum data
void * nm_data_chunk_baseptr_get(const struct nm_data_s *p_data, nm_len_t chunk_offset, nm_len_t chunk_len)
find base pointer for a data chunk known to be contiguous
void nm_data_slicer_ucontext_init(nm_data_slicer_t *p_slicer, const struct nm_data_s *p_data)
static int nm_data_slicer_isnull(const nm_data_slicer_t *p_slicer)
tests whether a slicer is null
struct nm_data_slicer_s nm_data_slicer_t
internal state of a data slicer.
void nm_data_slicer_forward(nm_data_slicer_t *p_slicer, nm_len_t offset)
void nm_data_slicer_generator_destroy(nm_data_slicer_t *p_slicer)
nm_data_slicer_kind_t
various kinds of slicer implementations
void nm_data_slicer_generator_init(nm_data_slicer_t *p_slicer, const struct nm_data_s *p_data)
enum nm_data_slicer_op_e nm_data_slicer_op_t
void nm_data_slicer_ucontext_op(nm_data_slicer_t *p_slicer, void *ptr, nm_len_t len, nm_data_slicer_op_t op)
void nm_data_slicer_copy_to(nm_data_slicer_t *p_slicer, const void *src_ptr, nm_len_t slice_len)
void nm_data_slicer_destroy(nm_data_slicer_t *p_slicer)
void nm_data_slicer_copy_from(nm_data_slicer_t *p_slicer, void *dest_ptr, nm_len_t slice_len)
void nm_data_slicer_coroutine_op(nm_data_slicer_t *p_slicer, void *ptr, nm_len_t len, nm_data_slicer_op_t op)
void nm_data_slicer_coroutine_init(nm_data_slicer_t *p_slicer, const struct nm_data_s *p_data)
void nm_data_slicer_generator_op(nm_data_slicer_t *p_slicer, void *ptr, nm_len_t slice_len, nm_data_slicer_op_t op)
void nm_data_slicer_coroutine_destroy(nm_data_slicer_t *p_slicer)
void nm_data_slicer_ucontext_destroy(nm_data_slicer_t *p_slicer)
void nm_data_slicer_init(nm_data_slicer_t *p_slicer, const struct nm_data_s *p_data)
void nm_data_slicer_op(nm_data_slicer_t *p_slicer, void *ptr, nm_len_t len, nm_data_slicer_op_t op)
@ NM_DATA_SLICER_UCONTEXT
ucontext-based coroutine slicer, when stack jumping is not available through longjmp
@ NM_DATA_SLICER_GENERATOR
generator-based slicer, optimal for types with a dedicated generator; slow otherwise
@ NM_DATA_SLICER_COROUTINE
coroutine longjmp-based slicer, optimal for types without generator, when stack jumping is possible w...
@ NM_SLICER_OP_FORWARD
fast forward in slicer
@ NM_SLICER_OP_NONE
no operation selected
@ NM_SLICER_OP_COPY_FROM
copy from iterator to user buffer
@ NM_SLICER_OP_COPY_TO
copy to iterator, from user buffer
const struct nm_data_ops_s nm_data_ops_excerpt
static void nm_data_contiguous_build(struct nm_data_s *p_data, void *ptr, nm_len_t len)
static void nm_data_excerpt_set(struct nm_data_s *p_data, struct nm_data_excerpt_s value)
static void nm_data_iov_build(struct nm_data_s *p_data, const struct iovec *v, int n)
static void nm_data_datav_build(struct nm_data_s *p_datav_data, struct nm_datav_s *p_datav)
frontend to build a nm_data from a datav
static void nm_data_datav_set(struct nm_data_s *p_data, struct nm_data_datav_s value)
const struct nm_data_ops_s nm_data_ops_null
const struct nm_data_ops_s nm_data_ops_iov
static void nm_data_excerpt_build(struct nm_data_s *p_data, struct nm_data_s *p_inner_data, nm_len_t chunk_offset, nm_len_t chunk_len)
build a data descriptor as an excerpt of another data.
static void nm_data_iov_set(struct nm_data_s *p_data, struct nm_data_iov_s value)
static void nm_data_null_set(struct nm_data_s *p_data, struct nm_data_null_s value)
static int nm_data_isnull(struct nm_data_s *p_data)
static void nm_data_null_build(struct nm_data_s *p_data)
const struct nm_data_ops_s nm_data_ops_contiguous
static void nm_data_contiguous_set(struct nm_data_s *p_data, struct nm_data_contiguous_s value)
const struct nm_data_ops_s nm_data_ops_datav
#define NM_FATAL(format,...)
nm_len_t size
size of the onsided data (not incuding target-side completion)
uint64_t nm_len_t
data length used by nmad
chunk of data returned by generators
nm_len_t len
length of chunk
void * ptr
pointer to chunk
data descriptor for contiguous data
void * ptr
base pointer for block
data descriptor for datav in a nm_data (embedd a vector of nm_data in nm_data)
struct nm_datav_s * p_datav
data as an excerpt of another data.
struct nm_data_s * p_data
state of a data generator
const struct nm_data_s * p_data
data descriptor for iov data (embedd iovec in nm_data)
data descriptor for 'null' data
int dummy
unused, to avoid non-portable empty structure
set of operations available on data type.
nm_data_generator_next_t p_generator_next
get next chunk from generator (optionnal)
nm_data_properties_compute_t p_properties_compute
optimized function to compute data properties (optionnal)
nm_data_generator_destroy_t p_generator_destroy
destroy a generator after use (optionnal, may be NULL even if p_generator_init != NULL)
nm_data_generator_init_t p_generator_init
initializes a new generator (chunks enumerator) (optionnal)
nm_data_traversal_t p_traversal
operation to apply a given function to all chunks of data (required)
block of static properties for a given data descriptor
nm_len_t size
total size in bytes (accumulator)
int is_contig
data is contiguous; data may be contiguous even with blocks > 1, if blocks are next to each other
nm_len_t blocks
number of blocks; -1 if properties are not initialized
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
struct nm_data_ops_s ops
collection of iterators
struct nm_data_properties_s props
cache for properties
char _content[64]
placeholder for type-dependant content
internal state of a data slicer.
struct nm_data_slicer_ucontext_s * p_uslicer
struct nm_data_slicer_coroutine_s * p_coroutine
struct nm_data_slicer_generator_s * p_generator
nm_data_slicer_kind_t kind
encapsulate a dynamic vector of nm_data
struct nm_data_s data[4]
vector of data
int n_data
number of entries actually used in the above array
struct nm_data_s * p_data
vector of nm_data; either dynamically allocated, or points to data[0]
int allocated
allocated number of entries in p_data