version 0.16

This commit is contained in:
shyallegro
2020-09-10 16:45:48 +03:00
parent c82de80f5e
commit df72cc8bd1
655 changed files with 6164 additions and 6681 deletions

View File

@@ -37,21 +37,6 @@ export class CustomOutputLabelAdded implements Action {
export class ModelSelected implements Action {
readonly type = MODEL_SELECTED;
public payload: {
model: Model;
fieldsToPopulate: { labelEnum: boolean; networkDesign: boolean };
};
constructor(payload: {
model: Model;
fieldsToPopulate: { labelEnum: boolean; networkDesign: boolean };
}) {
this.payload = payload;
}
}
export class UpdateSectionKnowledge implements Action {
readonly type = UPDATE_SECTION_KNOWLEDGE;
@@ -61,7 +46,6 @@ export class UpdateSectionKnowledge implements Action {
export class ExperimentDataUpdated implements Action {
readonly type = EXPERIMENT_DATA_UPDATED;
constructor(public payload: { id: Task['id']; changes: Partial<IExperimentInfo> }) {
}
}

View File

@@ -6,6 +6,7 @@
[editable]="editable$ | async"
[isInDev]="isInDev$ | async"
[formData]="executionInfo$ | async"
[showExtraDataSpinner]="showExtraDataloader$ | async"
[saving]="saving$ |async"
(formDataChanged)="onFormValuesChanged($event)"
(saveFormData)="saveExecutionData()"

View File

@@ -4,19 +4,20 @@ import {Observable, Subscription} from 'rxjs';
import {IExecutionForm} from '../../shared/experiment-execution.model';
import {ISelectedExperiment} from '../../shared/experiment-info.model';
import {IExperimentInfoState} from '../../reducers/experiment-info.reducer';
import {selectIsExperimentEditable, selectSelectedExperiment} from '../../reducers';
import {selectIsExperimentEditable, selectSelectedExperiment, selectShowExtraDataSpinner} from '../../reducers';
import * as infoActions from '../../actions/experiments-info.actions';
import {selectExperimentExecutionInfoData, selectIsExperimentSaving, selectIsSelectedExperimentInDev} from '../../../../webapp-common/experiments/reducers';
import {selectBackdropActive} from '../../../../webapp-common/core/reducers/view-reducer';
@Component({
selector : 'sm-experiment-info-input-model',
selector : 'sm-experiment-info-execution',
templateUrl: './experiment-info-execution.component.html',
styleUrls : ['./experiment-info-execution.component.scss']
})
export class ExperimentInfoExecutionComponent implements OnInit, OnDestroy {
public executionInfo$: Observable<IExecutionForm>;
public showExtraDataloader$: Observable<boolean>;
public selectedExperimentSubscrition: Subscription;
private selectedExperiment: ISelectedExperiment;
public editable$: Observable<boolean>;
@@ -26,6 +27,7 @@ export class ExperimentInfoExecutionComponent implements OnInit, OnDestroy {
constructor(private store: Store<IExperimentInfoState>) {
this.executionInfo$ = this.store.select(selectExperimentExecutionInfoData);
this.showExtraDataloader$ = this.store.select(selectShowExtraDataSpinner);
this.editable$ = this.store.select(selectIsExperimentEditable);
this.isInDev$ = this.store.select(selectIsSelectedExperimentInDev);
this.saving$ = this.store.select(selectIsExperimentSaving);

View File

@@ -1,16 +1,16 @@
<sm-experiment-info-header-status-progress-bar
[status]="selectedExperiment?.status"
[status]="(tableSelectedExperiment$| async)?.status || selectedExperiment?.status"
[editable]="editable$ | async"
[showMaximize]="showMaximize"
[showMaximize]="resultsTab"
(closeInfoClicked)="deselectExperiment()"
(maximizedClicked)="maximize()">
</sm-experiment-info-header-status-progress-bar>
<div class="experiment-info-container light-theme">
<sm-experiment-info-header
[experiment]="selectedExperiment"
[experiment]="(tableSelectedExperiment$| async) || selectedExperiment"
[infoData]="infoData$ | async"
[editable]=" ! isExample"
[editable]=" !isExample"
[showMenu]="true"
[backdropActive]="backdropActive$|async"
(experimentNameChanged)="updateExperimentName($event)"
@@ -20,8 +20,9 @@
<span routerLink="execution" queryParamsHandling="merge">
<sm-navbar-item header="execution" [active]="routerConfig.includes('execution')"></sm-navbar-item>
</span>
<span [routerLink]="['hyper-params']" queryParamsHandling="merge">
<sm-navbar-item header="hyper parameters" [active]="routerConfig.includes('hyper-params')"></sm-navbar-item>
<span [routerLink]="['hyper-params/hyper-param/_empty_']" queryParamsHandling="merge">
<sm-navbar-item header="configuration" [active]="routerConfig.includes('hyper-params')"></sm-navbar-item>
</span>
<span [routerLink]="['artifacts']" queryParamsHandling="preserve">
<sm-navbar-item header="artifacts" [active]="routerConfig.includes('artifacts')"></sm-navbar-item>

View File

@@ -14,12 +14,14 @@ import * as commonInfoActions from '../../../../webapp-common/experiments/action
import * as infoActions from '../../actions/experiments-info.actions';
import {AddMessage} from '../../../../webapp-common/core/actions/layout.actions';
import {IExperimentInfo, ISelectedExperiment} from '../../shared/experiment-info.model';
import {selectSelectedTableExperiment} from '../../../../webapp-common/experiments/reducers';
import {ITableExperiment} from '../../../../webapp-common/experiments/shared/common-experiment-model.model';
@Component({
selector : 'sm-experiment-info',
selector: 'sm-experiment-info',
templateUrl: './experiment-info.component.html',
styleUrls : ['./experiment-info.component.scss']
styleUrls: ['./experiment-info.component.scss']
})
export class ExperimentInfoComponent implements OnInit, OnDestroy {
@@ -32,20 +34,22 @@ export class ExperimentInfoComponent implements OnInit, OnDestroy {
public isExample: boolean;
private projectId: string;
private experimentId: string;
public showMaximize: boolean;
public resultsTab: boolean;
public queryParams$: Observable<Params>;
public routerConfig: string[];
private routerConfigSubscription: Subscription;
public tableSelectedExperiment$: Observable<ITableExperiment>;
constructor(
private router: Router,
private store: Store<IExperimentInfoState>,
private route: ActivatedRoute
) {
this.editable$ = this.store.select(selectIsExperimentEditable);
this.infoData$ = this.store.select(selectExperimentInfoData);
this.editable$ = this.store.select(selectIsExperimentEditable);
this.infoData$ = this.store.select(selectExperimentInfoData);
this.backdropActive$ = this.store.select(selectBackdropActive);
this.queryParams$ = this.store.select(selectRouterQueryParams);
this.queryParams$ = this.store.select(selectRouterQueryParams);
this.tableSelectedExperiment$ = this.store.select(selectSelectedTableExperiment)
}
@@ -53,16 +57,17 @@ export class ExperimentInfoComponent implements OnInit, OnDestroy {
this.selectedExperimentSubscription = this.store.select(selectSelectedExperiment)
.subscribe(experiment => {
this.selectedExperiment = experiment;
this.isExample = isExample(experiment);
this.isExample = isExample(experiment);
});
this.routerConfigSubscription = this.store.select(selectRouterConfig).subscribe(routerConfig => {
this.routerConfigSubscription = this.store.select(selectRouterConfig).subscribe(routerConfig => {
this.routerConfig = routerConfig;
});
this.paramsSubscription = this.store.select(selectRouterParams)
this.paramsSubscription = this.store.select(selectRouterParams)
.pipe(
tap((params) => {
this.projectId = get('projectId', params);
this.showMaximize = 'info-output' === this.route.firstChild.routeConfig.path;
this.projectId = get('projectId', params);
this.resultsTab = 'info-output' === this.route.firstChild.routeConfig.path;
}),
debounceTime(150),
map(params => get('experimentId', params)),
@@ -71,8 +76,12 @@ export class ExperimentInfoComponent implements OnInit, OnDestroy {
)
.subscribe(experimentId => {
this.experimentId = experimentId;
this.store.dispatch(new commonInfoActions.ResetExperimentInfo());
this.store.dispatch(new commonInfoActions.GetExperimentInfo(experimentId));
// We already have GetExperimentInfo in output (results) component
if (!this.resultsTab) {
this.store.dispatch(new commonInfoActions.ResetExperimentInfo());
this.store.dispatch(new commonInfoActions.GetExperimentInfo(experimentId));
}
});
}
@@ -80,7 +89,7 @@ export class ExperimentInfoComponent implements OnInit, OnDestroy {
this.paramsSubscription.unsubscribe();
this.selectedExperimentSubscription.unsubscribe();
this.routerConfigSubscription.unsubscribe();
this.store.dispatch(new commonInfoActions.SetExperiment(null));
// this.store.dispatch(new commonInfoActions.SetExperiment(null));
this.store.dispatch(new commonInfoActions.ResetExperimentInfo());
}

View File

@@ -18,6 +18,8 @@ import {ExperimentInfoInputModelComponent} from '../../webapp-common/experiments
import {ExperimentInfoOutputModelComponent} from '../../webapp-common/experiments/containers/experiment-info-output-model/experiment-info-output-model.component';
import {ExperimentInfoArtifactItemComponent} from '../../webapp-common/experiments/containers/experiment-info-artifact-item/experiment-info-artifact-item.component';
import {LeavingBeforeSaveAlertGuard} from '../../webapp-common/shared/guards/leaving-before-save-alert.guard';
import {ExperimentInfoTaskModelComponent} from '../../webapp-common/experiments/containers/experiment-info-task-model/experiment-info-task-model.component';
import {ExperimentInfoHyperParametersFormContainerComponent} from '../../webapp-common/experiments/containers/experiment-info-hyper-parameters-form-container/experiment-info-hyper-parameters-form-container.component';
export const routes: Routes = [
{
@@ -35,11 +37,17 @@ export const routes: Routes = [
{path: '', redirectTo: 'input-model', pathMatch: 'full'},
{path: 'input-model', component: ExperimentInfoInputModelComponent},
{path: 'output-model', component: ExperimentInfoOutputModelComponent},
{path: 'artifact/:artifactId', children:[{ path:':mode', component: ExperimentInfoArtifactItemComponent}]},
{path: 'other/:artifactId', children:[{ path:':mode', component: ExperimentInfoArtifactItemComponent}]}
{path: 'artifact/:artifactId', children: [{path: ':mode', component: ExperimentInfoArtifactItemComponent}]},
{path: 'other/:artifactId', children: [{path: ':mode', component: ExperimentInfoArtifactItemComponent}]}
]
},
{
path : 'hyper-params', component: ExperimentInfoHyperParametersComponent, canDeactivate: [LeavingBeforeSaveAlertGuard],
children: [
{path: 'configuration/:configObject', component: ExperimentInfoTaskModelComponent},
{path: 'hyper-param/:hyperParamId', component: ExperimentInfoHyperParametersFormContainerComponent}
]
},
{path: 'hyper-params', component: ExperimentInfoHyperParametersComponent, canDeactivate: [LeavingBeforeSaveAlertGuard]},
{path: 'general', component: ExperimentInfoGeneralComponent},
{
path : 'info-output',

View File

@@ -24,6 +24,7 @@ export const EXPERIMENT_INFO_ONLY_FIELDS = [
'output.model.project',
'output.model.design',
'output.model.uri',
'hyperparams',
'execution',
'execution.model.name',
'execution.model.uri',
@@ -32,11 +33,19 @@ export const EXPERIMENT_INFO_ONLY_FIELDS = [
'execution.model.task.project.id',
'execution.model.project.id',
'execution.model.labels',
'script',
'execution.model.design',
'script.binary',
'script.repository',
'script.tag',
'script.branch',
'script.version_num',
'script.entry_point',
'script.working_dir',
'script.requirements',
'system_tags',
'published',
'last_iteration',
'tags'
'tags',
];
export const INITIAL_EXPERIMENT_TABLE_COLS: ISmCol[] = [
@@ -98,6 +107,7 @@ export const INITIAL_EXPERIMENT_TABLE_COLS: ISmCol[] = [
},
{
id : EXPERIMENTS_TABLE_COL_FIELDS.USER,
getter : 'user.name',
headerType : ColHeaderTypeEnum.sortFilter,
searchableFilter: true,
filterable : true,

View File

@@ -4,7 +4,7 @@ import {experimentSections, experimentSectionsEnum} from '../shared/experiments.
import {get, set} from 'lodash/fp';
import {commonExperimentInfoReducer, ICommonExperimentInfoState, initialCommonExperimentInfoState} from '../../../webapp-common/experiments/reducers/common-experiment-info.reducer';
import * as actions from '../../../webapp-common/experiments/actions/common-experiments-info.actions';
import {SET_EXPERIMENT} from '../../../webapp-common/experiments/actions/common-experiments-info.actions';
import {deleteHyperParamsSection, hyperParamsSectionUpdated, saveExperimentConfigObj, saveHyperParamsSection, SET_EXPERIMENT, setExperimentSaving, updateExperimentAtPath} from '../../../webapp-common/experiments/actions/common-experiments-info.actions';
export interface IExperimentInfoState extends ICommonExperimentInfoState {
activeSectionEdit: string;
@@ -16,13 +16,13 @@ export interface IExperimentInfoState extends ICommonExperimentInfoState {
export const initialState: IExperimentInfoState = {
...initialCommonExperimentInfoState,
activeSectionEdit : null,
saving : false,
infoDataFreeze : null,
userKnowledge : {
activeSectionEdit: null,
saving : false,
infoDataFreeze : null,
userKnowledge : {
[experimentSections.MODEL_INPUT]: false
} as any,
errors : {
errors : {
model : null,
execution: null,
},
@@ -40,8 +40,17 @@ export function experimentInfoReducer(state: IExperimentInfoState = initialState
return {...state, infoData: {...state.infoData, model: {...state.infoData.model, ...action.payload}}};
case EXPERIMENT_DATA_UPDATED:
return {...state, infoData: {...state.infoData, ...action.payload.changes}};
case hyperParamsSectionUpdated.type:
return {...state, infoData: {...state.infoData, hyperparams: {...state.infoData.hyperparams, [action.section]: action.hyperparams}}};
case EXPERIMENT_SAVE:
return {...state, saving: true};
case saveHyperParamsSection.type:
return {...state, saving: true};
case saveExperimentConfigObj.type:
return {...state, saving: true};
case deleteHyperParamsSection.type:
return {...state, saving: true};
case ACTIVATE_EDIT:
return {...state, activeSectionEdit: action.payload, infoDataFreeze: state.infoData};
case SET_FREEZE_INFO:
@@ -52,6 +61,11 @@ export function experimentInfoReducer(state: IExperimentInfoState = initialState
return {...state, infoData: state.infoDataFreeze ? state.infoDataFreeze : state.infoData};
case EXPERIMENT_DETAILS_UPDATED:
return {...state, infoData: {...state.infoData, ...action.payload.changes}};
case setExperimentSaving.type:
return {...state, saving: action.saving};
case updateExperimentAtPath.type:
const newInfoData = set(action.path, action.value, state.infoData);
return {...state, infoData: newInfoData as any};
case actions.EXPERIMENT_UPDATED_SUCCESSFULLY:
return {...state, saving: false};
case ADD_CUSTOM_OUTPUT_LABEL: {

View File

@@ -12,7 +12,7 @@ export function experimentsViewReducer(state: IExperimentsViewState = initialSta
switch (action.type) {
case commonActions.RESET_EXPERIMENTS:
return {...state, experiments: [], selectedExperiment: null, metricVariants: []};
return {...state, experiments: [], selectedExperiment: null, metricVariants: [], showAllSelectedIsActive: false};
default:
return <IExperimentsViewState>commonExperimentsViewReducer(state, action);
}

View File

@@ -34,6 +34,8 @@ export const selectMetricsLoading = createSelector(experimentsView, (sta
export const experimentInfo = createSelector(experiments, (state): IExperimentInfoState => state ? state.info : {});
export const selectSelectedExperiment = createSelector(experimentInfo, (state): ISelectedExperiment => state.selectedExperiment);
export const selectExperimentInfoData = createSelector(experimentInfo, (state): IExperimentInfo => state.infoData);
export const selectShowExtraDataSpinner = createSelector(experimentInfo, state => state.showExtraDataSpinner);
// output selectors

View File

@@ -1,4 +1,4 @@
<div *ngIf="showButton" mat-button [matMenuTriggerFor]="experimentMenu" class="p-0 cell menu-button btn icon sm i-list-view"></div>
<div *ngIf="showButton" mat-button [matMenuTriggerFor]="experimentMenu" class="p-0 cell menu-button btn al-icon sm-md al-ico-bars-menu al-color light-grey-blue"></div>
<div *ngIf="!showButton" #contextTrigger
style="visibility: hidden; position: fixed"
[style.left.px]="position.x"
@@ -13,10 +13,10 @@
<i [class]="'fa '+ ICONS.QUEUED"></i>Manage Queue
</button>
<button mat-menu-item (click)="viewWorkerClicked()" [disabled]="experiment?.status !== TaskStatusEnum.InProgress">
<i [class]="'fa '+ ICONS.WORKER"></i>View worker
<i [class]="'fa '+ ICONS.WORKER"></i>View Worker
</button>
<hr>
<button mat-menu-item (click)="restoreArchivePopup()" [disabled]="isExample">
<button mat-menu-item (click)="restoreArchive()" [disabled]="isExample">
<i [class]="'fa ' + (experiment && experiment?.system_tags && experiment?.system_tags.includes('archived') ? ICONS.SHOW : ICONS.HIDE)"></i>
{{experiment?.system_tags && experiment?.system_tags.includes('archived') ? 'Restore from archive' : 'Archive' + (numSelected > 1 ? ' (' + numSelected + ' items)' : '')}}
</button>
@@ -36,7 +36,11 @@
<i [class]="'fa ' + ICONS.PUBLISHED"></i>Publish
</button>
<hr>
<button mat-menu-item [matMenuTriggerFor]="tagMenu" (menuOpened)="tagMenuOpened()" (menuClosed)="tagMenuContent.clear()">
<button mat-menu-item
[matMenuTriggerFor]="tagMenu"
[disabled]="isExample"
(menuOpened)="tagMenuOpened()"
(menuClosed)="tagMenuContent.clear()">
<i class="fas fa-tag rotate-135"></i>
<span>{{'Add Tag' + (numSelected > 1 ? ' (' + numSelected + ' items)' : '')}}</span>
</button>
@@ -45,7 +49,7 @@
<i class="fa fa-clone"></i>Clone
</button>
<button mat-menu-item (click)="moveToProjectPopup()" [disabled]="isExample">
<i class="fa fa-arrow-right"></i>Move To Project
<i class="fa fa-arrow-right"></i>Move to Project
</button>
</mat-menu>

View File

@@ -20,3 +20,6 @@ button {
}
}
.al-ico-bars-menu {
line-height: 20px;
}

View File

@@ -6,10 +6,11 @@ import {TaskStatusEnum} from '../../../business-logic/model/tasks/taskStatusEnum
import {Project} from '../../../business-logic/model/projects/project';
import {Script} from '../../../business-logic/model/tasks/script';
import {IExecutionForm} from './experiment-execution.model';
import {Execution} from '../../../business-logic/model/tasks/execution';
import {IHyperParamsForm} from '../../../webapp-common/experiments/shared/experiment-hyper-params.model';
import {Artifact} from '../../../business-logic/model/tasks/artifact';
import {IExperimentModelInfo} from '../../../webapp-common/experiments/shared/common-experiment-model.model';
import {ParamsItem} from '../../../business-logic/model/tasks/paramsItem';
import {ConfigurationItem} from '../../../business-logic/model/tasks/configurationItem';
/**
* an extended object of task that includes projection, will come from the server as an api response.
@@ -38,6 +39,8 @@ export interface ISelectedExperiment {
status_message?: string;
status_reason?: string;
last_iteration?: number;
hyperparams?: { [section: string]: { [key: string]: ParamsItem } };
configuration?: { [key: string]: ConfigurationItem };
}
/**
@@ -49,7 +52,8 @@ export interface IExperimentInfo {
comment?: string;
model?: IExperimentModelInfo;
execution?: IExecutionForm;
hyperParams?: IHyperParamsForm;
hyperparams?: { [key: string]: { [key: string]: ParamsItem }; };
configuration?: any;
artifacts?: Artifact[];
}
@@ -70,6 +74,7 @@ export interface ISelectedExperimentExecution {
id: Model['id'],
name: Model['name'],
uri: Model['uri'],
design?: Model['design'];
created: Model['created'],
labels: Model['labels'],
task: {
@@ -85,8 +90,6 @@ export interface ISelectedExperimentExecution {
name: User['name'];
},
};
parameters: Execution['parameters'];
model_desc?: any;
framework?: any;
model_labels?: { [key: string]: number; };
artifacts?: Artifact[];

View File

@@ -21,7 +21,7 @@ export const EXPERIMENTS_TABLE_COL_FIELDS = {
TYPE : 'type' as ExperimentTableColFieldsEnum,
NAME : 'name' as ExperimentTableColFieldsEnum,
TAGS : 'tags' as ExperimentTableColFieldsEnum,
USER : 'user.name' as ExperimentTableColFieldsEnum,
USER : 'users' as ExperimentTableColFieldsEnum,
STARTED : 'started' as ExperimentTableColFieldsEnum,
COMPLETED : 'completed' as ExperimentTableColFieldsEnum,
STATUS : 'status' as ExperimentTableColFieldsEnum,

View File

@@ -24,19 +24,18 @@ export class ExperimentConverterService {
if (!isEqual(executionInfoNoOutputDest, executionInfoNoOutputDestBeforeChange) ||
!isEqual(experimentInfo.model, experimentInfoBeforeChange.model) ||
!isEqual(experimentInfo.hyperParams, experimentInfoBeforeChange.hyperParams) ||
!isEqual(experimentInfo.hyperparams, experimentInfoBeforeChange.hyperparams) ||
!isEqual(experimentInfo.model, experimentInfoBeforeChange.model)
) {
convertedExperiment.execution = this.convertExecution(experimentInfo.execution,
experimentInfo.model, experimentInfo.hyperParams);
experimentInfo.model);
}
return convertedExperiment;
}
convertExecution(execution: IExecutionForm, model: IExperimentModelInfo,
hyperParams: IHyperParamsForm): Execution {
convertExecution(execution: IExecutionForm, model: IExperimentModelInfo): Execution {
return {
...this.commonExperimentConverterService.commonConvertExecution(execution, model, hyperParams),
...this.commonExperimentConverterService.commonConvertExecution(execution, model),
};
}