You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datalab.apache.org by dg...@apache.org on 2021/02/02 14:44:40 UTC
[incubator-datalab] 01/05: [DATALAB-2233]: Add possibility to
create jupiter with GPU
This is an automated email from the ASF dual-hosted git repository.
dgnatyshyn pushed a commit to branch DATALAB-2246
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 47ef2bebb27ff756cb781cdb90849efa37f86f82
Author: Dmytro_Gnatyshyn <di...@ukr.net>
AuthorDate: Mon Feb 1 14:33:16 2021 +0200
[DATALAB-2233]: Add possibility to create jupiter with GPU
---
.../webapp/src/app/core/util/helpUtils.ts | 20 ++++++
...mputational-resource-create-dialog.component.ts | 26 +------
.../create-environment.component.html | 82 +++++++++++++++++++---
.../create-environment.component.scss | 5 ++
.../create-environment.component.ts | 75 +++++++++++++++++---
5 files changed, 167 insertions(+), 41 deletions(-)
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/util/helpUtils.ts b/services/self-service/src/main/resources/webapp/src/app/core/util/helpUtils.ts
index 68178d5..edd51c9 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/util/helpUtils.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/util/helpUtils.ts
@@ -35,4 +35,24 @@ export class HelpUtils {
return;
}
}
+
+ public static setGPUCount(type, gpuType): Array<number> {
+ let count = [];
+ switch (type) {
+ case 'n1-highmem-32' || 'n1-highcpu-32':
+ count = [4, 8];
+ break;
+ case 'n1-highmem-16':
+ count = [2, 4, 8];
+ break;
+ default:
+ count = [1, 2, 4, 8];
+ break;
+ }
+ if (gpuType === 'nvidia-tesla-t4') {
+ count.pop();
+ }
+
+ return count;
+ }
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
index 4822dc0..9411daa 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
@@ -24,7 +24,7 @@ import { ToastrService } from 'ngx-toastr';
import { ComputationalResourceModel } from './computational-resource-create.model';
import { UserResourceService } from '../../../core/services';
-import { HTTP_STATUS_CODES, PATTERNS, CheckUtils, SortUtils } from '../../../core/util';
+import {HTTP_STATUS_CODES, PATTERNS, CheckUtils, SortUtils, HelpUtils} from '../../../core/util';
import { DICTIONARY } from '../../../../dictionary/global.dictionary';
import { CLUSTER_CONFIGURATION } from './cluster-configuration-templates';
@@ -350,33 +350,13 @@ export class ComputationalResourceCreateDialogComponent implements OnInit {
}
}
- public setGPUCount(type, gpuType): Array<number> {
- let count = [];
- switch (type) {
- case 'n1-highmem-32' || 'n1-highcpu-32':
- count = [4, 8];
- break;
- case 'n1-highmem-16':
- count = [2, 4, 8];
- break;
- default:
- count = [1, 2, 4, 8];
- break;
- }
- if (gpuType === 'nvidia-tesla-t4') {
- count.pop();
- }
-
- return count;
- }
-
public setCount(type: any, gpuType: any): void {
if (type === 'master') {
const masterShape = this.resourceForm.controls['shape_master'].value;
- this.masterGPUcount = this.setGPUCount(masterShape, gpuType);
+ this.masterGPUcount = HelpUtils.setGPUCount(masterShape, gpuType);
} else {
const slaveShape = this.resourceForm.controls['shape_slave'].value;
- this.slaveGPUcount = this.setGPUCount(slaveShape, gpuType);
+ this.slaveGPUcount = HelpUtils.setGPUCount(slaveShape, gpuType);
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.html
index eabff73..9cd1c8c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.html
@@ -164,18 +164,84 @@
<div *ngIf="currentTemplate">
<div class="checkbox-group"
*ngIf="currentTemplate?.image !== 'docker.datalab-zeppelin' && currentTemplate?.image !== 'docker.datalab-superset' && currentTemplate?.image !== 'docker.datalab-jupyterlab'">
- <label>
- <input #configurationNode type="checkbox" (change)="selectConfiguration()"/> Spark configurations
- </label>
- <div class="config-details" [ngClass]="{ show: configuration?.nativeElement['checked'] || false }">
+<!-- <label>-->
+<!-- <input #configurationNode type="checkbox" (change)="selectConfiguration()"/> Spark configurations-->
+<!-- </label>-->
+ <div class="d-flex cursor-pointer label m-bott-20" (click)="selectConfiguration()">
+ <div class="empty-checkbox" [ngClass]="{'checked': this.additionalParams.configurationNode}">
+ <span class="checked-checkbox" *ngIf="this.additionalParams.configurationNode"></span>
+ </div>
+ <span class=" pl-5">Spark configurations</span>
+ </div>
+ <div class="config-details" [ngClass]="{ show: this.additionalParams.configurationNode}">
<textarea formControlName="cluster_config" placeholder="Cluster configuration template, JSON"
data-gramm_editor="false" id="config"></textarea>
- <span class="error spark-config"
- *ngIf="!createExploratoryForm?.controls.cluster_config.valid && createExploratoryForm?.controls['cluster_config'].dirty">Configuration
+ <span class="error spark-config"
+ *ngIf="!createExploratoryForm?.controls.cluster_config.valid && createExploratoryForm?.controls['cluster_config'].dirty">Configuration
parameters is not in a valid format.</span>
- </div>
+ </div>
</div>
+ <ng-template [ngIf]="selectedCloud === 'gcp'">
+ <div class="checkbox-group">
+ <div class="d-flex cursor-pointer label m-bott-20" (click)="addGpuFields()">
+ <div class="empty-checkbox" [ngClass]="{'checked': this.additionalParams.gpu}">
+ <span class="checked-checkbox" *ngIf="this.additionalParams.gpu"></span>
+ </div>
+ <span class=" pl-5">GPU</span>
+ </div>
+ <ng-template [ngIf]="this.additionalParams.gpu">
+ <div class="control-group">
+ <label class="label">Master GPU type</label>
+ <div class="control selector-wrapper"
+ [matTooltip]="'Please, select instance size.'"
+ matTooltipPosition="above"
+ [matTooltipClass]="'full-size-tooltip'"
+ [matTooltipDisabled]="!!createExploratoryForm.controls['shape'].value"
+ >
+ <span class="form-field-wrapper" [ngClass]="{ 'not-active': !createExploratoryForm.controls['shape'].value}">
+ <mat-form-field>
+ <mat-label>Select master GPU type</mat-label>
+ <mat-select formControlName="master_GPU_type" disableOptionCentering [disabled]="!createExploratoryForm.controls['shape'].value"
+ panelClass="create-resources-shapes" placeholder="Master GPU type">
+ <mat-option *ngFor="let list_item of masterGPUtype" [value]="list_item.Gpu_type" (click)="setCount('', list_item.Gpu_type)">
+ <strong class="highlight icon-label">{{ list_item.Size }}</strong> {{ list_item.Gpu_type }}
+ </mat-option>
+ </mat-select>
+ <button class="caret">
+ <i class="material-icons">keyboard_arrow_down</i>
+ </button>
+ </mat-form-field>
+ </span>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="label">Master GPU count</label>
+ <div class="control selector-wrapper"
+ [matTooltip]="'Please, select master GPU type.'"
+ matTooltipPosition="above"
+ [matTooltipClass]="'full-size-tooltip'"
+ [matTooltipDisabled]="!!createExploratoryForm.controls['master_GPU_type'].value"
+ >
+ <span class="form-field-wrapper" [ngClass]="{ 'not-active': !createExploratoryForm.controls['master_GPU_type'].value}">
+ <mat-form-field>
+ <mat-label>Select master GPU count</mat-label>
+ <mat-select formControlName="master_GPU_count" disableOptionCentering [disabled]="!createExploratoryForm.controls['master_GPU_type'].value"
+ panelClass="create-resources-shapes" placeholder="Master GPU count">
+ <mat-option *ngFor="let list_item of masterGPUcount" [value]="list_item">
+ {{ list_item }}
+ </mat-option>
+ </mat-select>
+ <button class="caret">
+ <i class="material-icons">keyboard_arrow_down</i>
+ </button>
+ </mat-form-field>
+ </span>
+ </div>
+ </div>
+ </ng-template>
+ </div>
+ </ng-template>
<small *ngIf="currentTemplate?.image === 'docker.datalab-zeppelin'">
Spark default configuration for Apache Zeppelin can not be changed from DataLab UI. Currently it can be
done directly through Apache Zeppelin interpreter menu.
@@ -185,7 +251,7 @@
</small>
</div>
- <div class="text-center m-top-30">
+ <div class="text-center m-top-30" id="buttons">
<button mat-raised-button type="button" class="butt action" (click)="dialogRef.close()">Cancel</button>
<button mat-raised-button type="button" class="butt butt-success action"
[disabled]="!createExploratoryForm?.valid"
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.scss
index aecad81..6baf727 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.scss
@@ -18,6 +18,11 @@
*/
.checkbox-group {
+
+ .empty-checkbox{
+ margin: 0;
+ }
+
.config-details {
height: 0;
opacity: 0;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.ts
index f7cb25a..1c50761 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/create-environment/create-environment.component.ts
@@ -24,10 +24,11 @@ import { ToastrService } from 'ngx-toastr';
import { Project } from '../../../administration/project/project.component';
import { UserResourceService, ProjectService } from '../../../core/services';
-import { CheckUtils, SortUtils, HTTP_STATUS_CODES, PATTERNS } from '../../../core/util';
+import {CheckUtils, SortUtils, HTTP_STATUS_CODES, PATTERNS, HelpUtils} from '../../../core/util';
import { DICTIONARY } from '../../../../dictionary/global.dictionary';
import { CLUSTER_CONFIGURATION } from '../../computational/computational-resource-create-dialog/cluster-configuration-templates';
import {tap} from 'rxjs/operators';
+import {timer} from 'rxjs';
@Component({
selector: 'create-environment',
@@ -49,8 +50,19 @@ export class ExploratoryEnvironmentCreateComponent implements OnInit {
images: Array<any>;
maxNotebookLength: number = 14;
public areShapes: boolean;
+ public selectedCloud: string = '';
+ public masterGPUcount: Array<number>;
+ public masterGPUtype = [
+ {Size: 'S', Gpu_type: 'nvidia-tesla-t4'},
+ {Size: 'M', Gpu_type: 'nvidia-tesla-v100'}
+ ];
+
+ public additionalParams = {
+ configurationNode: false,
+ gpu: false,
+ };
+
- @ViewChild('configurationNode') configuration;
constructor(
@Inject(MAT_DIALOG_DATA) public data: any,
@@ -91,13 +103,18 @@ export class ExploratoryEnvironmentCreateComponent implements OnInit {
public setEndpoints(project) {
if (this.images) this.images = [];
-
+ if (this.selectedCloud) this.selectedCloud = '';
this.endpoints = project.endpoints
.filter(e => e.status === 'RUNNING')
.map(e => e.name);
+
}
public getTemplates(project, endpoint) {
+ if (this.selectedCloud) this.selectedCloud = '';
+ const endpoints = this.data.environments.find(env => env.project === project).endpoints;
+ this.selectedCloud = endpoints.find(endp => endp.name === endpoint).cloudProvider.toLowerCase();
+
this.userResourceService.getExploratoryTemplates(project, endpoint)
.pipe(tap(results => {
@@ -153,11 +170,47 @@ export class ExploratoryEnvironmentCreateComponent implements OnInit {
}
public selectConfiguration() {
- const value = (this.configuration.nativeElement.checked && this.createExploratoryForm)
- ? JSON.stringify(CLUSTER_CONFIGURATION.SPARK, undefined, 2) : '';
+ this.additionalParams.configurationNode = !this.additionalParams.configurationNode;
+ if (this.additionalParams.configurationNode) {
+ const value = (this.additionalParams.configurationNode && this.createExploratoryForm)
+ ? JSON.stringify(CLUSTER_CONFIGURATION.SPARK, undefined, 2) : '';
+ timer(500).subscribe(_ => {
+ document.querySelector('#buttons').scrollIntoView({ block: 'start', behavior: 'smooth' });
+ });
+ this.createExploratoryForm.controls['cluster_config'].setValue(value);
+ }
+ }
+
+ public addGpuFields() {
+ this.additionalParams.gpu = !this.additionalParams.gpu;
+
+ const controls = ['master_GPU_type', 'master_GPU_count'];
+ if (!this.additionalParams.gpu) {
+ controls.forEach(control => {
+ this.createExploratoryForm.controls[control].setValue(null);
+ this.createExploratoryForm.controls[control].clearValidators();
+ this.createExploratoryForm.controls[control].updateValueAndValidity();
+ });
+
+ } else {
+ controls.forEach(control => {
+ this.createExploratoryForm.controls[control].setValidators([Validators.required]);
+ this.createExploratoryForm.controls[control].updateValueAndValidity();
+ });
+ timer(100).subscribe(_ => {
+ document.querySelector('#buttons').scrollIntoView({ block: 'start', behavior: 'smooth' });
+ });
+ }
+ }
- document.querySelector('#config').scrollIntoView({ block: 'start', behavior: 'smooth' });
- this.createExploratoryForm.controls['cluster_config'].setValue(value);
+ public setCount(type: any, gpuType: any): void {
+ // if (type === 'master') {
+ const masterShape = this.createExploratoryForm.controls['shape'].value;
+ this.masterGPUcount = HelpUtils.setGPUCount(masterShape, gpuType);
+ // } else {
+ // const slaveShape = this.resourceForm.controls['shape_slave'].value;
+ // this.slaveGPUcount = HelpUtils.setGPUCount(slaveShape, gpuType);
+ // }
}
private initFormModel(): void {
@@ -174,7 +227,9 @@ export class ExploratoryEnvironmentCreateComponent implements OnInit {
this.checkDuplication.bind(this)
]],
cluster_config: ['', [this.validConfiguration.bind(this)]],
- custom_tag: ['', [Validators.pattern(PATTERNS.namePattern)]]
+ custom_tag: ['', [Validators.pattern(PATTERNS.namePattern)]],
+ master_GPU_type: [null],
+ master_GPU_count: [null],
});
}
@@ -193,8 +248,8 @@ export class ExploratoryEnvironmentCreateComponent implements OnInit {
}
private validConfiguration(control) {
- if (this.configuration)
- return this.configuration.nativeElement['checked']
+ if (this.additionalParams.configurationNode)
+ return this.additionalParams.configurationNode
? (control.value && control.value !== null && CheckUtils.isJSON(control.value) ? null : { valid: false })
: null;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datalab.apache.org
For additional commands, e-mail: commits-help@datalab.apache.org