Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generic VPU example #15

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ For more details about each sample metadata, please check the [samples.json](sam
Sample showing an example using Tensorflow Lite with hardware acceleration
on the IMX8 SoCs with Vivante GPU.
Examples available in Python.

- **vpu:**
Sample showing an example of using VPU on i.MX8 for encoding and decoding
Example available as a generic Dockerfile.
8 changes: 8 additions & 0 deletions samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,13 @@
"baseTemplateSupport": "Toradex",
"sampleSupport": "Community"
}
},
"VPU": {
"generic": {
"folder": "vpuGeneric",
"baseTemplate": "genericTemplate",
"baseTemplateSupport": "Toradex",
"sampleSupport": "Community"
}
andreriesco marked this conversation as resolved.
Show resolved Hide resolved
}
}
1 change: 1 addition & 0 deletions vpu/generic/vpuGeneric/.conf/.container
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vpugeneric
1 change: 1 addition & 0 deletions vpu/generic/vpuGeneric/.conf/.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
genericTemplate
70 changes: 70 additions & 0 deletions vpu/generic/vpuGeneric/.conf/checkCIEnv.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# suppress warnings that we need to use
param()

$_envVarsSettings = @(
"DOCKER_REGISTRY",
"DOCKER_LOGIN",
"DOCKER_TAG",
"TCB_CLIENTID",
"TCB_CLIENTSECRET",
"TCB_PACKAGE",
"TCB_FLEET",
"TORIZON_ARCH"
)

$_envVarsSecrets = @(
# secrets
"DOCKER_PSSWD",
"PLATFORM_CLIENT_ID",
"PLATFORM_CLIENT_SECRET",
"PLATFORM_CREDENTIALS"
)

function _gotoError {
Write-Host -ForegroundColor DarkYellow `
"`n⚠️ THESE ENV VARIABLES NEED TO BE SET IN YOUR CI/CD ENVIRONMENT`n"
exit 69
}

$_missingEnvVarSettings = $false
$_missingEnvVarSecrets = $false

# check if we are running in a GitLab CI or GitHub Actions environment
if (
($Env:GITLAB_CI -eq $true) -or
($Env:CI -eq $true)
) {
# validate the environment variables
foreach ($var in $_envVarsSettings) {
if ((Test-Path "Env:$var") -eq $false) {
Write-Host -ForegroundColor DarkRed `
"❌ $var is not set"
$_missingEnvVarSettings = $true
}
}

if ($_missingEnvVarSettings) {
Write-Host -ForegroundColor DarkRed `
"Missing settings.json properties, aborting`n"
}

foreach ($var in $_envVarsSecrets) {
if ((Test-Path "Env:$var") -eq $false) {
Write-Host -ForegroundColor DarkRed `
"❌ $var is not set"
$_missingEnvVarSecrets = $true
}
}

if ($_missingEnvVarSecrets) {
Write-Host -ForegroundColor DarkRed `
"Missing protected environment variables, aborting`n"
}

if (
$_missingEnvVarSettings -or
$_missingEnvVarSecrets
) {
_gotoError
}
}
87 changes: 87 additions & 0 deletions vpu/generic/vpuGeneric/.conf/checkDeps.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# suppress warnings that we need to use
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidOverwritingBuiltInCmdlets', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingInvokeExpression', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingPositionalParameters', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidGlobalVars', ""
)]
param()

$env:DOCKER_HOST = ""

if ($Env:GITLAB_CI -eq $true) {
Write-Host "ℹ️ :: GITLAB_CI :: ℹ️"
$Env:DOCKER_HOST = "tcp://docker:2375"
}

# tested on Ubuntu 22.04
$_packages = Get-Content .conf/deps.json | ConvertFrom-Json

# docker and docker-compose are special cases
# TODO: check also for podman or other runtime
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
Write-Host -ForegroundColor DarkRed "❌ you need docker installed"
exit 69
}

$_dockerComposeV = (docker compose version)

if ($? -eq $false || [string]::IsNullOrEmpty($_dockerComposeV)) {
Write-Host -ForegroundColor DarkRed "❌ you need docker compose plugin installed"
exit 69
}

# ok docker and docker-compose exist so let's check the packages
$_packagesToInstall = New-Object Collections.Generic.List[string]

Write-Host -ForegroundColor Yellow "Checking dependencies ..."

foreach ($package in $_packages.packages) {
dpkg -s $package > /dev/null 2>&1

if ($? -eq $false) {
$_packagesToInstall.Add($package)
Write-Host -ForegroundColor DarkRed "😵 $package not installed"
} else {
Write-Host -ForegroundColor DarkGreen "👍 $package installed"
}
}

# ask if the user want to install the packages that are not installed
if ($_packagesToInstall.Count -gt 0) {
$_installConfirm = Read-Host `
"Do you want to try to install the dependencies? <y/N>"

if ($_installConfirm -eq 'y') {
# make sure to update the list first
sudo apt-get update

foreach ($item in $_packagesToInstall) {
sudo apt-get install -y $item

if ($? -eq $false) {
Write-Host -ForegroundColor DarkRed "❌ error trying to install package $item"
exit 69
}
}

Write-Host -ForegroundColor DarkGreen "✅ All packages installed successfully"

# all packages installed then dep ok
New-Item -Path .conf/ -Name .depok -ItemType File 2>&1 | out-null
}
} else {
Write-Host -ForegroundColor DarkGreen "✅ All packages already installed"

# we need to ran the check deps only if it's not ran yet
New-Item -Path .conf/ -Name .depok -ItemType File 2>&1 | out-null
}
214 changes: 214 additions & 0 deletions vpu/generic/vpuGeneric/.conf/createDockerComposeProduction.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# suppress warnings that we need to use
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidOverwritingBuiltInCmdlets', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingInvokeExpression', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingPositionalParameters', ""
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidGlobalVars', ""
)]
param()

$ErrorActionPreference = "Stop"
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSUseDeclaredVarsMoreThanAssignments', "Internal PS variable"
)]
$PSNativeCommandUseErrorActionPreference = $true

$env:DOCKER_HOST = ""

if ($Env:GITLAB_CI -eq $true) {
Write-Host "ℹ️ :: GITLAB_CI :: ℹ️"
$Env:DOCKER_HOST = "tcp://docker:2375"
}

# args are needed
$compoFilePath = $args[0]
$dockerLogin = $args[1]
$tag = $args[2]
$registry = $args[3]
$imageName = $args[4]

# can be null
$gpu = $args[5]

$_iterative = $true

if ($null -eq $gpu) {
$gpu = ""
} else {
$env:GPU = $gpu
}

if ($null -eq $env:DOCKER_PSSWD) {
throw "❌ DOCKER_PSSWD not set"
} else {
$psswd = $env:DOCKER_PSSWD
}

if ($null -eq $env:TORIZON_ARCH) {
throw "❌ TORIZON_ARCH not set"
} else {
$imageArch = $env:TORIZON_ARCH
}

if ($null -eq $env:APP_ROOT) {
throw "❌ APP_ROOT not set"
} else {
$appRoot = $env:APP_ROOT
}

if ($env:TASKS_ITERATIVE -eq $False) {
$_iterative = $False
}

if ([string]::IsNullOrEmpty($compoFilePath)) {
if ($_iterative) {
$compoFilePath = Read-Host "docker-compose.yml root file path"
}

if ([string]::IsNullOrEmpty($compoFilePath)) {
throw "❌ docker-compose.yml root file path cannot be empty"
}
}

if ([string]::IsNullOrEmpty($dockerLogin)) {
if ($_iterative) {
$dockerLogin = Read-Host "Image repository"
}

if ([string]::IsNullOrEmpty($dockerLogin)) {
throw "❌ Docker image repository cannot be empty"
}
}

if ([string]::IsNullOrEmpty($psswd)) {
if ($_iterative) {
$tag = Read-Host "Docker registry password"
}

if ([string]::IsNullOrEmpty($psswd)) {
throw "❌ Docker registry password cannot be empty"
}
}

if ([string]::IsNullOrEmpty($imageName)) {
if ($_iterative) {
$imageName = Read-Host "Image name"
}

if ([string]::IsNullOrEmpty($imageName)) {
throw "❌ Docker image name cannot be empty"
}
}

if ([string]::IsNullOrEmpty($tag)) {
if ($_iterative) {
$tag = Read-Host "Image tag"
}

if ([string]::IsNullOrEmpty($tag)) {
throw "❌ Docker image tag cannot be empty"
}
}

# rebuild and tag
Write-Host "Rebuilding $dockerLogin/$($imageName):$tag ..."

$objSettings = Get-Content ("$compoFilePath/.vscode/settings.json") | `
Out-String | ConvertFrom-Json
$localRegistry = $objSettings.host_ip

$env:LOCAL_REGISTRY="$($localRegistry):5002"
$env:TAG="$tag"
if ([string]::IsNullOrEmpty($registry)) {
$env:DOCKER_LOGIN="$dockerLogin"
} else {
$env:DOCKER_LOGIN="$registry/$dockerLogin"
}
Set-Location $compoFilePath

docker compose build `
--build-arg APP_ROOT=$appRoot `
--build-arg IMAGE_ARCH=$imageArch `
--build-arg GPU=$gpu `
$imageName

Set-Location -

Write-Host -ForegroundColor DarkGreen "✅ Image rebuild and tagged"

# push it
Write-Host "Pushing it $dockerLogin/$($imageName):$tag ..."

Write-Output "$psswd" | docker login $registry -u $dockerLogin --password-stdin
docker push $env:DOCKER_LOGIN/$($imageName):$tag

Write-Host -ForegroundColor DarkGreen "✅ Image push OK"

# check if the yaml module is installed
Write-Host "Importing powershell-yaml ..."
if (-not (Get-Module -ListAvailable -Name "powershell-yaml")) {
Write-Host -ForegroundColor Yellow "Installing powershell-yaml ..."
Install-Module -Name "powershell-yaml" -Confirm:$false -Force
}

Import-Module -Name "powershell-yaml"
Write-Host -ForegroundColor DarkGreen "✅ powershell-yaml loaded"

# read the yaml file
Write-Host "Reading docker-compose.yml file ..."
$composeContent = Get-Content ("$compoFilePath/docker-compose.yml") | Out-String
$composeLoad = ConvertFrom-Yaml $composeContent -AllDocuments
$composeServices = $composeLoad.Services
$removeKeys = New-Object Collections.Generic.List[String]
$prodKeys = New-Object Collections.Generic.List[String]

Write-Host -ForegroundColor DarkGreen "✅ docker-compose.yml loaded"


# get the keys that need to be removed
Write-Host "Cleaning services ..."

foreach ($key in $composeServices.Keys) {
if ($key.toString().contains("debug")) {
$removeKeys.Add($key)
} else {
$prodKeys.Add($key)
}
}

# remove it
foreach ($key in $removeKeys) {
$composeServices.Remove($key)
}

Write-Host -ForegroundColor DarkGreen "✅ services cleaned"

# replace all the env variables
Write-Host "Replacing variables ..."

foreach ($key in $prodKeys) {
$composeServices[$key].Remove("build")
$composeServices[$key].image = `
$composeServices[$key].image.replace("`${DOCKER_LOGIN}", $dockerLogin)
$composeServices[$key].image = `
$composeServices[$key].image.replace("`${TAG}", $tag)
$composeServices[$key].image = `
$composeServices[$key].image.replace("`${GPU}", $gpu)
}

Write-Host -ForegroundColor DarkGreen "✅ variables replaced"

# write the torizon.io ready docker-compose
ConvertTo-Yaml $composeLoad `
-OutFile "$compoFilePath/docker-compose.prod.yml" -Force

Write-Host -ForegroundColor DarkGreen "✅ docker-compose.prod.yml created"
Loading