00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef BSP_EXPTABLE_H
00028 #define BSP_EXPTABLE_H
00029
00039 #define MAX(x,y) ( ((x) > (y))?(x):(y))
00040
00042 #define MIN(x,y) ( ((x) < (y))?(x):(y))
00043
00044 #include <stdlib.h>
00045 #include <memory.h>
00046 #include "bsp_alloc.h"
00047
00048 #ifdef UNITTESTING
00049 #include "../tests/bsp_test.h"
00050 #else
00051 #include <mpi.h>
00052 #endif
00053
00054 #include <config.h>
00055
00060 inline static int no_slots(const int bytes, const int slot_size)
00061 {
00062 return (bytes + slot_size - 1) / slot_size;
00063 }
00064
00073 typedef struct
00074 {
00075 int tag_size;
00076 int slot_offset;
00077 int inslot_offset;
00078 int n_mesg;
00079 int n_mesg_deq;
00080 int accum_size;
00081 } MesgQInfo;
00088 typedef char * MemRegElement;
00089
00091 typedef struct
00092 {
00093 int numremov;
00094 int * restrict removed;
00095 int memoized_src_proc;
00096 const MemRegElement * memoized_data_iter;
00097 const MemRegElement * memoized_end;
00098 int memoized_srccol;
00099 } MemRegInfo;
00101
00102
00103
00104
00105
00106
00111 typedef struct
00112 {
00113 int size, offset;
00114 char *src, *dst;
00115 } ReqElement;
00120 typedef enum _ItemType
00121 { popreg, pushreg, put, get, send, settag } ItemType;
00122
00124 typedef struct
00125 {
00126 int item_count;
00127 int item_size;
00128 } PutObject;
00129
00131 typedef struct
00132 {
00133 int tag_size;
00134 int payload_size;
00135 int item_count;
00136 } SendObject;
00137
00139 typedef struct
00140 {
00141 const char *address;
00142 } PushRegObject;
00143
00145 typedef struct
00146 {
00147 const char *address;
00148 } PopRegObject;
00149
00151 typedef struct
00152 {
00153 int tag_size;
00154 } SetTagObject;
00155
00157 union _VarSzInfo
00158 {
00159 PutObject put;
00160 SendObject send;
00161 PushRegObject push;
00162 PopRegObject pop;
00163 SetTagObject settag;
00164 } ;
00165
00168 typedef struct
00169 {
00170 int size;
00171 ItemType type;
00172 union _VarSzInfo info;
00176 const char * restrict data;
00177 } VarSizeElement;
00181 typedef struct
00182 {
00185 VarSizeElement ** restrict latest_pushed_element;
00186 } DelivInfo;
00187
00189 union SpecInfo
00190 {
00191 MemRegInfo reg;
00192 DelivInfo deliv;
00193
00194 MesgQInfo mesgq;
00195 };
00196
00199
00204 typedef struct _ExpandableTable
00205 {
00206 int nprocs;
00207 int rows;
00210 int * restrict count;
00212 int * restrict used_slot_count;
00214 int slot_size;
00215
00217 union SpecInfo info;
00218
00220 char *data;
00221 } ExpandableTable;
00222
00223
00224 void
00225 expandableTable_comm (const ExpandableTable * restrict send,
00226 ExpandableTable * restrict recv, MPI_Comm communicator );
00227
00228
00229
00230
00231
00232
00233
00234
00235 static inline void
00236 expandableTable_initialize (ExpandableTable * restrict table, const int nprocs,
00237 const int rows, const int elsize,
00238 const union SpecInfo info)
00239 {
00240 table->nprocs = nprocs;
00241 table->rows = rows;
00242 table->slot_size = elsize;
00243 table->info = info;
00244 table->data = bsp_malloc (nprocs * rows, elsize);
00245
00246 table->count = bsp_calloc (nprocs, sizeof (int));
00247 table->used_slot_count = bsp_calloc (nprocs, sizeof (int));
00248 }
00249
00253 static inline void
00254 expandableTable_reset (ExpandableTable * restrict table)
00255 {
00256 memset (table->count, 0, sizeof (int) * table->nprocs);
00257 memset (table->used_slot_count, 0, sizeof (int) * table->nprocs);
00258 }
00259
00263 static inline void
00264 expandableTable_destruct (ExpandableTable * restrict table)
00265 {
00266 bsp_free (table->data);
00267 bsp_free (table->count);
00268 bsp_free (table->used_slot_count);
00269 }
00270
00277 static inline void
00278 expandableTable_expand (ExpandableTable * restrict table, const int rows,
00279 const union SpecInfo newinfo)
00280 {
00281 int newrows = rows + table->rows;
00282 char *newdata =
00283 bsp_malloc( newrows * table->nprocs, table->slot_size);
00284 int i;
00285
00286 for (i = 0; i < table->nprocs; i++)
00287 memcpy( newdata + i * newrows * table->slot_size,
00288 table->data + i * table->rows * table->slot_size,
00289 table->used_slot_count[i] * table->slot_size);
00290
00291 bsp_free(table->data);
00292 table->data = newdata;
00293 table->rows = newrows;
00294 table->info = newinfo;
00295 }
00309 static inline void
00310 fixedElSizeTable_initialize (ExpandableTable * restrict table, const int nprocs, const int rows,
00311 const int elsize, const union SpecInfo info)
00312 {
00313 expandableTable_initialize (table, nprocs, rows, elsize, info);
00314 }
00315
00325 static inline void
00326 fixedElSizeTable_push (ExpandableTable * restrict table, const int proc,
00327 void (*changeinfo) (union SpecInfo *restrict, int, int),
00328 const void *restrict element)
00329 {
00330 int j;
00331
00332
00333 if (table->used_slot_count[proc] == table->rows)
00334 {
00335 union SpecInfo info = table->info;
00336 (*changeinfo) (&info, table->rows, 3*table->rows );
00337 expandableTable_expand (table, 2 * table->rows , info);
00338 }
00339
00340
00341 j = table->used_slot_count[proc] + proc * table->rows;
00342 memcpy (table->data + j * table->slot_size,
00343 element, table->slot_size);
00344
00345 table->used_slot_count[proc] ++;
00346 table->count[proc]++;
00347 }
00354
00362 static inline void
00363 varElSizeTable_initialize (ExpandableTable *restrict table, const int nprocs,
00364 const int rows, const union SpecInfo info)
00365 {
00366 expandableTable_initialize (table, nprocs, rows, sizeof (VarSizeElement), info);
00367 }
00368
00376 static inline int
00377 varElSizeTable_push (ExpandableTable *restrict table, const int proc,
00378 void (*changeinfo) (union SpecInfo *restrict , int,int ),
00379 VarSizeElement elem)
00380 {
00381
00382 const int tag_size = sizeof(VarSizeElement);
00383 const int object_size = no_slots(tag_size + elem.size, tag_size);
00384 int old_space = table->rows - table->used_slot_count[proc];
00385 VarSizeElement *pelem;
00386
00387 if (object_size > old_space)
00388 {
00389 union SpecInfo info = table->info;
00390 int space_needed = MAX(table->rows * 2, object_size - old_space);
00391 (*changeinfo)(&info, table->rows, space_needed + table->rows);
00392 expandableTable_expand(table, space_needed, info);
00393 }
00394
00395 pelem = (VarSizeElement *) table->data +
00396 table->used_slot_count[proc] + proc * table->rows;
00397
00398
00399 memcpy (pelem + 1, elem.data, elem.size);
00400 elem.data = NULL;
00401
00402 *pelem = elem;
00403
00404 table->used_slot_count[proc] += object_size;
00405 table->count[proc]++;
00406 return 0;
00407 }
00410 #endif