ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
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 
37 BLACBUFF *BI_GetBuff(int length)
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 }
BUFFALIGN
#define BUFFALIGN
Definition: Bdef.h:75
BI_GetBuff
BLACBUFF * BI_GetBuff(int length)
Definition: BI_GetBuff.c:36
bLaCbUfF::Buff
char * Buff
Definition: Bdef.h:56
BI_EmergencyBuff
void BI_EmergencyBuff(int length)
Definition: BI_EmergencyBuff.c:8
bLaCbUfF::Len
int Len
Definition: Bdef.h:57
bLaCbUfF
Definition: Bdef.h:54
BI_ReadyB
BLACBUFF * BI_ReadyB
Definition: BI_GlobalVars.c:8
bLaCbUfF::Aops
MPI_Request * Aops
Definition: Bdef.h:59
BI_Np
int BI_Np
Definition: BI_GlobalVars.c:7
bLaCbUfF::nAops
int nAops
Definition: Bdef.h:58
Bdef.h
BLACBUFF
struct bLaCbUfF BLACBUFF
Definition: Bdef.h:53