-
Notifications
You must be signed in to change notification settings - Fork 63
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
Output cleanup -- release as many file resources as possible when they are no longer needed #722
base: master
Are you sure you want to change the base?
Changes from all commits
1b5fc82
e2546d4
7102588
d64795d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,13 @@ namespace utils | |
stream->open(path, std::ios::trunc); | ||
output_stream = stream; | ||
} | ||
virtual ~FileStreamHandler(){} | ||
|
||
virtual ~FileStreamHandler() override { | ||
auto tmp = std::static_pointer_cast<std::ofstream>(output_stream); | ||
if(tmp){ | ||
tmp->close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is needed, unless we were checking the failbit. When There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not remembering exactly why I did this (that's what I get for leaving it sitting in my working tree for so long 😵💫). I think you are correct, and this may be an artifact of some early attempts to ensure the files were were closed but due to the shared references of formulations they were not and it took me a while to sort that out haha. I'll take a closer look and remove this if it isn't being useful. |
||
} | ||
} | ||
}; | ||
|
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -539,6 +539,17 @@ int main(int argc, char *argv[]) { | |
|
||
} //done time | ||
|
||
//Close down any file handles we have | ||
for(auto& f : nexus_outfiles){ | ||
f.second.close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to below, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nexus output handling is still pretty rough, there's been a long standing TODO to refactor it -- but its been pretty low priority. |
||
} | ||
//std::cout<<"Clearning manger with "<<manager.use_count()<<" references\n"; | ||
//Need to release all formulation references, those stored in hy_features object and the | ||
//references used by the formulation manager | ||
//this will ensure all formulation destructors are called and resources released. | ||
features.release_formulations(); | ||
manager->clear(); | ||
Comment on lines
+550
to
+551
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm not understanding it, what's the reason for using shared pointers if we're going to handle manually decrementing the reference counts anyways? It would make more sense to put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jumping around here in my responses, but they are all somewhat related.
The formulation manager (which superseded the network indexing I'll discuss momentarily) exists entirely to abstract and encapsulate the parsing, configuring, and instantiation of formulations, i.e. ready to execute models associated with some feature. It does this reasonalby well, and ultimately creates a I'm not sure if that helped in understanding or not. I can try to articulate that more completely if needed. To your point on using RAII blocks...yes, that would be one solution. The functions to explicitly release the resources by clearing the underlying maps that hold the references are another. Having these functions provides some additional flexibility beyond relying on the RAII blocks, though. For example, a |
||
|
||
#if NGEN_MPI_ACTIVE | ||
MPI_Barrier(MPI_COMM_WORLD); | ||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to use pointers anyways, why not just use
std::ostream
classes directly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StreamHandler is a bit of an abstract wrapper around
ostream
...the original intent was the ability to have an abstract output interface that was easily connected to existing mechanics (like ofstream for csv/file output) but also be able to implement more complicated output mechanics, such as writing to NetCDF, using the same stream operator/semantics and have a simple way of reconfiguring and switching between these using the base StreamHandler interface.This could definitely evolve and change.
I think the reason I moved these to unique pointers was to provide some protection against pass by value copies, but I could be wrong on that motivation. I know I definitely wanted to ensure that a given formulation/realization was only ever associated with a single output resource that was tightly tied to it its lifecycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside to actually reviewing this PR, I'm pretty sure we should just make
StreamHandler
go away.