Skip to content

Commit 05acfee

Browse files
authored
enable azure gpu on frontend (#4226)
1 parent ad7ad6d commit 05acfee

File tree

6 files changed

+394
-228
lines changed

6 files changed

+394
-228
lines changed

dashboard/src/components/AzureProvisionerSettings.tsx

Lines changed: 98 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ import InputRow from "./form-components/InputRow";
3333
import Button from "./porter/Button";
3434
import Error from "./porter/Error";
3535
import Icon from "./porter/Icon";
36+
import InputSlider from "./porter/InputSlider";
3637
import Link from "./porter/Link";
38+
import Select from "./porter/Select";
3739
import Spacer from "./porter/Spacer";
3840
import Step from "./porter/Step";
3941
import Text from "./porter/Text";
@@ -53,6 +55,7 @@ type Props = RouteComponentProps & {
5355
provisionerError?: string;
5456
credentialId: string;
5557
clusterId?: number;
58+
gpuModal?: boolean;
5659
};
5760

5861
const VALID_CIDR_RANGE_PATTERN =
@@ -71,6 +74,11 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
7174
const [clusterName, setClusterName] = useState("");
7275
const [azureLocation, setAzureLocation] = useState("eastus");
7376
const [machineType, setMachineType] = useState("Standard_B2als_v2");
77+
const [gpuMinInstances, setGpuMinInstances] = useState(1);
78+
const [gpuMaxInstances, setGpuMaxInstances] = useState(5);
79+
const [gpuInstanceType, setGpuInstanceType] = useState(
80+
"Standard_NC4as_T4_v3"
81+
);
7482
const [isExpanded, setIsExpanded] = useState(false);
7583
const [minInstances, setMinInstances] = useState(1);
7684
const [maxInstances, setMaxInstances] = useState(10);
@@ -85,13 +93,22 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
8593
regionFilteredMachineTypeOptions,
8694
setRegionFilteredMachineTypeOptions,
8795
] = useState<MachineTypeOption[]>(azureSupportedMachineTypes(azureLocation));
96+
const [
97+
regionFilteredGPUMachineTypeOptions,
98+
setRegionFilteredGPUMachineTypeOptions,
99+
] = useState<MachineTypeOption[]>(
100+
azureSupportedMachineTypes(azureLocation, true)
101+
);
88102

89103
const { showIntercomWithMessage } = useIntercom();
90104

91105
useEffect(() => {
92106
setRegionFilteredMachineTypeOptions(
93107
azureSupportedMachineTypes(azureLocation)
94108
);
109+
setRegionFilteredGPUMachineTypeOptions(
110+
azureSupportedMachineTypes(azureLocation, true)
111+
);
95112
}, [azureLocation]);
96113

97114
const markStepStarted = async (
@@ -188,6 +205,42 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
188205
console.log(err);
189206
}
190207

208+
const nodePools = [
209+
new AKSNodePool({
210+
instanceType: "Standard_B2als_v2",
211+
minInstances: 1,
212+
maxInstances: 3,
213+
nodePoolType: NodePoolType.SYSTEM,
214+
mode: "User",
215+
}),
216+
new AKSNodePool({
217+
instanceType: "Standard_B2as_v2",
218+
minInstances: 1,
219+
maxInstances: 3,
220+
nodePoolType: NodePoolType.MONITORING,
221+
mode: "User",
222+
}),
223+
new AKSNodePool({
224+
instanceType: machineType,
225+
minInstances: minInstances || 1,
226+
maxInstances: maxInstances || 10,
227+
nodePoolType: NodePoolType.APPLICATION,
228+
mode: "User",
229+
}),
230+
];
231+
232+
// Conditionally add the last EKSNodeGroup if gpuModal is enabled
233+
if (props.gpuModal) {
234+
nodePools.push(
235+
new AKSNodePool({
236+
instanceType: gpuInstanceType,
237+
minInstances: gpuMinInstances || 0,
238+
maxInstances: gpuMaxInstances || 5,
239+
nodePoolType: NodePoolType.CUSTOM,
240+
})
241+
);
242+
}
243+
191244
const data = new Contract({
192245
cluster: new Cluster({
193246
projectId: currentProject.id,
@@ -201,29 +254,7 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
201254
clusterVersion: clusterVersion || "v1.27.3",
202255
cidrRange: cidrRange || "10.78.0.0/16",
203256
location: azureLocation,
204-
nodePools: [
205-
new AKSNodePool({
206-
instanceType: "Standard_B2als_v2",
207-
minInstances: 1,
208-
maxInstances: 3,
209-
nodePoolType: NodePoolType.SYSTEM,
210-
mode: "User",
211-
}),
212-
new AKSNodePool({
213-
instanceType: "Standard_B2as_v2",
214-
minInstances: 1,
215-
maxInstances: 3,
216-
nodePoolType: NodePoolType.MONITORING,
217-
mode: "User",
218-
}),
219-
new AKSNodePool({
220-
instanceType: machineType,
221-
minInstances: minInstances || 1,
222-
maxInstances: maxInstances || 10,
223-
nodePoolType: NodePoolType.APPLICATION,
224-
mode: "User",
225-
}),
226-
],
257+
nodePools,
227258
skuTier,
228259
}),
229260
},
@@ -317,7 +348,10 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
317348

318349
// TODO: pass in contract as the already parsed object, rather than JSON (requires changes to AWS/GCP provisioning)
319350
const contract = Contract.fromJsonString(
320-
JSON.stringify(props.selectedClusterVersion)
351+
JSON.stringify(props.selectedClusterVersion),
352+
{
353+
ignoreUnknownFields: true,
354+
}
321355
);
322356

323357
if (
@@ -471,6 +505,46 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
471505
);
472506
};
473507

508+
if (props.gpuModal) {
509+
return (
510+
<>
511+
<Select
512+
options={regionFilteredGPUMachineTypeOptions}
513+
width="350px"
514+
disabled={isReadOnly}
515+
value={gpuInstanceType}
516+
setValue={(x: string) => {
517+
setGpuInstanceType(x);
518+
}}
519+
label="GPU Instance type"
520+
/>
521+
<Spacer y={1} />
522+
<InputSlider
523+
label="Max Instances: "
524+
unit="nodes"
525+
min={0}
526+
max={5}
527+
step={1}
528+
width="350px"
529+
disabled={isReadOnly}
530+
value={gpuMaxInstances.toString()}
531+
setValue={(x: number) => {
532+
setGpuMaxInstances(x);
533+
}}
534+
/>
535+
<Button
536+
disabled={isDisabled()}
537+
onClick={createCluster}
538+
status={getStatus()}
539+
>
540+
Provision
541+
</Button>
542+
543+
<Spacer y={0.5} />
544+
</>
545+
);
546+
}
547+
474548
return (
475549
<>
476550
<StyledForm>{renderForm()}</StyledForm>

dashboard/src/components/azureUtils.ts

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,34 @@ export const AzureLocationOptions = [
2525
export type MachineTypeOption = {
2626
value: string;
2727
label: string;
28+
resources: { vCPU: number; RAM: number; GPU?: number };
2829
supportedRegions: Set<string>;
2930
};
3031

3132
export const azureSupportedMachineTypes = (
32-
region: string
33+
region: string,
34+
gpu?: boolean
3335
): MachineTypeOption[] => {
34-
return AzureMachineTypeOptions.filter((option) =>
35-
option.supportedRegions.has(region)
36+
return AzureMachineTypeOptions.filter(
37+
(option) =>
38+
option.supportedRegions.has(region) && !!option.resources.GPU === !!gpu
3639
);
3740
};
3841

42+
export const azureMachineTypeDetails = (
43+
type: string
44+
): MachineTypeOption | undefined => {
45+
const matches = AzureMachineTypeOptions.filter(
46+
(option) => option.value === type
47+
);
48+
49+
if (matches.length === 0) {
50+
return undefined;
51+
}
52+
53+
return matches[0];
54+
};
55+
3956
// Retrieve updated list of supported regions by running the following command: az vm list-skus --all --output table | grep <INSTANCE_TYPE> | grep 1,2,3 | grep None | awk '{print "\047" tolower($2) "\047"}' | paste -s -d, -
4057
// last updated 12/19/2020
4158
//
@@ -44,6 +61,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
4461
{
4562
value: "Standard_B2als_v2",
4663
label: "Standard_B2als_v2",
64+
resources: { vCPU: 2, RAM: 4 },
4765
supportedRegions: new Set<string>([
4866
"australiaeast",
4967
"brazilsouth",
@@ -71,6 +89,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
7189
{
7290
value: "Standard_B2as_v2",
7391
label: "Standard_B2as_v2",
92+
resources: { vCPU: 2, RAM: 8 },
7493
supportedRegions: new Set<string>([
7594
"australiaeast",
7695
"brazilsouth",
@@ -98,6 +117,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
98117
{
99118
value: "Standard_A2_v2",
100119
label: "Standard_A2_v2",
120+
resources: { vCPU: 2, RAM: 4 },
101121
supportedRegions: new Set<string>([
102122
"australiaeast",
103123
"canadacentral",
@@ -122,6 +142,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
122142
{
123143
value: "Standard_A4_v2",
124144
label: "Standard_A4_v2",
145+
resources: { vCPU: 4, RAM: 8 },
125146
supportedRegions: new Set<string>([
126147
"australiaeast",
127148
"canadacentral",
@@ -146,6 +167,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
146167
{
147168
value: "Standard_DS1_v2",
148169
label: "Standard_DS1_v2",
170+
resources: { vCPU: 1, RAM: 3.5 },
149171
supportedRegions: new Set<string>([
150172
"australiaeast",
151173
"canadacentral",
@@ -170,6 +192,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
170192
{
171193
value: "Standard_DS2_v2",
172194
label: "Standard_DS2_v2",
195+
resources: { vCPU: 2, RAM: 7 },
173196
supportedRegions: new Set<string>([
174197
"australiaeast",
175198
"canadacentral",
@@ -202,6 +225,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
202225
{
203226
value: "Standard_D2ads_v5",
204227
label: "Standard_D2ads_v5",
228+
resources: { vCPU: 2, RAM: 8 },
205229
supportedRegions: new Set<string>([
206230
"australiaeast",
207231
"canadacentral",
@@ -221,6 +245,7 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
221245
{
222246
value: "Standard_B4als_v2",
223247
label: "Standard_B4als_v2",
248+
resources: { vCPU: 4, RAM: 8 },
224249
supportedRegions: new Set<string>([
225250
"australiaeast",
226251
"brazilsouth",
@@ -245,4 +270,76 @@ const AzureMachineTypeOptions: MachineTypeOption[] = [
245270
"westus3",
246271
]),
247272
},
273+
{
274+
value: "Standard_NC4as_T4_v3",
275+
label: "Standard_NC4as_T4_v3",
276+
resources: { vCPU: 4, RAM: 28, GPU: 1 },
277+
supportedRegions: new Set<string>([
278+
"australiaeast",
279+
"centralindia",
280+
"eastus",
281+
"eastus2",
282+
"japaneast",
283+
"northeurope",
284+
"southcentralus",
285+
"southeastasia",
286+
"uksouth",
287+
"westeurope",
288+
"westus2",
289+
]),
290+
},
291+
{
292+
value: "Standard_NC8as_T4_v3",
293+
label: "Standard_NC8as_T4_v3",
294+
resources: { vCPU: 8, RAM: 56, GPU: 1 },
295+
supportedRegions: new Set<string>([
296+
"australiaeast",
297+
"centralindia",
298+
"eastus",
299+
"eastus2",
300+
"japaneast",
301+
"northeurope",
302+
"southcentralus",
303+
"southeastasia",
304+
"uksouth",
305+
"westeurope",
306+
"westus2",
307+
]),
308+
},
309+
{
310+
value: "Standard_NC16as_T4_v3",
311+
label: "Standard_NC16as_T4_v3",
312+
resources: { vCPU: 16, RAM: 110, GPU: 1 },
313+
supportedRegions: new Set<string>([
314+
"australiaeast",
315+
"centralindia",
316+
"eastus",
317+
"eastus2",
318+
"japaneast",
319+
"northeurope",
320+
"southcentralus",
321+
"southeastasia",
322+
"uksouth",
323+
"westeurope",
324+
"westus2",
325+
]),
326+
},
327+
{
328+
value: "Standard_NC64as_T4_v3",
329+
label: "Standard_NC64as_T4_v3",
330+
resources: { vCPU: 64, RAM: 440, GPU: 4 },
331+
supportedRegions: new Set<string>([
332+
"australiaeast",
333+
"centralindia",
334+
"eastus",
335+
"eastus2",
336+
"japaneast",
337+
"northeurope",
338+
"southcentralus",
339+
"southeastasia",
340+
"uksouth",
341+
"westeurope",
342+
"westus2",
343+
]),
344+
},
248345
];

0 commit comments

Comments
 (0)