1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-23 15:29:42 +02:00

feat(gpu) EE-3191 Add GPU support for containers (#7146)

This commit is contained in:
congs 2022-07-18 11:02:14 +12:00 committed by GitHub
parent f0456cbf5f
commit 4997e9c7be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 758 additions and 10 deletions

View file

@ -69,6 +69,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.containerWebhookFeature = FeatureId.CONTAINER_WEBHOOK;
$scope.formValues = {
alwaysPull: true,
GPU: {
enabled: false,
useSpecific: false,
selectedGPUs: [],
capabilities: ['compute', 'utility'],
},
Console: 'none',
Volumes: [],
NetworkContainer: null,
@ -149,6 +155,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
Runtime: null,
ExtraHosts: [],
Devices: [],
DeviceRequests: [],
CapAdd: [],
CapDrop: [],
Sysctls: {},
@ -199,6 +206,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.config.HostConfig.Devices.splice(index, 1);
};
$scope.onGpuChange = function (values) {
return $async(async () => {
$scope.formValues.GPU = values;
});
};
$scope.addSysctl = function () {
$scope.formValues.Sysctls.push({ name: '', value: '' });
};
@ -417,6 +430,36 @@ angular.module('portainer.docker').controller('CreateContainerController', [
config.HostConfig.CapDrop = notAllowed.map(getCapName);
}
function prepareGPUOptions(config) {
const driver = 'nvidia';
const gpuOptions = $scope.formValues.GPU;
const existingDeviceRequest = _.find($scope.config.HostConfig.DeviceRequests, function (o) {
return o.Driver === driver || o.Capabilities[0][0] === 'gpu';
});
if (existingDeviceRequest) {
_.pullAllBy(config.HostConfig.DeviceRequests, [existingDeviceRequest], 'Driver');
}
if (!gpuOptions.enabled) {
return;
}
const deviceRequest = existingDeviceRequest || {
Driver: driver,
Count: -1,
DeviceIDs: [], // must be empty if Count != 0 https://github.com/moby/moby/blob/master/daemon/nvidia_linux.go#L50
Capabilities: [], // array of ORed arrays of ANDed capabilites = [ [c1 AND c2] OR [c1 AND c3] ] : https://github.com/moby/moby/blob/master/api/types/container/host_config.go#L272
// Options: { property1: "string", property2: "string" }, // seems to never be evaluated/used in docker API ?
};
deviceRequest.DeviceIDs = gpuOptions.selectedGPUs;
deviceRequest.Count = 0;
deviceRequest.Capabilities = [gpuOptions.capabilities];
config.HostConfig.DeviceRequests.push(deviceRequest);
}
function prepareConfiguration() {
var config = angular.copy($scope.config);
prepareCmd(config);
@ -433,6 +476,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
prepareLogDriver(config);
prepareCapabilities(config);
prepareSysctls(config);
prepareGPUOptions(config);
return config;
}
@ -571,6 +615,24 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.config.HostConfig.Devices = path;
}
function loadFromContainerDeviceRequests() {
const deviceRequest = _.find($scope.config.HostConfig.DeviceRequests, function (o) {
return o.Driver === 'nvidia' || o.Capabilities[0][0] === 'gpu';
});
if (deviceRequest) {
$scope.formValues.GPU.enabled = true;
$scope.formValues.GPU.useSpecific = deviceRequest.Count !== -1;
$scope.formValues.GPU.selectedGPUs = deviceRequest.DeviceIDs || [];
if ($scope.formValues.GPU.useSpecific) {
$scope.formValues.GPU.selectedGPUs = deviceRequest.DeviceIDs;
}
// we only support a single set of capabilities for now
// UI needs to be reworked in order to support OR combinations of AND capabilities
$scope.formValues.GPU.capabilities = deviceRequest.Capabilities[0];
$scope.formValues.GPU = { ...$scope.formValues.GPU };
}
}
function loadFromContainerSysctls() {
for (var s in $scope.config.HostConfig.Sysctls) {
if ({}.hasOwnProperty.call($scope.config.HostConfig.Sysctls, s)) {
@ -651,6 +713,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
loadFromContainerLabels(d);
loadFromContainerConsole(d);
loadFromContainerDevices(d);
loadFromContainerDeviceRequests(d);
loadFromContainerImageConfig(d);
loadFromContainerResources(d);
loadFromContainerCapabilities(d);
@ -715,6 +778,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
function (d) {
var containers = d;
$scope.runningContainers = containers;
$scope.gpuUseAll = $scope.endpoint.Snapshots[0].GpuUseAll;
$scope.gpuUseList = $scope.endpoint.Snapshots[0].GpuUseList;
if ($transition$.params().from) {
loadFromContainerSpec();
} else {