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