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
BLACS
SRC
BI_GetBuff.c
Generated by
1.8.16