Skip to content

Commit

Permalink
Arm64 Support (microsoft#1108)
Browse files Browse the repository at this point in the history
* Adds ARM64 toolchain file and logic to determine target architecture

* Enables non-sse version of rgbz transformation

* Adds arm64 cross compile support to Dockerfile

* Add ARM64 builds to pipeline

* Enabling Functional Testing on ARM64

* Updating Display for ARM64 and glxinfo

* fixing up build artifact names

* Switch to publishing GNU binaries

* Moving DepthEngine properly

* Moving DepthEngine properly

* fixing case

* Don't run multi device tests on ARM64

Co-authored-by: Matt Schulte <[email protected]>
Co-authored-by: Matt Schulte <[email protected]>
  • Loading branch information
3 people authored Mar 6, 2020
1 parent 52cfb4a commit 6dea37e
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 108 deletions.
11 changes: 5 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(CMAKE_BUILD_RPATH "\$ORIGIN")
endif()

set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
include(DetermineTargetArch)
determine_target_arch(TARGET_ARCH)

# CMake doesn't set the target processor correctly for MSVC
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
Expand All @@ -149,16 +150,14 @@ if ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")

# Check what architecture we are building for. This assumes all 64-bit architectures are amd64, which will break
# if we decide to support arm.
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(TARGET_ARCH "amd64")
if ("${TARGET_ARCH}" STREQUAL "x86_64")
configure_file(k4a.props.in ${CMAKE_CURRENT_SOURCE_DIR}/src/csharp/k4a.x64.props)
configure_file(StubGenerator.xml.in ${CMAKE_CURRENT_SOURCE_DIR}/src/csharp/StubGenerator.x64.xml)
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(TARGET_ARCH "x86")
elseif("${TARGET_ARCH}" STREQUAL "i686")
configure_file(k4a.props.in ${CMAKE_CURRENT_SOURCE_DIR}/src/csharp/k4a.x86.props)
configure_file(StubGenerator.xml.in ${CMAKE_CURRENT_SOURCE_DIR}/src/csharp/StubGenerator.x86.xml)
else()
message(FATAL_ERROR "Unknown architecture with size of void* = ${CMAKE_SIZEOF_VOID_P}")
message(FATAL_ERROR "Unknown architecture for MSVC: ${TARGET_ARCH}")
endif()
endif()

Expand Down
102 changes: 71 additions & 31 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,28 +369,47 @@ jobs:

- job: LinuxK4ABuildTest
displayName: Linux
pool:
vmImage: 'ubuntu-16.04'
container: mcr.microsoft.com/akbuilder-linux:v3
strategy:
maxParallel: 100
matrix:
x64-clang_debug_ninja:
CMakeLinuxTargetTriple: 'x86_64-linux-clang'
CMakeConfiguration: 'debug'
UsesOpenCV: 'TRUE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-amd64'
x64-gnu_debug_ninja:
CMakeLinuxTargetTriple: 'x86_64-linux-gnu'
CMakeConfiguration: 'debug'
UsesOpenCV: 'TRUE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-amd64'
x64-clang_rel_ninja:
CMakeLinuxTargetTriple: 'x86_64-linux-clang'
CMakeConfiguration: 'relwithdebinfo'
UsesOpenCV: 'TRUE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-amd64'
x64-gnu_rel_ninja:
CMakeLinuxTargetTriple: 'x86_64-linux-gnu'
CMakeConfiguration: 'relwithdebinfo'
UsesOpenCV: 'TRUE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-amd64'
# arm64-clang_debug_ninja:
# CMakeLinuxTargetTriple: 'arm64-linux-clang'
# CMakeConfiguration: 'debug'
# UsesOpenCV: 'FALSE'
arm64-gnu_debug_ninja:
CMakeLinuxTargetTriple: 'arm64-linux-gnu'
CMakeConfiguration: 'debug'
UsesOpenCV: 'FALSE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-arm64'
# arm64-clang_rel_ninja:
# CMakeLinuxTargetTriple: 'arm64-linux-clang'
# CMakeConfiguration: 'relwithdebinfo'
# UsesOpenCV: 'FALSE'
arm64-gnu_rel_ninja:
CMakeLinuxTargetTriple: 'arm64-linux-gnu'
CMakeConfiguration: 'relwithdebinfo'
UsesOpenCV: 'FALSE'
container: 'mcr.microsoft.com/akbuilder-linux:v5-arm64'

# 32-bit builds are currently broken
# i386-unknown-linux-clang_debug_ninja:
Expand All @@ -405,6 +424,9 @@ jobs:
# i386-unknown-linux-gnu_relwithdebinfo_ninja:
# CMakeLinuxTargetTriple: 'i386-linux-gnu'
# CMakeConfiguration: 'relwithdebinfo'
pool:
vmImage: 'ubuntu-18.04'
container: $[ variables['container'] ]

steps:
- checkout: self
Expand Down Expand Up @@ -470,7 +492,7 @@ jobs:
ArtifactName: '$(CMakeLinuxTargetTriple)-$(CMakeConfiguration)'
parallel: true
parallelCount: 8
condition: and(succeeded(), contains(variables['CMakeLinuxTargetTriple'], 'clang'))
condition: and(succeeded(), contains(variables['CMakeLinuxTargetTriple'], 'gnu'))

- job: DocumentationBuild
displayName: Documentation Build
Expand Down Expand Up @@ -657,41 +679,41 @@ jobs:
inputs:
sourceFolder: "$(System.ArtifactsDirectory)/depthengineplugin/windows/amd64/release/"
contents: "depthengine*.dll"
targetFolder: "$(System.ArtifactsDirectory)/amd64-windows-msvc-RelWithDebInfo/bin"
targetFolder: "$(System.ArtifactsDirectory)/amd64-windows-msvc-relwithdebinfo/bin"
flattenFolders: true

- task: CopyFiles@2
displayName: "Copy DepthEngine into C# functional tests folder"
inputs:
sourceFolder: "$(System.ArtifactsDirectory)/depthengineplugin/windows/amd64/release/"
contents: "depthengine*.dll"
targetFolder: "$(System.ArtifactsDirectory)/amd64-windows-msvc-RelWithDebInfo/bin/Release/Microsoft.AzureKinect.FunctionalTests/netcoreapp2.1/"
targetFolder: "$(System.ArtifactsDirectory)/amd64-windows-msvc-relwithdebinfo/bin/Release/Microsoft.AzureKinect.FunctionalTests/netcoreapp2.1/"
flattenFolders: true

- script: '.\amd64-windows-msvc-RelWithDebInfo\bin\AzureKinectFirmwareTool.exe -r'
- script: '.\amd64-windows-msvc-relwithdebinfo\bin\AzureKinectFirmwareTool.exe -r'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Reset K4A Device'

- script: '.\amd64-windows-msvc-RelWithDebInfo\bin\AzureKinectFirmwareTool.exe -u firmware/AzureKinectDK_Fw_$(firmware_version).bin'
- script: '.\amd64-windows-msvc-relwithdebinfo\bin\AzureKinectFirmwareTool.exe -u firmware/AzureKinectDK_Fw_$(firmware_version).bin'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Update Device'

- script: '.\amd64-windows-msvc-RelWithDebInfo\bin\enumerate_devices.exe'
- script: '.\amd64-windows-msvc-relwithdebinfo\bin\enumerate_devices.exe'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Check Device Health'

- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_test_list.txt --bin bin/ --output=xml --gtest_filter=-*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-RelWithDebInfo'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-relwithdebinfo'
displayName: 'Run Functional Tests'
timeoutInMinutes: 15

- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_custom_test_list.txt --bin bin/ --output=xml --gtest_filter=-*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-RelWithDebInfo'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-relwithdebinfo'
displayName: 'Run Custom Functional Tests'
timeoutInMinutes: 15

- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_test_list.txt --bin bin/ --output=xml --gtest_filter=*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-RelWithDebInfo'
workingDirectory: '$(System.ArtifactsDirectory)/amd64-windows-msvc-relwithdebinfo'
displayName: 'Run Functional Tests - Onboarding'
timeoutInMinutes: 15
continueOnError: true
Expand All @@ -714,10 +736,19 @@ jobs:
dependsOn: LinuxK4ABuildTest
variables:
firmware_version: "$(linux_firmware_version)"
strategy:
maxParallel: 100
matrix:
x86_64:
CMakeLinuxTargetTriple: 'x86_64-linux-gnu'
EdenArch: 'x64'
arm64:
CMakeLinuxTargetTriple: 'arm64-linux-gnu'
EdenArch: 'arm64'
pool:
name: Analog-FwConnected
demands:
- Eden
- EdenArch -equals $(EdenArch)
- Agent.OS -equals Linux

steps:
Expand All @@ -730,7 +761,7 @@ jobs:
- task: DownloadBuildArtifacts@0
displayName: 'Download Build Artifacts'
inputs:
artifactName: 'x86_64-linux-clang-RelWithDebInfo'
artifactName: '$(CMakeLinuxTargetTriple)-relwithdebinfo'
parallelizationLimit: 8

- task: NuGetToolInstaller@0
Expand All @@ -755,19 +786,19 @@ jobs:
displayName: "Temp List files"

- task: CopyFiles@2
displayName: "Copy DepthEngine into amd64/debug artifacts folder"
displayName: "Copy DepthEngine into $(EdenArch)/debug artifacts folder"
inputs:
sourceFolder: "$(System.ArtifactsDirectory)/NugetOutputDir/Microsoft.Azure.Kinect.Sensor.$(NuGetPackageVersion)/linux/lib/native/x64/release/"
sourceFolder: "$(System.ArtifactsDirectory)/NugetOutputDir/Microsoft.Azure.Kinect.Sensor.$(NuGetPackageVersion)/linux/lib/native/$(EdenArch)/release/"
contents: "libdepthengine*"
targetFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/x86_64/debug"
targetFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/$(EdenArch)/debug"
flattenFolders: true

- task: CopyFiles@2
displayName: "Copy DepthEngine into amd64/release artifacts folder"
displayName: "Copy DepthEngine into $(EdenArch)/release artifacts folder"
inputs:
sourceFolder: "$(System.ArtifactsDirectory)/NugetOutputDir/Microsoft.Azure.Kinect.Sensor.$(NuGetPackageVersion)/linux/lib/native/x64/release/"
sourceFolder: "$(System.ArtifactsDirectory)/NugetOutputDir/Microsoft.Azure.Kinect.Sensor.$(NuGetPackageVersion)/linux/lib/native/$(EdenArch)/release/"
contents: "libdepthengine*"
targetFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/x86_64/release"
targetFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/$(EdenArch)/release"
flattenFolders: true

- task: CopyFiles@2
Expand All @@ -788,17 +819,22 @@ jobs:
- task: CopyFiles@2
displayName: "Copy DepthEnginePlugin into Build Artifacts"
inputs:
sourceFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/x86_64/release/"
sourceFolder: "$(System.ArtifactsDirectory)/depthengineplugin/linux/$(EdenArch)/release/"
contents: "libdepthengine.so*"
targetFolder: "$(System.ArtifactsDirectory)/x86_64-linux-clang-relwithdebinfo/bin/"
targetFolder: "$(System.ArtifactsDirectory)/$(CMakeLinuxTargetTriple)-relwithdebinfo/bin/"
flattenFolders: true

- script: 'chmod +x ./x86_64-linux-clang-relwithdebinfo/bin/*'
- script: 'chmod +x ./$(CMakeLinuxTargetTriple)-relwithdebinfo/bin/*'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Add execution property to binary files'

# Set the DISPLAY variable since DepthEngine needs to open a display window (even there is no visual display).
- script: 'echo "##vso[task.setvariable variable=DISPLAY]:0"'
- script: |
if [ $(EdenArch) == "arm64" ]; then
echo "##vso[task.setvariable variable=DISPLAY]:1"
else
echo "##vso[task.setvariable variable=DISPLAY]:0"
fi
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'set DISPLAY variable'
Expand All @@ -807,34 +843,38 @@ jobs:
displayName: 'Check openGL version'
timeoutInMinutes: 5

- script: './x86_64-linux-clang-relwithdebinfo/bin/AzureKinectFirmwareTool -r'
- script: './$(CMakeLinuxTargetTriple)-relwithdebinfo/bin/AzureKinectFirmwareTool -r'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Reset K4A Device'
env:
K4A_LOG_LEVEL: 'I'

- script: './x86_64-linux-clang-relwithdebinfo/bin/AzureKinectFirmwareTool -u firmware/AzureKinectDK_Fw_$(firmware_version).bin'
- script: './$(CMakeLinuxTargetTriple)-relwithdebinfo/bin/AzureKinectFirmwareTool -u firmware/AzureKinectDK_Fw_$(firmware_version).bin'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Update Device'
env:
K4A_LOG_LEVEL: 'I'

- script: './x86_64-linux-clang-relwithdebinfo/bin/enumerate_devices'
- script: './$(CMakeLinuxTargetTriple)-relwithdebinfo/bin/enumerate_devices'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Check Device Health'

- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_test_list.txt --bin bin/ --output=xml --gtest_filter=-*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/x86_64-linux-clang-relwithdebinfo'
workingDirectory: '$(System.ArtifactsDirectory)/$(CMakeLinuxTargetTriple)-relwithdebinfo'
displayName: 'Run Functional Tests'
timeoutInMinutes: 15

- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_custom_test_list.txt --bin bin/ --output=xml --gtest_filter=-*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/x86_64-linux-clang-relwithdebinfo'
- script: |
# skip testing on ARM64 Jetson Nano doesn't like 2 USB devices running at once.
if [ $(EdenArch) == "x64" ]; then
python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_custom_test_list.txt --bin bin/ --output=xml --gtest_filter=-*ONBOARDING*
fi
workingDirectory: '$(System.ArtifactsDirectory)/$(CMakeLinuxTargetTriple)-relwithdebinfo'
displayName: 'Run Custom Functional Tests'
timeoutInMinutes: 15
- script: 'python $(Build.SourcesDirectory)/scripts/RunTestList.py --list bin/functional_test_list.txt --bin bin/ --output=xml --gtest_filter=*ONBOARDING*'
workingDirectory: '$(System.ArtifactsDirectory)/x86_64-linux-clang-relwithdebinfo'
workingDirectory: '$(System.ArtifactsDirectory)/$(CMakeLinuxTargetTriple)-relwithdebinfo'
displayName: 'Run Functional Tests - Onboarding'
timeoutInMinutes: 15
continueOnError: true
53 changes: 53 additions & 0 deletions cmake/DetermineTargetArch.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function(determine_target_arch OUTPUT_VARIABLE)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86")
set(ARCH "i686")
elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64")
set(ARCH "x86_64")
elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM")
set(ARCH "arm")
elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64")
set(ARCH "arm64")
else()
message(FATAL_ERROR "Unrecognized architecture ${MSVC_C_ARCHITECTURE_ID} from ${CMAKE_C_COMPILER}")
endif()
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMD_ARGS "-target" "${CMAKE_C_COMPILER_TARGET}" "-dumpmachine")
else()
set(CMD_ARGS "-dumpmachine")
endif()
execute_process(
COMMAND
${CMAKE_C_COMPILER} ${CMD_ARGS}
RESULT_VARIABLE
RESULT
OUTPUT_VARIABLE
ARCH
ERROR_QUIET)
if(RESULT)
message(FATAL_ERROR "Failed to determine target architecture triplet: ${RESULT}")
endif()
string(REGEX MATCH "([^-]+).*" ARCH_MATCH ${ARCH})
if(NOT CMAKE_MATCH_1 OR NOT ARCH_MATCH)
message(FATAL_ERROR "Failed to match the target architecture triplet: ${ARCH}")
endif()
set(ARCH ${CMAKE_MATCH_1})

if("${ARCH}" STREQUAL "x86_64")
# Do nothing
elseif("${ARCH}" STREQUAL "aarch64")
set(ARCH "arm64")
elseif("${ARCH}" STREQUAL "i686")
# Do nothing
elseif("${ARCH}" STREQUAL "i386")
# Do nothing
else()
message(FATAL_ERROR "Unrecognized architecture ${ARCH} from ${CMAKE_C_COMPILER}")
endif()
else()
message(FATAL_ERROR "Unrecognized Compiler ${CMAKE_C_COMPILER_ID}")
endif()
message(STATUS "Target architecture - ${ARCH}")
set(${OUTPUT_VARIABLE} ${ARCH} PARENT_SCOPE)
endfunction()
22 changes: 22 additions & 0 deletions cmake/toolchains/arm64-linux-clang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

# the name of the target OS and arch
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm64)
SET(triple aarch64-linux-gnu)

# which compilers to use
SET(CMAKE_C_COMPILER "clang-6.0")
SET(CMAKE_C_COMPILER_TARGET ${triple})
SET(CMAKE_CXX_COMPILER "clang++-6.0")
SET(CMAKE_CXX_COMPILER_TARGET ${triple})

# Tell pkgconfig to use aarch64
SET(ENV{PKG_CONFIG_PATH} "/usr/lib/aarch64-linux-gnu/pkgconfig")

# Tell CMake to use qemu to emulate
# Note: This should be automatically done by Ubuntu using binfmt_misc, but that
# seems to be broken on WSL (https://github.com/microsoft/WSL/issues/2620) so
# explicitly setting the emulator for now.
SET(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64-static)
19 changes: 19 additions & 0 deletions cmake/toolchains/arm64-linux-gnu.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

# the name of the target OS and arch
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm64)

# which compilers to use
SET(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)

# Tell pkgconfig to use arm64
SET(ENV{PKG_CONFIG_PATH} "/usr/lib/aarch64-linux-gnu/pkgconfig")

# Tell CMake to use qemu to emulate
# Note: This should be automatically done by Ubuntu using binfmt_misc, but that
# seems to be broken on WSL (https://github.com/microsoft/WSL/issues/2620) so
# explicitly setting the emulator for now.
SET(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64-static)
5 changes: 3 additions & 2 deletions cmake/toolchains/x86_64-linux-clang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
# the name of the target OS and arch
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
SET(triple x86_64-linux-gnu)

# which compilers to use
SET(CMAKE_C_COMPILER "clang-6.0")
SET(CMAKE_C_FLAGS -m64)
SET(CMAKE_C_COMPILER_TARGET ${triple})
SET(CMAKE_CXX_COMPILER "clang++-6.0")
SET(CMAKE_CXX_FLAGS -m64)
SET(CMAKE_CXX_COMPILER_TARGET ${triple})

# save flags to cache
SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "C Flags" FORCE)
Expand Down
Loading

0 comments on commit 6dea37e

Please sign in to comment.