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