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

#9000 - Average values for integer output variables fail debug assert and are rounded to 1 place #9294

Merged
merged 7 commits into from
Mar 21, 2022

Conversation

jmarrec
Copy link
Contributor

@jmarrec jmarrec commented Feb 22, 2022

Pull request overview

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@jmarrec jmarrec added the Defect Includes code to repair a defect in EnergyPlus label Feb 22, 2022
@jmarrec jmarrec self-assigned this Feb 22, 2022
@Myoldmopar
Copy link
Member

This is definitely an improvement, and although we can have a broader discussion about the output significance, this one issue is not widespread in any sense of the word, and we should just take this cleanup as soon as it's ready.

@jmarrec jmarrec added the NotIDDChange Code does not impact IDD (can be merged after IO freeze) label Feb 22, 2022
Comment on lines 385 to 388
// We'll be formating a number between -1 and 1 as scientific notation, so we want some amount of decimals to be meaningful
if (specs_.precision == -1) {
specs_.precision = 4;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the N case, default to precision = 4.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose if we were fine with having around 6 precision, we could delete that block and let fmt default it in the Z case which it forwards to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wouldn't care either way, but I think it's reasonable, and we don't need to belabor this corner case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the default precision for the Fortran output? This whole code is to emulate Fortran output styles within the fmt library.

Comment on lines 278 to 280
} else if (specs_.precision != -1) {
// We need AT LEAST one in precision so we capture a '.' below
// If specs_.precision is -1, we don't need to do anything, keep the fmt defaults which are sane
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Z case, if the precision wasn't set already, then let fmt default it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, if we want control then we just need to be explicit about the precision we want.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the default precision for the Fortran output? This whole code is to emulate Fortran output styles within the fmt library.

@@ -4644,7 +4644,7 @@ namespace OutputProcessor {
NumberOut = "0.0";
} else {
NumberOut = format("{:N}", repVal);
strip_trailing_zeros(trim(NumberOut));
strip_trailing_zeros(strip(NumberOut));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual crash. v9.3.0 uses strip. Then during the move away from gio::write, it was first removed then added back as trim instead of strip

cf

strip_trailing_zeros(strip(NumberOut));

5dee4a2#diff-bd9d5281a7fe99bacbcd3d7112772f7804d8e091f10a56a0954a7639c24384fcR4946

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines 177 to 181
// Tested with E+ 9.3.0
EXPECT_EQ(format("{:N}", 0.03576388888888889), " 0.3576E-01");
EXPECT_EQ(format("{:.3N}", 0.03576388888888889), "0.358E-01");
EXPECT_EQ(format("{:.4N}", 0.03576388888888889), "0.3576E-01");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New format test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It says in the comments "Tested with E+ 9.3.0", does that mean NumberOut below will be "0.3576E-01"?

ObjexxFCL::gio::Fmt fmtLD("*");
std::string NumberOut;
ObjexxFCL::gio::write(NumberOut, fmtLD) << repVal;
strip_trailing_zeros(strip(NumberOut));

Comment on lines 1086 to 1087
WriteReportIntegerData(*state, 1, "1", 25.75, StoreType::Averaged, 720, ReportingFrequency::Monthly, 0, 4010115, 1, 4011560);
EXPECT_TRUE(compare_eso_stream(delimited_string({"1,0.3576E-01,0, 1, 1,15,1, 1,15,60"}, "\n")));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This triggered the assert throw in debug mode before.

Comment on lines 278 to 280
} else if (specs_.precision != -1) {
// We need AT LEAST one in precision so we capture a '.' below
// If specs_.precision is -1, we don't need to do anything, keep the fmt defaults which are sane
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, if we want control then we just need to be explicit about the precision we want.

Comment on lines 385 to 388
// We'll be formating a number between -1 and 1 as scientific notation, so we want some amount of decimals to be meaningful
if (specs_.precision == -1) {
specs_.precision = 4;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wouldn't care either way, but I think it's reasonable, and we don't need to belabor this corner case.

@@ -4644,7 +4644,7 @@ namespace OutputProcessor {
NumberOut = "0.0";
} else {
NumberOut = format("{:N}", repVal);
strip_trailing_zeros(trim(NumberOut));
strip_trailing_zeros(strip(NumberOut));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Myoldmopar
Copy link
Member

I'll go ahead and let the integration debug build finish but assuming it is fine then I'll merge this. Thanks for the fix @jmarrec and the unit test and walkthrough.

Copy link
Contributor

@mbadams5 mbadams5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My overall comment is to make sure these changes are inline with Fortran output style. Since I said in my individual comments that this code is solely to emulate Fortran output within the fmt library. Turner originally wrote this code when he converted the GIO output to FMT.

If NumberOut should have a different precision or output style than Fortran, it might be better to just change it to a true fmt::format("Foo", repVal); instead of using this shim.

Comment on lines 177 to 181
// Tested with E+ 9.3.0
EXPECT_EQ(format("{:N}", 0.03576388888888889), " 0.3576E-01");
EXPECT_EQ(format("{:.3N}", 0.03576388888888889), "0.358E-01");
EXPECT_EQ(format("{:.4N}", 0.03576388888888889), "0.3576E-01");

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It says in the comments "Tested with E+ 9.3.0", does that mean NumberOut below will be "0.3576E-01"?

ObjexxFCL::gio::Fmt fmtLD("*");
std::string NumberOut;
ObjexxFCL::gio::write(NumberOut, fmtLD) << repVal;
strip_trailing_zeros(strip(NumberOut));

Comment on lines 385 to 388
// We'll be formating a number between -1 and 1 as scientific notation, so we want some amount of decimals to be meaningful
if (specs_.precision == -1) {
specs_.precision = 4;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the default precision for the Fortran output? This whole code is to emulate Fortran output styles within the fmt library.

Comment on lines 278 to 280
} else if (specs_.precision != -1) {
// We need AT LEAST one in precision so we capture a '.' below
// If specs_.precision is -1, we don't need to do anything, keep the fmt defaults which are sane
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the default precision for the Fortran output? This whole code is to emulate Fortran output styles within the fmt library.

@Myoldmopar
Copy link
Member

My overall comment is to make sure these changes are inline with Fortran output style.

I hope that's no longer the guiding principle. I would just say let's make sensible output, not try too hard to match Fortran.

@mbadams5
Copy link
Contributor

I don't think we should write new code using the Fortran syntax either. Which is why I suggested rewriting NumberOut = format("{:N}", repVal); to use true FMT syntax NumberOut = fmt::format("{:something.something}", repVal); instead of changing the Fortran shim since we have good coverage of output changes but obviously not complete given the issue this PR is solving.

@Myoldmopar Myoldmopar added this to the EnergyPlus 22.1 milestone Feb 28, 2022
@mjwitte
Copy link
Contributor

mjwitte commented Mar 15, 2022

Looks like @Myoldmopar approved this and was ready to merge, but then @mbadams5 made some further comments.
Is this ready or waiting on further changes?

@Myoldmopar
Copy link
Member

OK, so in an effort to get this merged in, I reverted out the two latter commits which modified the output reporting. This PR now just includes the unit test demonstrating the issue (that initially fails) plus the tiny code change to get the unit test passing. We can have discussions about how to handle the other changes later, but I'd like to get this defect fixed at least.

I then pulled develop in, ran tests, including regressions, and it was entirely clean. I'm inclined to wait for CI to verify that for me since I ran just one release build on just Linux. I'll move on to other PRs while CI catches up here and go from there.

@Myoldmopar
Copy link
Member

Looking good so far, I'll let the unit test debug build run, and I'll let the debug integration tests at least get started before merging.

@Myoldmopar
Copy link
Member

No issues here, merging this in. Won't cause any diffs for the rainfall PR which is staged for next merge.

@Myoldmopar Myoldmopar merged commit d016c0a into develop Mar 21, 2022
@Myoldmopar Myoldmopar deleted the 9000_WriteReportIntegerData branch March 21, 2022 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Includes code to repair a defect in EnergyPlus NotIDDChange Code does not impact IDD (can be merged after IO freeze)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Average values for integer output variables fail debug assert and are rounded to 2 places
8 participants