| 279 | } |
| 280 | |
| 281 | void LoopStatistics::writeSamples(const std::string& outputPrefix, |
| 282 | bool isLoopStatisticsNetcdfOutputOn) { |
| 283 | if (isLoopStatisticsNetcdfOutputOn) { |
| 284 | const auto loopStatFile = outputPrefix + "-loopStat-"; |
| 285 | const auto rank = MPI::mpi.rank(); |
| 286 | #if defined(USE_NETCDF) && defined(USE_MPI) |
| 287 | logInfo(rank) << "Starting to write loop statistics samples to disk."; |
| 288 | const unsigned nRegions = regions.size(); |
| 289 | for (unsigned region = 0; region < nRegions; ++region) { |
| 290 | const std::ofstream file; |
| 291 | std::stringstream ss; |
| 292 | ss << loopStatFile << regions[region].name << ".nc"; |
| 293 | const std::string fileName = ss.str(); |
| 294 | |
| 295 | long nSamples = regions[region].times.size(); |
| 296 | long sampleOffset = 0; |
| 297 | MPI_Scan(&nSamples, &sampleOffset, 1, MPI_LONG, MPI_SUM, MPI::mpi.comm()); |
| 298 | |
| 299 | int ncid = 0; |
| 300 | int stat = 0; |
| 301 | stat = nc_create_par(fileName.c_str(), |
| 302 | NC_MPIIO | NC_CLOBBER | NC_NETCDF4, |
| 303 | MPI::mpi.comm(), |
| 304 | MPI_INFO_NULL, |
| 305 | &ncid); |
| 306 | check_err(stat, __LINE__, __FILE__); |
| 307 | |
| 308 | int sampledim = 0; |
| 309 | int rankdim = 0; |
| 310 | int timespectyp = 0; |
| 311 | int sampletyp = 0; |
| 312 | int offsetid = 0; |
| 313 | int sampleid = 0; |
| 314 | |
| 315 | stat = nc_def_dim(ncid, "rank", 1 + MPI::mpi.size(), &rankdim); |
| 316 | check_err(stat, __LINE__, __FILE__); |
| 317 | stat = nc_def_dim(ncid, "sample", NC_UNLIMITED, &sampledim); |
| 318 | check_err(stat, __LINE__, __FILE__); |
| 319 | |
| 320 | stat = nc_def_compound(ncid, sizeof(timespec), "timespec", ×pectyp); |
| 321 | check_err(stat, __LINE__, __FILE__); |
| 322 | { |
| 323 | stat = nc_insert_compound(ncid, |
| 324 | timespectyp, |
| 325 | "sec", |
| 326 | NC_COMPOUND_OFFSET(timespec, tv_sec), |
| 327 | type2nc<decltype(timespec::tv_sec)>()); |
| 328 | check_err(stat, __LINE__, __FILE__); |
| 329 | stat = nc_insert_compound(ncid, |
| 330 | timespectyp, |
| 331 | "nsec", |
| 332 | NC_COMPOUND_OFFSET(timespec, tv_nsec), |
| 333 | type2nc<decltype(timespec::tv_nsec)>()); |
| 334 | check_err(stat, __LINE__, __FILE__); |
| 335 | } |
| 336 | |
| 337 | stat = nc_def_compound(ncid, sizeof(Sample), "Sample", &sampletyp); |
| 338 | check_err(stat, __LINE__, __FILE__); |