Adding pack and iovec files. More updates.
This commit was SVN r738.
Этот коммит содержится в:
родитель
39553e4be5
Коммит
dafdb897a6
@ -14,6 +14,7 @@
|
||||
#ifndef LAM_DATATYPE_H_INCLUDED
|
||||
#define LAM_DATATYPE_H_INCLUDED 1
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <string.h>
|
||||
@ -274,6 +275,24 @@ int lam_datatype_convert(void *dst,
|
||||
lam_memcpy_state_t *check);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize pack state structure
|
||||
*
|
||||
* @param state Pointer to state structure
|
||||
* @return LAM return code
|
||||
*/
|
||||
static inline int lam_pack_state_init(lam_pack_state_t *state)
|
||||
{
|
||||
assert(state);
|
||||
|
||||
state->type_index = 0;
|
||||
state->repeat_index = 0;
|
||||
state->element_index = 0;
|
||||
state->datavec_offset = 0;
|
||||
state->packed_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Incrementally pack or unpack a buffer to/from an array of
|
||||
* datatypes.
|
||||
@ -352,6 +371,8 @@ static inline int lam_datatype_unpack(lam_pack_state_t *state,
|
||||
ntype, datatype, memcpy_fn, check,
|
||||
LAM_DATATYPE_UNPACK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Incrementally generate an iovec for gathering from an array of
|
||||
* datatypes
|
||||
@ -425,6 +446,9 @@ int lam_datatype_scatter_iovec(lam_pack_state_t *state,
|
||||
lam_memcpy_state_t *check);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* incremental memcpy with checksum / CRC functions
|
||||
*/
|
||||
|
120
src/mpi/datatype/datatype_iovec.c
Обычный файл
120
src/mpi/datatype/datatype_iovec.c
Обычный файл
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/* lam_dataype_t pack function(s) */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "datatype.h"
|
||||
|
||||
/**
|
||||
* Incrementally generate an iovec referencing a datatype (or fragment
|
||||
* of a dataype).
|
||||
*
|
||||
* @param state current state of the incremental pack/unpack
|
||||
* @param vec iovec buffer
|
||||
* @param vec_count maximum length of iovec buffer
|
||||
* @param max_bytes maximum bytes addressed by iovec
|
||||
* @param typebuf array of types
|
||||
* @param ntype size of type array
|
||||
* @param type type descriptor
|
||||
* @return 0 if complete, non-zero otherwise
|
||||
*
|
||||
* Incrementally traverse an array of datatypes and generate an iovec
|
||||
* of at most length vec_count and addressing at most max_bytes. This
|
||||
* can be used to do a (partial) RDMA gather of the datatype array.
|
||||
*
|
||||
* The state (all members) should be initialized to 0 before the first
|
||||
* call.
|
||||
*/
|
||||
int lam_datatype_get_iovec(lam_pack_state_t *state,
|
||||
struct iovec *vec,
|
||||
size_t vec_count,
|
||||
size_t max_bytes,
|
||||
const void *typebuf,
|
||||
size_t ntype,
|
||||
lam_datatype_t *datatype)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**** OLD STUFF BELOW ****/
|
||||
|
||||
|
||||
/**
|
||||
* Incrementally generate an iovec for gathering from an array of
|
||||
* datatypes
|
||||
*
|
||||
* @param state current state of the incremental pack/unpack
|
||||
* @param base_addr base address for iovec offsets
|
||||
* @param vec iovec buffer
|
||||
* @param vec_count maximum length of iovec buffer
|
||||
* @param max_bytes maximum bytes addressed by iovec
|
||||
* @param buf buffer to pack into/unpack from
|
||||
* @param bufsize size of buffer
|
||||
* @param typebuf array of types
|
||||
* @param ntype size of type array
|
||||
* @param type type descriptor
|
||||
* @return 0 if complete, non-zero otherwise
|
||||
*
|
||||
* Incrementally traverse an array of datatypes and generate an iovec
|
||||
* of at most length vec_count and addressing at most max_bytes. This
|
||||
* can be used to do a (partial) RDMA gather of the datatype array.
|
||||
*
|
||||
* The state (all members) should be initialized to 0 before the first
|
||||
* call.
|
||||
*/
|
||||
int lam_datatype_gather_iovec(lam_pack_state_t *state,
|
||||
void *base_addr,
|
||||
struct iovec *vec,
|
||||
size_t vec_count,
|
||||
size_t max_bytes,
|
||||
const void *typebuf,
|
||||
size_t ntype,
|
||||
lam_datatype_t *datatype,
|
||||
lam_checksum_t *checksum);
|
||||
|
||||
/**
|
||||
* Incrementally generate an iovec for scattering from a packed array
|
||||
* of datatypes
|
||||
*
|
||||
* @param state current state of the incremental pack/unpack
|
||||
* @param base_addr base address for iovec offsets
|
||||
* @param vec iovec buffer
|
||||
* @param vec_count maximum length of iovec buffer
|
||||
* @param max_bytes maximum bytes addressed by iovec
|
||||
* @param buf packed buffer
|
||||
* @param bufsize size of buffer
|
||||
* @param typebuf array of types
|
||||
* @param ntype size of type array
|
||||
* @param type type descriptor
|
||||
* @return 0 if complete, non-zero otherwise
|
||||
*
|
||||
* Incrementally copy data type arrays to/from a packed buffer. by
|
||||
* iterating over the type and type_map until we finish or run out of
|
||||
* room.
|
||||
*
|
||||
* Incrementally traverse a packed array of datatypes and generate an
|
||||
* iovec of at most length vec_count and addressing at most max_bytes.
|
||||
* This can be used to do a (partial) RDMA scatter of the datatype
|
||||
* array.
|
||||
*
|
||||
* The state (all members) should be initialized to 0 before the first
|
||||
* call.
|
||||
*/
|
||||
int lam_datatype_scatter_iovec(lam_pack_state_t *state,
|
||||
void *base_addr,
|
||||
struct iovec *vec,
|
||||
size_t vec_count,
|
||||
size_t max_bytes,
|
||||
const void *buf,
|
||||
size_t bufsize,
|
||||
lam_datatype_t *datatype,
|
||||
lam_memcpy_fn_t *memcpy_fn,
|
||||
lam_memcpy_state_t *check);
|
||||
|
||||
|
@ -4,14 +4,13 @@
|
||||
|
||||
/* alternative memcpy function */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lam_config.h"
|
||||
#include "datatype.h"
|
||||
|
||||
#define ALIGNED32(X) (((uint32_t)(X) & (uint32_t) 3) == (uint32_t) 0 ? 1 : 0)
|
||||
|
||||
/*
|
||||
* Alternative memcpy function: On some systems, this performs better
|
||||
* than the system memcpy.
|
||||
@ -19,7 +18,10 @@
|
||||
void *lam_memcpy_alt(void *dst, const void *src, size_t size,
|
||||
lam_memcpy_state_t *dummy)
|
||||
{
|
||||
if (ALIGNED32(src) && ALIGNED32(dst)) {
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
if (LAM_IS_32BIT_ALIGNED(src) && LAM_IS_32BIT_ALIGNED(dst)) {
|
||||
uint32_t *restrict p = (uint32_t *) dst;
|
||||
uint32_t *restrict q = (uint32_t *) src;
|
||||
uint32_t i;
|
||||
|
121
src/mpi/datatype/datatype_pack.c
Обычный файл
121
src/mpi/datatype/datatype_pack.c
Обычный файл
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/* lam_dataype_t pack function(s) */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "datatype.h"
|
||||
|
||||
/*
|
||||
* Incrementally pack or unpack an array of datatypes to/from a buffer
|
||||
*/
|
||||
int lam_datatype_packer(lam_pack_state_t *state,
|
||||
void *buf,
|
||||
size_t bufsize,
|
||||
void *typebuf,
|
||||
size_t ntype,
|
||||
lam_datatype_t *d,
|
||||
lam_memcpy_fn_t *memcpy_fn,
|
||||
lam_memcpy_state_t *check,
|
||||
int pack_direction)
|
||||
{
|
||||
if (LAM_DATATYPE_STATE_CONTIGUOUS & d->flags) {
|
||||
|
||||
unsigned char *b;
|
||||
unsigned char *t;
|
||||
size_t copied_so_far;
|
||||
size_t left_to_copy;
|
||||
size_t size;
|
||||
|
||||
b = (unsigned char *) buf + state->packed_offset;
|
||||
t = (unsigned char *) typebuf
|
||||
+ state->type_index * d->extent
|
||||
+ state->repeat_index * d->datavec->repeat_offset
|
||||
+ state->datavec_offset;
|
||||
bufsize -= state->packed_offset;
|
||||
|
||||
copied_so_far =
|
||||
state->type_index * d->extent + state->datavec_offset;
|
||||
size = bufsize;
|
||||
left_to_copy = ntype * d->extent - copied_so_far;
|
||||
if (size > left_to_copy) {
|
||||
size = left_to_copy;
|
||||
}
|
||||
if (LAM_DATATYPE_PACK == pack_direction) {
|
||||
memcpy(b, t, size);
|
||||
} else {
|
||||
memcpy(t, b, size);
|
||||
}
|
||||
copied_so_far += size;
|
||||
state->packed_offset += size;
|
||||
state->type_index = copied_so_far / d->extent;
|
||||
state->datavec_offset =
|
||||
copied_so_far - state->type_index * d->extent;
|
||||
if (copied_so_far != (ntype * d->extent)) {
|
||||
return LAM_DATATYPE_PACK_INCOMPLETE;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
unsigned char *ptr;
|
||||
unsigned char *b;
|
||||
unsigned char *t;
|
||||
size_t size;
|
||||
lam_datavec_t *dv;
|
||||
|
||||
ptr = (unsigned char *) typebuf
|
||||
+ state->type_index * d->extent,
|
||||
+ state->repeat_index * dv->repeat_offset;
|
||||
b = (unsigned char *) buf + state->packed_offset;
|
||||
bufsize -= state->packed_offset;
|
||||
dv = d->datavec;
|
||||
|
||||
while (state->type_index < ntype) {
|
||||
while (state->repeat_index < dv->nrepeat) {
|
||||
while (state->element_index < dv->nelement) {
|
||||
t = ptr + dv->element[state->element_index].offset;
|
||||
size = dv->element[state->element_index].size;
|
||||
if (state->datavec_offset > 0) {
|
||||
t += state->datavec_offset;
|
||||
size -= state->datavec_offset;
|
||||
if (size <= bufsize) {
|
||||
state->datavec_offset = 0;
|
||||
}
|
||||
}
|
||||
if (size > bufsize) {
|
||||
size = bufsize;
|
||||
state->datavec_offset += size;
|
||||
}
|
||||
if (LAM_DATATYPE_PACK == pack_direction) {
|
||||
memcpy(b, t, size);
|
||||
} else {
|
||||
memcpy(t, b, size);
|
||||
}
|
||||
state->packed_offset += size;
|
||||
if (state->datavec_offset > 0) {
|
||||
return LAM_DATATYPE_PACK_INCOMPLETE;
|
||||
}
|
||||
bufsize -= size;
|
||||
b += size;
|
||||
state->element_index += 1;
|
||||
if (bufsize == 0
|
||||
&& state->element_index < (size_t) dv->nelement) {
|
||||
return LAM_DATATYPE_PACK_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
ptr += dv->repeat_offset;
|
||||
state->repeat_index += 1;
|
||||
}
|
||||
ptr += d->extent;
|
||||
state->type_index += 1;
|
||||
state->element_index = 0;
|
||||
if (bufsize == 0 && state->type_index < ntype) {
|
||||
return LAM_DATATYPE_PACK_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LAM_DATATYPE_PACK_COMPLETE;
|
||||
}
|
Загрузка…
Ссылка в новой задаче
Block a user