extern int MPE_COUNTER_KEYVAL; extern int MPEi_CounterFree(MPI_Win counter_win, int keyval, void *attr_val, void *extra_state); void MPE_Counter_create(MPI_Comm comm, int num, MPI_Win *counter_win) { int size, rank, lnum, lleft, i, *counterMem=0; MPI_Aint counterSize; MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &size); lnum = num / size; lleft = num % size; if (rank < lleft) lnum++; counterSize = lnum * sizeof(int); if (counterSize > 0) { MPI_Alloc_mem(counterSize, MPI_INFO_NULL, &counterMem); for (i=0; i<lnum; i++) counterMem[i] = 0; } /* By using MPI_Alloc_mem first, we ensure that the initial value of the counters are zero. See text */ MPI_Win_create(counterMem, counterSize, sizeof(int), MPI_INFO_NULL, comm, counter_win); /* Create key if necessary and store the number of counters */ if (MPE_COUNTER_KEYVAL == MPI_KEYVAL_INVALID) { MPI_Win_create_keyval(MPI_WIN_NULL_COPY_FN, MPEi_CounterFree, &MPE_COUNTER_KEYVAL, NULL); } MPI_Win_set_attr(*counter_win, MPE_COUNTER_KEYVAL, (void*)(MPI_Aint)num); }