Statistics
| Branch: | Revision:

root / synthbench / skampi / measurements / coll.c

History | View | Annotate | Download (26.7 kB)

1
/* SKaMPI   MPI-Benchmark
2

3
Copyright 2003-2008 Werner Augustin
4
Lehrstuhl Informatik fuer Naturwissenschaftler und Ingenieure 
5
Fakultaet fuer Informatik
6
University of Karlsruhe
7

8
This program is free software; you can redistribute it and/or modify
9
it under the terms of version 2 of the GNU General Public License as
10
published by the Free Software Foundation
11

12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16

17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20

    
21
#include <stdlib.h>
22
#include <math.h>
23
#include <mpi.h>
24
#include <assert.h>
25

    
26
#include <unistd.h>
27

    
28
#include "../misc.h"
29
#include "../synchronize.h"
30

    
31
#pragma weak begin_skampi_extensions
32

    
33
static MPI_Request *req_array;
34
static MPI_Status *status_array;
35
static MPI_Aint send_dt_extent, recv_dt_extent;
36

    
37
static int *recv_counts;
38
static int *send_counts;
39
static int *recv_displs;
40
static int *send_displs;
41

    
42
static int *initialize_counts(int count)
43
{
44
  int i;
45
  int *counts;
46

    
47
  counts = (int*)malloc(get_measurement_size()*sizeof(int));
48
  assert( counts != NULL );
49

    
50
  for( i = 0; i < get_measurement_size(); i++)
51
    counts[i] = count / get_measurement_size();
52

    
53
  for( i = 0; i < count % get_measurement_size(); i++) 
54
    counts[i*get_measurement_size() / (count % get_measurement_size())]++;
55

    
56
  return counts;
57
}
58

    
59
static int *initialize_displs(int *counts)
60
{
61
  int i;
62
  int *displs;
63

    
64
  displs = (int*)malloc(get_measurement_size()*sizeof(int));
65
  assert( displs != NULL );
66

    
67
  displs[0] = 0;
68
  for( i = 1; i < get_measurement_size(); i++ )
69
    displs[i] = displs[i-1] + counts[i-1];
70

    
71
  return displs;
72
}
73

    
74
static void initialize_req_array(int n)
75
{
76
  req_array = (MPI_Request*)malloc(n*sizeof(MPI_Request));
77
  assert( req_array != NULL );
78
}
79

    
80
static void initialize_status_array(int n)
81
{
82
  status_array = (MPI_Status*)malloc(n*sizeof(MPI_Status));
83
  assert( status_array != NULL );
84
}
85

    
86
/*---------------------------------------------------------------------------*/
87

    
88
void init_Bcast(int count, MPI_Datatype dt, int root)
89
{
90
  set_send_buffer_usage(get_extent(count, dt));
91
  set_reported_message_size(get_extent(count, dt));
92
  set_recv_buffer_usage(0);
93
  init_synchronization();
94
}
95

    
96
double measure_Bcast(int count, MPI_Datatype dt, int root)
97
{
98
  double start_time, end_time;
99

    
100
  start_time = start_synchronization();
101
  MPI_Bcast(get_send_buffer(), count, dt, root, get_measurement_comm());
102
  end_time = stop_synchronization();
103
  return  end_time - start_time;
104
}
105

    
106
/*---------------------------------------------------------------------------*/
107

    
108
static MPI_Comm mycomm;
109
static int myrank;
110

    
111
void init_Bcast_using_Send_Recv(int count, MPI_Datatype dt, int root)
112
{
113
  set_send_buffer_usage(get_extent(count, dt));
114
  set_reported_message_size(get_extent(count, dt));
115
  set_recv_buffer_usage(0);
116
  MPI_Comm_split(get_measurement_comm(), 0, (get_measurement_rank()+get_measurement_size()-root) % get_measurement_size(), 
117
                 &mycomm);
118
  MPI_Comm_rank(mycomm, &myrank);
119
  init_synchronization();
120
}
121

    
122
double measure_Bcast_using_Send_Recv(int count, MPI_Datatype dt, int root)
123
{
124
  MPI_Status status;
125
  double start_time, end_time;
126

    
127
  start_time = start_synchronization();
128
  if( myrank != 0 ) 
129
    MPI_Recv(get_send_buffer(), count, dt, (myrank-1)/2, 0, mycomm, &status);
130

    
131
  if( 2*myrank+1 < get_measurement_size() ) 
132
    MPI_Send(get_send_buffer(), count, dt, 2*myrank+1, 0, mycomm);
133
  if( 2*myrank+2 < get_measurement_size() )
134
    MPI_Send(get_send_buffer(), count, dt, 2*myrank+2, 0, mycomm);
135
  end_time = stop_synchronization();
136
  return end_time - start_time;
137
}
138

    
139
void finalize_Bcast_using_Send_Recv(int count, MPI_Datatype dt, int root) 
140
{
141
  MPI_Comm_free(&mycomm);
142
}
143

    
144
/*---------------------------------------------------------------------------*/
145

    
146
void init_Barrier(void)
147
{
148
  init_synchronization();
149
}
150

    
151
double measure_Barrier(void)
152
{
153
  double start_time, end_time;
154

    
155
  start_time = start_synchronization();
156
  MPI_Barrier(get_measurement_comm());
157
  end_time = stop_synchronization();
158
  return end_time - start_time;
159
}
160

    
161
/*---------------------------------------------------------------------------*/
162

    
163
void init_Reduce(int count, MPI_Datatype dt, MPI_Op op, int root)
164
{
165
  MPI_Aint extent;
166

    
167
  extent = get_extent(count, dt);
168
  set_send_buffer_usage(extent);
169
  set_reported_message_size(extent);
170
  set_recv_buffer_usage(extent);
171
  init_synchronization();
172
}
173

    
174
double measure_Reduce(int count, MPI_Datatype dt, MPI_Op op, int root)
175
{
176
  double start_time, end_time;
177

    
178
  start_time = start_synchronization();
179
  MPI_Reduce(get_send_buffer(), get_recv_buffer(), count, dt, op, root, 
180
             get_measurement_comm());
181
  end_time = stop_synchronization();
182
  return end_time - start_time;
183
}
184

    
185
/*---------------------------------------------------------------------------*/
186

    
187
void init_Allreduce(int count, MPI_Datatype dt, MPI_Op op)
188
{
189
  MPI_Aint extent;
190

    
191
  extent = get_extent(count, dt);
192
  set_send_buffer_usage(extent);
193
  set_reported_message_size(extent);
194
  set_recv_buffer_usage(extent);
195
  init_synchronization();
196
}
197

    
198
double measure_Allreduce(int count, MPI_Datatype dt, MPI_Op op)
199
{
200
  double start_time, end_time;
201

    
202
  start_time = start_synchronization();
203
  MPI_Allreduce(get_send_buffer(), get_recv_buffer(), count, dt, op,
204
                get_measurement_comm());
205
  end_time = stop_synchronization();
206
  return end_time - start_time;
207
}
208

    
209
/*---------------------------------------------------------------------------*/
210

    
211
void init_Allreduce_using_Reduce_Bcast(int count, MPI_Datatype dt, MPI_Op op, int root)
212
{
213
  MPI_Aint extent;
214

    
215
  extent = get_extent(count, dt);
216
  set_send_buffer_usage(extent);
217
  set_reported_message_size(extent);
218
  set_recv_buffer_usage(extent);
219
  init_synchronization();
220
}
221

    
222
double measure_Allreduce_using_Reduce_Bcast(int count, MPI_Datatype dt, MPI_Op op, int root)
223
{
224
  double start_time, end_time;
225

    
226
  start_time = start_synchronization();
227
  MPI_Reduce(get_send_buffer(), get_recv_buffer(), count, dt, op, root, 
228
             get_measurement_comm());
229
  MPI_Bcast(get_recv_buffer(), count, dt, root, get_measurement_comm());
230
  end_time = stop_synchronization();
231
  return end_time - start_time;
232
}
233

    
234
/*---------------------------------------------------------------------------*/
235

    
236
void init_Reduce_scatter(int count, MPI_Datatype dt, MPI_Op op, int root)
237
{
238
  recv_counts = initialize_counts(count);
239
  set_send_buffer_usage(get_extent(count, dt));
240
  set_reported_message_size(get_extent(count, dt));
241
  set_recv_buffer_usage(get_extent(recv_counts[get_measurement_rank()], dt));
242
  init_synchronization();
243
}
244

    
245
double measure_Reduce_scatter(int count, MPI_Datatype dt, MPI_Op op, int root)
246
{
247
  double start_time, end_time;
248

    
249
  start_time = start_synchronization();
250
  MPI_Reduce_scatter(get_send_buffer(), get_recv_buffer(), recv_counts, 
251
                     dt, op, get_measurement_comm());
252
  end_time = stop_synchronization();
253
  return end_time - start_time;
254
}
255

    
256
void finalize_Reduce_scatter(int count, MPI_Datatype dt, MPI_Op op, int root)
257
{
258
  free(recv_counts);
259
}
260

    
261
/*---------------------------------------------------------------------------*/
262

    
263
void init_Alltoall(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
264
{
265
  set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
266
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
267
  set_reported_message_size(get_extent(send_count, send_dt));
268
  init_synchronization();
269
}
270

    
271
double measure_Alltoall(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
272
{
273
  double start_time, end_time;
274

    
275
  start_time = start_synchronization();
276
  MPI_Alltoall(get_send_buffer(), send_count, send_dt,
277
               get_recv_buffer(), recv_count, recv_dt, get_measurement_comm());
278
  end_time = stop_synchronization();
279
  return end_time - start_time;
280
}
281

    
282
/*---------------------------------------------------------------------------*/
283

    
284
void init_Alltoall_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
285
{
286
  initialize_req_array(2*get_measurement_size());
287
  initialize_status_array(2*get_measurement_size());
288

    
289
  send_dt_extent = get_extent(1, send_dt);
290
  recv_dt_extent = get_extent(1, recv_dt);
291

    
292
  set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
293
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
294
  set_reported_message_size(get_extent(send_count, send_dt));
295
  init_synchronization();
296
}
297

    
298
double measure_Alltoall_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
299
{
300
  double start_time, end_time;
301
  int i;
302

    
303
  start_time = start_synchronization();
304
  for( i = 0; i < get_measurement_size(); i++)
305
    MPI_Irecv((char*)get_recv_buffer() + i*recv_dt_extent, recv_count, recv_dt, i, 
306
              0, get_measurement_comm(), &(req_array[i]));
307

    
308
  for( i = 0; i < get_measurement_size(); i++)
309
    MPI_Isend((char*)get_send_buffer() + i*send_dt_extent, send_count, send_dt, i, 
310
              0, get_measurement_comm(), &(req_array[i+get_measurement_size()]));
311

    
312
  MPI_Waitall(2*get_measurement_size(), req_array, status_array);
313
  end_time = stop_synchronization();
314
  return end_time - start_time;
315
}
316

    
317
void finalize_Alltoall_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
318
{
319
  free(req_array);
320
  free(status_array);
321
}
322

    
323
/*---------------------------------------------------------------------------*/
324

    
325
void init_Gather(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
326
{
327
  set_send_buffer_usage(get_extent(send_count, send_dt));
328
  set_reported_message_size(get_extent(send_count, send_dt));
329
  if( get_measurement_rank() == root )
330
    set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
331
  else
332
    set_recv_buffer_usage(0);
333
  init_synchronization();
334
}
335

    
336
double measure_Gather(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
337
{
338
  double start_time, end_time;
339

    
340
  start_time = start_synchronization();
341
  MPI_Gather(get_send_buffer(), send_count, send_dt, 
342
             get_recv_buffer(), recv_count, recv_dt,
343
             root, get_measurement_comm());
344
  end_time = stop_synchronization();
345
  return end_time - start_time;
346
}
347

    
348
/*---------------------------------------------------------------------------*/
349

    
350
void init_Gather_using_Send_Recv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
351
{
352
  set_send_buffer_usage(get_extent(send_count, send_dt));
353
  set_reported_message_size(get_extent(send_count, send_dt));
354
  if( get_measurement_rank() == root )
355
    set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
356
  else
357
    set_recv_buffer_usage(0);
358
  recv_dt_extent = get_extent(1, recv_dt);
359
  init_synchronization();
360
}
361

    
362
double measure_Gather_using_Send_Recv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
363
{
364
  MPI_Status status;
365
  double start_time, end_time;
366
  int i;
367

    
368
  if( get_measurement_rank() == root ) {
369
    start_time = start_synchronization();
370
    for( i = 0; i < get_measurement_size(); i++)
371
      if( i != root )
372
        MPI_Recv((char*)get_recv_buffer() + i*recv_count*recv_dt_extent, recv_count,
373
                 recv_dt, i, 0, get_measurement_comm(), &status);
374
    end_time = stop_synchronization();
375
    return end_time - start_time;
376
  } else {
377
    start_time = start_synchronization();
378
    MPI_Send(get_send_buffer(), send_count, send_dt, root, 0, get_measurement_comm());
379
    end_time = stop_synchronization();
380
    return end_time - start_time;
381
  }
382
}
383

    
384
/*---------------------------------------------------------------------------*/
385

    
386
void init_Gather_using_Isend_Irecv_Waitall(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
387
{
388
  set_send_buffer_usage(get_extent(send_count, send_dt));
389
  set_reported_message_size(get_extent(send_count, send_dt));
390
  if( get_measurement_rank() == root ) {
391
    set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
392
    initialize_req_array(get_measurement_size());
393
    initialize_status_array(get_measurement_size());
394
  } else
395
    set_recv_buffer_usage(0);
396
  recv_dt_extent = get_extent(1, recv_dt);
397
  init_synchronization();
398
}
399

    
400
double measure_Gather_using_Isend_Irecv_Waitall(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
401
{
402
  MPI_Request req;
403
  MPI_Status status;
404
  double start_time, end_time;
405
  int i;
406

    
407
  if( get_measurement_rank() == root ) {
408
    start_time = start_synchronization();
409
    for( i = 0; i < get_measurement_size(); i++)
410
      if( i != root )
411
        MPI_Irecv((char*)get_recv_buffer() + i*recv_count*recv_dt_extent, recv_count,
412
                 recv_dt, i, 0, get_measurement_comm(), &req_array[i]);
413
    req_array[root] = MPI_REQUEST_NULL;
414
    MPI_Waitall(get_measurement_size(), req_array, status_array);
415
    end_time = stop_synchronization();
416
  } else {
417
    start_time = start_synchronization();
418
    MPI_Isend(get_send_buffer(), send_count, send_dt, root, 0, get_measurement_comm(), 
419
              &req);
420
    end_time = stop_synchronization();
421
    MPI_Wait(&req, &status);
422
  }
423
  return end_time - start_time;
424
}
425

    
426
void finalize_Gather_using_Isend_Irecv_Waitall(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
427
{
428
  if( get_measurement_rank() == root ) {
429
    free(req_array);
430
    free(status_array);
431
  }
432
}
433
  
434
/*---------------------------------------------------------------------------*/
435

    
436
void init_Allgather(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
437
{
438
  set_send_buffer_usage(get_extent(send_count, send_dt));
439
  set_reported_message_size(get_extent(send_count, send_dt));
440
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
441
  init_synchronization();
442
}
443

    
444
double measure_Allgather(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
445
{
446
  double start_time, end_time;
447

    
448
  start_time = start_synchronization();
449
  MPI_Allgather(get_send_buffer(), send_count, send_dt, 
450
                get_recv_buffer(), recv_count, recv_dt, get_measurement_comm());
451
  end_time = stop_synchronization();
452
  return end_time - start_time;
453
}
454

    
455
/*---------------------------------------------------------------------------*/
456

    
457
void init_Scatter(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
458
{
459
  if( get_measurement_rank() == root )
460
    set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
461
  else
462
    set_send_buffer_usage(0);
463
  set_recv_buffer_usage(get_extent(recv_count, recv_dt));
464
  set_reported_message_size(get_extent(recv_count, recv_dt));
465
  init_synchronization();
466
}
467

    
468
double measure_Scatter(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
469
{
470
  double start_time, end_time;
471

    
472
  start_time = start_synchronization();
473
  MPI_Scatter(get_send_buffer(), send_count, send_dt, 
474
             get_recv_buffer(), recv_count, recv_dt,
475
             root, get_measurement_comm());
476
  end_time = stop_synchronization();
477
  return end_time - start_time;
478
}
479

    
480
/*---------------------------------------------------------------------------*/
481

    
482
void init_Reduce_Scatterv(int count, MPI_Datatype dt, MPI_Op op, int root)
483
{
484
  MPI_Aint extent;
485

    
486
  send_counts = initialize_counts(count);
487
  send_displs = initialize_displs(send_counts);
488

    
489
  extent = get_extent(count, dt);
490
  set_send_buffer_usage(extent);
491
  set_reported_message_size(extent);
492
  if( get_measurement_rank() == root ) 
493
    set_recv_buffer_usage(extent);
494
  else
495
    set_recv_buffer_usage(0);
496
  init_synchronization();
497
}
498

    
499
double measure_Reduce_Scatterv(int count, MPI_Datatype dt, MPI_Op op, int root)
500
{
501
  double start_time, end_time;
502

    
503
  start_time = start_synchronization();
504
  MPI_Reduce(get_send_buffer(), get_recv_buffer(), count, dt, op, root, 
505
             get_measurement_comm());
506
  MPI_Scatterv(get_recv_buffer(), send_counts, send_displs, dt, 
507
               get_send_buffer(), send_counts[get_measurement_rank()], dt, 
508
               root, get_measurement_comm());
509
  end_time = stop_synchronization();
510
  return end_time - start_time;
511
}
512

    
513
void finalize_Reduce_Scatterv(int count, MPI_Datatype dt, MPI_Op op, int root)
514
{
515
  free(send_counts);
516
  free(send_displs);
517
}
518

    
519
/*---------------------------------------------------------------------------*/
520

    
521
void init_Alltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
522
{
523
  send_counts = initialize_counts(send_count*get_measurement_size());
524
  send_displs = initialize_displs(send_counts);
525
  recv_counts = initialize_counts(recv_count*get_measurement_size());
526
  recv_displs = initialize_displs(recv_counts);
527
  
528
  set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
529
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
530
  set_reported_message_size(get_extent(send_count, send_dt));
531
  init_synchronization();
532
}
533

    
534
double measure_Alltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
535
{
536
  double start_time, end_time;
537

    
538
  start_time = start_synchronization();
539
  MPI_Alltoallv(get_send_buffer(), send_counts, send_displs, send_dt,
540
                get_recv_buffer(), recv_counts, recv_displs, recv_dt, 
541
                get_measurement_comm());
542
  end_time = stop_synchronization();
543
  return end_time - start_time;
544
}
545

    
546
void finalize_Alltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
547
{
548
  free(send_counts);
549
  free(send_displs);
550
  free(recv_counts);
551
  free(recv_displs);
552
}
553

    
554
/*---------------------------------------------------------------------------*/
555

    
556
void init_Alltoallv_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
557
{
558
  send_counts = initialize_counts(send_count*get_measurement_size());
559
  send_displs = initialize_displs(send_counts);
560
  recv_counts = initialize_counts(recv_count*get_measurement_size());
561
  recv_displs = initialize_displs(recv_counts);
562

    
563
  initialize_req_array(2*get_measurement_size());
564
  initialize_status_array(2*get_measurement_size());
565
  
566
  send_dt_extent = get_extent(1, send_dt);
567
  recv_dt_extent = get_extent(1, recv_dt);
568

    
569
  set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
570
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
571
  set_reported_message_size(get_extent(send_count, send_dt));
572
  init_synchronization();
573
}
574

    
575
double measure_Alltoallv_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
576
{
577
  double start_time, end_time;
578
  int i;
579

    
580
  start_time = start_synchronization();
581
  for( i = 0; i < get_measurement_size(); i++)
582
    MPI_Irecv((char*)get_recv_buffer() + recv_displs[i]*recv_dt_extent, recv_count, 
583
              recv_dt, i, 0, get_measurement_comm(), &(req_array[i]));
584

    
585
  for( i = 0; i < get_measurement_size(); i++)
586
    MPI_Isend((char*)get_send_buffer() + send_displs[i]*send_dt_extent, send_count, 
587
              send_dt, i, 0, get_measurement_comm(), &(req_array[i+get_measurement_size()]));
588

    
589
  MPI_Waitall(2*get_measurement_size(), req_array, status_array);
590
  end_time = stop_synchronization();
591
  return end_time - start_time;
592
}
593

    
594
void finalize_Alltoallv_using_Isend_Irecv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
595
{
596
  free(send_counts);
597
  free(send_displs);
598
  free(recv_counts);
599
  free(recv_displs);
600
  free(req_array);
601
  free(status_array);
602
}
603

    
604
/*---------------------------------------------------------------------------*/
605

    
606
void init_Gatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
607
{
608
  recv_counts = initialize_counts(recv_count*get_measurement_size());
609
  recv_displs = initialize_displs(recv_counts);
610

    
611
  set_send_buffer_usage(get_extent(send_count, send_dt));
612
  set_reported_message_size(get_extent(send_count, send_dt));
613
  if( get_measurement_rank() == root )
614
    set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
615
  else
616
    set_recv_buffer_usage(0);
617
  init_synchronization();
618
}
619

    
620
double measure_Gatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
621
{
622
  double start_time, end_time;
623

    
624
  start_time = start_synchronization();
625
  MPI_Gatherv(get_send_buffer(), send_count, send_dt, 
626
              get_recv_buffer(), recv_counts, recv_displs, recv_dt,
627
              root, get_measurement_comm());
628
  end_time = stop_synchronization();
629
  return end_time - start_time;
630
}
631

    
632
void finalize_Gatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
633
{
634
  free(recv_counts);
635
  free(recv_displs);
636
}
637

    
638
/*---------------------------------------------------------------------------*/
639

    
640
void init_Allgatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
641
{
642
  recv_counts = initialize_counts(recv_count*get_measurement_size());
643
  recv_displs = initialize_displs(recv_counts);
644

    
645
  set_send_buffer_usage(get_extent(send_count, send_dt));
646
  set_reported_message_size(get_extent(send_count, send_dt));
647
  set_recv_buffer_usage(get_measurement_size()*get_extent(recv_count, recv_dt));
648
  init_synchronization();
649
}
650

    
651
double measure_Allgatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
652
{
653
  double start_time, end_time;
654

    
655
  start_time = start_synchronization();
656
  MPI_Allgatherv(get_send_buffer(), send_count, send_dt, 
657
                 get_recv_buffer(), recv_counts, recv_displs, recv_dt, 
658
                 get_measurement_comm());
659
  end_time = stop_synchronization();
660
  return end_time - start_time;
661
}
662

    
663
void finalize_Allgatherv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt)
664
{
665
  free(recv_counts);
666
  free(recv_displs);
667
}
668

    
669
/*---------------------------------------------------------------------------*/
670

    
671
void init_Scatterv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
672
{
673
  send_counts = initialize_counts(send_count*get_measurement_size());
674
  send_displs = initialize_displs(send_counts);
675

    
676
  if( get_measurement_rank() == root )
677
    set_send_buffer_usage(get_measurement_size()*get_extent(send_count, send_dt));
678
  else
679
    set_send_buffer_usage(0);
680
  set_recv_buffer_usage(get_extent(recv_count, recv_dt));
681
  set_reported_message_size(get_extent(recv_count, recv_dt));
682
  init_synchronization();
683
}
684

    
685
double measure_Scatterv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
686
{
687
  double start_time, end_time;
688

    
689
  start_time = start_synchronization();
690
  MPI_Scatterv(get_send_buffer(), send_counts, send_displs, send_dt, 
691
              get_recv_buffer(), recv_count, recv_dt, root, get_measurement_comm());
692
  end_time = stop_synchronization();
693
  return end_time - start_time;
694
}
695

    
696
void finalize_Scatterv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int root)
697
{
698
  free(send_counts);
699
  free(send_displs);
700
}
701

    
702
/*---------------------------------------------------------------------------*/
703

    
704
void init_Scan(int count, MPI_Datatype dt, MPI_Op op)
705
{
706
  MPI_Aint extent;
707

    
708
  extent = get_extent(count, dt);
709
  set_send_buffer_usage(extent);
710
  set_reported_message_size(extent);
711
  set_recv_buffer_usage(extent);
712
  init_synchronization();
713
}
714

    
715
double measure_Scan(int count, MPI_Datatype dt, MPI_Op op)
716
{
717
  double start_time, end_time;
718

    
719
  start_time = start_synchronization();
720
  MPI_Scan(get_send_buffer(), get_recv_buffer(), count, dt, op, get_measurement_comm());
721
  end_time = stop_synchronization();
722
  return end_time - start_time;
723
}
724

    
725
/*---------------------------------------------------------------------------*/
726

    
727
void init_Comm_split(void)
728
{
729
  init_synchronization();
730
}
731

    
732
double measure_Comm_split(void)
733
{
734
  double start_time, end_time;
735
  MPI_Comm new_comm;
736

    
737
  start_time = start_synchronization();
738
  MPI_Comm_split(get_measurement_comm(), get_measurement_rank() % 2, 0, &new_comm);
739
  end_time = stop_synchronization();
740
  MPI_Comm_free(&new_comm);
741
  return end_time - start_time;
742
}
743

    
744
/*---------------------------------------------------------------------------*/
745

    
746
void init_Comm_dup(void)
747
{
748
  init_synchronization();
749
}
750

    
751
double measure_Comm_dup(void)
752
{
753
  double start_time, end_time;
754
  MPI_Comm new_comm;
755

    
756
  start_time = start_synchronization();
757
  MPI_Comm_dup(get_measurement_comm(), &new_comm);
758
  end_time = stop_synchronization();
759
  MPI_Comm_free(&new_comm);
760
  return end_time - start_time;
761
}
762

    
763
/*---------------------------------------------------------------------------*/
764

    
765

    
766
int *init_send_counts(int count, int charged_rank, double ratio)
767
{
768
  int i;
769
  int *counts;
770

    
771
  counts = (int*)malloc(get_measurement_size()*sizeof(int));
772
  assert( counts != NULL );
773

    
774
  for( i = 0; i < get_measurement_size(); i++){
775
    if( i == charged_rank ){
776
      counts[i] = (int)(count * ratio) / get_measurement_size();
777
    }
778
    else{
779
      counts[i] = (int)(count / ratio) / get_measurement_size();
780
    }
781
  }
782

    
783
  for( i = 0; i < count % get_measurement_size(); i++) 
784
    counts[i*get_measurement_size() / (count % get_measurement_size())]++;
785

    
786
  return counts;
787
}
788

    
789
int *init_recv_counts(int count, int charged_rank, double ratio)
790
{
791
  int i;
792
  int *counts;
793

    
794
  counts = (int*)malloc(get_measurement_size()*sizeof(int));
795
  assert( counts != NULL );
796

    
797
  if( get_measurement_rank() == charged_rank ){
798
    for( i = 0; i < get_measurement_size(); i++){
799
      counts[i] = (int)(count * ratio) / get_measurement_size();
800
    }
801
  }
802
  else{
803
    for( i = 0; i < get_measurement_size(); i++){
804
      counts[i] = (int)(count / ratio) / get_measurement_size();
805
    }
806
  }
807

    
808
  if( count % get_measurement_size() && 
809
      (get_measurement_rank() % (get_measurement_size() / (count % get_measurement_size())) == 0) ){
810
    for( i = 0; i < get_measurement_size(); i++){
811
      counts[i]++;
812
    }
813
  }
814
  return counts;
815
}
816

    
817
void init_myalltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int charged_rank, double ratio)
818
{
819
  int p;
820
  int send_buffer_usage, recv_buffer_usage;
821

    
822

    
823
  send_counts = init_send_counts(send_count*get_measurement_size(), charged_rank, ratio);
824
  send_displs = initialize_displs(send_counts);
825
  recv_counts = init_recv_counts(recv_count*get_measurement_size(), charged_rank, ratio);
826
  recv_displs = initialize_displs(recv_counts);
827

    
828
  send_buffer_usage = 0;
829
  recv_buffer_usage = 0;
830
  for(p = 0; p < get_measurement_size(); p++) {
831
    send_buffer_usage += get_extent(send_counts[p], send_dt);
832
    recv_buffer_usage += get_extent(recv_counts[p], recv_dt);
833
  }
834
  set_send_buffer_usage(send_buffer_usage);
835
  set_recv_buffer_usage(recv_buffer_usage);
836
  set_reported_message_size(send_buffer_usage);
837

    
838
  init_synchronization();
839
}
840

    
841
double measure_myalltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int charged_rank, double ratio)
842
{
843
  double start_time, end_time;
844

    
845
  start_time = start_synchronization();
846
  MPI_Alltoallv(get_send_buffer(), send_counts, send_displs, send_dt,
847
                get_recv_buffer(), recv_counts, recv_displs, recv_dt, 
848
                get_measurement_comm());
849
  end_time = stop_synchronization();
850
  return end_time - start_time;
851
}
852

    
853
void finalize_myalltoallv(int send_count, MPI_Datatype send_dt, int recv_count, MPI_Datatype recv_dt, int charged_rank, double ratio)
854
{
855
  free(send_counts);
856
  free(send_displs);
857
  free(recv_counts);
858
  free(recv_displs);
859
}
860

    
861
#pragma weak end_skampi_extensions
862