#include #include "cmdline.h" int global_index(int local_index, int num_points, int myID) { return local_index + myID*num_points; } void parse_arguments(int argc, char *argv[], int myID, int *nx, int *maxsteps, double *threshold, bool *print_flag, FILE **outfile) { char *usage_msg = "usage is %s points max_iterations convergence_threshold [outfilename]\n"; *nx = get_integer_arg_extended(argc, argv, 1, 1, "points", usage_msg, (myID == 0), (void (*)(void))MPI_Finalize); *maxsteps = get_integer_arg_extended(argc, argv, 2, 1, "max_iterations", usage_msg, (myID == 0), (void (*)(void))MPI_Finalize); *threshold = get_floating_arg_extended(argc, argv, 3, 0.0, "convergence_threshold", usage_msg, (myID == 0), (void (*)(void))MPI_Finalize); *print_flag = false; if (argc > 4) { FILE *out = NULL; int out_okay = 0; if (myID == 0) { out = fopen(argv[4], "w"); if (out == NULL) { fprintf(stderr, "Cannot open outfile %s\n", argv[4]); fprintf(stderr, usage_msg, argv[0]); } else { out_okay = 1; } } /* ugly(?) hack since only process 0 should try the fopen? */ MPI_Bcast(&out_okay, 1, MPI_INT, 0, MPI_COMM_WORLD); if (out_okay == 0) { MPI_Finalize(); exit(EXIT_FAILURE); } *print_flag = true; *outfile = out; } else { *outfile = NULL; } } void print_value(FILE *outfile, int index, double value) { fprintf(outfile, "uk[%010d] = %14.10f\n", index, value); } void print_values(FILE *outfile, double uk[], int num_points, int num_procs, int myID) { MPI_Status status; if (myID == 0) { /* left endpoint */ print_value(outfile, global_index(0, num_points, 0), LEFTVAL); /* loop over all processes */ for (int p = 0; p < num_procs; ++p) { if (p != 0) { /* get data from next process */ MPI_Recv(&uk[1], num_points, MPI_DOUBLE, p, 0, MPI_COMM_WORLD, &status); } /* print */ for (int i = 1; i <= num_points; ++i) { int global_i = global_index(i, num_points, p); print_value(outfile, global_i, uk[i]); } } /* right endpoint */ print_value(outfile, global_index(num_points+1, num_points, num_procs-1), RIGHTVAL); } else { /* send data to process 0 */ MPI_Send(&uk[1], num_points, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } }