int phg_map_GIDs_to_processes(ZZ *zz, ZOLTAN_ID_PTR eid, int size, int lenGID, int **hashedProc, int nprocs) { int i, j; int *procList; static char *yo = "map_GIDs_to_processes"; *hashedProc = NULL; if (size < 1){ return ZOLTAN_OK; } procList = (int *)ZOLTAN_MALLOC(sizeof(int) * size); if (!procList){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error."); return ZOLTAN_MEMERR; } for (i=0; i<size; i++){ j = Zoltan_Hash(eid, lenGID, nprocs); procList[i] = j; eid += lenGID; } *hashedProc = procList; return ZOLTAN_OK; }
int Zoltan_G2LHash_Insert(G2LHash *hash, ZOLTAN_GNO_TYPE gno) { int i, lno; G2LHashNode *ptr; if (gno<hash->base || gno>hash->baseend) { i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize); for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next); if (!ptr) { if (hash->size >= hash->maxsize) { char st[2048]; sprintf(st, "Hash is full! #entries=%d maxsize=%d", hash->size, hash->maxsize); ZOLTAN_PRINT_ERROR(-1, "Zoltan_G2LHash_G2L", st); return -1; } ptr = &(hash->nodes[hash->size]); ptr->gno = gno; lno = ptr->lno = hash->nlvtx + hash->size; ptr->next = hash->table[i]; hash->table[i] = ptr; ++hash->size; } else lno = ptr->lno; } else return gno-hash->base; return lno; }
void remove_from_hash( int globalID ) { int idx, hidx, prev; ZOLTAN_ID_TYPE tmp; tmp = globalID; hidx = Zoltan_Hash(&tmp, 1, New_Elem_Index_Size); idx = New_Elem_Hash_Table[hidx]; prev = -1; while (idx != -1 && New_Elem_Hash_Nodes[idx].globalID != globalID) { prev = idx; idx = New_Elem_Hash_Nodes[idx].next; } if (prev == -1) New_Elem_Hash_Table[hidx] = New_Elem_Hash_Nodes[idx].next; else New_Elem_Hash_Nodes[prev].next = New_Elem_Hash_Nodes[idx].next; New_Elem_Hash_Nodes[idx].globalID = -1; New_Elem_Hash_Nodes[idx].localID = -1; New_Elem_Hash_Nodes[idx].next = -1; }
int Zoltan_Map_Find(ZZ *zz, ZOLTAN_MAP* map, int *key, int *data) { char *yo = "Zoltan_Map_Find"; int index, match; ZOLTAN_ENTRY *element; ZOLTAN_ID_PTR zkey = (ZOLTAN_ID_PTR)key; *data = ZOLTAN_NOT_FOUND; if (!map){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Map specified does not exist\n"); return ZOLTAN_FATAL; } index = Zoltan_Hash(zkey, map->id_size, map->max_index); element = map->entries[index]; match = 0; while (element != NULL){ match = key_match(map->id_size, element->key, key); if (match){ *data = element->data; break; } element = element->next; } return ZOLTAN_OK; }
void Zoltan_Reftree_Hash_Remove (ZZ *zz, ZOLTAN_REFTREE *reftree_node, struct Zoltan_Reftree_hash_node **hashtab, int n) { int i; struct Zoltan_Reftree_hash_node *ptr, *prev, *next; i = Zoltan_Hash(reftree_node->global_id, zz->Num_GID, (unsigned int)n); ptr = hashtab[i]; prev = NULL; while (ptr != NULL) { if (ZOLTAN_EQ_GID(zz, ptr->gid, reftree_node->global_id)) { next = ptr->next; ZOLTAN_FREE(&(ptr->gid)); ZOLTAN_FREE(&ptr); if (prev == NULL) { hashtab[i] = next; } else { prev->next = next; } ptr = NULL; } else { prev = ptr; ptr = ptr->next; } } }
int Zoltan_KVHash_Insert(KVHash *hash, ZOLTAN_GNO_TYPE key, int value) { int i; G2LHashNode *ptr; i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&key, hash->num_gid_entries, (unsigned int) hash->maxsize); for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next); if (!ptr) { if (hash->size >= hash->maxsize) { ZOLTAN_PRINT_ERROR(-1, "Zoltan_KVHash_Insert", "Hash is full!"); return -1; } ptr = &(hash->nodes[hash->size]); ptr->gno = key; ptr->lno = value; ptr->next = hash->table[i]; hash->table[i] = ptr; ++hash->size; } else value = ptr->lno; return value; }
phg_GID_lookup *phg_create_GID_lookup_table2(ZOLTAN_ID_PTR gids, int ngids, int lenGID) { int i, j, k, tsize, found; struct Hash_Node *hn; ZOLTAN_ID_PTR nextGID, nextUniqueGID; phg_GID_lookup *lu = NULL; tsize = ngids; /* actually may be larger than number of unique ids */ nextGID = nextUniqueGID = gids; lu = (phg_GID_lookup *)ZOLTAN_MALLOC(sizeof(phg_GID_lookup)); if (!lu){ return NULL; } lu->ht = (struct Hash_Node **)ZOLTAN_CALLOC(sizeof(struct Hash_Node*) , tsize); hn = lu->htTop = (struct Hash_Node *)ZOLTAN_MALLOC(sizeof(struct Hash_Node) * ngids); if (tsize && (!lu->htTop || !lu->ht)){ ZOLTAN_FREE(&lu); ZOLTAN_FREE(&lu->htTop); ZOLTAN_FREE(&lu->ht); return NULL; } lu->lenGID = lenGID; lu->table_size = tsize; lu->numGIDs = 0; for (i=0; i<ngids; i++, nextGID += lenGID){ found = phg_lookup_GID(lu, nextGID); if (found >= 0) continue; hn->gid = nextUniqueGID; hn->gno = lu->numGIDs; if (nextUniqueGID < nextGID){ for (k=0; k<lenGID; k++){ nextUniqueGID[k] = nextGID[k]; } } j = Zoltan_Hash(nextGID, lenGID, tsize); hn->next = lu->ht[j]; lu->ht[j] = hn; hn++; nextUniqueGID += lenGID; lu->numGIDs++; } return lu; }
int Zoltan_KVHash_GetValue(KVHash *hash, ZOLTAN_GNO_TYPE key) { int i; G2LHashNode *ptr; i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *) &key, hash->num_gid_entries, (unsigned int) hash->maxsize); for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next); if (!ptr) return -1; else return ptr->lno; }
void insert_in_hash( int globalID, int localID ) { int j; New_Elem_Hash_Nodes[localID].globalID = globalID; New_Elem_Hash_Nodes[localID].localID = localID; j = Zoltan_Hash((ZOLTAN_ID_PTR) &globalID,1,New_Elem_Index_Size); New_Elem_Hash_Nodes[localID].next = New_Elem_Hash_Table[j]; New_Elem_Hash_Table[j] = localID; }
int find_in_hash( ZOLTAN_ID_TYPE globalID ) { int idx; idx = Zoltan_Hash(&globalID, 1, New_Elem_Index_Size); idx = New_Elem_Hash_Table[idx]; while (idx != -1 && New_Elem_Hash_Nodes[idx].globalID != globalID) { idx = New_Elem_Hash_Nodes[idx].next; } return idx; }
int Zoltan_G2LHash_G2L(G2LHash *hash, ZOLTAN_GNO_TYPE gno) { int i; G2LHashNode *ptr; if (gno<hash->base || gno>hash->baseend) { i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize); for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next); if (!ptr) return -1; else return ptr->lno; } else return gno-hash->base; }
int Zoltan_Reftree_inthash_lookup (ZZ *zz, struct Zoltan_Reftree_inthash_node **hashtab, ZOLTAN_ID_PTR key, int n) { int i; struct Zoltan_Reftree_inthash_node *ptr; i = Zoltan_Hash(key, zz->Num_GID, (unsigned int)n); for (ptr=hashtab[i]; ptr != NULL; ptr = ptr->next){ if (ZOLTAN_EQ_GID(zz, ptr->gid, key)) return (ptr->lid); } /* Key not in hash table */ return -1; }
void Zoltan_Reftree_Hash_Insert(ZZ *zz, ZOLTAN_REFTREE *reftree_node, struct Zoltan_Reftree_hash_node **hashtab, int size) { int i; struct Zoltan_Reftree_hash_node *new_entry; i = Zoltan_Hash(reftree_node->global_id, zz->Num_GID, (unsigned int)size); new_entry = (struct Zoltan_Reftree_hash_node *) ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_hash_node)); new_entry->gid = ZOLTAN_MALLOC_GID(zz); ZOLTAN_SET_GID(zz, new_entry->gid,reftree_node->global_id); new_entry->reftree_node = reftree_node; new_entry->next = hashtab[i]; hashtab[i] = new_entry; }
void Zoltan_Reftree_IntHash_Insert(ZZ *zz, ZOLTAN_ID_PTR gid, int lid, struct Zoltan_Reftree_inthash_node **hashtab, int size) { int i; struct Zoltan_Reftree_inthash_node *new_entry; i = Zoltan_Hash(gid, zz->Num_GID, (unsigned int)size); new_entry = (struct Zoltan_Reftree_inthash_node *) ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_inthash_node)); new_entry->gid = ZOLTAN_MALLOC_GID(zz); ZOLTAN_SET_GID(zz, new_entry->gid,gid); new_entry->lid = lid; new_entry->next = hashtab[i]; hashtab[i] = new_entry; }
static int search_hash_table(ZZ *zz, ZOLTAN_ID_PTR gid, struct Hash_Node **ht, int tableSize) { int j, found; struct Hash_Node *hn; found = -1; j = Zoltan_Hash(gid, zz->Num_GID, tableSize); hn = ht[j]; while (hn){ if (ZOLTAN_EQ_GID(zz, gid, hn->gid)){ found = hn->gno; break; } hn = hn->next; } return found; }
phg_GID_lookup *phg_create_GID_lookup_table(ZOLTAN_ID_PTR gids, int size, int lenGID) { int i, j, tsize; phg_GID_lookup *lu = NULL; lu = (phg_GID_lookup *)ZOLTAN_MALLOC(sizeof(phg_GID_lookup)); if (!lu){ return NULL; } tsize = size * 1.25; lu->htTop = (struct Hash_Node *)ZOLTAN_MALLOC(sizeof(struct Hash_Node)*size); lu->ht = (struct Hash_Node **)ZOLTAN_CALLOC(sizeof(struct Hash_Node*), tsize); if (tsize && (!lu->htTop || !lu->ht)){ ZOLTAN_FREE(&lu->htTop); ZOLTAN_FREE(&lu->ht); ZOLTAN_FREE(&lu); return NULL; } lu->table_size = tsize; lu->numGIDs = size; lu->lenGID = lenGID; for (i=0; i<size; i++){ lu->htTop[i].gid = gids + (i * lenGID); lu->htTop[i].gno = i; j = Zoltan_Hash(lu->htTop[i].gid, lenGID, tsize); lu->htTop[i].next = lu->ht[j]; lu->ht[j] = lu->htTop + i; } return lu; }
int phg_lookup_GID(phg_GID_lookup *lu, ZOLTAN_ID_PTR gid) { struct Hash_Node *hn; int i, k, match; if (lu->table_size < 1) return -1; if (lu->numGIDs < 1) return -1; i = Zoltan_Hash(gid, lu->lenGID, (unsigned int) lu->table_size); for (hn=lu->ht[i]; hn != NULL; hn = hn->next){ match = 1; for (k=0; k<lu->lenGID; k++){ if (hn->gid[k] != gid[k]){ match = 0; break; } } if (match){ return (hn->gno); } } return -1; }
void read_input_file(int me , int nproc, char *fname, GRAPH_DATA *graph) { char buf[512]; int bufsize; int numGlobalVertices, numGlobalNeighbors; int num, nnbors, ack=0; int vGID; int i, j, procID; int vals[128], send_count[2]; int *idx; ZOLTAN_ID_TYPE id; FILE *fp; MPI_Status status; int ack_tag = 5, count_tag = 10, id_tag = 15; GRAPH_DATA *send_graph; if (me == 0){ bufsize = 512; fp = fopen(fname, "r"); /* Get the number of vertices */ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(nproc, count_tag, 1); num = sscanf(buf, "%d", &numGlobalVertices); if (num != 1) input_file_error(nproc, count_tag, 1); /* Get the number of vertex neighbors */ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(nproc, count_tag, 1); num = sscanf(buf, "%d", &numGlobalNeighbors); if (num != 1) input_file_error(nproc, count_tag, 1); /* Allocate arrays to read in entire graph */ graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalVertices); graph->nborIndex = (int *)malloc(sizeof(int) * (numGlobalVertices + 1)); graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalNeighbors); graph->nborPart = (int *)malloc(sizeof(int) * numGlobalNeighbors); graph->vertex_capacity = numGlobalVertices; graph->nbor_capacity = numGlobalNeighbors; graph->nborIndex[0] = 0; for (i=0; i < numGlobalVertices; i++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(nproc, count_tag, 1); num = get_line_ints(buf, bufsize, vals); if (num < 2) input_file_error(nproc, count_tag, 1); vGID = vals[0]; nnbors = vals[1]; if (num < (nnbors + 2)) input_file_error(nproc, count_tag, 1); graph->vertexGID[i] = (ZOLTAN_ID_TYPE)vGID; for (j=0; j < nnbors; j++){ graph->nborGID[graph->nborIndex[i] + j] = (ZOLTAN_ID_TYPE)vals[2 + j]; } graph->nborIndex[i+1] = graph->nborIndex[i] + nnbors; } fclose(fp); /* Assign each vertex to a process using a hash function */ for (i=0; i <numGlobalNeighbors; i++){ id = graph->nborGID[i]; graph->nborPart[i] = Zoltan_Hash(&id, 1, nproc); } /* Create a sub graph for each process */ send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , nproc); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; procID = Zoltan_Hash(&id, 1, nproc); send_graph[procID].numMyVertices++; } for (i=0; i < nproc; i++){ num = send_graph[i].numMyVertices; send_graph[i].vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num); send_graph[i].nborIndex = (int *)calloc(sizeof(int) , (num + 1)); } idx = (int *)calloc(sizeof(int), nproc); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; nnbors = graph->nborIndex[i+1] - graph->nborIndex[i]; procID = Zoltan_Hash(&id, 1, nproc); j = idx[procID]; send_graph[procID].vertexGID[j] = id; send_graph[procID].nborIndex[j+1] = send_graph[procID].nborIndex[j] + nnbors; idx[procID] = j+1; } for (i=0; i < nproc; i++){ num = send_graph[i].nborIndex[send_graph[i].numMyVertices]; send_graph[i].nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num); send_graph[i].nborPart= (int *)malloc(sizeof(int) * num); } memset(idx, 0, sizeof(int) * nproc); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; nnbors = graph->nborIndex[i+1] - graph->nborIndex[i]; procID = Zoltan_Hash(&id, 1, nproc); j = idx[procID]; if (nnbors > 0){ memcpy(send_graph[procID].nborGID + j, graph->nborGID + graph->nborIndex[i], nnbors * sizeof(ZOLTAN_ID_TYPE)); memcpy(send_graph[procID].nborPart + j, graph->nborPart + graph->nborIndex[i], nnbors * sizeof(int)); idx[procID] = j + nnbors; } } free(idx); /* Process zero sub-graph */ free(graph->vertexGID); free(graph->nborIndex); free(graph->nborGID); free(graph->nborPart); *graph = send_graph[0]; /* Send other processes their subgraph */ for (i=1; i < nproc; i++){ send_count[0] = send_graph[i].numMyVertices; send_count[1] = send_graph[i].nborIndex[send_graph[i].numMyVertices]; MPI_Send(send_count, 2, MPI_INT, i, count_tag, MPI_COMM_WORLD); MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status); if (send_count[0] > 0){ MPI_Send(send_graph[i].vertexGID, send_count[0], ZOLTAN_ID_MPI_TYPE , i, id_tag, MPI_COMM_WORLD); free(send_graph[i].vertexGID); MPI_Send(send_graph[i].nborIndex, send_count[0] + 1, MPI_INT, i, id_tag + 1, MPI_COMM_WORLD); free(send_graph[i].nborIndex); if (send_count[1] > 0){ MPI_Send(send_graph[i].nborGID, send_count[1], ZOLTAN_ID_MPI_TYPE , i, id_tag + 2, MPI_COMM_WORLD); free(send_graph[i].nborGID); MPI_Send(send_graph[i].nborPart, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD); free(send_graph[i].nborPart); } } } free(send_graph); /* signal all procs it is OK to go on */ ack = 0; for (i=1; i < nproc; i++){ MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD); } } else{ MPI_Recv(send_count, 2, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status); if (send_count[0] < 0){ MPI_Finalize(); exit(1); } ack = 0; graph->numMyVertices = send_count[0]; if (send_count[0] > 0){ graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[0]); graph->nborIndex = (int *)malloc(sizeof(int) * (send_count[0] + 1)); if (send_count[1] > 0){ graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[1]); graph->nborPart = (int *)malloc(sizeof(int) * send_count[1]); } } MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD); if (send_count[0] > 0){ MPI_Recv(graph->vertexGID,send_count[0], ZOLTAN_ID_MPI_TYPE, 0, id_tag, MPI_COMM_WORLD, &status); MPI_Recv(graph->nborIndex,send_count[0] + 1, MPI_INT, 0, id_tag + 1, MPI_COMM_WORLD, &status); if (send_count[1] > 0){ MPI_Recv(graph->nborGID,send_count[1], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 2, MPI_COMM_WORLD, &status); MPI_Recv(graph->nborPart,send_count[1], MPI_INT, 0, id_tag + 3, MPI_COMM_WORLD, &status); } } /* ok to go on? */ MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); if (ack < 0){ MPI_Finalize(); exit(1); } graph->vertex_capacity = send_count[0]; graph->nbor_capacity = send_count[1]; } }
int Zoltan_Map_Find_Add(ZZ *zz, ZOLTAN_MAP* map, int *key, int datain, int *dataout) { char *yo = "Zoltan_Map_Add"; int index, match, i; ZOLTAN_ENTRY *element; ZOLTAN_ID_PTR zkey = (ZOLTAN_ID_PTR)key; if (!map){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Map specified does not exist\n"); return ZOLTAN_FATAL; } index = Zoltan_Hash(zkey, map->id_size, map->max_index); /* If this key is not found in the map, then add it */ element = map->entries[index]; match = 0; while (element != NULL){ match = key_match(map->id_size, element->key, key); if (match){ break; } element = element->next; } if (!match){ i = map->entry_count; if (!map->dynamicEntries && (i == map->max_entries)){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Fixed size map overflow\n"); return ZOLTAN_FATAL; } if (map->dynamicEntries){ element = (ZOLTAN_ENTRY *)ZOLTAN_MALLOC(sizeof(ZOLTAN_ENTRY)); if (!element) return ZOLTAN_MEMERR; } else{ element = map->top + i; } if (map->copyKeys){ if(map->dynamicEntries) { element->key = (int *)ZOLTAN_MALLOC(sizeof(int) * map->id_size); if (!element->key) return ZOLTAN_MEMERR; } else element->key = map->keys + map->entry_count; memcpy(element->key, key, sizeof(int)*map->id_size); } else{ element->key = key; } element->data = datain; element->next = map->entries[index]; map->entries[index] = element; map->entry_count++; } if (dataout != NULL) { *dataout = element->data; } return ZOLTAN_OK; }