void IMB_set_buf(struct comm_info* c_info, int selected_rank, size_t s_pos1, size_t s_pos2, size_t r_pos1, size_t r_pos2) /* Sets Send/Recv buffers for a selected rank (by call to => IMB_ass_buf) Input variables: -selected_rank (type int) Relevant process rank (Can be different from local rank: for checking purposes) -s_pos1 (type int) -s_pos2 (type int) s_pos1 .. s_pos2 positions for send buffer -r_pos1 (type int) -r_pos2 (type int) r_pos1 .. r_pos2 positions for recv buffer In/out variables: -c_info (type struct comm_info*) Collection of all base data for MPI; see [1] for more information Corresponding buffer components are assigned values */ { /* Sets c_info->s_buffer/c_info->r_buffer int byte positions s_pos1..s_pos2/r_pos1..r_pos2 Values are taken for "selected_rank" Checks right allocation. */ size_t s_len, r_len; s_len = (max(s_pos2-s_pos1,0)/asize+1)*asize; r_len = (max(r_pos2-r_pos1,0)/asize+1)*asize; IMB_alloc_buf(c_info, "set_buf 1",s_len, r_len); if( s_pos2 >= s_pos1 ) IMB_ass_buf( c_info->s_buffer, selected_rank, s_pos1, s_pos2, 1); if( r_pos2 >= r_pos1 ) IMB_ass_buf( c_info->r_buffer, selected_rank, r_pos1, r_pos2, 0); }
void IMB_accumulate (struct comm_info* c_info, int size, struct iter_schedule* ITERATIONS, MODES RUN_MODE, double* time) /* MPI-2 benchmark kernel Benchmarks MPI_Accumulate Input variables: -c_info (type struct comm_info*) Collection of all base data for MPI; see [1] for more information -size (type int) Basic message size in bytes -ITERATIONS (type struct iter_schedule *) Repetition scheduling -RUN_MODE (type MODES) Mode (aggregate/non aggregate; blocking/nonblocking); see "IMB_benchmark.h" for definition Output variables: -time (type double*) Timing result per sample */ { double t1, t2; Type_Size s_size,r_size; int s_num, r_num; /* IMB 3.1 << */ int r_off; /* >> IMB 3.1 */ int s_tag, r_tag; int dest, source, root; int i; MPI_Status stat; #ifdef CHECK defect=0; #endif ierr = 0; /* GET SIZE OF DATA TYPE */ MPI_Type_size(c_info->red_data_type,&s_size); /* IMB 3.1 << */ s_num=size/s_size; r_size=s_size; r_num=s_num; r_off=ITERATIONS->r_offs/r_size; /* >> IMB 3.1 */ root = (c_info-> rank == 0); if( c_info-> rank < 0 ) *time = 0.; else { if( !RUN_MODE->AGGREGATE ) { *time = MPI_Wtime(); for(i=0;i< ITERATIONS->n_sample;i++) { ierr = MPI_Accumulate( (char*)c_info->s_buffer+i%ITERATIONS->s_cache_iter*ITERATIONS->s_offs, s_num, c_info->red_data_type, 0, i%ITERATIONS->r_cache_iter*r_off, r_num, c_info->red_data_type, c_info->op_type, c_info->WIN ); MPI_ERRHAND(ierr); ierr = MPI_Win_fence(0, c_info->WIN); MPI_ERRHAND(ierr); #ifdef CHECK if( root ) { CHK_DIFF("Accumulate",c_info, (char*)c_info->r_buffer+i%ITERATIONS->r_cache_iter*ITERATIONS->r_offs, 0, size, size, asize, put, 0, ITERATIONS->n_sample, i, -1, &defect); IMB_ass_buf((char*)c_info->r_buffer+i%ITERATIONS->r_cache_iter*ITERATIONS->r_offs, 0, 0, size-1, 0); } MPI_Barrier(c_info->communicator); #endif } *time=(MPI_Wtime()-*time)/ITERATIONS->n_sample; } if( RUN_MODE->AGGREGATE ) { for(i=0; i<N_BARR; i++) MPI_Barrier(c_info->communicator); *time = MPI_Wtime(); #ifdef CHECK for(i=0;i< ITERATIONS->r_cache_iter; i++) #else for(i=0;i< ITERATIONS->n_sample;i++) #endif { ierr = MPI_Accumulate( (char*)c_info->s_buffer+i%ITERATIONS->s_cache_iter*ITERATIONS->s_offs, s_num, c_info->red_data_type, 0, i%ITERATIONS->r_cache_iter*r_off, r_num, c_info->red_data_type, c_info->op_type, c_info->WIN ); MPI_ERRHAND(ierr); } ierr = MPI_Win_fence(0, c_info->WIN); MPI_ERRHAND(ierr); *time=(MPI_Wtime()-*time)/ITERATIONS->n_sample; #ifdef CHECK if( root ) { for(i=0;i< ITERATIONS->r_cache_iter; i++) { CHK_DIFF("Accumulate", c_info, (char*)c_info->r_buffer+i*ITERATIONS->r_offs, 0, size, size, asize, put, 0, ITERATIONS->n_sample, i, -1, &defect); } } #endif } } }