bsp_delivtable.h

Go to the documentation of this file.
00001 /*
00002     BSPonMPI. This is an implementation of the BSPlib standard on top of MPI
00003     Copyright (C) 2006  Wijnand J. Suijlen
00004                                                                                 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009                                                                                 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014                                                                                 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018                                                                                 
00019     You may contact me via electronic mail:
00020       wjsuijle@users.sourceforge.net
00021     or snail mail:
00022       W.J. Suijlen
00023       Kraaiheidelaan 10
00024       2803 VP Gouda
00025       The Netherlands
00026 */
00027 #ifndef BSP_DELIVTABLE_H
00028 #define BSP_DELIVTABLE_H
00029 
00054 #include "bsp_exptable.h"
00055 #include <config.h>
00056 void
00057 deliveryTable_execute (ExpandableTable *restrict , ExpandableTable *restrict ,
00058                        ExpandableTable *restrict );
00059 
00066 static inline void
00067 deliveryTable_initialize (ExpandableTable * restrict table, const int nprocs, const int rows)
00068 {
00069   union SpecInfo info;
00070   info.deliv.latest_pushed_element = 
00071     bsp_calloc(nprocs, sizeof(VarSizeElement *));
00072   varElSizeTable_initialize (table, nprocs, rows, info);
00073 }
00074 
00078 static inline void
00079 deliveryTable_reset(ExpandableTable * restrict table)
00080 {
00081   memset(table->info.deliv.latest_pushed_element, 0, 
00082       sizeof(VarSizeElement *) * table->nprocs);
00083   expandableTable_reset(table);
00084 }  
00085 
00088 static inline void
00089 deliveryTable_destruct (ExpandableTable * restrict table)
00090 {
00091   free(table->info.deliv.latest_pushed_element);
00092   expandableTable_destruct (table);
00093 }
00094 
00100 static inline void
00101 deliveryTable_expand (ExpandableTable * restrict table, const int rows)
00102 {
00103   union SpecInfo info = table->info;
00104   int offsets[table->nprocs], null[table->nprocs];
00105   int i;
00106 
00107   for (i = 0; i < table->nprocs; i++)
00108     {
00109       offsets[i] = info.deliv.latest_pushed_element[i] - table->rows * i -
00110                    (VarSizeElement *) table->data;
00111       null[i] = (info.deliv.latest_pushed_element[i] == NULL);
00112     }  
00113   expandableTable_expand (table, rows, info);
00114 
00115   for (i = 0; i < table->nprocs; i++)
00116     info.deliv.latest_pushed_element[i] =  null[i] ? NULL :
00117         (VarSizeElement *) table->data + table->rows * i + offsets[i];
00118   table->info = info;   
00119 }
00120 
00121 static void
00122 delivInfoMake (union SpecInfo * restrict info , int b , int c)
00123 {
00124 }
00125 
00131 static inline void
00132 deliveryTable_push (ExpandableTable * restrict table, const int proc, const VarSizeElement elem)
00133 {
00134   int offsets[table->nprocs], null[table->nprocs];
00135   int i;
00136 
00137   for (i = 0; i < table->nprocs; i++)
00138     {
00139       offsets[i] = (i==proc) ?
00140                       table->used_slot_count[i]
00141                      :
00142                       table->info.deliv.latest_pushed_element[i] - table->rows * i -
00143                         (VarSizeElement *) table->data;
00144                       
00145       null[i] = (table->info.deliv.latest_pushed_element[i] == NULL);
00146     } 
00147   varElSizeTable_push (table, proc, &delivInfoMake, elem);
00148 
00149   for (i = 0; i < table->nprocs; i++)
00150     {
00151       table->info.deliv.latest_pushed_element[i] = null[i] && i!=proc ? NULL : 
00152         (VarSizeElement *) table->data + i * table->rows + offsets[i];
00153     }   
00154  }
00155 
00164 static inline void 
00165 deliveryTable_pushSend(ExpandableTable * restrict table, const int proc, 
00166                        const void * restrict tag, const int tag_size,
00167                        const void * restrict payload, const int payload_size)
00168 {
00169   /* add table if necessary */
00170   SendObject sendobj; VarSizeElement element;
00171   VarSizeElement * restrict latest_element = table->info.deliv.latest_pushed_element[proc];
00172   int free_space, used_space, object_size; // sizes in bytes!
00173   int old_element_slot_size, new_element_slot_size;
00174   char * restrict pointer;
00175 
00178   if (latest_element != NULL && 
00179       latest_element->type == send && 
00180       latest_element->info.send.payload_size == payload_size&&
00181       latest_element->info.send.tag_size == tag_size )
00182     {
00183       /* determine whether there is enough memory allocated and expand if
00184        * needed */
00185       object_size = tag_size + payload_size;
00186       used_space = 
00187         (table->used_slot_count[proc] - 1)*sizeof(VarSizeElement) + latest_element->size;
00188       free_space = table->rows * sizeof(VarSizeElement) - used_space; 
00189 
00190       if (object_size > free_space)
00191         {
00192           deliveryTable_expand(table, MAX(table->rows * 2, 1 + object_size / sizeof(VarSizeElement)));
00193           latest_element = table->info.deliv.latest_pushed_element[proc];
00194         }  
00195 
00196       /* set the pointer */
00197       pointer = 
00198         (char *) latest_element + sizeof(VarSizeElement) + 
00199         latest_element->info.send.item_count * (tag_size + payload_size);
00200           
00201       new_element_slot_size = 
00202          no_slots( sizeof(VarSizeElement) + latest_element->size + object_size
00203                  , sizeof(VarSizeElement));
00204       old_element_slot_size = 
00205          no_slots( sizeof(VarSizeElement) + latest_element->size
00206                  , sizeof(VarSizeElement));
00207       table->used_slot_count[proc] += new_element_slot_size - old_element_slot_size;
00208       //table->count doesn't change
00209       
00210       latest_element->size += object_size;
00211       latest_element->info.send.item_count++;
00212       // latest_element->info.send.payload_size && tag_size don't change
00213     }     
00214   else
00215     { /* else make a brand new VarSizeElement */
00216       sendobj.tag_size = tag_size; sendobj.payload_size = payload_size;
00217       sendobj.item_count = 1;
00218       element.size = tag_size + payload_size;
00219       element.type = send;
00220       element.info.send = sendobj;
00221       element.data = NULL;
00222 
00223       object_size = no_slots( sizeof(VarSizeElement) + element.size
00224                             , sizeof(VarSizeElement)); 
00225       free_space = table->rows - table->used_slot_count[proc];
00226  
00227       if (free_space < object_size)
00228          deliveryTable_expand(table, MAX(table->rows * 2, object_size ));
00229 
00230       pointer = (char *) 
00231         ( (VarSizeElement *) table->data + proc * table->rows + table->used_slot_count[proc]);
00232       table->info.deliv.latest_pushed_element[proc] = (VarSizeElement *) pointer;
00233 
00234       /* copy VarSizeElement */
00235       * (VarSizeElement *) pointer = element;
00236       pointer += sizeof(VarSizeElement);
00237       
00238       new_element_slot_size = 
00239          no_slots( sizeof(VarSizeElement) + payload_size+tag_size
00240                  , sizeof(VarSizeElement));
00241       table->used_slot_count[proc] += new_element_slot_size;
00242       //table->count doesn't change
00243 
00244     }
00245 
00246   /* copy the tag */
00247   memcpy( pointer, tag, tag_size);
00248   pointer += tag_size;
00249   /* copy the payload */
00250   memcpy( pointer, payload, payload_size); 
00251 }
00252 
00260 static inline void 
00261 deliveryTable_pushPut(ExpandableTable * restrict table, 
00262        const int proc, const void * const dst, 
00263        const void * const restrict data, const int size)
00264 {
00265   VarSizeElement * restrict latest_element = table->info.deliv.latest_pushed_element[proc];
00266   int free_space, used_space, object_size; // sizes in bytes!
00267   int old_element_slot_size, new_element_slot_size;
00268   char * restrict pointer;
00269 
00271   if (latest_element != NULL && 
00272       latest_element->type == put && 
00273       latest_element->info.put.item_size == size)
00274     {
00275       /* determine whether there is enough memory allocated and expand if
00276        * needed */
00277       object_size = sizeof( void * ) + size;
00278       used_space = 
00279         (table->used_slot_count[proc] - 1)*sizeof(VarSizeElement) + latest_element->size;
00280       free_space = table->rows * sizeof(VarSizeElement) - used_space; 
00281 
00282       if (object_size > free_space)
00283         {
00284           deliveryTable_expand(table, MAX(table->rows * 2, 1 + object_size / sizeof(VarSizeElement)));
00285           latest_element = table->info.deliv.latest_pushed_element[proc];
00286         }  
00287 
00288       /* set the pointer */
00289       pointer = 
00290         (char *) latest_element + sizeof(VarSizeElement) + 
00291         latest_element->info.put.item_count *
00292           (latest_element->info.put.item_size + sizeof (void *));
00293           
00294       new_element_slot_size = 
00295          no_slots( sizeof(VarSizeElement) + latest_element->size + object_size
00296                  , sizeof(VarSizeElement));
00297       old_element_slot_size = 
00298          no_slots( sizeof(VarSizeElement) + latest_element->size
00299                  , sizeof(VarSizeElement));
00300       table->used_slot_count[proc] += new_element_slot_size - old_element_slot_size;
00301       //table->count doesn't change
00302       
00303       latest_element->size += object_size;
00304       latest_element->info.put.item_count++;
00305       // latest_element->info.put.item_size doesn't change
00306     }     
00307   else
00308     { /* else push a brand new VarSizeElement */
00309       PutObject putobj; 
00310       VarSizeElement element; 
00311       putobj.item_count = 1; putobj.item_size=size;
00312       element.size = size + sizeof(void *);
00313       element.type = put;
00314       element.info.put = putobj;
00315       element.data = NULL;
00316  
00317       free_space = table->rows - table->used_slot_count[proc];
00318       object_size = 
00319          no_slots(sizeof(VarSizeElement) + size, sizeof(VarSizeElement));       
00320       if (free_space < object_size)
00321          deliveryTable_expand(table, MAX(table->rows * 2, object_size ));
00322 
00323       pointer = (char *) 
00324         ( (VarSizeElement *) table->data + proc * table->rows + table->used_slot_count[proc]);
00325       table->info.deliv.latest_pushed_element[proc] = (VarSizeElement *) pointer;
00326 
00327       /* copy VarSizeElement */
00328       * (VarSizeElement *) pointer = element;
00329       pointer += sizeof(VarSizeElement);
00330       
00331       new_element_slot_size = 
00332          no_slots( sizeof(VarSizeElement) + size + sizeof(void *)
00333                  , sizeof(VarSizeElement));
00334       table->used_slot_count[proc] += new_element_slot_size;
00335       //table->count doesn't change
00336 
00337     }
00338 
00339   /* copy the destination */
00340   memcpy( pointer, &dst, sizeof(void const *));
00341   pointer += sizeof(void *);
00342   /* copy the data */
00343   memcpy( pointer, data, size); 
00344 }
00345 
00346 
00347 #endif

Generated on Sat Apr 8 12:56:54 2006 for BSPonMPI by  doxygen 1.4.6