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

Improve performance for file reading/writing #8996

Merged
merged 60 commits into from
Sep 3, 2021
Merged

Conversation

mbadams5
Copy link
Contributor

Pull request overview

This pull request grew from its initial scope to something quite large. This PR focused mostly on improving performance when reading and writing files, including Schedule:File, Schedule:File:Shading, EPW weather files, epJSON, and more.

This PR also improves performance in other portions of the code, such as strings to integers and doubles.

Another large change is moving FMT library from 6.1.2 to 8.0.1, which required understanding the custom Fortran formatting code and adapting it to the new FMT api for custom formatting.

The performance improvements can be seen in the tables below:

HybridZoneModel_shadow113.idf
Develop (ms) Branch (ms) Runtime Reduction
Overall 41130 4190 89.8%
ProcessScheduleInput 35350 355 99.0%
ReadEPlusWeatherForDay 964 26 97.3%
InterpretWeatherDataLine 935 10 98.9%
commonRun 325 104 68.0%
WriteTimeStampFormatData 120 80 33.3%
WriteNumericData 71 57 19.7%
SetCurrentWeather 340 176 48.2%
ProcessNumber 528 1 99.8%
HybridZoneModel.idf
Develop (ms) Branch (ms) Runtime Reduction
Overall 4400 3490 20.7%
ProcessScheduleInput 164 38 76.8%
ReadEPlusWeatherForDay 828 33 96.0%
InterpretWeatherDataLine 809 10 98.8%
commonRun 261 97 62.8%
WriteTimeStampFormatData 104 69 33.7%
WriteNumericData 68 62 8.8%
SetCurrentWeather 273 151 44.7%
ProcessNumber 36 3 91.7%

NOTE: ENHANCEMENTS MUST FOLLOW A SUBMISSION PROCESS INCLUDING A FEATURE PROPOSAL AND DESIGN DOCUMENT PRIOR TO SUBMITTING CODE

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

# Conflicts:
#	src/ConvertInputFormat/main.cpp
#	src/EnergyPlus/AirflowNetworkBalanceManager.cc
#	src/EnergyPlus/DaylightingManager.cc
#	src/EnergyPlus/GroundHeatExchangers.cc
#	src/EnergyPlus/HeatBalanceIntRadExchange.cc
#	src/EnergyPlus/InputProcessing/IdfParser.cc
#	src/EnergyPlus/InternalHeatGains.cc
#	src/EnergyPlus/OutputReportTabular.hh
#	src/EnergyPlus/OutputReports.cc
#	tst/EnergyPlus/unit/PVWatts.unit.cc
@mbadams5 mbadams5 added the Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus label Aug 23, 2021
@mbadams5 mbadams5 added this to the EnergyPlus 9.6 Release milestone Aug 23, 2021
@mbadams5 mbadams5 requested a review from Myoldmopar August 23, 2021 16:33
mbadams5 and others added 23 commits August 25, 2021 01:26
New schedule:file parser is more strict
Changed "z" in LocalEnvData.csv to 0 to match previous implementation
Gtest is more strict about exact matching or something now too for other
unit test
This was causing issues with std::string_view and fmt to some extent
This is a hacky solution for now to just create a string but it would
be good to avoid the string creation if possible
It wasn't implicitly converting the iterator to a pointer
This uses the data() call which is a const char * to accomplish the same
effect
This was causing build errors on MSVC due to ambiguity in FMT and Objexx
# Conflicts:
#	src/EnergyPlus/InputProcessing/InputProcessor.cc
Apparently MSVC doesn't like this being unique_ptr since something, somewhere is terminating the pointer but then tries to delete it again.....? Anyways, changing this to shared_ptr since it won't delete until all references are 0. The original code was a memory leak (although probably not a bad one).
Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

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

This is littered with great stuff. There are 836 files changed, so obviously I'm not going to be able to go line by line. The changes I have looked over look great though, and CI is very happy. I think this is ready to go.

@@ -152,7 +152,7 @@ class Data:


def parse_idd(data):
root = {'$schema': "http://json-schema.org/draft-04/schema#", 'properties': {}}
root = {'$schema': "https://json-schema.org/draft-07/schema#", 'properties': {}}
Copy link
Member

Choose a reason for hiding this comment

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

What are the implications of changing to draft 7? Does it unlock more capabilities in the schema?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it does. There was only 1 minor change needed to update our schema to draft 7 (exclusiveMinimum and exclusiveMaximum are now values instead of boolean, basically you put either minimum or exclusiveMinimum, not both, now).

@@ -19,7 +19,7 @@ int main( int argc, char const *argv[] )
auto const input_json = json::parse( schema_stream );
auto const v_cbor = json::to_cbor( input_json );

printf(" const static std::array< std::uint8_t, %zu > embeddedSchema = {{\n", v_cbor.size() );
printf(" static constexpr std::array< std::uint8_t, %zu > embeddedSchema = {{\n", v_cbor.size() );
Copy link
Member

Choose a reason for hiding this comment

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

Does this have any impact on performance or is it just more appropriate?

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 don't think it affects performance, however, it can be used in constexpr functions now (It likely could have before, but I haven't tested or read to see if that is true)

@@ -312,9 +312,9 @@ void BaseSizer::reportSizerOutput(EnergyPlusData &state,
Optional<Real64 const> UsrValue)
{

static constexpr fmt::string_view Format_990(
static constexpr std::string_view Format_990(
Copy link
Member

Choose a reason for hiding this comment

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

👍

@@ -798,7 +798,7 @@ namespace AirLoopHVACDOAS {
}
AirLoopMixer thisAirLoopMixer;
thisDOAS.m_CompPointerAirLoopMixer = thisAirLoopMixer.factory(state, thisDOAS.m_AirLoopMixerIndex, thisDOAS.AirLoopMixerName);
thisDOAS.AirLoopSplitterName = UtilityRoutines::MakeUPPERCase(AsString(fields.at("airloophvac_splitter_name"))); //
thisDOAS.AirLoopSplitterName = UtilityRoutines::MakeUPPERCase(fields.at("airloophvac_splitter_name").get<std::string>()); //
Copy link
Member

Choose a reason for hiding this comment

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

Much nicer.

str.remove_prefix(first_char);
}
double result = 0;
auto answer = fast_float::from_chars(str.data(), str.data() + str.size(), result);
Copy link
Member

Choose a reason for hiding this comment

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

👍

RE2 *pattern;
RE2 *case_insensitive_pattern;
std::shared_ptr<RE2> pattern = nullptr;
std::shared_ptr<RE2> case_insensitive_pattern = nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

This will be helpful 👍


template <FileTypes fileType> std::string getJSON(const nlohmann::json &data, int const indent = 4)
{
if constexpr (is_json_type(fileType)) {
Copy link
Member

Choose a reason for hiding this comment

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

Nice.

static constexpr std::array<std::string_view, NumSingleChars>SingleChars{"/", ":", "-"};
static constexpr int NumDoubleChars(6);
static constexpr std::array<std::string_view, NumDoubleChars> DoubleChars{"ST ", "ND ", "RD ", "TH ", "OF ", "IN "}; // Need trailing spaces: Want thse only at end of words
static constexpr std::array<std::string_view, 12> Months{"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
Copy link
Member

Choose a reason for hiding this comment

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

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants