Skip to content

Commit 513f409

Browse files
authored
feat: enable support for gpu configuration (#50)
feat: enable support for gpu configuration Refs: #40 --------- Signed-off-by: seven <[email protected]>
1 parent 6a3155e commit 513f409

File tree

7 files changed

+100
-6
lines changed

7 files changed

+100
-6
lines changed

samples/aliyun-poc-fc-gpu.yml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ functions:
2828
cmd: "npm start"
2929
port: 9000
3030
memory: 512
31+
gpu: TESLA_8
3132
timeout: 10
3233
network:
3334
vpc_id: vpc-2vc8v9btc8470laqui9bk

src/parser/functionParser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FunctionDomain, FunctionRaw, NasStorageClassEnum } from '../types';
1+
import { FunctionDomain, FunctionGpuEnum, FunctionRaw, NasStorageClassEnum } from '../types';
22
import { isEmpty } from 'lodash';
33

44
export const parseFunction = (functions?: {
@@ -13,6 +13,7 @@ export const parseFunction = (functions?: {
1313
code: func.code,
1414
container: func.container,
1515
memory: func.memory,
16+
gpu: func.gpu as FunctionGpuEnum,
1617
timeout: func.timeout,
1718
environment: func.environment,
1819
log: func.log,

src/stack/rosStack/function.ts

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { ActionContext, FunctionDomain, NasStorageClassEnum, ServerlessIac } from '../../types';
1+
import {
2+
ActionContext,
3+
FunctionDomain,
4+
FunctionGpuEnum,
5+
NasStorageClassEnum,
6+
ServerlessIac,
7+
} from '../../types';
28
import {
39
CODE_ZIP_SIZE_LIMIT,
410
encodeBase64ForRosId,
@@ -25,13 +31,25 @@ const storageClassMap = {
2531
[NasStorageClassEnum.EXTREME_STANDARD]: { fileSystemType: 'extreme', storageType: 'standard' },
2632
[NasStorageClassEnum.EXTREME_ADVANCE]: { fileSystemType: 'extreme', storageType: 'advance' },
2733
};
34+
2835
const securityGroupRangeMap: { [key: string]: string } = {
2936
TCP: '1/65535',
3037
UDP: '1/65535',
3138
ICMP: '-1/-1',
3239
GRE: '-1/-1',
3340
ALL: '-1/-1',
3441
};
42+
const gpuConfigMap = {
43+
[FunctionGpuEnum.TESLA_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.tesla.1' },
44+
[FunctionGpuEnum.TESLA_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.tesla.1' },
45+
[FunctionGpuEnum.TESLA_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.tesla.1' },
46+
[FunctionGpuEnum.AMPERE_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.ampere.1' },
47+
[FunctionGpuEnum.AMPERE_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.ampere.1' },
48+
[FunctionGpuEnum.AMPERE_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.ampere.1' },
49+
[FunctionGpuEnum.AMPERE_24]: { gpuMemorySize: 24576, gpuType: 'fc.gpu.ampere.1' },
50+
[FunctionGpuEnum.ADA_48]: { gpuMemorySize: 49152, gpuType: 'fc.gpu.ada.1' },
51+
};
52+
3553
const transformSecurityRules = (rules: Array<string>, ruleType: 'INGRESS' | 'EGRESS') => {
3654
return rules.map((rule) => {
3755
const [protocol, cidrIp, portRange] = rule.split(':');
@@ -49,6 +67,13 @@ const transformSecurityRules = (rules: Array<string>, ruleType: 'INGRESS' | 'EGR
4967
});
5068
};
5169

70+
const transformGpuConfig = (gpu: FunctionDomain['gpu']) => {
71+
if (!gpu) {
72+
return undefined;
73+
}
74+
75+
return gpuConfigMap[gpu];
76+
};
5277
export const resolveFunctions = (
5378
scope: ros.Construct,
5479
functions: Array<FunctionDomain> | undefined,
@@ -248,8 +273,9 @@ export const resolveFunctions = (
248273
{
249274
functionName: replaceReference(fnc.name, context),
250275
memorySize: replaceReference(fnc.memory, context),
251-
timeout: replaceReference(fnc.timeout, context),
252276
diskSize: fnc.storage?.disk,
277+
gpuConfig: transformGpuConfig(fnc.gpu),
278+
timeout: replaceReference(fnc.timeout, context),
253279
environmentVariables: replaceReference(fnc.environment, context),
254280
logConfig,
255281
vpcConfig,

src/types/domains/function.ts

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type FunctionRaw = {
1111
port: number;
1212
};
1313
memory: number;
14+
gpu: string;
1415
timeout: number;
1516
log?: boolean;
1617
environment?: {
@@ -48,6 +49,7 @@ export type FunctionDomain = {
4849
port: number;
4950
};
5051
memory: number;
52+
gpu?: FunctionGpuEnum;
5153
timeout: number;
5254
log?: boolean;
5355
environment?: {
@@ -77,3 +79,14 @@ export enum NasStorageClassEnum {
7779
EXTREME_STANDARD = 'EXTREME_STANDARD',
7880
EXTREME_ADVANCE = 'EXTREME_ADVANCE',
7981
}
82+
83+
export enum FunctionGpuEnum {
84+
TESLA_8 = 'TESLA_8',
85+
TESLA_12 = 'TESLA_12',
86+
TESLA_16 = 'TESLA_16',
87+
AMPERE_8 = 'AMPERE_8',
88+
AMPERE_12 = 'AMPERE_12',
89+
AMPERE_16 = 'AMPERE_16',
90+
AMPERE_24 = 'AMPERE_24',
91+
ADA_48 = 'ADA_48',
92+
}

src/validator/functionSchema.ts

+13
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ export const functionSchema = {
4646
},
4747
},
4848
memory: { type: 'number' },
49+
gpu: {
50+
type: 'string',
51+
enum: [
52+
'TESLA_8',
53+
'TESLA_12',
54+
'TESLA_16',
55+
'AMPERE_8',
56+
'AMPERE_12',
57+
'AMPERE_16',
58+
'AMPERE_24',
59+
'ADA_48',
60+
],
61+
},
4962
timeout: { type: 'number' },
5063
log: { type: 'boolean' },
5164
environment: {

tests/fixtures/deployFixture.ts

+26
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,32 @@ export const oneFcWithContainerRos = {
994994
},
995995
};
996996

997+
export const oneFcWithGpuIac = {
998+
...oneFcIac,
999+
functions: [
1000+
{
1001+
...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}),
1002+
gpu: 'TESLA_8',
1003+
},
1004+
],
1005+
} as ServerlessIac;
1006+
export const oneFcWithGpuRos = {
1007+
...oneFcRos,
1008+
Resources: {
1009+
...oneFcRos.Resources,
1010+
hello_fn: {
1011+
...oneFcRos.Resources.hello_fn,
1012+
Properties: {
1013+
...oneFcRos.Resources.hello_fn.Properties,
1014+
GpuConfig: {
1015+
GpuMemorySize: 8192,
1016+
GpuType: 'fc.gpu.tesla.1',
1017+
},
1018+
},
1019+
},
1020+
},
1021+
};
1022+
9971023
export const largeCodeRos = {
9981024
Description: 'my-demo-service stack',
9991025
Mappings: {

tests/stack/deploy.test.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
oneFcRos,
2020
oneFcWithContainerIac,
2121
oneFcWithContainerRos,
22+
oneFcWithGpuIac,
23+
oneFcWithGpuRos,
2224
oneFcWithStageRos,
2325
referredServiceIac,
2426
referredServiceRos,
@@ -217,7 +219,7 @@ describe('Unit tests for stack deployment', () => {
217219
});
218220
});
219221

220-
describe('unit test for function nas attachment', () => {
222+
describe('unit test for serverless Gpu', () => {
221223
it('should deploy function with nas when nas field is provided', async () => {
222224
const stackName = 'my-demo-stack-with-nas';
223225
mockedRosStackDeploy.mockResolvedValue(stackName);
@@ -231,9 +233,7 @@ describe('Unit tests for stack deployment', () => {
231233
{ stackName },
232234
]);
233235
});
234-
});
235236

236-
describe('unit test for function with container', () => {
237237
it('should deploy function with container when container field is provided', async () => {
238238
const stackName = 'my-demo-stack-with-container';
239239
mockedRosStackDeploy.mockResolvedValue(stackName);
@@ -247,5 +247,19 @@ describe('Unit tests for stack deployment', () => {
247247
{ stackName },
248248
]);
249249
});
250+
251+
it('should deploy function with gpu configured', async () => {
252+
const stackName = 'my-demo-stack-with-gpu';
253+
mockedRosStackDeploy.mockResolvedValue(stackName);
254+
255+
await deployStack(stackName, oneFcWithGpuIac, { stackName } as ActionContext);
256+
257+
expect(mockedRosStackDeploy).toHaveBeenCalledTimes(2);
258+
expect(mockedRosStackDeploy.mock.calls[1]).toEqual([
259+
stackName,
260+
oneFcWithGpuRos,
261+
{ stackName },
262+
]);
263+
});
250264
});
251265
});

0 commit comments

Comments
 (0)