-
Notifications
You must be signed in to change notification settings - Fork 1.7k
HParams: Create hparams effects to trigger data to be fetched from the hparams plugin #6540
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
Conversation
@@ -43,6 +45,8 @@ export const HPARAMS_FEATURE_KEY = 'hparams'; | |||
|
|||
export interface HparamsState { | |||
specs: ExperimentToHparams; | |||
currentSpecs: HparamAndMetricSpec; |
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.
Could you elaborate a bit on what the final data model is going to look like? Introduction of "currentSpecs" and "sessionGroups" isn't clearly going in the direction that I hoped this would. It could just be a naming issue, though.
Ultimately I think the data model should look something like:
export interface HparamsState {
listSpecs: Record<string, HparamAndMetricSpec> ;
listSessionGroups: Record<string, SessionGroup[]>;
listFilters: Record<string, Filters>;
dashboardSpecs: HparamAndMetricSpec;
dashboardSessionGroups: SessionGroup[];
dashboardFilters: Filters;
}
Notably, there is no notion of a single "current" spec since (1) there is also no notion of a "previous" spec and (2) you could have multiple active lists at the same time - multiple in the experiment list and one in the dashboard.
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.
I do think this is a naming issue. I agree that dashboardSpecs
seems like a better name as it helps clarify the usease. I chose ccurrentSpecs
to indicate that it's value would change as the experiment ids changed, but in hindsight that is implicit with redux properties.
) {} | ||
|
||
private readonly runTableShown$: Observable<string[]> = this.actions$.pipe( | ||
ofType(runsActions.runTableShown), |
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 I understand correctly, runTableShown is fired when any run table is shown - either in experiment list or in dashboard, right?
If so, then loading any runs table ultimately dispatches an instance of hparamsFetchSessionGroupsSucceeded which populates the same state over and over - overwriting whatever was there before. The action doesn't clarify which run table you've loaded data for - is it one of the tables in the experiment list or is it the table in the dashboard?
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.
I'm unsure how we can differentiate between them. This does remind me that I had intended to ensure the events are only dispatched on the dashboard routes. How would you feel about that solution?
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.
I think you could encode the information in the action that triggers the logic. For example:
- have two different actions
runTableShownInExperimentList
andrunTableShownInDashboard
- or make it a property of the
runTableShown
action. Maybe an enum of typeRunTableLocation
.
On the other hand, using route information for this seems ok. But just to confirm: Do you intend that this logic will also handle the run tables in the experiment list? And, if so, do you plan to somehow differentiate the two cases when you dispatch the action after retrieving the data - perhaps add a property to hparamsFetchSessionGroupsSucceeded
(again maybe an enum type RunTableLocation
).
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.
At the moment I do not intend for this to be active on the experiment list at all. Once this portion of the code is stable I plan to do a refactor of the data fetching logic on the experiment list though and at that point I may try to merge these. If that happens I will probably add an enum to the runTableShown
action payload.
filter( | ||
([, getEnableHparamsInTimeSeries]) => getEnableHparamsInTimeSeries | ||
), | ||
throttleTime(10), |
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.
Is the reason for this because when we navigate to timeseries we also trigger runTableShown? So we are just avoiding a duplicate call?
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.
Yeah, that's exactly it.
@@ -43,6 +45,8 @@ export const HPARAMS_FEATURE_KEY = 'hparams'; | |||
|
|||
export interface HparamsState { | |||
specs: ExperimentToHparams; |
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.
Nit: To avoid confusion I think this should be name experimentListSpecs or something like that.
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.
I agree but I'd like to refactor the experiment list portion of the state in a separate PR once the dashboard flow is fully checked in. I think this new flow is better and I am hopeful that we can remove a lot of the old code.
@@ -19,3 +19,9 @@ limitations under the License. | |||
export type DeepReadonly<T> = { | |||
readonly [P in keyof T]: DeepReadonly<T[P]>; | |||
}; | |||
|
|||
export type DeepPartial<T> = T extends object |
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.
useful
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.
I'm surprised to discover that you can branch type definitions based on conditions on the type parameters . Kind of neat.
A minor error in the description:
actions file => effects file |
@@ -19,3 +19,9 @@ limitations under the License. | |||
export type DeepReadonly<T> = { | |||
readonly [P in keyof T]: DeepReadonly<T[P]>; | |||
}; | |||
|
|||
export type DeepPartial<T> = T extends object |
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.
I'm surprised to discover that you can branch type definitions based on conditions on the type parameters . Kind of neat.
) {} | ||
|
||
private readonly runTableShown$: Observable<string[]> = this.actions$.pipe( | ||
ofType(runsActions.runTableShown), |
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.
I think you could encode the information in the action that triggers the logic. For example:
- have two different actions
runTableShownInExperimentList
andrunTableShownInDashboard
- or make it a property of the
runTableShown
action. Maybe an enum of typeRunTableLocation
.
On the other hand, using route information for this seems ok. But just to confirm: Do you intend that this logic will also handle the run tables in the experiment list? And, if so, do you plan to somehow differentiate the two cases when you dispatch the action after retrieving the data - perhaps add a property to hparamsFetchSessionGroupsSucceeded
(again maybe an enum type RunTableLocation
).
@@ -50,3 +54,11 @@ export const hparamsMetricFilterChanged = createAction( | |||
includeUndefined: boolean; | |||
}>() | |||
); | |||
|
|||
export const hparamsFetchSessionGroupsSucceeded = createAction( |
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.
Do you have plans to introduce the other actions we typically also have for data source fetches?
hparamsFetchSessionGroupsRequested
hparamsFetchSessionGroupsFailed
(I'd ok - in fact, I prefer - if these come in a different PR. I just want to make sure they are on your radar).
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.
Yeah, I'll make sure these get added soon. I wanted to get the MVP out as soon as possible to unblock James.
routeKind: RouteKind.EXPERIMENT, | ||
params: {}, | ||
}); | ||
store.overrideSelector(selectors.getExperimentIdsFromRoute, ['exp1']); |
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.
Should we rename to perhaps 'expFromRoute' to make it a bit clearer where the navigated, reload, and manualReload tests are getting this from?
…ects (#6544) ## Motivation for features / changes This is a continuation of #6540 Now that data is being retrieved from the hparams plugin and written to the store I am adding a pair of selectors to retrieve it and inject it into the the data retrieved from `getRuns` and `getRunsForExperimentId`. The logic used to translate `SessionGroups` to `Record<RunId/Group, Value>` is very similar to that being used by the old code in `runs_data_source`. I could imagine this being refactored to retrieve the run/group relationships from another part of the store in the future in order to better integrate with our plans to stop relying on the metrics portion of the hparams payload. ## Note For Reviewer(s) A large majority of the lines changed in this PR are indent changes resulting from changing the method used to mock the state during tests. I have opted not to add additional test to the runs or common selectors (though I did have to fix 16) as the intention is for this to be a drop in replacement with no new features added. The number of test failures which I had to fix left me feeling confident of the existing test coverage.
…e hparams plugin (tensorflow#6540) ## Motivation for features / changes This is a natural continuation of the work done in tensorflow#6535 I added a new effects file which fires a newly created action whenever the runs table is shown, a navigation occurs, or the user reloads the data. The data loading is then filtered and throttled by the existence of experiment ids. Finally the raw response from the `hparams_data_source` is written to the redux state. In a future PR I will add a series of selectors to remap and inject that data into the runs metadata. ## Alternate designs / implementations considered (or N/A) I've opted to include the effects and data source in the hparams module but hide the functionality behind the feature flag. This should make it easier to develop changes downstream from this pr. In the future I will gate the existing behavior behind the inverse of this flag and that should allow us to test the full flow without needing to remove the old code (I have tested removing the old code). The reducer change could have been split out from this but it's quite small and I thought including it made it easier to see the entire write path. Because I added two new attributes to the hparams redux state there are a few changes to test utilities that are not strictly necessary but are useful to have.
…ects (tensorflow#6544) ## Motivation for features / changes This is a continuation of tensorflow#6540 Now that data is being retrieved from the hparams plugin and written to the store I am adding a pair of selectors to retrieve it and inject it into the the data retrieved from `getRuns` and `getRunsForExperimentId`. The logic used to translate `SessionGroups` to `Record<RunId/Group, Value>` is very similar to that being used by the old code in `runs_data_source`. I could imagine this being refactored to retrieve the run/group relationships from another part of the store in the future in order to better integrate with our plans to stop relying on the metrics portion of the hparams payload. ## Note For Reviewer(s) A large majority of the lines changed in this PR are indent changes resulting from changing the method used to mock the state during tests. I have opted not to add additional test to the runs or common selectors (though I did have to fix 16) as the intention is for this to be a drop in replacement with no new features added. The number of test failures which I had to fix left me feeling confident of the existing test coverage.
## Motivation for features / changes Now that we are fetching the hparams data using the newly created hparams_effects (#6540) we no longer need to fetch them using the old method. Note that the experiment list SHOULD still use the old method.
Motivation for features / changes
This is a natural continuation of the work done in #6535
I added a new effects file which fires a newly created action whenever the runs table is shown, a navigation occurs, or the user reloads the data.
The data loading is then filtered and throttled by the existence of experiment ids.
Finally the raw response from the
hparams_data_source
is written to the redux state. In a future PR I will add a series of selectors to remap and inject that data into the runs metadata.Alternate designs / implementations considered (or N/A)
I've opted to include the effects and data source in the hparams module but hide the functionality behind the feature flag. This should make it easier to develop changes downstream from this pr. In the future I will gate the existing behavior behind the inverse of this flag and that should allow us to test the full flow without needing to remove the old code (I have tested removing the old code).
The reducer change could have been split out from this but it's quite small and I thought including it made it easier to see the entire write path.
Because I added two new attributes to the hparams redux state there are a few changes to test utilities that are not strictly necessary but are useful to have.