Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to SEACAS-Snapshot-01-2025 #13782

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions packages/seacas/libraries/exodus/src/ex_get_init_ext.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright(C) 1999-2022, 2024 National Technology & Engineering Solutions
* Copyright(C) 1999-2022, 2024, 2025 National Technology & Engineering Solutions
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
* NTESS, the U.S. Government retains certain rights in this software.
*
Expand Down Expand Up @@ -28,14 +28,21 @@ static void exi_get_entity_count(int exoid, ex_init_params *info)
{
int include_parent_group = 0; // Only want dims in current group
int ndims = 0;
#if NC_HAS_NC4
nc_inq_dimids(exoid, &ndims, NULL, include_parent_group);
int *dimids = calloc(ndims, sizeof(int));
nc_inq_dimids(exoid, &ndims, dimids, include_parent_group);

#else
nc_inq(exoid, &ndims, NULL, NULL, NULL);
#endif
for (int dimid = 0; dimid < ndims; dimid++) {
char dim_nm[NC_MAX_NAME + 1] = {'\0'};
size_t dim_sz;
#if NC_HAS_NC4
nc_inq_dim(exoid, dimids[dimid], dim_nm, &dim_sz);
#else
nc_inq_dim(exoid, dimid, dim_nm, &dim_sz);
#endif
/* For assemblies, we check for a dim starting with "num_entity_assembly" */
if (strncmp(dim_nm, "num_entity_assembly", 19) == 0) {
info->num_assembly++;
Expand All @@ -44,7 +51,9 @@ static void exi_get_entity_count(int exoid, ex_init_params *info)
info->num_blob++;
}
}
#if NC_HAS_NC4
free(dimids);
#endif
}

/* Used to reduce repeated code below */
Expand Down
113 changes: 59 additions & 54 deletions packages/seacas/libraries/ioss/src/exodus/Ioex_DatabaseIO.C
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright(C) 1999-2024 National Technology & Engineering Solutions
// Copyright(C) 1999-2025 National Technology & Engineering Solutions
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
// NTESS, the U.S. Government retains certain rights in this software.
//
Expand Down Expand Up @@ -731,60 +731,65 @@ namespace Ioex {
{
Ioss::SerializeIO serializeIO_(this);
timestepCount = ex_inquire_int(get_file_pointer(), EX_INQ_TIME);
int exTimestepCount = timestepCount;
// Need to sync timestep count across ranks if parallel...
if (isParallel) {
auto min_timestep_count =
util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MIN);
if (min_timestep_count == 0) {
auto max_timestep_count =
util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MAX);
if (max_timestep_count != 0) {
if (myProcessor == 0) {
// NOTE: Don't want to warn on all processors if the
// timestep count is zero on some, but not all ranks.
fmt::print(Ioss::WarnOut(),
"At least one database has no timesteps. No times will be read on ANY"
" database for consistency.\n");
}
}
}
timestepCount = min_timestep_count;
}

if (timestepCount <= 0) {
return tsteps;
}

// For an exodus file, timesteps are global and are stored in the region.
// Read the timesteps and add to the region
tsteps.resize(exTimestepCount, -std::numeric_limits<double>::max());

// The `EXODUS_CALL_GET_ALL_TIMES=NO` is typically only used in
// isSerialParallel mode and the client is responsible for
// making sure that the step times are handled correctly. All
// databases will know about the number of timesteps, but if
// this is skipped, then the times will all be zero. Use case
// is that in isSerialParallel, each call to
// `ex_get_all_times` for all files is performed sequentially,
// so if you have hundreds to thousands of files, the time for
// the call is additive and since timesteps are record
// variables in netCDF, accessing the data for all timesteps
// involves lseeks throughout the file.
bool call_ex_get_all_times = true;
Ioss::Utils::check_set_bool_property(properties, "EXODUS_CALL_GET_ALL_TIMES",
call_ex_get_all_times);
if (call_ex_get_all_times) {
int error = ex_get_all_times(get_file_pointer(), Data(tsteps));
if (error < 0) {
Ioex::exodus_error(get_file_pointer(), __LINE__, __func__, __FILE__);
}
}

// See if the "last_written_time" attribute exists and if it
// does, check that it matches the largest time in 'tsteps'.
exists = Ioex::read_last_time_attribute(get_file_pointer(), &last_time);
}
int exTimestepCount = timestepCount;
// Need to sync timestep count across ranks if parallel...
if (isParallel) {
auto min_timestep_count =
util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MIN);
if (min_timestep_count == 0) {
auto max_timestep_count =
util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MAX);
if (max_timestep_count != 0) {
if (myProcessor == 0) {
// NOTE: Don't want to warn on all processors if the
// timestep count is zero on some, but not all ranks.
fmt::print(Ioss::WarnOut(),
"At least one database has no timesteps. No times will be read on ANY"
" database for consistency.\n");
}
}
}
timestepCount = min_timestep_count;
}

if (timestepCount <= 0) {
return tsteps;
}

// For an exodus file, timesteps are global and are stored in the region.
// Read the timesteps and add to the region
tsteps.resize(exTimestepCount, -std::numeric_limits<double>::max());

// The `EXODUS_CALL_GET_ALL_TIMES=NO` is typically only used in
// isSerialParallel mode and the client is responsible for
// making sure that the step times are handled correctly. All
// databases will know about the number of timesteps, but if
// this is skipped, then the times will all be zero. Use case
// is that in isSerialParallel, each call to
// `ex_get_all_times` for all files is performed sequentially,
// so if you have hundreds to thousands of files, the time for
// the call is additive and since timesteps are record
// variables in netCDF, accessing the data for all timesteps
// involves lseeks throughout the file.
bool call_ex_get_all_times = true;
Ioss::Utils::check_set_bool_property(properties, "EXODUS_CALL_GET_ALL_TIMES",
call_ex_get_all_times);
if (call_ex_get_all_times) {
Ioss::SerializeIO serializeIO_(this);
int error = ex_get_all_times(get_file_pointer(), Data(tsteps));
if (error < 0) {
Ioex::exodus_error(get_file_pointer(), __LINE__, __func__, __FILE__);
}
}

// See if the "last_written_time" attribute exists and if it
// does, check that it matches the largest time in 'tsteps'.
{
Ioss::SerializeIO serializeIO_(this);
exists = Ioex::read_last_time_attribute(get_file_pointer(), &last_time);
}

if (exists && isParallel) {
// Assume that if it exists on 1 processor, it exists on
// all... Sync value among processors since could have a
Expand Down
Loading