-
Notifications
You must be signed in to change notification settings - Fork 35
Tupek/gretl refactor #1432
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
Open
tupek2
wants to merge
68
commits into
develop
Choose a base branch
from
tupek/gretl_refactor
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Tupek/gretl refactor #1432
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
4ccb49e
Initial gretl in serac. Need to work on some tests, maybe documentin…
tupek2 77b56ab
Revert back to original gretl.
tupek2 f7e758b
--amend
tupek2 c19b7ba
Trying to get original checkpoint tests passing again.
tupek2 4ec0b48
Operation gretl again.
tupek2 b72a057
Make it a bit less likely toa accidentally no specify a valid zero_du…
tupek2 ae86ce3
Additional cleanup of compilation warnings.
tupek2 0746ec4
Add in a highly nonlinear and more complicated graph.
tupek2 1ce7e8d
Add in a highly nonlinear and more complicated graph.
tupek2 2490a51
Get test tolerance in place.
tupek2 471dfa5
Fix style.
tupek2 a928494
Try to fix some gcc build issues.
tupek2 449b438
Fix another gcc issue.
tupek2 bb271cf
add all headers to cmake lists.
tupek2 dbe1feb
Another header missing.
tupek2 f5898c5
Another gcc build fix.
tupek2 be0ea51
Try again to fix gcc13 warnings.
tupek2 96fcff9
Trying to address gcc issues.
tupek2 37c76a7
Try to fix gcc warnings.
tupek2 61fd848
Try again to resolve gcc warning.
tupek2 44107f6
Debugging gretl.
tupek2 c90d23f
Trying to simplify gretl.
tupek2 0469141
Simplifying gretl implementation, no checkpointing yet.
tupek2 ba58d95
Seemingly got gretl, no checkpoint working again.
tupek2 02c56fd
Cleanup the initial, not dynamically checkpointed gretl.
tupek2 37c7340
Remove some prints, only clear shared pointer if no one else has a ha…
tupek2 ddee2ce
style.
tupek2 80d7b4d
Fix build.
tupek2 fce33b1
Fix style.
tupek2 094c1d0
Fix style.
tupek2 0474505
Trying to work out the dynamic checkpointing interface.
tupek2 5a7c418
Working toward dynamic implementation.
tupek2 1cb451f
Working toward gretl redesign.
tupek2 fa0e7cf
Get gretl tests working again with backend refactor.
tupek2 9e2b7a9
Cleanup some prints.
tupek2 feb37e1
Get test passing again.
tupek2 e6ce787
Nearly working dynamic checkpointing. forward pass looks to be correct.
tupek2 6206f9e
still seeming have forward part operating... need to figure out rever…
tupek2 065a335
Trying to manage the counting of the pass through states.
tupek2 0b72bd6
Progressing on graph dynamic checkpointing.
tupek2 c6078f6
Trying to be more careful tracking states and their passthroughts.
tupek2 457a261
Progress on checkpointing.
tupek2 1cc225b
Just have a single data store... we can make the Checkpointmanager vi…
tupek2 dda8d50
style.
tupek2 19a6bed
Get all checkpointing tests working again after refactor.
tupek2 bd16a6b
Remove some prints
tupek2 6458244
Fix some warnings and small cleanups.
tupek2 ea31d01
Get optimizations in. Need to document and figure out how to test co…
tupek2 40b10a6
Some more internal asserts to ensure correctness.
tupek2 b648971
Get other test working.
tupek2 0d0fb7a
Remove comments.
tupek2 1b7366d
Fix style.
tupek2 450e7b9
Working on documenting the gretl interface a bit more.
tupek2 3118646
Fix style and docs.
tupek2 13440ea
Fix last line.
tupek2 b620140
More ending lines.
tupek2 3e1423f
More docs improvements and file naming adjustments.
tupek2 c7a4c66
small fix.
tupek2 9a67661
Change upstream implementation, fix library name to serac.
tupek2 6cbf528
Try to fix gcc issues.
tupek2 d34c80b
Fix maybe nullptr.
tupek2 d8caccd
Try to fix maybe nullptr.
tupek2 fd371bf
Merge branch 'develop' into tupek/gretl_refactor
tupek2 5e3204d
Merge branch 'tupek/residual_interface_adjustments' into tupek/gretl_…
tupek2 eadb07f
Another working adjustment.
tupek2 40fab88
Merge branch 'develop' into tupek/gretl_refactor
tupek2 e8f0ebb
Merge branch 'develop' into tupek/gretl_refactor
tupek2 29cf89a
Fix some commented on issues.
tupek2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Copyright (c) Lawrence Livermore National Security, LLC and | ||
| # other Serac Project Developers. See the top-level LICENSE file for | ||
| # details. | ||
| # | ||
| # SPDX-License-Identifier: (BSD-3-Clause) | ||
|
|
||
| set(serac_gretl_sources | ||
| data_store.cpp | ||
| state_base.cpp | ||
| vector_state.cpp | ||
| ) | ||
|
|
||
| set(serac_gretl_headers | ||
| checkpoint.hpp | ||
| data_store.hpp | ||
| test_utils.hpp | ||
| state_base.hpp | ||
| state.hpp | ||
| create_state.hpp | ||
| upstream_state.hpp | ||
| double_state.hpp | ||
| vector_state.hpp | ||
| print_utils.hpp | ||
| ) | ||
|
|
||
| blt_add_library( | ||
| NAME serac_gretl | ||
| SOURCES ${serac_gretl_sources} | ||
| HEADERS ${serac_gretl_headers} | ||
| ) | ||
|
|
||
| target_include_directories(serac_gretl PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..> | ||
| $<INSTALL_INTERFACE:include> | ||
| ) | ||
|
|
||
| install(FILES ${serac_gretl_headers} DESTINATION include/serac/gretl ) | ||
|
|
||
| install(TARGETS serac_gretl | ||
| EXPORT serac-targets | ||
| DESTINATION lib | ||
| ) | ||
|
|
||
| if(SERAC_ENABLE_TESTS) | ||
| add_subdirectory(tests) | ||
| endif() | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,235 @@ | ||
| // Copyright (c) Lawrence Livermore National Security, LLC and | ||
| // other Serac Project Developers. See the top-level LICENSE file for | ||
| // details. | ||
| // | ||
| // SPDX-License-Identifier: (BSD-3-Clause) | ||
|
|
||
| /** | ||
| * @file checkpoint.hpp | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <set> | ||
| #include <map> | ||
| #include <ostream> | ||
| #include <iostream> | ||
| #include <cassert> | ||
| #include <limits> | ||
|
|
||
| /// @brief gretl_assert that prints line and file info before throwing in release and halting in debug | ||
| #define gretl_assert(x) \ | ||
| if (!(x)) \ | ||
| throw std::runtime_error{"Error on line " + std::to_string(__LINE__) + " in file " + std::string(__FILE__)}; \ | ||
| assert(x); | ||
|
|
||
| /// @brief gretl_assert_msg that prints message, line and file info before throwing in release and halting in debug | ||
| #define gretl_assert_msg(x, msg_name_) \ | ||
| if (!(x)) \ | ||
| throw std::runtime_error{"Error on line " + std::to_string(__LINE__) + " in file " + std::string(__FILE__) + \ | ||
| std::string(", ") + std::string(msg_name_)}; \ | ||
| assert(x); | ||
|
|
||
| namespace gretl { | ||
|
|
||
| /// @brief checkpoint struct which tracks level and step per "Minimal Repetition Dynamic Checkpointing Algorithm for | ||
| /// Unsteady Adjoint Calculation", Wang, et al. , 2009. | ||
| struct Checkpoint { | ||
| size_t level; ///< level | ||
| size_t step; ///< step | ||
| static constexpr size_t infinity() | ||
| { | ||
| return std::numeric_limits<size_t>::max(); | ||
| } ///< The largest possible step and level value | ||
| }; | ||
|
|
||
| /// @brief comparison operator between two checkpoints to determine which is most disposable per the dynamic | ||
| /// checkpointing algorithm | ||
| inline bool operator<(const Checkpoint& a, const Checkpoint& b) | ||
| { | ||
| if (a.level == Checkpoint::infinity() && b.level == Checkpoint::infinity()) { | ||
| return a.step > b.step; | ||
| } | ||
| if (a.level == Checkpoint::infinity()) return false; | ||
| if (b.level == Checkpoint::infinity()) return true; | ||
| return a.step > b.step; | ||
| } | ||
|
|
||
| /// @brief output stream for a single checkpoint | ||
| inline std::ostream& operator<<(std::ostream& stream, const Checkpoint& p); | ||
|
|
||
| /// @brief CheckpointManager class which encapsulates the logic of when and which steps should be dynamically saved a | ||
| /// fetched | ||
| struct CheckpointManager { | ||
| static constexpr size_t invalidCheckpointIndex = | ||
| std::numeric_limits<size_t>::max(); ///< magic number of invalid checkpoint | ||
|
|
||
| /// @brief utilty for checking if an index is valid. There is a magic number, invalidCheckpointIndex, which | ||
| /// represents an invalid checkpoint | ||
| static bool valid_checkpoint_index(size_t i) { return i != invalidCheckpointIndex; } | ||
|
|
||
| /// @brief returns const_iterator to currently most dispensable checkpoint step | ||
| std::set<gretl::Checkpoint>::const_iterator most_dispensable() const | ||
| { | ||
| size_t maxHigherTimeLevel = 0; | ||
| for (auto rIter = cps.begin(); rIter != cps.end(); ++rIter) { | ||
| if (rIter->level < maxHigherTimeLevel) { | ||
| return rIter; | ||
| } | ||
| maxHigherTimeLevel = std::max(rIter->level, maxHigherTimeLevel); | ||
| } | ||
| return cps.end(); | ||
| } | ||
|
|
||
| /// @brief this does multiple things | ||
| /// 1. it adds checkpoints into the database, and updates internal data structures | ||
| /// 2. it determines if a checkpoint needs to be removed | ||
| /// 3. if a checkpoint needs to be removed, it returns the index for that checkpoint | ||
| /// 4. otherwise, it returns zero | ||
| size_t add_checkpoint_and_get_index_to_remove(size_t step, bool persistent = false) | ||
| { | ||
| size_t levelupAmount = 1; //= relativeCost >= 2.0 ? 3 : 1; | ||
|
|
||
| Checkpoint nextStep{.level = levelupAmount - 1, .step = step}; | ||
|
|
||
| size_t nextEraseStep = invalidCheckpointIndex; | ||
|
|
||
| // don't include persistent data in data quota. MRT, this might change | ||
| if (persistent) { | ||
| maxNumStates++; | ||
| nextStep.level = Checkpoint::infinity(); | ||
| gretl_assert(cps.size() < maxNumStates); | ||
| } | ||
|
|
||
| if (cps.size() < maxNumStates) { | ||
| cps.insert(nextStep); | ||
| } else { | ||
| auto iterToMostDispensable = most_dispensable(); | ||
| if (iterToMostDispensable != cps.end()) { | ||
| nextEraseStep = iterToMostDispensable->step; | ||
| cps.erase(iterToMostDispensable); | ||
| cps.insert(nextStep); | ||
| } else { | ||
| nextEraseStep = cps.begin()->step; | ||
| nextStep.level = cps.begin()->level + levelupAmount; | ||
|
|
||
| cps.erase(cps.begin()); | ||
| cps.insert(nextStep); | ||
| } | ||
| } | ||
|
|
||
| return nextEraseStep; | ||
| } | ||
|
|
||
| /// @brief return largest currently checkpointed step | ||
| size_t last_checkpoint_step() const { return cps.begin()->step; } | ||
|
|
||
| /// @brief erase | ||
| bool erase_step(size_t stepIndex) | ||
| { | ||
| for (std::set<Checkpoint>::iterator it = cps.begin(); it != cps.end(); ++it) { | ||
| if (it->step == stepIndex) { | ||
| if (it->level != Checkpoint::infinity()) { | ||
| cps.erase(it); | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| /// @brief check if this step is currently checkpointed. This could potentially use performance optimization down the | ||
| /// way. | ||
| bool contains_step(size_t stepIndex) const | ||
| { | ||
| for (auto& c : cps) { | ||
| if (c.step == stepIndex) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| /// @brief erase all non persistent checkpoints | ||
| void reset() | ||
| { | ||
| for (auto cp_it = cps.begin(); cp_it != cps.end(); ++cp_it) { | ||
| if (cp_it->level == Checkpoint::infinity()) { | ||
| cps.erase(cps.begin(), cp_it); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| size_t maxNumStates = | ||
| 20; ///< The maximum number of non-persistent, not-in-scope states stored by the CheckpointManager | ||
| std::set<Checkpoint> cps; ///< Vector of checkpoints | ||
| }; | ||
|
|
||
| /// @brief interface to run forward with a linear graph, checkpoint, then automatically backpropagate the sensitivities | ||
| /// given the reverse_callback vjp. | ||
| /// @tparam T type of each state's data | ||
| /// @param numSteps number of forward iterations | ||
| /// @param storageSize maximum states to save in memory at a time | ||
| /// @param x initial condition | ||
| /// @param update_func function which evaluates the forward response | ||
| /// @param reverse_callback vjp function (action of Jacobian-transposed) to back propagate sensitivities | ||
| /// @return | ||
| template <typename T> | ||
| T advance_and_reverse_steps(size_t numSteps, size_t storageSize, T x, std::function<T(size_t n, const T&)> update_func, | ||
| std::function<void(size_t n, const T&)> reverse_callback) | ||
| { | ||
| gretl::CheckpointManager cps{.maxNumStates = storageSize, .cps{}}; | ||
| std::map<size_t, T> savedCps; | ||
| savedCps[0] = x; | ||
|
|
||
| cps.add_checkpoint_and_get_index_to_remove(0, true); | ||
| for (size_t i = 0; i < numSteps; ++i) { | ||
| x = update_func(i, savedCps[i]); | ||
| size_t eraseStep = cps.add_checkpoint_and_get_index_to_remove(i + 1, false); | ||
| if (cps.valid_checkpoint_index(eraseStep)) { | ||
| savedCps.erase(eraseStep); | ||
| } | ||
|
|
||
| savedCps[i + 1] = x; | ||
| } | ||
|
|
||
| double xf = x; | ||
|
|
||
| for (size_t i = numSteps; i + 1 > 0; --i) { | ||
| while (cps.last_checkpoint_step() < i) { | ||
| size_t lastCp = cps.last_checkpoint_step(); | ||
| x = update_func(lastCp, savedCps[lastCp]); | ||
| size_t eraseStep = cps.add_checkpoint_and_get_index_to_remove(lastCp + 1, false); | ||
| if (cps.valid_checkpoint_index(eraseStep)) { | ||
| savedCps.erase(eraseStep); | ||
| } | ||
| savedCps[lastCp + 1] = x; | ||
| } | ||
| reverse_callback(i, savedCps[i]); | ||
|
|
||
| cps.erase_step(i); | ||
| savedCps.erase(i); | ||
| } | ||
|
|
||
| return xf; | ||
| } | ||
|
|
||
| /// @brief ostream operator for writing out checkpoint information | ||
| inline std::ostream& operator<<(std::ostream& stream, const Checkpoint& p) | ||
| { | ||
| return stream << " lvl=" << p.level << ", step=" << p.step; | ||
| } | ||
|
|
||
| /// @brief ostream operator for writing out information about the entire checkpoint manager to see the set of currently | ||
| /// checkpointed states | ||
| inline std::ostream& operator<<(std::ostream& stream, const CheckpointManager& set) | ||
| { | ||
| stream << "CHECKPOINTS: capacity = " << set.maxNumStates << std::endl; | ||
| for (const auto& s : set.cps) { | ||
| stream << s << "\n"; | ||
| } | ||
| return stream; | ||
| } | ||
|
|
||
| } // namespace gretl |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
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.
yep!