forked from jeffhammond/foMPI
-
Notifications
You must be signed in to change notification settings - Fork 1
/
fompi_win_pscw.c
227 lines (188 loc) · 7.64 KB
/
fompi_win_pscw.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Copyright (c) 2012 The Trustees of University of Illinois. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <assert.h>
//#include <intrinsics.h>
#include <stdlib.h>
#include "fompi.h"
int foMPI_Win_start(MPI_Group group, int assert, foMPI_Win win) {
#ifdef PAPI
timing_record( -1 );
#endif
int* temp = NULL;
MPI_Group group_win_comm;
int size, i;
win->pscw_access_group_ranks = NULL;
/* get the real ranks of the processes in the group */
MPI_Group_size( group, &size );
win->pscw_access_group_size = size;
win->pscw_access_group_ranks = _foMPI_ALLOC( win->pscw_access_group_size * sizeof(int) );
assert( win->pscw_access_group_ranks != NULL );
temp = _foMPI_ALLOC( win->pscw_access_group_size * sizeof(int) );
assert( temp != NULL );
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
temp[i] = i;
}
MPI_Comm_group(win->comm, &group_win_comm);
MPI_Group_translate_ranks(group, win->pscw_access_group_size, &temp[0], group_win_comm, &(win->pscw_access_group_ranks[0]));
_foMPI_FREE(temp);
MPI_Group_free(&group_win_comm);
/* begin the access epoch */
/* begin a new epoch with the ranks in group */
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
win->pscw_matching_access[win->pscw_access_group_ranks[i]]++;
}
uint64_t* pscw_matching_exposure_ptr;
/* wait for every process in the access group to post MPI_Win_post */
if ( win->create_flavor == foMPI_WIN_FLAVOR_DYNAMIC ) {
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
/* local busy waiting */
pscw_matching_exposure_ptr = &(win->dynamic_list[win->commrank].pscw_matching_exposure[win->pscw_access_group_ranks[i]]);
while( win->pscw_matching_access[win->pscw_access_group_ranks[i]] != *(volatile uint64_t*)pscw_matching_exposure_ptr ) {}
}
} else {
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
/* local busy waiting */
pscw_matching_exposure_ptr = &(win->win_array[win->commrank].pscw_matching_exposure[win->pscw_access_group_ranks[i]]);
while( win->pscw_matching_access[win->pscw_access_group_ranks[i]] != *(volatile uint64_t*)pscw_matching_exposure_ptr ) {}
}
}
#ifdef PAPI
timing_record( 11 );
#endif
return MPI_SUCCESS;
}
int foMPI_Win_complete(foMPI_Win win) {
#ifdef PAPI
timing_record( -1 );
#endif
dmapp_return_t status;
int i;
/* completion */
foMPI_Win_flush_all(win);
/*if (win->nbi_counter > 0) {
status = dmapp_gsync_wait();
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
win->nbi_counter = 0;
}*/
if ( win->create_flavor == foMPI_WIN_FLAVOR_DYNAMIC ) {
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
status = dmapp_aadd_qw_nbi( (void*) &(win->dynamic_list[win->pscw_access_group_ranks[i]].win_ptr->global_counter), &(win->dynamic_list[win->pscw_access_group_ranks[i]].win_ptr_seg.dmapp),
win->group_ranks[win->pscw_access_group_ranks[i]] , 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
}
} else {
#ifdef XPMEM
/* XPMEM completion */
__sync_synchronize();
#endif
for( i=0 ; i<win->pscw_access_group_size ; i++ ) {
#ifdef XPMEM
int target_rank = win->pscw_access_group_ranks[i];
int local_rank = foMPI_onnode_rank_global_to_local( target_rank, win );
if ( local_rank != -1 ) {
__sync_fetch_and_add (&(win->xpmem_array[local_rank].win_ptr->xpmem_global_counter), 1);
} else {
status = dmapp_aadd_qw_nbi( (void*) &(win->win_array[target_rank].win_ptr->global_counter), &(win->win_array[target_rank].win_ptr_seg.dmapp), win->group_ranks[target_rank] , 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
}
#else
status = dmapp_aadd_qw_nbi( (void*) &(win->win_array[win->pscw_access_group_ranks[i]].win_ptr->global_counter), &(win->win_array[win->pscw_access_group_ranks[i]].win_ptr_seg.dmapp),
win->group_ranks[win->pscw_access_group_ranks[i]] , 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
#endif
}
}
_foMPI_FREE(win->pscw_access_group_ranks);
#ifdef PAPI
timing_record( 12 );
#endif
return MPI_SUCCESS;
}
int foMPI_Win_post(MPI_Group group, int assert, foMPI_Win win) {
#ifdef PAPI
timing_record( -1 );
#endif
dmapp_return_t status;
int* temp = NULL;
int* temp_exposure_ranks = NULL;
MPI_Group group_win_comm;
int size, i;
/* get the real ranks of the processes in the group */
MPI_Group_size( group, &size );
win->pscw_exposure_group_size = size;
temp = _foMPI_ALLOC( win->pscw_exposure_group_size * sizeof(int) );
assert( temp != NULL ); /* TODO: assure all of this assert kinds with a NULL intialization */
temp_exposure_ranks = _foMPI_ALLOC( win->pscw_exposure_group_size * sizeof(int) );
assert( temp_exposure_ranks != NULL );
for( i=0 ; i<win->pscw_exposure_group_size ; i++ ) {
temp[i] = i;
}
MPI_Comm_group(win->comm, &group_win_comm);
MPI_Group_translate_ranks(group, win->pscw_exposure_group_size, &temp[0], group_win_comm, &temp_exposure_ranks[0]);
_foMPI_FREE(temp);
MPI_Group_free(&group_win_comm);
/* set the counter for the Win_wait */
win->global_counter = 0;
#ifdef XPMEM
win->xpmem_global_counter = 0;
#endif
/* begin a new exposure epoch with the ranks in group */
if ( win->create_flavor == foMPI_WIN_FLAVOR_DYNAMIC ) {
for( i=0 ; i<win->pscw_exposure_group_size ; i++ ) {
status = dmapp_aadd_qw_nbi( &(win->dynamic_list[temp_exposure_ranks[i]].pscw_matching_exposure[win->commrank]), &(win->dynamic_list[temp_exposure_ranks[i]].pscw_matching_exposure_seg.dmapp),
win->group_ranks[temp_exposure_ranks[i]], (int64_t) 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
}
} else {
for( i=0 ; i<win->pscw_exposure_group_size ; i++ ) {
#ifdef XPMEM
int target_rank = temp_exposure_ranks[i];
int local_rank = foMPI_onnode_rank_global_to_local( target_rank, win );
if ( local_rank != -1 ) {
__sync_fetch_and_add ((volatile int64_t*) &(win->xpmem_array[local_rank].pscw_matching_exposure[win->commrank]), 1);
} else {
status = dmapp_aadd_qw_nbi( &(win->win_array[target_rank].pscw_matching_exposure[win->commrank]), &(win->win_array[target_rank].pscw_matching_exposure_seg.dmapp),
win->group_ranks[target_rank], (int64_t) 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
}
#else
status = dmapp_aadd_qw_nbi( &(win->win_array[temp_exposure_ranks[i]].pscw_matching_exposure[win->commrank]), &(win->win_array[temp_exposure_ranks[i]].pscw_matching_exposure_seg.dmapp),
win->group_ranks[temp_exposure_ranks[i]], (int64_t) 1 );
_check_dmapp_status(status, DMAPP_RC_SUCCESS, (char*) __FILE__, __LINE__);
#endif
}
}
_foMPI_FREE( temp_exposure_ranks );
#ifdef PAPI
timing_record( 13 );
#endif
return MPI_SUCCESS;
}
int foMPI_Win_wait(foMPI_Win win) {
#ifdef PAPI
timing_record( -1 );
#endif
/* local busy waiting */
#ifdef XPMEM
while( ((volatile uint64_t) win->global_counter + (volatile char) win->xpmem_global_counter ) != win->pscw_exposure_group_size) {}
#else
while( ((volatile uint64_t) win->global_counter ) != win->pscw_exposure_group_size) {}
#endif
#ifdef PAPI
timing_record( 14 );
#endif
return MPI_SUCCESS;
}
int foMPI_Win_test(foMPI_Win win, int *flag) {
#ifdef XPMEM
if ( (win->global_counter+win->xpmem_global_counter) != win->pscw_exposure_group_size ) {
#else
if ( win->global_counter != win->pscw_exposure_group_size ) {
#endif
*flag = 0;
} else {
*flag = 1;
}
return MPI_SUCCESS;
}