SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
All Classes Files Functions Variables Typedefs Macros
BI_GetBuff.c
Go to the documentation of this file.
1#include "Bdef.h"
2/***************************************************************************
3 * The mpi implements globally blocking sends. I.e., a send blocks until *
4 * the dest. node issues a recv. The BLACS assume locally-blocking sends.*
5 * Therefore, the BLACS must fake locally-blocking sends. To do this *
6 * requires an indeterminate number of buffers and the use of *
7 * non-blocking sends. However, it is very important that even though I *
8 * provide a dynamic number of buffers, that getting these buffers does *
9 * not take too long in the critical part of a send operation. *
10 * Therefore, the buffer management is broken into two routines. *
11 * *
12 * Inside the BLACS there are two states a buffer may be in. If the buff *
13 * is currently being used (for instance, an asynchronous send is coming *
14 * from it), it is classified as an ACTIVE buffer, and is on the active *
15 * buffer queue. Otherwise, a buffer is READY: it is not being used *
16 * and is available for the next buffer operation. *
17 * In order to avoid buffer proliferation, only one ready buffer is kept, *
18 * and as active buffers become inactive they either become the ready *
19 * buffer, or are freed. *
20 * *
21 * The first routine, BI_GetBuff, checks if the ready buffer is big enough *
22 * to fulfill the buffer request. If not, the present ready buffer is *
23 * is freed, and a new buffer of the required length is allocated. If *
24 * the buffer is of sufficent size already, no action is taken. *
25 * This routine is purposely very short, as it is called at the beginning *
26 * of each broadcast/send operation. All participating nodes *
27 * are waiting on the source node, so this routine must be very cheap. *
28 * *
29 * The second routine, BI_UpdateBuffs, moves the ready buffer to the active *
30 * buffer queue (if needed). It also checks the entire active buffer *
31 * queue to see if any have finished their operations. If so, they are *
32 * are either moved to the ready buff, or freed. This routine is called *
33 * AFTER the send/broadcast has been started, and thus I am free to make *
34 * it a little more complex. *
35 ***************************************************************************/
36
38{
39 void BI_EmergencyBuff(Int length);
40
41 char *cptr;
42 Int i, j;
43 extern Int BI_Np;
44 extern BLACBUFF *BI_ReadyB;
45
46/*
47 * If ready buffer already exists, and is big enough, return it. Otherwise,
48 * free the buffer (if it exists) and get one of correct size
49 */
50 if (BI_ReadyB)
51 {
52 if (BI_ReadyB->Len >= length) return(BI_ReadyB);
53 else free(BI_ReadyB);
54 }
55/*
56 * Make sure all buffers aligned correctly
57 */
58 j = sizeof(BLACBUFF);
59 if (j % sizeof(MPI_Request))
60 j += sizeof(MPI_Request) - j % sizeof(MPI_Request);
61 i = j + BI_Np*sizeof(MPI_Request);
62 if (i % BUFFALIGN) i += BUFFALIGN - i % BUFFALIGN;
63 cptr = malloc(i + length);
64 BI_ReadyB = (BLACBUFF *) cptr;
65
66 if (BI_ReadyB != NULL)
67 {
68 BI_ReadyB->nAops = 0;
69 BI_ReadyB->Aops = (MPI_Request *) &cptr[j];
70 BI_ReadyB->Buff = &cptr[i];
71 BI_ReadyB->Len = length;
72 }
73 else BI_EmergencyBuff(length);
74
75 return(BI_ReadyB);
76}
void BI_EmergencyBuff(Int length)
BLACBUFF * BI_GetBuff(Int length)
Definition BI_GetBuff.c:37
BLACBUFF * BI_ReadyB
Int BI_Np
#define Int
Definition Bconfig.h:22
struct bLaCbUfF BLACBUFF
Definition Bdef.h:53
#define BUFFALIGN
Definition Bdef.h:75
Int Len
Definition Bdef.h:57
MPI_Request * Aops
Definition Bdef.h:59
Int nAops
Definition Bdef.h:58
char * Buff
Definition Bdef.h:56