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

Use first three metrics and params in table tooltips & quick picks #4155

Merged
merged 8 commits into from
Jun 23, 2023
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
38 changes: 27 additions & 11 deletions extension/src/experiments/columns/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,16 @@ describe('ColumnsModel', () => {
expect(model.getColumnOrder()).toStrictEqual(persistedState)
})

it('should return the first three none hidden columns (minus created) from the persisted state', async () => {
it('should return the first three visible columns for both metrics and params from the persisted state', async () => {
const persistedState = [
'id',
'Created',
'params:params.yaml:dvc_logs_dir',
'params:params.yaml:process.threshold',
'params:params.yaml:process.test_arg',
'params:params.yaml:dropout',
'metrics:summary.json:loss',
'metrics:summary.json:accuracy',
'deps:src/prepare.py',
'deps:src/featurization.py'
]
Expand All @@ -280,34 +282,48 @@ describe('ColumnsModel', () => {
)
await model.transformAndSet(outputFixture)

expect(model.getFirstThreeColumnOrder()).toStrictEqual(
persistedState.slice(2, 5)
)
expect(model.getSummaryColumnOrder()).toStrictEqual([
'params:params.yaml:dvc_logs_dir',
'params:params.yaml:process.threshold',
'params:params.yaml:process.test_arg',
'metrics:summary.json:loss',
'metrics:summary.json:accuracy'
])

model.toggleStatus('params:params.yaml:dvc_logs_dir')

expect(model.getFirstThreeColumnOrder()).toStrictEqual(
persistedState.slice(3, 6)
)
expect(model.getSummaryColumnOrder()).toStrictEqual([
'params:params.yaml:process.threshold',
'params:params.yaml:process.test_arg',
'params:params.yaml:dropout',
'metrics:summary.json:loss',
'metrics:summary.json:accuracy'
])
})

it('should return the first three none hidden columns (minus created) collected from data if state is empty', async () => {
it('should return the first three metric and param columns (none hidden) collected from data if state is empty', async () => {
const model = new ColumnsModel(
exampleDvcRoot,
buildMockMemento(),
mockedColumnsOrderOrStatusChanged
)
await model.transformAndSet(outputFixture)

expect(model.getFirstThreeColumnOrder()).toStrictEqual([
expect(model.getSummaryColumnOrder()).toStrictEqual([
'params:params.yaml:code_names',
'params:params.yaml:epochs',
'params:params.yaml:learning_rate',
'metrics:summary.json:loss',
'metrics:summary.json:accuracy',
'metrics:summary.json:val_loss'
])

model.toggleStatus('Created')
model.toggleStatus('params:params.yaml:code_names')

expect(model.getFirstThreeColumnOrder()).toStrictEqual([
expect(model.getSummaryColumnOrder()).toStrictEqual([
'params:params.yaml:epochs',
'params:params.yaml:learning_rate',
'params:params.yaml:dvc_logs_dir',
'metrics:summary.json:loss',
'metrics:summary.json:accuracy',
'metrics:summary.json:val_loss'
Expand Down
23 changes: 16 additions & 7 deletions extension/src/experiments/columns/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
collectParamsFiles
} from './collect'
import { EXPERIMENT_COLUMN_ID, timestampColumn } from './constants'
import { SummaryAcc, collectFromColumnOrder } from './util'
import { Column, ColumnType } from '../webview/contract'
import { ExpShowOutput } from '../../cli/dvc/contract'
import { PersistenceKey } from '../../persistence/constants'
Expand Down Expand Up @@ -44,13 +45,21 @@ export class ColumnsModel extends PathSelectionModel<Column> {
return this.columnOrderState
}

public getFirstThreeColumnOrder(): string[] {
return this.columnOrderState
.filter(
path =>
this.status[path] && this.status[path] === 2 && path !== 'Created'
)
.slice(0, 3)
public getSummaryColumnOrder(): string[] {
const acc: SummaryAcc = { metrics: [], params: [] }
for (const path of this.columnOrderState) {
const reachedMaxSummaryOrderLength =
acc.metrics.length >= 3 && acc.params.length >= 3
if (
this.status[path] !== Status.SELECTED ||
reachedMaxSummaryOrderLength
) {
continue
}
collectFromColumnOrder(path, acc)
}

return [...acc.params.slice(0, 3), ...acc.metrics.slice(0, 3)]
}

public getColumnWidths(): Record<string, number> {
Expand Down
14 changes: 14 additions & 0 deletions extension/src/experiments/columns/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ColumnType } from '../webview/contract'

export type SummaryAcc = {
metrics: string[]
params: string[]
}

export const collectFromColumnOrder = (path: string, acc: SummaryAcc) => {
if (path.startsWith(ColumnType.METRICS)) {
acc.metrics.push(path)
} else if (path.startsWith(ColumnType.PARAMS)) {
acc.params.push(path)
}
}
16 changes: 8 additions & 8 deletions extension/src/experiments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export class Experiments extends BaseRepository<TableData> {

const selected = await pickExperimentsToPlot(
experiments,
this.columns.getFirstThreeColumnOrder()
this.columns.getSummaryColumnOrder()
)
if (!selected) {
return
Expand All @@ -365,30 +365,30 @@ export class Experiments extends BaseRepository<TableData> {
public pickCommitOrExperiment() {
return pickExperiment(
this.experiments.getCommitsAndExperiments(),
this.getFirstThreeColumnOrder()
this.getSummaryColumnOrder()
)
}

public pickRunningExperiments() {
return pickExperiments(
this.experiments.getRunningExperiments(),
this.getFirstThreeColumnOrder(),
this.getSummaryColumnOrder(),
Title.SELECT_EXPERIMENTS_STOP
)
}

public pickExperimentsToRemove() {
return pickExperiments(
this.experiments.getExperimentsAndQueued(),
this.getFirstThreeColumnOrder(),
this.getSummaryColumnOrder(),
Title.SELECT_EXPERIMENTS_REMOVE
)
}

public pickExperimentsToPush() {
return pickExperiments(
this.experiments.getExperiments(),
this.getFirstThreeColumnOrder(),
this.getSummaryColumnOrder(),
Title.SELECT_EXPERIMENTS_PUSH
)
}
Expand Down Expand Up @@ -502,8 +502,8 @@ export class Experiments extends BaseRepository<TableData> {
return this.experiments.getCliError()
}

public getFirstThreeColumnOrder() {
return this.columns.getFirstThreeColumnOrder()
public getSummaryColumnOrder() {
return this.columns.getSummaryColumnOrder()
}

public getColumnTerminalNodes() {
Expand Down Expand Up @@ -584,7 +584,7 @@ export class Experiments extends BaseRepository<TableData> {

return await pickExperiment(
this.experiments.getCombinedList(),
this.getFirstThreeColumnOrder(),
this.getSummaryColumnOrder(),
Title.SELECT_BASE_EXPERIMENT
)
}
Expand Down
39 changes: 18 additions & 21 deletions extension/src/experiments/model/quickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ type QuickPickItemAccumulator = {

const getItem = (
experiment: Experiment,
firstThreeColumnOrder: string[]
summaryColumnOrder: string[]
): QuickPickItemWithValue<Experiment | undefined> => ({
detail: getColumnPathsQuickPickDetail(experiment, firstThreeColumnOrder),
detail: getColumnPathsQuickPickDetail(experiment, summaryColumnOrder),
label: experiment.label,
value: experiment
})

const getItemWithDescription = (
experiment: Experiment,
firstThreeColumnOrder: string[]
summaryColumnOrder: string[]
) => {
const item = getItem(experiment, firstThreeColumnOrder)
const item = getItem(experiment, summaryColumnOrder)
if (experiment.description) {
item.description = `${experiment.commit ? '$(git-commit)' : ''}${
experiment.description
Expand All @@ -43,10 +43,10 @@ const getItemWithDescription = (
const collectItem = (
acc: QuickPickItemAccumulator,
experiment: Experiment,
firstThreeColumnOrder: string[],
summaryColumnOrder: string[],
transformer = getItem
) => {
const item = transformer(experiment, firstThreeColumnOrder)
const item = transformer(experiment, summaryColumnOrder)
acc.items.push(item)
if (experiment.selected) {
acc.selectedItems.push(item)
Expand All @@ -56,32 +56,29 @@ const collectItem = (

const collectItems = (
experiments: Experiment[],
firstThreeColumnOrder: string[]
summaryColumnOrder: string[]
) => {
const acc: QuickPickItemAccumulator = {
items: [],
selectedItems: []
}

for (const experiment of experiments) {
collectItem(acc, experiment, firstThreeColumnOrder, getItemWithDescription)
collectItem(acc, experiment, summaryColumnOrder, getItemWithDescription)
}

return acc
}

export const pickExperimentsToPlot = (
experiments: Experiment[],
firstThreeColumnOrder: string[]
summaryColumnOrder: string[]
): Promise<Experiment[] | undefined> => {
if (!definedAndNonEmpty(experiments)) {
return Toast.showError(noExperimentsToSelect)
}

const { items, selectedItems } = collectItems(
experiments,
firstThreeColumnOrder
)
const { items, selectedItems } = collectItems(experiments, summaryColumnOrder)

return quickPickLimitedValues<Experiment | undefined>(
items,
Expand All @@ -101,14 +98,14 @@ type ExperimentItem = {

const getExperimentItems = (
experiments: Experiment[],
firstThreeColumnOrder: string[]
summaryColumnOrder: string[]
): ExperimentItem[] =>
experiments.map(experiment => {
const { label, id, description, commit } = experiment
return {
description:
description && `${commit ? '$(git-commit)' : ''}${description}`,
detail: getColumnPathsQuickPickDetail(experiment, firstThreeColumnOrder),
detail: getColumnPathsQuickPickDetail(experiment, summaryColumnOrder),
label,
value: id
}
Expand All @@ -121,15 +118,15 @@ const pickExperimentOrExperiments = <
T extends QuickPickExperiment | QuickPickExperiments
>(
experiments: Experiment[],
firstThreeColumnOrder: string[],
summaryColumnOrder: string[],
title: Title,
quickPick: T
): ReturnType<T> | Promise<undefined> => {
if (!definedAndNonEmpty(experiments)) {
return Toast.showError(noExperimentsToSelect)
}

const items = getExperimentItems(experiments, firstThreeColumnOrder)
const items = getExperimentItems(experiments, summaryColumnOrder)

return quickPick(items, {
matchOnDescription: true,
Expand All @@ -140,24 +137,24 @@ const pickExperimentOrExperiments = <

export const pickExperiment = (
experiments: Experiment[],
firstThreeColumnOrder: string[],
summaryColumnOrder: string[],
title: Title = Title.SELECT_EXPERIMENT
): Thenable<string | undefined> =>
pickExperimentOrExperiments<QuickPickExperiment>(
experiments,
firstThreeColumnOrder,
summaryColumnOrder,
title,
quickPickValue
)

export const pickExperiments = (
experiments: Experiment[],
firstThreeColumnOrder: string[],
summaryColumnOrder: string[],
title: Title = Title.SELECT_EXPERIMENTS
): Thenable<string[] | undefined> =>
pickExperimentOrExperiments<QuickPickExperiments>(
experiments,
firstThreeColumnOrder,
summaryColumnOrder,
title,
quickPickManyValues
)
Loading