int main(int argc, char *argv[]) { int my_rank, num_procs; const int max_iters = 10000; /// maximum number of iteration to perform /** Simulation parameters parsed from the input datasets */ int nintci, nintcf; /// internal cells start and end index /// external cells start and end index. The external cells are only ghost cells. /// They are accessed only through internal cells int nextci, nextcf; int **lcc; /// link cell-to-cell array - stores neighboring information /// Boundary coefficients for each volume cell (South, East, North, West, High, Low) double *bs, *be, *bn, *bw, *bl, *bh; double *bp; /// Pole coefficient double *su; /// Source values double residual_ratio; /// the ratio between the reference and the current residual double *var; /// the variation vector -> keeps the result in the end /** Additional vectors required for the computation */ double *cgup, *oc, *cnorm; /** Geometry data */ int points_count; /// total number of points that define the geometry int** points; /// coordinates of the points that define the cells - size [points_cnt][3] int* elems; /// definition of the cells using their nodes (points) - each cell has 8 points /** Mapping between local and remote cell indices */ int* local_global_index; /// local to global index mapping int* global_local_index; /// global to local index mapping /** Lists of cells requires for the communication */ int neighbors_count = 0; /// total number of neighbors to communicate with int* send_count; /// number of elements to send to each neighbor (size: neighbors_count) /// send lists for the other neighbors(cell ids which should be sent)(size:[#neighbors][#cells] int** send_list; int* recv_count; /// how many elements are in the recv lists for each neighbor int** recv_list; /// send lists for the other neighbor (see send_list) /** Metis Results */ int* epart; /// partition vector for the elements of the mesh int* npart; /// partition vector for the points (nodes) of the mesh int objval; /// resulting edgecut of total communication volume (classical distrib->zeros) MPI_Init(&argc, &argv); /// Start MPI MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /// Get current process id MPI_Comm_size(MPI_COMM_WORLD, &num_procs); /// get number of processes if ( argc < 3 ) { fprintf(stderr, "Usage: ./gccg <input_file> <output_prefix> <partition_type>\n"); MPI_Abort(MPI_COMM_WORLD, -1); } char *file_in = argv[1]; char *out_prefix = argv[2]; char *part_type = (argc == 3 ? "classical" : argv[3]); /********** START INITIALIZATION **********/ int init_status = initialization(file_in, part_type, &nintci, &nintcf, &nextci, &nextcf, &lcc, &bs, &be, &bn, &bw, &bl, &bh, &bp, &su, &points_count, &points, &elems, &var, &cgup, &oc, &cnorm, &local_global_index, &global_local_index, &neighbors_count, &send_count, &send_list, &recv_count, &recv_list, &epart, &npart, &objval); if ( init_status != 0 ) { fprintf(stderr, "Failed to initialize data!\n"); MPI_Abort(MPI_COMM_WORLD, my_rank); } if ( my_rank == 2 ) { char file_vtk_out[1000]; file_vtk_out[0] = '\0'; strcat(file_vtk_out, out_prefix); strcat(file_vtk_out, "_"); strcat(file_vtk_out, file_in); strcat(file_vtk_out, ".vtk"); test_distribution(file_in, file_vtk_out, local_global_index, nintcf, cgup); test_communication(file_in, file_vtk_out, local_global_index, nintcf, neighbors_count, send_count, send_list, recv_count, recv_list); } /********** END INITIALIZATION **********/ /********** START COMPUTATIONAL LOOP **********/ // int total_iters = compute_solution(max_iters, nintci, nintcf, nextcf, lcc, bp, bs, bw, bl, // bn, // be, bh, cnorm, var, su, cgup, &residual_ratio, // local_global_index, global_local_index, neighbors_count, // send_count, send_list, recv_count, recv_list); /********** END COMPUTATIONAL LOOP **********/ /********** START FINALIZATION **********/ // finalization(file_in, out_prefix, total_iters, residual_ratio, nintci, nintcf, points_count, // points, elems, var, cgup, su); /********** END FINALIZATION **********/ // free(cnorm); // free(oc); // free(var); free(cgup); // free(su); free(bp); free(bh); free(bl); free(bw); free(bn); free(be); free(bs); // free(elems); /* int i; for(i = 0; i < nintcf + 1; i++) { free(lcc[i]); } free(lcc); for(i = 0; i < points_count; i++) { free(points[i]); } free(points); */ MPI_Finalize(); /// Cleanup MPI return 0; }
int initialization(char* file_in, char* part_type, char* read_type, int nprocs, int myrank, int* nintci, int* nintcf, int* nextci, int* nextcf, int*** lcc, double** bs, double** be, double** bn, double** bw, double** bl, double** bh, double** bp, double** su, int* points_count, int*** points, int** elems, double** var, double** cgup, double** oc, double** cnorm, int** local_global_index) { /********** START INITIALIZATION **********/ printf("INIT!\n"); int i = 0; // read-in the input file int f_status = read_binary_geo(file_in, &*nintci, &*nintcf, &*nextci, &*nextcf, &*lcc, &*bs, &*be, &*bn, &*bw, &*bl, &*bh, &*bp, &*su, &*points_count, &*points, &*elems); // ====================== For testing purposes ====================== // For allread // int *loc_global_index; // int *rank = (int*) malloc(sizeof(int)*(*nintcf + 1)); // int nintci_loc, nintcf_loc, nextci_loc, nextcf_loc; // int r; // // int numproc = 3; // // for (r=0; r<numproc; r++) // { // // allread_calc_global_idx(&loc_global_index, &nintci_loc, &nintcf_loc, &nextci_loc, // &nextcf_loc, part_type, read_type, numproc, r, // *nintci, *nintcf, *nextci, // *nextcf, *lcc, *elems, *points_count); // // for (i=nintci_loc; i <= nintcf_loc; i++) { // rank[loc_global_index[i - nintci_loc]] = r; // } // // free(loc_global_index); // } // // For oneread int **loc_global_index; int *rank = (int*) malloc(sizeof(int)*(*nintcf + 1)); int *nintci_loc, *nintcf_loc, *nextci_loc, *nextcf_loc; int r; int numproc = 4; oneread_calc_global_idx(&loc_global_index, &nintci_loc, &nintcf_loc, &nextci_loc, &nextcf_loc, part_type, read_type, numproc, *nintci, *nintcf, *nextci, *nextcf, *lcc, *elems, *points_count); for (r=0;r<numproc;r++) { printf("%d\t%d\n", r, nintcf_loc[r]); for (i=nintci_loc[r]; i <= nintcf_loc[r]; i++) { rank[(loc_global_index[r][i - nintci_loc[r]])] = r; } } // for (r=0; r<numproc; r++) // { // free(loc_global_index[r]); // } // free(loc_global_index); // free(nintcf_loc); // free(nintci_loc); // free(nextci_loc); // free(nextcf_loc); // vtk_write_unstr_grid_header("a", "b.vtk", *nintci, *nintcf, *points_count, *points, *elems); // vtk_append_integer("b.vtk", "rank", *nintci, *nintcf, rank); double *scalars = (double*) calloc(nextci_loc[2], sizeof(double)); for (i=0; i<nextci_loc[2]; i++) { scalars[i] = 1.0; } test_distribution(file_in, "bb.vtk", loc_global_index[2], nextci_loc[2], scalars); free(scalars); free(rank); for (r=0; r<numproc; r++) { free(loc_global_index[r]); } free(loc_global_index); free(nintcf_loc); free(nintci_loc); free(nextci_loc); free(nextcf_loc); // ====================== For testing purposes ====================== if ( f_status != 0 ) return f_status; *var = (double*) calloc(sizeof(double), (*nextcf + 1)); *cgup = (double*) calloc(sizeof(double), (*nextcf + 1)); *cnorm = (double*) calloc(sizeof(double), (*nintcf + 1)); // initialize the arrays for ( i = 0; i <= 10; i++ ) { (*cnorm)[i] = 1.0; } for ( i = (*nintci); i <= (*nintcf); i++ ) { (*var)[i] = 0.0; } for ( i = (*nintci); i <= (*nintcf); i++ ) { (*cgup)[i] = 1.0 / ((*bp)[i]); } for ( i = (*nextci); i <= (*nextcf); i++ ) { (*var)[i] = 0.0; (*cgup)[i] = 0.0; (*bs)[i] = 0.0; (*be)[i] = 0.0; (*bn)[i] = 0.0; (*bw)[i] = 0.0; (*bh)[i] = 0.0; (*bl)[i] = 0.0; } return 0; }