1 /*****************************************************************************
2 * *
3 * Copyright (c) 2003-2006 Intel Corporation. *
4 * All rights reserved. *
5 * *
6 *****************************************************************************
7
8 This code is covered by the Community Source License (CPL), version
9 1.0 as published by IBM and reproduced in the file "license.txt" in the
10 "license" subdirectory. Redistribution in source and binary form, with
11 or without modification, is permitted ONLY within the regulations
12 contained in above mentioned license.
13
14 Use of the name and trademark "Intel(R) MPI Benchmarks" is allowed ONLY
15 within the regulations of the "License for Use of "Intel(R) MPI
16 Benchmarks" Name and Trademark" as reproduced in the file
17 "use-of-trademark-license.txt" in the "license" subdirectory.
18
19 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 solely responsible for determining the appropriateness of using and
24 distributing the Program and assumes all risks associated with its
25 exercise of rights under this Agreement, including but not limited to
26 the risks and costs of program errors, compliance with applicable
27 laws, damage to or loss of data, programs or equipment, and
28 unavailability or interruption of operations.
29
30 EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
31 ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
32 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
33 WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
34 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
36 DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
38
39 EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
40 YOUR JURISDICTION. It is licensee's responsibility to comply with any
41 export regulations applicable in licensee's jurisdiction. Under
42 CURRENT U.S. export regulations this software is eligible for export
43 from the U.S. and can be downloaded by or otherwise exported or
44 reexported worldwide EXCEPT to U.S. embargoed destinations which
45 include Cuba, Iraq, Libya, North Korea, Iran, Syria, Sudan,
46 Afghanistan and any other country to which the U.S. has embargoed
47 goods and services.
48
49 ***************************************************************************
50
51 For more documentation than found here, see
52
53 [1] doc/ReadMe_IMB.txt
54
55 [2] Intel (R) MPI Benchmarks
56 Users Guide and Methodology Description
57 In
58 doc/IMB_ug.pdf
59
60 File: IMB_mem_manager.c
61
62 Implemented functions:
63
64 IMB_v_alloc;
65 IMB_i_alloc;
66 IMB_alloc_buf;
67 IMB_alloc_aux;
68 IMB_free_aux;
69 IMB_v_free;
70 IMB_ass_buf;
71 IMB_set_buf;
72 IMB_init_pointers;
73 IMB_init_buffers;
74 IMB_free_all;
75 IMB_del_s_buf;
76 IMB_del_r_buf;
77
78 ***************************************************************************/
79
80
81
82 #include "IMB_declare.h"
83 #include "IMB_benchmark.h"
84
85 #include "IMB_prototypes.h"
86
87
88
89
IMB_v_alloc(int Len,char * where)90 void* IMB_v_alloc(int Len, char* where)
91 /*
92
93
94 Allocates void* memory
95
96
97
98 Input variables:
99
100 -Len (type int)
101 #bytes to allocate
102
103
104 -where (type char*)
105 Comment (marker for calling place)
106
107
108
109 Return value (type void*)
110 Allocated pointer
111
112
113
114 */
115 {
116 void* B;
117 Len=max(asize,Len);
118 if( (B = (void*)malloc(Len) ) == NULL )
119 {
120 printf ("Memory allocation failed. code position: %s. tried to alloc. %d bytes\n",where,Len);
121 return NULL;
122 }
123 return B;
124 }
125
126
127
128
IMB_i_alloc(int ** B,int Len,char * where)129 void IMB_i_alloc(int** B, int Len, char* where )
130 /*
131
132
133 Allocates int memory
134
135
136
137 Input variables:
138
139 -Len (type int)
140 #int's to allocate
141
142
143 -where (type char*)
144 Comment (marker for calling place)
145
146
147
148 In/out variables:
149
150 -B (type int**)
151 *B contains allocated memory
152
153
154
155 */
156 {
157 Len=max(1,Len);
158 *B = (int*) IMB_v_alloc(sizeof(int)*Len, where);
159 }
160
161
162
163
IMB_alloc_buf(struct comm_info * c_info,char * where,int s_len,int r_len)164 void IMB_alloc_buf(struct comm_info* c_info, char* where, int s_len,
165 int r_len)
166 /*
167
168
169 Allocates send/recv buffers for message passing
170
171
172
173 Input variables:
174
175 -where (type char*)
176 Comment (marker for calling place)
177
178
179 -s_len (type int)
180 Send buffer length (bytes)
181
182
183 -r_len (type int)
184 Recv buffer length (bytes)
185
186
187
188 In/out variables:
189
190 -c_info (type struct comm_info*)
191 Collection of all base data for MPI;
192 see [1] for more information
193
194 Send/Recv buffer components get allocated
195
196
197
198 */
199 {
200 /* July 2002 V2.2.1 change: use MPI_Alloc_mem */
201 #if ( defined EXT || defined MPIIO )
202 MPI_Aint slen = (MPI_Aint)(max(1,s_len));
203 MPI_Aint rlen = (MPI_Aint)(max(1,r_len));
204 int ierr;
205 #else
206 s_len=max(1,s_len);
207 r_len=max(1,r_len);
208 #endif
209 if( c_info->s_alloc < s_len )
210 {
211 if( c_info->s_alloc > 0 )
212 /* July 2002 V2.2.1 change: use MPI_Alloc_mem */
213 #if ( defined EXT || defined MPIIO )
214 { MPI_Free_mem(c_info->s_buffer); }
215
216 ierr=MPI_Alloc_mem(slen, MPI_INFO_NULL, &c_info->s_buffer);
217 MPI_ERRHAND(ierr);
218 #else
219 { free(c_info->s_buffer); }
220
221 c_info->s_buffer = IMB_v_alloc(s_len,where);
222 #endif
223
224 c_info->s_alloc = s_len;
225 c_info->s_data = (assign_type*)c_info->s_buffer;
226 }
227 if( c_info->r_alloc < r_len )
228 {
229 if( c_info->r_alloc > 0 )
230 /* July 2002 V2.2.1 change: use MPI_Alloc_mem */
231 #if ( defined EXT || defined MPIIO )
232 { MPI_Free_mem(c_info->r_buffer); }
233
234 ierr=MPI_Alloc_mem(rlen, MPI_INFO_NULL, &c_info->r_buffer);
235 MPI_ERRHAND(ierr);
236 #else
237 { free(c_info->r_buffer); }
238
239 c_info->r_buffer = IMB_v_alloc(r_len,where);
240 #endif
241
242 c_info->r_alloc = r_len;
243 c_info->r_data = (assign_type*)c_info->r_buffer;
244 }
245
246 }
247
248
249
250
IMB_alloc_aux(int L,char * where)251 void IMB_alloc_aux(int L, char* where)
252 /*
253
254
255 Allocates global auxiliary memory AUX
256
257
258
259 Input variables:
260
261 -L (type int)
262 #Bytes to allocate
263
264
265 -where (type char*)
266 Comment (marker for calling place)
267
268
269
270 */
271 {
272 L=max(asize,L);
273 if( AUX_LEN < L)
274 {
275 if( AUX_LEN>0 ) free(AUX);
276
277 AUX = IMB_v_alloc(L, where);
278 AUX_LEN=L;
279 }
280 }
281
282
283
284
IMB_free_aux()285 void IMB_free_aux()
286 /*
287
288
289 Free-s global auxiliary memory AUX
290
291
292
293 */
294 {
295 if (AUX_LEN > 0 ) {free(AUX); AUX_LEN=0; }
296 }
297
298
IMB_v_free(void ** B)299 void IMB_v_free(void **B)
300 /*
301
302
303 Free-s memory
304
305
306
307 In/out variables:
308
309 -B (type void**)
310 (*B) will be free-d
311
312
313
314 */
315 {
316 if( *B ) free(*B);
317 *B=NULL;
318 }
319
320
321
322
IMB_ass_buf(void * buf,int rank,int pos1,int pos2,int value)323 void IMB_ass_buf(void* buf, int rank, int pos1,
324 int pos2, int value)
325 /*
326
327
328 Assigns values to a buffer
329
330
331
332 Input variables:
333
334 -rank (type int)
335 Rank of calling process
336
337
338 -pos1 (type int)
339 -pos2 (type int)
340 Assignment between byte positions pos1, pos2
341
342
343 -value (type int)
344 1/0 for non-zero (defined in IMB_settings.h)/ zero value
345
346
347
348 In/out variables:
349
350 -buf (type void*)
351 Values assigned within given positions
352
353
354
355 */
356 {
357
358 if( pos2>= pos1 )
359 {
360 int a_pos1, a_pos2, i, j;
361 a_pos1 = pos1/asize;
362 if( pos2>=pos1 )
363 a_pos2 = pos2/asize;
364 else
365 a_pos2 = a_pos1-1;
366
367 if( value )
368 for ( i=a_pos1,j=0 ; i<=a_pos2; i++,j++ )
369 ((assign_type *)buf)[j] = BUF_VALUE(rank,i);
370
371 else
372 for ( i=a_pos1,j=0 ; i<=a_pos2; i++,j++ )
373 ((assign_type *)buf)[j] = 0.;
374
375 if( a_pos1*asize != pos1 )
376 {
377 void* xx = (void*)(((char*)buf)+pos1-a_pos1*asize);
378 memmove(buf,xx,pos2-pos1+1);
379 }
380 }
381
382 }
383
384
385
386
IMB_set_buf(struct comm_info * c_info,int selected_rank,int s_pos1,int s_pos2,int r_pos1,int r_pos2)387 void IMB_set_buf(struct comm_info* c_info, int selected_rank, int s_pos1,
388 int s_pos2, int r_pos1, int r_pos2)
389 /*
390
391
392 Sets Send/Recv buffers for a selected rank
393 (by call to => IMB_ass_buf)
394
395
396
397 Input variables:
398
399 -selected_rank (type int)
400 Relevant process rank
401 (Can be different from local rank: for checking purposes)
402
403
404 -s_pos1 (type int)
405 -s_pos2 (type int)
406 s_pos1 .. s_pos2 positions for send buffer
407
408
409 -r_pos1 (type int)
410 -r_pos2 (type int)
411 r_pos1 .. r_pos2 positions for recv buffer
412
413
414
415 In/out variables:
416
417 -c_info (type struct comm_info*)
418 Collection of all base data for MPI;
419 see [1] for more information
420
421 Corresponding buffer components are assigned values
422
423
424
425 */
426 {
427 /*
428 Sets c_info->s_buffer/c_info->r_buffer int byte positions
429 s_pos1..s_pos2/r_pos1..r_pos2
430 Values are taken for "selected_rank"
431 Checks right allocation.
432 */
433 int s_len, r_len;
434
435 s_len = (max(s_pos2-s_pos1,0)/asize+1)*asize;
436 r_len = (max(r_pos2-r_pos1,0)/asize+1)*asize;
437
438 IMB_alloc_buf(c_info, "set_buf 1",s_len, r_len);
439
440
441 if( s_pos2 >= s_pos1 )
442 IMB_ass_buf( c_info->s_buffer, selected_rank, s_pos1, s_pos2, 1);
443 if( r_pos2 >= r_pos1 )
444 IMB_ass_buf( c_info->r_buffer, selected_rank, r_pos1, r_pos2, 0);
445
446 }
447
448
449
IMB_init_pointers(struct comm_info * c_info)450 void IMB_init_pointers(struct comm_info *c_info )
451 /*
452
453
454 Initializes pointer components of comm_info
455
456
457
458 In/out variables:
459
460 -c_info (type struct comm_info *)
461 Collection of all base data for MPI;
462 see [1] for more information
463
464 Corresponding pointer components are initialized
465
466
467
468 */
469 {
470 /********************************************************************
471
472
473 ---------------------------------------------------------------------
474 VARIABLE | TYPE | MEANING
475 ---------------------------------------------------------------------
476 In/Out : c_info | struct comm_info* | see comm_info.h
477 | | Pointers initialized
478 ----------------------------------------------------------------------*/
479
480 MPI_Comm_size(MPI_COMM_WORLD,&c_info->w_num_procs);
481 MPI_Comm_rank(MPI_COMM_WORLD,&c_info->w_rank );
482
483 c_info->s_data_type = MPI_BYTE; /* DATA TYPE of SEND BUFFER */
484 c_info->r_data_type = MPI_BYTE; /* DATA TYPE of RECEIVE BUFFER */
485
486 c_info->op_type = MPI_SUM; /* OPERATION TYPE IN Allred */
487 c_info->red_data_type = MPI_FLOAT; /* NOTE: NO 'CAST' CHECK IN. IBUF */
488
489 c_info -> s_buffer = c_info -> r_buffer = NULL;
490 c_info -> s_data = c_info -> r_data = NULL;
491 c_info -> s_alloc = c_info -> r_alloc = 0;
492
493 c_info->communicator= MPI_COMM_NULL;
494
495 /* Auxiliary space */
496 IMB_i_alloc(&c_info->g_ranks,c_info->w_num_procs,"Init_Pointers 1");
497 IMB_i_alloc(&c_info->g_sizes,c_info->w_num_procs,"Init_Pointers 2");
498
499 IMB_i_alloc(&c_info->sndcnt,c_info->w_num_procs,"Init_Pointers 3");
500 IMB_i_alloc(&c_info->sdispl,c_info->w_num_procs,"Init_Pointers 4");
501
502 IMB_i_alloc(&c_info->reccnt,c_info->w_num_procs,"Init_Pointers 5");
503 IMB_i_alloc(&c_info->rdispl,c_info->w_num_procs,"Init_Pointers 6");
504
505 #ifdef MPIIO
506 c_info->filename = c_info->datarep = (char*)NULL;
507 c_info->view = MPI_DATATYPE_NULL;
508 c_info->info = MPI_INFO_NULL;
509 c_info->fh = MPI_FILE_NULL;
510 #endif
511
512 all_times = NULL;
513 #ifdef CHECK
514 all_defect = NULL;
515 #endif
516
517 IMB_init_errhand(c_info);
518
519 }
520
521
522 /**********************************************************************/
523
524
525
IMB_init_buffers(struct comm_info * c_info,struct Bench * Bmark,int size)526 void IMB_init_buffers(struct comm_info* c_info, struct Bench* Bmark, int size)
527 /*
528
529
530 Initializes communications buffers (call set_buf)
531
532
533
534 Input variables:
535
536 -Bmark (type struct Bench*)
537 (For explanation of struct Bench type:
538 describes all aspects of modes of a benchmark;
539 see [1] for more information)
540
541 Current benchmark
542
543
544 -size (type int)
545 Message size
546
547
548
549 In/out variables:
550
551 -c_info (type struct comm_info*)
552 Collection of all base data for MPI;
553 see [1] for more information
554
555 Communications buffers are allocated and assigned values
556
557
558
559 */
560 {
561 int s_len, r_len, maxlen;
562 int init_size;
563
564 maxlen = 1<<MAXMSGLOG;
565 #ifdef MPIIO
566 init_size = size;
567 #endif
568 #ifdef EXT
569 init_size = max(maxlen,OVERALL_VOL);
570 if( OVERALL_VOL/MSGSPERSAMPLE > maxlen ) init_size = maxlen*MSGSPERSAMPLE;
571 #endif
572 #ifdef MPI1
573 init_size = maxlen;
574 #endif
575
576
577 if(c_info->rank < 0 ) return;
578
579 if(!strcmp(Bmark->name,"Alltoall") || !strcmp(Bmark->name,"Alltoallv"))
580 {
581 s_len = c_info->num_procs*init_size;
582 r_len = c_info->num_procs*init_size;
583 }
584 else if( !strcmp(Bmark->name,"Allgather") || !strcmp(Bmark->name,"Allgatherv") )
585 {
586 s_len = init_size;
587 r_len = c_info->num_procs*init_size;
588 }
589 else
590 s_len = r_len = init_size;
591
592 IMB_set_buf(c_info, c_info->rank, 0, s_len-1, 0, r_len-1);
593
594 }
595
596 /********************************************************************/
597
598
599
IMB_free_all(struct comm_info * c_info,struct Bench ** P_BList)600 void IMB_free_all(struct comm_info* c_info, struct Bench** P_BList)
601 /*
602
603
604 Free-s all allocated memory in c_info and P_Blist
605
606
607
608 In/out variables:
609
610 -c_info (type struct comm_info*)
611 Collection of all base data for MPI;
612 see [1] for more information
613
614
615 -P_BList (type struct Bench**)
616 (For explanation of struct Bench type:
617 describes all aspects of modes of a benchmark;
618 see [1] for more information)
619
620
621
622 */
623 {
624 IMB_del_s_buf(c_info);
625 IMB_del_r_buf(c_info);
626
627 IMB_v_free((void**)&c_info->msglen);
628
629 IMB_v_free((void**)&c_info->g_sizes);
630 IMB_v_free((void**)&c_info->g_ranks);
631
632 IMB_v_free((void**)&c_info->sndcnt);
633 IMB_v_free((void**)&c_info->sdispl);
634
635 IMB_v_free((void**)&c_info->reccnt);
636 IMB_v_free((void**)&c_info->rdispl);
637
638 if( c_info->communicator != MPI_COMM_NULL &&
639 c_info->communicator != MPI_COMM_SELF &&
640 c_info->communicator != MPI_COMM_WORLD )
641 {
642 IMB_del_errhand(c_info);
643 MPI_Comm_free(&c_info->communicator);
644 }
645
646 IMB_destruct_blist(P_BList);
647
648 #ifdef MPIIO
649 IMB_free_file(c_info);
650 #endif
651 if( all_times ) {free (all_times); all_times=(double*)NULL;}
652
653 #ifdef CHECK
654 if( all_defect ) {free (all_defect);all_defect=(double*)NULL;}
655
656 if( AUX_LEN > 0 ) {free(AUX); AUX_LEN = 0;}
657 #endif
658
659 #ifdef DEBUG
660 fclose(dbg_file);
661 #endif
662 }
663
664
IMB_del_s_buf(struct comm_info * c_info)665 void IMB_del_s_buf(struct comm_info* c_info )
666 /*
667
668
669 Deletes send buffer component of c_info
670
671
672
673 In/out variables:
674
675 -c_info (type struct comm_info*)
676 Collection of all base data for MPI;
677 see [1] for more information
678
679
680
681 */
682 {
683 /* July 2002 V2.2.1 change: use MPI_Free_mem */
684 if ( c_info->s_alloc> 0)
685 #if (defined EXT || defined MPIIO)
686 MPI_Free_mem( c_info->s_buffer );
687 #else
688 free( c_info->s_buffer );
689 #endif
690
691 c_info-> s_alloc = 0;
692 }
693
694
695
696
IMB_del_r_buf(struct comm_info * c_info)697 void IMB_del_r_buf(struct comm_info* c_info )
698 /*
699
700
701 Deletes recv buffer component of c_info
702
703
704
705 In/out variables:
706
707 -c_info (type struct comm_info*)
708 Collection of all base data for MPI;
709 see [1] for more information
710
711
712
713 */
714 {
715 /* July 2002 V2.2.1 change: use MPI_Free_mem */
716 if ( c_info->r_alloc> 0)
717 #if (defined EXT || defined MPIIO)
718 MPI_Free_mem( c_info->r_buffer );
719 #else
720 free( c_info->r_buffer );
721 #endif
722
723 c_info-> r_alloc = 0;
724 }
725
726