Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tensorboard/webapp/metrics/views/main_view/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,17 @@ tf_ts_library(
deps = [
"//tensorboard/webapp:app_state",
"//tensorboard/webapp:selectors",
"//tensorboard/webapp/app_routing:types",
"//tensorboard/webapp/hparams:types",
"//tensorboard/webapp/hparams/_redux:hparams_selectors",
"//tensorboard/webapp/metrics:utils",
"//tensorboard/webapp/metrics/data_source",
"//tensorboard/webapp/metrics/store",
"//tensorboard/webapp/metrics/views:types",
"//tensorboard/webapp/metrics/views:utils",
"//tensorboard/webapp/runs:types",
"//tensorboard/webapp/runs/views/runs_table:types",
"//tensorboard/webapp/util:matcher",
"//tensorboard/webapp/util:types",
"@npm//@ngrx/store",
],
Expand Down Expand Up @@ -185,15 +191,19 @@ tf_ts_library(
"//tensorboard/webapp/app_routing:testing",
"//tensorboard/webapp/app_routing/store:testing",
"//tensorboard/webapp/customization",
"//tensorboard/webapp/experiments/store:testing",
"//tensorboard/webapp/hparams:types",
"//tensorboard/webapp/metrics:test_lib",
"//tensorboard/webapp/metrics:types",
"//tensorboard/webapp/metrics/actions",
"//tensorboard/webapp/metrics/data_source",
"//tensorboard/webapp/metrics/store",
"//tensorboard/webapp/metrics/views:types",
"//tensorboard/webapp/metrics/views/card_renderer",
"//tensorboard/webapp/runs/store:selectors",
"//tensorboard/webapp/runs/store:testing",
"//tensorboard/webapp/runs/store:types",
"//tensorboard/webapp/runs/views/runs_table:types",
"//tensorboard/webapp/settings",
"//tensorboard/webapp/testing:dom",
"//tensorboard/webapp/testing:mat_icon",
Expand Down
159 changes: 159 additions & 0 deletions tensorboard/webapp/metrics/views/main_view/common_selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,33 @@ import {
getCurrentRouteRunSelection,
getMetricsHideEmptyCards,
getMetricsTagMetadata,
getExperimentIdsFromRoute,
getExperimentIdToExperimentAliasMap,
getExperimentNames,
getRunColorMap,
getRunSelectorRegexFilter,
getRouteKind,
getRunsFromExperimentIds,
} from '../../../selectors';
import {DeepReadonly} from '../../../util/types';
import {
getHparamFilterMapFromExperimentIds,
getMetricFilterMapFromExperimentIds,
} from '../../../hparams/_redux/hparams_selectors';
import {
DiscreteFilter,
DiscreteHparamValue,
DomainType,
IntervalFilter,
} from '../../../hparams/types';
import {RunTableItem} from '../../../runs/views/runs_table/types';
import {matchRunToRegex} from '../../../util/matcher';
import {isSingleRunPlugin, PluginType} from '../../data_source';
import {getNonEmptyCardIdsWithMetadata, TagMetadata} from '../../store';
import {compareTagNames} from '../../utils';
import {CardIdWithMetadata} from '../metrics_view_types';
import {RouteKind} from '../../../app_routing/types';
import {Run} from '../../../runs/types';

export const getScalarTagsForRunSelection = createSelector(
getMetricsTagMetadata,
Expand Down Expand Up @@ -86,7 +107,145 @@ export const getSortedRenderableCardIdsWithMetadata = createSelector<
});
});

const utils = {
filterRunItemsByRegex(
runItems: RunTableItem[],
regexString: string,
shouldIncludeExperimentName: boolean
): RunTableItem[] {
if (!regexString) {
return runItems;
}

return runItems.filter((item) => {
return matchRunToRegex(
{
runName: item.run.name,
experimentAlias: item.experimentAlias,
},
regexString,
shouldIncludeExperimentName
);
});
},

matchFilter(
filter: DiscreteFilter | IntervalFilter,
value: number | DiscreteHparamValue | undefined
): boolean {
if (value === undefined) {
return filter.includeUndefined;
}
if (filter.type === DomainType.DISCRETE) {
// (upcast to work around bad TypeScript libdefs)
const values: Readonly<Array<typeof filter.filterValues[number]>> =
Copy link
Contributor

Choose a reason for hiding this comment

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

this type is confusing me. What does the "number" thing do? DiscreteHparamValues are supposed to be arrays of numbers, strings, or booleans.

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 is confusing to me too (I didn't write it) but it seems to work and I don't really want to change it.

filter.filterValues;
return values.includes(value);
} else if (filter.type === DomainType.INTERVAL) {
return (
typeof value === 'number' &&
filter.filterLowerValue <= value &&
value <= filter.filterUpperValue
);
}
return false;
},

filterRunItemsByHparamAndMetricFilter(
runItems: RunTableItem[],
hparamFilters: Map<string, IntervalFilter | DiscreteFilter>,
metricFilters: Map<string, IntervalFilter>
) {
return runItems.filter(({hparams, metrics}) => {
const hparamMatches = [...hparamFilters.entries()].every(
([hparamName, filter]) => {
const value = hparams.get(hparamName);
return utils.matchFilter(filter, value);
}
);

const metricMatches = [...metricFilters.entries()].every(
([metricTag, filter]) => {
const value = metrics.get(metricTag);
return utils.matchFilter(filter, value);
}
);

return hparamMatches && metricMatches;
});
},
};

export function getRenderableRuns(experimentIds: string[]) {
return createSelector(
getRunsFromExperimentIds(experimentIds),
getExperimentNames(experimentIds),
getCurrentRouteRunSelection,
getRunColorMap,
getExperimentIdToExperimentAliasMap,
(
runs,
experimentNames,
selectionMap,
colorMap,
experimentIdToAlias
): Array<RunTableItem & {run: Run & {experimentId: string}}> => {
return runs.map((run) => {
const hparamMap: RunTableItem['hparams'] = new Map();
(run.hparams || []).forEach((hparam) => {
hparamMap.set(hparam.name, hparam.value);
});
const metricMap: RunTableItem['metrics'] = new Map();
(run.metrics || []).forEach((metric) => {
metricMap.set(metric.tag, metric.value);
});
return {
run,
experimentName: experimentNames[run.experimentId] || '',
experimentAlias: experimentIdToAlias[run.experimentId],
selected: Boolean(selectionMap && selectionMap.get(run.id)),
runColor: colorMap[run.id],
hparams: hparamMap,
metrics: metricMap,
};
});
}
);
}

export function getFilteredRenderableRuns(experimentIds: string[]) {
return createSelector(
getRunSelectorRegexFilter,
getRenderableRuns(experimentIds),
getHparamFilterMapFromExperimentIds(experimentIds),
getMetricFilterMapFromExperimentIds(experimentIds),
getRouteKind,
(regexFilter, runItems, hparamFilters, metricFilters, routeKind) => {
const regexFilteredItems = utils.filterRunItemsByRegex(
runItems,
regexFilter,
routeKind === RouteKind.COMPARE_EXPERIMENT
);

return utils.filterRunItemsByHparamAndMetricFilter(
regexFilteredItems,
hparamFilters,
metricFilters
);
}
);
}

export const getFilteredRenderableRunsFromRoute = createSelector(
(state) => state,
getExperimentIdsFromRoute,
(state, experimentIds) => {
return getFilteredRenderableRuns(experimentIds || [])(state);
}
);

export const TEST_ONLY = {
getRenderableCardIdsWithMetadata,
getScalarTagsForRunSelection,
utils,
};
Loading