#include #include #include int Waitall_via_MPIWaitany(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int rank; int index; MPI_Comm_rank(MPI_COMM_WORLD, &rank); while( 1 ) { MPI_Waitany(count, array_of_requests, &index, array_of_statuses); if( index == MPI_UNDEFINED ) break; } return MPI_SUCCESS; } int Waitall_via_MPIWaitsome(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int left = count; int done; int array_of_indices[50000]; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); while (left > 0) { MPI_Waitsome(count, array_of_requests, &done, array_of_indices, array_of_statuses); left -= done; } return MPI_SUCCESS; } int Waitall_via_PMPIWaitsome(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int left = count; int done; int array_of_indices[50000]; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); while (left > 0) { PMPI_Waitsome(count, array_of_requests, &done, array_of_indices, array_of_statuses); left -= done; } return MPI_SUCCESS; } int Waitall_via_PMPIWaitany(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int rank; int index; MPI_Comm_rank(MPI_COMM_WORLD, &rank); while( 1 ) { PMPI_Waitany(count, array_of_requests, &index, array_of_statuses); if( index == MPI_UNDEFINED ) break; } return MPI_SUCCESS; } int Waitall_via_MPIWaitall(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int left = count; int done; int array_of_indices[50000]; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); return MPI_Waitall( count, array_of_requests, array_of_statuses ); } int Waitall_via_PMPIWaitall(int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[]) { int left = count; int done; int array_of_indices[50000]; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); return PMPI_Waitall( count, array_of_requests, array_of_statuses ); } int main(int argc, char **argv) { int rank, size; int next, prev; int tokens; int rounds; int rc, i; int *token_send_data, *token_recv_data; MPI_Request *reqs; MPI_Status *status; double start_time, curr_time, end_time; int function_type; const char *function_names[] = { "MPI_Waitall", "MPI_Waitany", "MPI_Waitsome", "PMPI_Waitall", "PMPI_Waitany", "PMPI_Waitsome" }; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (argc != 4) { if (rank == 0) { fprintf(stderr, "Usage: `./ring [t] [r] [f]`\n"); fprintf(stderr, "Where:\n"); fprintf(stderr, "\t [t] : number of duplicate tokens\n"); fprintf(stderr, "\t [r] : number of rounds\n"); fprintf(stderr, "\t [f] : call type:\n"); fprintf(stderr, "\t\t 0 : MPI_Waitall\n"); fprintf(stderr, "\t\t 1 : MPI_Waitany\n"); fprintf(stderr, "\t\t 2 : MPI_Waitsome\n"); fprintf(stderr, "\t\t 3 : PMPI_Waitall\n"); fprintf(stderr, "\t\t 4 : PMPI_Waitany\n"); fprintf(stderr, "\t\t 5 : PMPI_Waitsome\n"); } exit(1); } next = (rank + 1) % size; prev = (rank + size-1) % size; tokens = atoi(argv[1]); rounds = atoi(argv[2]); function_type = atoi(argv[3]); if( function_type < 0 || function_type > 5 ) { fprintf(stderr,"Unrecognised function type %d\n",function_type); exit(1); } token_recv_data = (int *) malloc(sizeof(int) * tokens); token_send_data = (int *) malloc(sizeof(int) * tokens); reqs = (MPI_Request *) malloc(sizeof(MPI_Request) * tokens * 2); status = (MPI_Status *) malloc(sizeof(MPI_Status) * tokens * 2); MPI_Barrier(MPI_COMM_WORLD); start_time = MPI_Wtime(); for (;rounds > 0; rounds--) { /* curr_time = MPI_Wtime(); fprintf(stdout, "[%d] Rounds Left %d:\t Elapsed Time: %f\n", rank, rounds, curr_time - start_time); */ for (i = 0; i < tokens; i++) { while (MPI_SUCCESS != MPI_Irecv(&token_recv_data[i], 1, MPI_INT, prev, 0, MPI_COMM_WORLD, &reqs[i*2])) prev = (prev + size-1) % size; token_send_data[i] = i; while (MPI_SUCCESS != MPI_Isend(&token_send_data[i], 1, MPI_INT, next, 0, MPI_COMM_WORLD, &reqs[(i*2)+1])) next = (next + 1) % size; } do { switch( function_type ) { case 0: rc = Waitall_via_MPIWaitall(tokens * 2, reqs, status); break; case 1: rc = Waitall_via_MPIWaitany(tokens * 2, reqs, status); break; case 2: rc = Waitall_via_MPIWaitsome(tokens * 2, reqs, status); break; case 3: rc = Waitall_via_PMPIWaitall(tokens * 2, reqs, status); break; case 4: rc = Waitall_via_PMPIWaitany(tokens * 2, reqs, status); break; case 5: rc = Waitall_via_PMPIWaitsome(tokens * 2, reqs, status); break; } for (i = 0; i < tokens; i++) if (token_recv_data[i] != i) fprintf(stderr, "[%d] Token %d != %d\n", rank, i, token_recv_data[i]); if (rc != MPI_SUCCESS) { for (i = 0; i < tokens * 2; i++) { if (status->MPI_ERROR != MPI_SUCCESS) { if (i % 2) while (MPI_SUCCESS != MPI_Isend(&token_send_data[i/2], 1, MPI_INT, next, 0, MPI_COMM_WORLD, &reqs[(i*2)+1])) next = (next + 1) % size; else while (MPI_SUCCESS != MPI_Irecv(&token_recv_data[i/2], 1, MPI_INT, prev, 0, MPI_COMM_WORLD, &reqs[i*2])) prev = (prev + size-1) % size; } } } } while (rc != MPI_SUCCESS); } MPI_Barrier(MPI_COMM_WORLD); end_time = MPI_Wtime(); if (rank == 0) fprintf(stdout, "%15.15s : %f\n", function_names[function_type], end_time - start_time); MPI_Finalize(); return 0; }