Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
PoPs_Bcast.cc
Go to the documentation of this file.
1#ifdef PoPs_MPI
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "PoPs.h"
7#include "PoPs_private.h"
9
10#define NumberOfBcastArrays 3
11
12enum PoPs_Bcast_mode { PoPs_Bcast_mode_count, PoPs_Bcast_mode_pack, PoPs_Bcast_mode_unpack };
13
14typedef struct PoPs_Bcast_info {
15 enum PoPs_Bcast_mode mode;
16 int int_count, char_count, double_count;
17 int *int_array;
18 char *char_array;
19 double *double_array;
20} PoPs_Bcast_info;
21
22static int PoPs_Bcast3( statusMessageReporting *smr, MPI_Comm comm, PoPs_Bcast_info *info, unitsDB *unitsRoot, PoPs *popsRoot );
23static int PoPs_Bcast_PoPs( statusMessageReporting *smr, PoPs_Bcast_info *info, int index, PoPs *popsRoot );
24static int PoPs_Bcast_PoPs2( statusMessageReporting *smr, PoPs_Bcast_info *info, PoP *pop );
25static int PoPs_Bcast_int( statusMessageReporting *smr, PoPs_Bcast_info *info, int *value );
26static int PoPs_Bcast_charAllocate( statusMessageReporting *smr, PoPs_Bcast_info *info, char **value );
27static int PoPs_Bcast_double( statusMessageReporting *smr, PoPs_Bcast_info *info, double *value );
28/*
29========================================================================
30*/
31int PoPs_Bcast2( statusMessageReporting *smr, MPI_Comm comm, int bossRank, unitsDB *unitsRoot, PoPs *popsRoot ) {
32
33 int myRank, status;
34 int description[NumberOfBcastArrays];
35 PoPs_Bcast_info info = { PoPs_Bcast_mode_count, 0, 0, 0, NULL, NULL, NULL };
36
37 if( ( status = MPI_Errhandler_set( comm, MPI_ERRORS_RETURN ) ) != 0 ) return( status );
38/* New way but not on all systems yet.
39 if( ( status = MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN ) ) != 0 ) return( status );
40*/
41 if( ( status = MPI_Comm_rank( comm, &myRank ) ) != 0 ) return( status );
42
43 if( myRank == bossRank ) {
44 info.mode = PoPs_Bcast_mode_count;
45 if( ( status = PoPs_Bcast3( smr, comm, &info, unitsRoot, popsRoot ) ) != 0 ) return( status );
46 description[0] = info.int_count;
47 description[1] = info.char_count;
48 description[2] = info.double_count;
49 if( ( info.int_array = (int *) smr_malloc2( smr, info.int_count * sizeof( int ), 1, "info.int_array" ) ) == NULL ) goto err;
50 if( ( info.char_array = (char *) smr_malloc2( smr, info.char_count * sizeof( char ), 1, "info.char_array" ) ) == NULL ) goto err;
51 if( ( info.double_array = (double *) smr_malloc2( smr, info.double_count * sizeof( double ), 1, "info.double_array" ) ) == NULL ) goto err;
52
53 info.mode = PoPs_Bcast_mode_pack;
54 info.int_count = 0;
55 info.char_count = 0;
56 info.double_count = 0;
57 if( ( status = PoPs_Bcast3( smr, comm, &info, unitsRoot, popsRoot ) ) != 0 ) return( status );
58 if( info.int_count != description[0] ) {
59 smr_setReportError2( smr, PoPs_smr_ID, 1, "int counting count = %d != packing count = %d", info.int_count, description[0] );
60 goto err;
61 }
62 if( info.char_count != description[1] ) {
63 smr_setReportError2( smr, PoPs_smr_ID, 1, "char counting count = %d != packing count = %d", info.char_count, description[1] );
64 goto err;
65 }
66 if( info.double_count != description[2] ) {
67 smr_setReportError2( smr, PoPs_smr_ID, 1, "double counting count = %d != packing count = %d", info.double_count, description[2] );
68 goto err;
69 }
70 }
71
72 if( ( status = MPI_Bcast( description, NumberOfBcastArrays, MPI_INT, bossRank, comm ) ) != 0 ) goto err;
73
74 if( myRank != bossRank ) {
75 if( ( info.int_array = (int *) smr_malloc2( smr, description[0] * sizeof( int ), 1, "info.int_array (2)" ) ) == NULL ) goto err;
76 if( ( info.char_array = (char *) smr_malloc2( smr, description[1] * sizeof( char ), 1, "info.char_array (2)" ) ) == NULL ) goto err;
77 if( ( info.double_array = (double *) smr_malloc2( smr, description[2] * sizeof( double ), 1, "info.double_array (2)" ) ) == NULL ) goto err;
78 }
79 if( ( status = MPI_Bcast( info.int_array, description[0], MPI_INT, bossRank, comm ) ) != 0 ) goto err;
80 if( ( status = MPI_Bcast( info.char_array, description[1], MPI_CHAR, bossRank, comm ) ) != 0 ) goto err;
81 if( ( status = MPI_Bcast( info.double_array, description[2], MPI_DOUBLE, bossRank, comm ) ) != 0 ) goto err;
82
83 if( myRank != bossRank ) {
84 info.mode = PoPs_Bcast_mode_unpack;
85 if( ( status = PoPs_Bcast3( smr, comm, &info, unitsRoot, popsRoot ) ) != 0 ) goto err;
86 }
87
88 if( info.int_array != NULL ) smr_freeMemory( (void **) &(info.int_array) );
89 if( info.char_array != NULL ) smr_freeMemory( (void **) &(info.char_array) );
90 if( info.double_array != NULL ) smr_freeMemory( (void **) &(info.double_array) );
91
92 return( 0 );
93
94err:
95 if( info.int_array != NULL ) smr_freeMemory( (void **) &(info.int_array) );
96 if( info.char_array != NULL ) smr_freeMemory( (void **) &(info.char_array) );
97 if( info.double_array != NULL ) smr_freeMemory( (void **) &(info.double_array) );
98 if( unitsRoot->unsorted != NULL ) smr_freeMemory( (void **) &(unitsRoot->unsorted) );
99 if( popsRoot->pops != NULL ) smr_freeMemory( (void **) &(popsRoot->pops) );
100 if( popsRoot->sorted != NULL ) smr_freeMemory( (void **) &(popsRoot->sorted) );
101 return( -1 );
102}
103/*
104========================================================================
105*/
106static int PoPs_Bcast3( statusMessageReporting *smr, MPI_Comm comm, PoPs_Bcast_info *info, unitsDB *unitsRoot, PoPs *popsRoot ) {
107
108 int i, status, numberOfUnits, numberOfParticles;
109
110 if( info->mode == PoPs_Bcast_mode_unpack ) PoPs_releasePrivate( smr );
111 if( ( status = PoPs_Bcast_int( smr, info, &(unitsRoot->numberOfUnits) ) ) != 0 ) return( status );
112 numberOfUnits = unitsRoot->numberOfUnits;
113 if( info->mode == PoPs_Bcast_mode_unpack ) {
114 unitsRoot->allocated = unitsRoot->numberOfUnits;
115 unitsRoot->numberOfUnits = 0;
116 if( ( unitsRoot->unsorted = (char const **) smr_malloc2( smr, unitsRoot->allocated * sizeof( char const ** ), 1, "unitsRoot->unsorted" ) ) == NULL ) return( -1 );
117 }
118 for( i = 0; i < numberOfUnits; i++ ) {
119 if( ( status = PoPs_Bcast_charAllocate( smr, info, (char **) &(unitsRoot->unsorted[i]) ) ) != 0 ) return( status );
120 if( info->mode == PoPs_Bcast_mode_unpack ) unitsRoot->numberOfUnits++;
121 }
122
123 if( ( status = PoPs_Bcast_int( smr, info, &(popsRoot->numberOfParticles) ) ) != 0 ) return( status );
124 numberOfParticles = popsRoot->numberOfParticles;
125 if( info->mode == PoPs_Bcast_mode_unpack ) {
126 popsRoot->allocated = popsRoot->numberOfParticles;
127 popsRoot->numberOfParticles = 0;
128 if( ( popsRoot->pops = (PoP **) smr_malloc2( smr, popsRoot->allocated * sizeof( PoP * ), 1, "popsRoot->pops" ) ) == NULL ) return( -1 );
129 if( ( popsRoot->sorted = (PoP **) smr_malloc2( smr, popsRoot->allocated * sizeof( PoP * ), 1, "popsRoot->unsorted" ) ) == NULL ) return( -1 );
130 }
131 for( i = 0; i < numberOfParticles; i++ ) {
132 if( ( status = PoPs_Bcast_PoPs( smr, info, i, popsRoot ) ) != 0 ) return( status );
133 }
134 return( 0 );
135}
136/*
137========================================================================
138*/
139static int PoPs_Bcast_PoPs( statusMessageReporting *smr, PoPs_Bcast_info *info, int index, PoPs *popsRoot ) {
140
141 int status;
142 PoP pop;
143
144 if( info->mode != PoPs_Bcast_mode_unpack ) return( PoPs_Bcast_PoPs2( smr, info, popsRoot->pops[index] ) );
145 if( ( status = PoPs_Bcast_PoPs2( smr, info, &pop ) ) != 0 ) return( status );
146 return( 0 );
147}
148/*
149========================================================================
150*/
151static int PoPs_Bcast_PoPs2( statusMessageReporting *smr, PoPs_Bcast_info *info, PoP *pop ) {
152
153 int status, n = 0;
154
155 if( ( status = PoPs_Bcast_int( smr, info, &(pop->index) ) ) != 0 ) return( status );
156 if( ( status = PoPs_Bcast_int( smr, info, &(pop->properIndex) ) ) != 0 ) return( status );
157 if( ( status = PoPs_Bcast_int( smr, info, &(pop->aliasIndex) ) ) != 0 ) return( status ); /* Not needed, see below. */
158 if( ( status = PoPs_Bcast_int( smr, info, (int *) &(pop->genre) ) ) != 0 ) return( status );
159
160 if( ( status = PoPs_Bcast_int( smr, info, &(pop->Z) ) ) != 0 ) return( status );
161 if( ( status = PoPs_Bcast_int( smr, info, &(pop->A) ) ) != 0 ) return( status );
162 if( ( status = PoPs_Bcast_int( smr, info, &(pop->l) ) ) != 0 ) return( status );
163 if( ( status = PoPs_Bcast_double( smr, info, &(pop->mass) ) ) != 0 ) return( status );
164
165 if( info->mode == PoPs_Bcast_mode_pack ) {
166 n = -1;
167 if( pop->massUnit != NULL ) {
168 if( ( n = unitsDB_index( smr, pop->massUnit ) ) < 0 ) return( n );
169 }
170 }
171 if( ( status = PoPs_Bcast_int( smr, info, &n ) ) != 0 ) return( status );
172 if( ( status = PoPs_Bcast_charAllocate( smr, info, (char **) &(pop->name) ) ) != 0 ) return( status );
173
174 if( info->mode == PoPs_Bcast_mode_unpack ) {
175 pop->aliasIndex = -1; /* Reset here as it will be set in PoPs_addParticleIfNeeded via PoPs_copyAddParticleIfNeeded. */
176
177 if( n < 0 ) {
178 pop->massUnit = NULL; }
179 else {
180 if( ( pop->massUnit = unitsDB_stringFromIndex( smr, n ) ) == NULL ) goto err;
181 }
182 if( PoPs_copyAddParticleIfNeeded( smr, pop ) == NULL ) goto err;
183
184 if( pop->name != NULL ) smr_freeMemory( (void **) &(pop->name) );
185 }
186
187 return( 0 );
188
189err:
190 if( info->mode == PoPs_Bcast_mode_unpack ) {
191 if( pop->name != NULL ) smr_freeMemory( (void **) &(pop->name) );
192 }
193 return( -1 );
194}
195/*
196========================================================================
197*/
198static int PoPs_Bcast_int( statusMessageReporting *smr, PoPs_Bcast_info *info, int *value ) {
199
200 if( info->mode == PoPs_Bcast_mode_pack ) {
201 info->int_array[info->int_count] = *value; }
202 else if( info->mode == PoPs_Bcast_mode_unpack ) {
203 *value = info->int_array[info->int_count];
204 }
205 info->int_count++;
206 return( 0 );
207}
208/*
209========================================================================
210*/
211static int PoPs_Bcast_charAllocate( statusMessageReporting *smr, PoPs_Bcast_info *info, char **value ) {
212
213 int i, n = 0, status;
214
215 if( info->mode != PoPs_Bcast_mode_unpack ) {
216 n = (int) strlen( *value ) + 1;
217 if( ( status = PoPs_Bcast_int( smr, info, &n ) ) != 0 ) return( status );
218 if( info->mode == PoPs_Bcast_mode_pack ) {
219 for( i = 0; i < n; i++ ) info->char_array[info->char_count + i] = (*value)[i];
220 } }
221 else {
222 if( ( status = PoPs_Bcast_int( smr, info, &n ) ) != 0 ) return( status );
223 if( ( *value = (char *) smr_malloc2( smr, n * sizeof( char ), 0, "*value" ) ) == NULL ) return( -1 );
224 for( i = 0; i < n; i++ ) (*value)[i] = info->char_array[info->char_count + i];
225 }
226 info->char_count += n;
227
228 return( 0 );
229}
230/*
231========================================================================
232*/
233static int PoPs_Bcast_double( statusMessageReporting *smr, PoPs_Bcast_info *info, double *value ) {
234
235 if( info->mode == PoPs_Bcast_mode_pack ) {
236 info->double_array[info->double_count] = *value; }
237 else if( info->mode == PoPs_Bcast_mode_unpack ) {
238 *value = info->double_array[info->double_count];
239 }
240 info->double_count++;
241 return( 0 );
242}
243#endif /* End of #ifdef PoPs_MPI */
int PoPs_smr_ID
Definition PoPs.cc:35
PoP * PoPs_copyAddParticleIfNeeded(statusMessageReporting *smr, PoP *pop)
Definition PoPs.cc:153
int PoPs_Bcast2(statusMessageReporting *smr, MPI_Comm comm, int bossRank, unitsDB *unitsRoot, PoPs *popsRoot)
int PoPs_releasePrivate(statusMessageReporting *smr)
Definition PoPs.cc:98
char const * unitsDB_stringFromIndex(statusMessageReporting *smr, int index)
Definition PoPs.cc:737
int unitsDB_index(statusMessageReporting *smr, char const *unit)
Definition PoPs.cc:725
#define smr_setReportError2(smr, libraryID, code, fmt,...)
void * smr_freeMemory(void **p)
#define smr_malloc2(smr, size, zero, forItem)
Definition PoPs.h:45
int aliasIndex
Definition PoPs.h:46
int Z
Definition PoPs.h:49
int properIndex
Definition PoPs.h:46
char const * massUnit
Definition PoPs.h:51
enum PoPs_genre genre
Definition PoPs.h:47
char const * name
Definition PoPs.h:48
double mass
Definition PoPs.h:50
int l
Definition PoPs.h:49
int index
Definition PoPs.h:46
int A
Definition PoPs.h:49
int allocated
PoP ** pops
int numberOfParticles
PoP ** sorted
int numberOfUnits
char const ** unsorted