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