void read_input_objects(int myRank, int numProcs, char *fname, MESH_DATA *myMesh) { char *buf; int bufsize = 512; int num, nobj, remaining, ack=0; int i, j; int *gids; float *xcoord, *ycoord; FILE *fp; MPI_Status status; int ack_tag = 5, count_tag = 10, id_tag = 15; int x_tag = 20, y_tag = 25; if (myRank == 0){ buf = (char *)malloc(sizeof(char) * bufsize); fp = fopen(fname, "r"); num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, count_tag, 1); num = sscanf(buf, "%d", &myMesh->numGlobalPoints); if (num != 1) input_file_error(numProcs, count_tag, 1); if (numProcs > 1){ nobj = myMesh->numGlobalPoints / 2; remaining = myMesh->numGlobalPoints - nobj; } else{ nobj = myMesh->numGlobalPoints; remaining = 0; } myMesh->myGlobalIDs = (int *)malloc(sizeof(int) * nobj); myMesh->x = (float *)malloc(sizeof(float) * nobj); myMesh->y = (float *)malloc(sizeof(float) * nobj); myMesh->numMyPoints= nobj; for (i=0; i < nobj; i++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, count_tag, 1); num = sscanf(buf, "%d %f %f", myMesh->myGlobalIDs + i, myMesh->x + i, myMesh->y + i); if (num != 3) input_file_error(numProcs, count_tag, 1); } gids = (int *)malloc(sizeof(int) * (nobj + 1)); xcoord = (float *)malloc(sizeof(float) * (nobj + 1)); ycoord = (float *)malloc(sizeof(float) * (nobj + 1)); for (i=1; i < numProcs; i++){ if (remaining > 1){ nobj = remaining / 2; remaining -= nobj; } else if (remaining == 1){ nobj = 1; remaining = 0; } else{ nobj = 0; } if ((i == numProcs - 1) && (remaining > 0)) nobj += remaining; if (nobj > 0){ for (j=0; j < nobj; j++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, count_tag, i); num = sscanf(buf, "%d %f %f", gids + j, xcoord + j, ycoord + j); if (num != 3) input_file_error(numProcs, count_tag, i); } } MPI_Send(&nobj, 1, MPI_INT, i, count_tag, MPI_COMM_WORLD); MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status); if (nobj > 0){ MPI_Send(gids, nobj, MPI_INT, i, id_tag, MPI_COMM_WORLD); MPI_Send(xcoord, nobj, MPI_FLOAT, i, x_tag, MPI_COMM_WORLD); MPI_Send(ycoord, nobj, MPI_FLOAT, i, y_tag, MPI_COMM_WORLD); } } free(gids); free(xcoord); free(ycoord); fclose(fp); free(buf); /* signal all procs it is OK to go on */ ack = 0; for (i=1; i < numProcs; i++){ MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD); } } else{ MPI_Recv(&myMesh->numMyPoints, 1, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status); ack = 0; if (myMesh->numMyPoints > 0){ myMesh->myGlobalIDs = (int *)malloc(sizeof(int) * myMesh->numMyPoints); myMesh->x = (float *)malloc(sizeof(float) * myMesh->numMyPoints); myMesh->y = (float *)malloc(sizeof(float) * myMesh->numMyPoints); MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD); MPI_Recv(myMesh->myGlobalIDs, myMesh->numMyPoints, MPI_INT, 0, id_tag, MPI_COMM_WORLD, &status); MPI_Recv(myMesh->x, myMesh->numMyPoints, MPI_FLOAT, 0, x_tag, MPI_COMM_WORLD, &status); MPI_Recv(myMesh->y, myMesh->numMyPoints, MPI_FLOAT, 0, y_tag, MPI_COMM_WORLD, &status); } else if (myMesh->numMyPoints == 0){ MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD); } else{ MPI_Finalize(); exit(1); } MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); if (ack < 0){ MPI_Finalize(); exit(1); } } }
void read_input_file(int myRank, int numProcs, 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; unsigned int id; FILE *fp; MPI_Status status; int ack_tag = 5, count_tag = 10, id_tag = 15; GRAPH_DATA *send_graph; if (myRank == 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(numProcs, count_tag, 1); num = sscanf(buf, "%d", &numGlobalVertices); if (num != 1) input_file_error(numProcs, count_tag, 1); /* Get the number of vertex neighbors */ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, count_tag, 1); num = sscanf(buf, "%d", &numGlobalNeighbors); if (num != 1) input_file_error(numProcs, 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->nborProc = (int *)malloc(sizeof(int) * numGlobalNeighbors); graph->nborIndex[0] = 0; for (i=0; i < numGlobalVertices; i++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, count_tag, 1); num = get_line_ints(buf, bufsize, vals); if (num < 2) input_file_error(numProcs, count_tag, 1); vGID = vals[0]; nnbors = vals[1]; if (num < (nnbors + 2)) input_file_error(numProcs, 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->nborProc[i] = simple_hash(&id, numProcs); } /* Create a sub graph for each process */ send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , numProcs); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; procID = simple_hash(&id, numProcs); send_graph[procID].numMyVertices++; } for (i=0; i < numProcs; 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), numProcs); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; nnbors = graph->nborIndex[i+1] - graph->nborIndex[i]; procID = simple_hash(&id, numProcs); 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 < numProcs; 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].nborProc= (int *)malloc(sizeof(int) * num); send_graph[i].numAllNbors = num; } memset(idx, 0, sizeof(int) * numProcs); for (i=0; i < numGlobalVertices; i++){ id = graph->vertexGID[i]; nnbors = graph->nborIndex[i+1] - graph->nborIndex[i]; procID = simple_hash(&id, numProcs); 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].nborProc + j, graph->nborProc + 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->nborProc); *graph = send_graph[0]; /* Send other processes their subgraph */ for (i=1; i < numProcs; i++){ send_count[0] = send_graph[i].numMyVertices; send_count[1] = send_graph[i].numAllNbors; 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].nborProc, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD); free(send_graph[i].nborProc); } } } free(send_graph); /* signal all procs it is OK to go on */ ack = 0; for (i=1; i < numProcs; 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]; graph->numAllNbors = send_count[1]; 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->nborProc = (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->nborProc,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); } } }
void read_input_objects(int myRank, int numProcs, char *fname, OBJECT_DATA *myData) { char *buf; int bufsize = 512; int num, nobj, remainingObj, ack=0; int i, j; int *gids; FILE *fp; MPI_Status status; int obj_ack_tag = 5, obj_count_tag = 10, obj_id_tag = 15; if (myRank == 0){ buf = (char *)malloc(sizeof(char) * bufsize); fp = fopen(fname, "r"); num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, obj_count_tag, 1); num = sscanf(buf, "%d", &myData->numGlobalObjects); if (num != 1) input_file_error(numProcs, obj_count_tag, 1); if (numProcs > 1){ nobj = myData->numGlobalObjects / 2; remainingObj = myData->numGlobalObjects - nobj; } else{ nobj = myData->numGlobalObjects; remainingObj = 0; } myData->myGlobalIDs = (int *)malloc(sizeof(int) * nobj); myData->numMyObjects = nobj; for (i=0; i < nobj; i++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, obj_count_tag, 1); num = sscanf(buf, "%d", myData->myGlobalIDs + i); if (num != 1) input_file_error(numProcs, obj_count_tag, 1); } gids = (int *)malloc(sizeof(int) * (nobj + 1)); for (i=1; i < numProcs; i++){ if (remainingObj > 1){ nobj = remainingObj / 2; remainingObj -= nobj; } else if (remainingObj == 1){ nobj = 1; remainingObj = 0; } else{ nobj = 0; } if ((i == numProcs - 1) && (remainingObj > 0)) nobj += remainingObj; if (nobj > 0){ for (j=0; j < nobj; j++){ num = get_next_line(fp, buf, bufsize); if (num == 0) input_file_error(numProcs, obj_count_tag, i); num = sscanf(buf, "%d", gids + j); if (num != 1) input_file_error(numProcs, obj_count_tag, i); } } MPI_Send(&nobj, 1, MPI_INT, i, obj_count_tag, MPI_COMM_WORLD); MPI_Recv(&ack, 1, MPI_INT, i, obj_ack_tag, MPI_COMM_WORLD, &status); if (nobj > 0) MPI_Send(gids, nobj, MPI_INT, i, obj_id_tag, MPI_COMM_WORLD); } free(gids); fclose(fp); free(buf); /* signal all procs it is OK to go on */ ack = 0; for (i=1; i < numProcs; i++){ MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD); } } else{ MPI_Recv(&myData->numMyObjects, 1, MPI_INT, 0, obj_count_tag, MPI_COMM_WORLD, &status); ack = 0; if (myData->numMyObjects > 0){ myData->myGlobalIDs = (int *)malloc(sizeof(int) * myData->numMyObjects); MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD); MPI_Recv(myData->myGlobalIDs, myData->numMyObjects, MPI_INT, 0, obj_id_tag, MPI_COMM_WORLD, &status); } else if (myData->numMyObjects == 0){ MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD); } else{ MPI_Finalize(); exit(1); } MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); if (ack < 0){ MPI_Finalize(); exit(1); } } }