#include "BSprivate.h" /*@ BSfree_off_map - Free an offset mapping Input Parameters: . map - the map to be freed Returns: void @*/ void BSfree_off_map(BSoff_map *map) { MY_FREE(map->proc_id); MY_FREE(map->offset); MY_FREE(map); } /*@ BSmake_off_map - Generate a mapping from global rows to processor id Input Parameters: . offset - the offset of the local processor in the global numbering . procinfo - the usual processor information . max - the number of global rows Returns: the mapping Notes: For example, processor 0 has 10 rows and an offset of 0, processor 1 has 3 rows and an offset of 10 and processor 2 has 4 rows and an offset of 13 (there are 3 processors and 17 rows). The offset mapping (see BSsparse.h) would have the offsets in sorted order with the corresponding processor id. In this way, given a global row number, one could determine the processor on which it lies. @*/ BSoff_map *BSmake_off_map(int offset, BSprocinfo *procinfo, int max) { BSoff_map *map; int i; MY_MALLOCN(map,(BSoff_map *),sizeof(BSoff_map),1); MPI_Comm_size(procinfo->procset,&(map->length)); MY_MALLOCN(map->proc_id,(int *),sizeof(int)*map->length,2); MY_MALLOCN(map->offset,(int *),sizeof(int)*((map->length)+1),3); MPI_Allgather(&offset,1,MPI_INT,map->offset,1,MPI_INT,procinfo->procset); map->offset[map->length] = max; /* get the numbers of all the nodes in my procset */ for (i=0;ilength;i++) { map->proc_id[i] = i; } /* sort by offset */ BSheap_sort1(map->length,map->offset,map->proc_id); CHKERRN(0); for (i=0;ilength;i++) { if (map->proc_id[i] == procinfo->my_id) { map->my_ind = i; break; } } return(map); } /*@ BSfreel2g - Free a local to global mapping Input Parameters: . data - the structure to be freed Returns: void @*/ void BSfreel2g(void *data) { MY_FREE(data); } /*@ BSloc2glob - Map local row numbers to global row numbers Input Parameters: . length - the number of row numbers to map . req_array - the row numbers to map . procinfo - the usual processor information . map - the map to use Output Parameters: . ans_array - on exit, the corresponding global row numbers Returns: void Notes: Only valid for local row numbers that reside on the calling processor @*/ void BSloc2glob(int length,int *req_array,int *ans_array, BSprocinfo *procinfo, BSmapping *map) { int i; int offset; offset = *((int *) map->vlocal2global); for (i=0;ivglobal2proc; /* start out mid with the index for my processor */ /* after that let mid start at the index of the last place */ mid = trans->my_ind; for (i=0;ilength-1; found = FALSE; while (!found) { if (req_array[i] < trans->offset[mid]) { right = mid-1; mid = (left+right) / 2; } else if (req_array[i] >= trans->offset[mid+1]) { left = mid+1; mid = (left+right) / 2; } else { found = TRUE; } } ans_array[i] = trans->proc_id[mid]; } } /*@ BSfreeg2l - Free a global to local mapping Input Parameters: . data - the structure to be freed Returns: void @*/ void BSfreeg2l(void *data) { MY_FREE(data); } /*@ BSglob2loc - Map global row numbers to local row numbers Input Parameters: . length - the number of row numbers to map . req_array - the row numbers to map . procinfo - the usual processor information . map - the map to use Output Parameters: . ans_array - on exit, the corresponding local row numbers or a -1 if the row does not reside on the calling processor Returns: void @*/ void BSglob2loc(int length,int *req_array,int *ans_array, BSprocinfo *procinfo,BSmapping *map) { int i; int offset; offset = *((int *) map->vlocal2global); BSglob2proc(length,req_array,ans_array,procinfo,map); CHKERR(0); for (i=0;imy_id) { ans_array[i] = -1; } else { ans_array[i] = req_array[i] - offset; } } }