1 |
#include "Distribution.h" |
2 |
|
3 |
#ifdef PASO_MPI |
4 |
|
5 |
/* |
6 |
* allocates memory arrays for a node distribution. |
7 |
* assumes that numLocal and numExternal are greater than zero. |
8 |
* numNeigbhours may be zero. |
9 |
*/ |
10 |
void Finley_NodeDistibution_allocTable( Finley_NodeDistribution *in, dim_t numLocal, dim_t numExternal, dim_t numNeighbours ) |
11 |
{ |
12 |
index_t i; |
13 |
index_t *neighbours=NULL, *vtxdist=NULL, *indexExternal=NULL; |
14 |
Finley_NodeGhostEdge **edges=NULL; |
15 |
|
16 |
if( Finley_checkPtr(in) ) |
17 |
return; |
18 |
|
19 |
if( numNeighbours ) |
20 |
{ |
21 |
neighbours = MEMALLOC( numNeighbours, index_t ); |
22 |
edges = MEMALLOC( numNeighbours, Finley_NodeGhostEdge* ); |
23 |
} |
24 |
vtxdist = MEMALLOC( in->MPIInfo->size+1, index_t ); |
25 |
indexExternal = MEMALLOC( numExternal, index_t ); |
26 |
|
27 |
if( (numNeighbours && ( Finley_checkPtr(neighbours) || Finley_checkPtr(edges) )) || Finley_checkPtr(vtxdist) || Finley_checkPtr(indexExternal) ) |
28 |
{ |
29 |
MEMFREE( neighbours ); |
30 |
MEMFREE( edges ); |
31 |
MEMFREE( vtxdist ); |
32 |
MEMFREE( indexExternal ); |
33 |
} |
34 |
else |
35 |
{ |
36 |
Finley_NodeDistribution_deallocTable( in ); |
37 |
in->neighbours = neighbours; |
38 |
in->edges = edges; |
39 |
in->vtxdist = vtxdist; |
40 |
in->indexExternal = indexExternal; |
41 |
|
42 |
/* initialise dummy values */ |
43 |
for( i=0; i<numNeighbours; i++ ) |
44 |
{ |
45 |
neighbours[i] = -1; |
46 |
edges[i] = NULL; |
47 |
} |
48 |
for( i=0; i<numExternal; i++ ) |
49 |
indexExternal[i] = -1; |
50 |
|
51 |
/* MPI Communication to determine global info from local info */ |
52 |
MPI_Allreduce( &numLocal, &in->numGlobal, 1, MPI_INT, MPI_SUM, in->MPIInfo->comm ); |
53 |
vtxdist[0] = 0; |
54 |
MPI_Allgather( &numLocal, 1, MPI_INT, vtxdist+1, 1, MPI_INT, in->MPIInfo->comm ); |
55 |
for( i=1; i<in->MPIInfo->size+1; i++ ) |
56 |
vtxdist[i] += vtxdist[i-1]; |
57 |
|
58 |
/* table dimensions */ |
59 |
in->numLocal = numLocal; |
60 |
in->numInternal = 0; |
61 |
in->numExternal = numExternal; |
62 |
in->numBoundary = 0; |
63 |
in->numNeighbours = numNeighbours; |
64 |
} |
65 |
|
66 |
return; |
67 |
} |
68 |
|
69 |
void Finley_NodeDistribution_deallocTable( Finley_NodeDistribution *in ) |
70 |
{ |
71 |
index_t i; |
72 |
|
73 |
if( in!=NULL ) |
74 |
{ |
75 |
MEMFREE( in->neighbours ); |
76 |
MEMFREE( in->vtxdist ); |
77 |
MEMFREE( in->indexExternal ); |
78 |
for( i=0; i<in->numNeighbours; i++ ) |
79 |
Finley_NodeGhostEdge_dealloc( in->edges[i] ); |
80 |
MEMFREE( in->edges ); |
81 |
|
82 |
in->numBoundary = 0; |
83 |
in->numInternal = 0; |
84 |
in->numLocal = 0; |
85 |
in->numNeighbours = 0; |
86 |
in->numExternal = 0; |
87 |
in->numGlobal = 0; |
88 |
} |
89 |
} |
90 |
|
91 |
/* TODO */ |
92 |
/* maybe these should be replaced by a routine to compile the edge list automatically */ |
93 |
void Finley_NodeGhostEdge_allocTable( Finley_NodeGhostEdge *in, dim_t numForward, dim_t numBackward ) |
94 |
{ |
95 |
index_t *indexForward=NULL, *indexBackward=NULL; |
96 |
|
97 |
if( Finley_checkPtr(in) ) |
98 |
return; |
99 |
|
100 |
if( numForward ) |
101 |
{ |
102 |
indexForward = MEMALLOC( numForward, index_t ); |
103 |
} |
104 |
if( numBackward ) |
105 |
{ |
106 |
indexBackward = MEMALLOC( numBackward, index_t ); |
107 |
} |
108 |
|
109 |
if( (numForward && Finley_checkPtr(indexForward)) || (numBackward && Finley_checkPtr(indexBackward)) ) |
110 |
{ |
111 |
MEMFREE( indexForward ); |
112 |
MEMFREE( indexBackward ); |
113 |
} |
114 |
else |
115 |
{ |
116 |
Finley_NodeGhostEdge_deallocTable( in ); |
117 |
in->indexForward = indexForward; |
118 |
in->indexBackward = indexBackward; |
119 |
in->numForward = numForward; |
120 |
in->numBackward = numBackward; |
121 |
} |
122 |
return; |
123 |
} |
124 |
|
125 |
void Finley_NodeGhostEdge_deallocTable( Finley_NodeGhostEdge *in ) |
126 |
{ |
127 |
if( in!=NULL ) |
128 |
{ |
129 |
in->numForward = in->numBackward = 0; |
130 |
MEMFREE( in->indexForward); |
131 |
MEMFREE( in->indexBackward ); |
132 |
} |
133 |
} |
134 |
|
135 |
|
136 |
#endif |