Usage

Usage on Linux

You can enable the graph and tensor layers using environment variables only, without modifying the Vulkan® application. The following environment variables are used:

  • Use the LD_LIBRARY_PATH environment variable to point at the VkLayer_Graph and VkLayer_Tensor libraries.

  • Use the VK_ADD_LAYER_PATH environment variable to point at the VkLayer_Graph.json and VkLayer_Tensor.json manifest file.

    • If your loader ignores VK_ADD_LAYER_PATH (older SDKs before 1.4.328.1), use VK_LAYER_PATH.

  • You must enable the graph layer before the tensor layer. To do this, use the VK_INSTANCE_LAYERS environment variable.

If you have installed the ML Emulation Layer for Vulkan® into a deploy folder, use the following environment variables to enable the layers:

export LD_LIBRARY_PATH=$PWD/deploy/lib:$LD_LIBRARY_PATH
export VK_ADD_LAYER_PATH=$PWD/deploy/share/vulkan/explicit_layer.d
export VK_INSTANCE_LAYERS=VK_LAYER_ML_Graph_Emulation:VK_LAYER_ML_Tensor_Emulation

You can also enable logging using environment variables. Logging must be set before the application is started. Logging severity can be one of error, warning, info, or debug. Logging severity is set independently for the graph and tensor layer using the following commands:

export VMEL_GRAPH_SEVERITY=debug
export VMEL_TENSOR_SEVERITY=info

Common severity for both layers can be set using the following command:

export VMEL_COMMON_SEVERITY=debug

Usage on Windows®

You can enable the graph and tensor layers using environment variables only, without modifying the Vulkan® application. The following environment variables are used:

  • Use the VK_ADD_LAYER_PATH environment variable to point at the VkLayer_Graph.json and VkLayer_Tensor.json manifest files.

  • You must enable the graph layer before the tensor layer. To do this, use the VK_INSTANCE_LAYERS environment variable.

If you have installed the ML Emulation Layer for Vulkan® into a deploy folder, use the following environment variables to enable the layers:

$env:VK_LAYER_PATH="$PWD\deploy\bin"
$env:VK_INSTANCE_LAYERS="VK_LAYER_ML_Graph_Emulation;VK_LAYER_ML_Tensor_Emulation"

Alternatively, you can use the Windows® registry keys to load the manifest files. This can be done using the Windows® GUI. Or, if you have installed the ML Emulation Layer for Vulkan® into a deploy folder, you set the path to the manifest files using:

reg add HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ExplicitLayers /v `
{ABSOLUTE_PATH}\deploy\bin /t REG_DWORD /d 0 /f

$env:VK_INSTANCE_LAYERS="VK_LAYER_ML_Graph_Emulation;VK_LAYER_ML_Tensor_Emulation"

Note

If running a Windows® terminal with elevated permissions, VK_ADD_LAYER_PATH is ignored for security reasons. However, if VK_ADD_LAYER_PATH is set and not ignored, then Vulkan skips searching the registry keys for manifest files.

You can also enable logging using environment variables. Logging must be set before the application is started. Logging severity can be one of error, warning, info, or debug. Logging severity is set independently for the graph and tensor layer using the following commands:

$env:VMEL_GRAPH_SEVERITY="debug"
$env:VMEL_TENSOR_SEVERITY="info"

Usage on Android™

You can pack the graph and tensor layer libraries into the Application Package Kit (APK) or push to the /data/local/debug/vulkan directory for Android™ to discover the ML Emulation Layer for Vulkan®. Applications can enable the layers during Vulkan instance creation or you can enable the layers without modifying the application by using following commands:

adb shell settings put global enable_gpu_debug_layers 1
adb shell settings put global gpu_debug_app $TARGET_APP_PKG
adb shell settings put global gpu_debug_layers \
    VK_LAYER_ML_Graph_Emulation:VK_LAYER_ML_Tensor_Emulation

APK Packaging

If you want to package the ML Emulation Layer for Vulkan® as an Android™ APK, set the following variables first:

export EMULATION_LAYER_ROOT=/path/to/emulation-layer
export NDK=/path/to/android-ndk
export ANDROID_HOME=/path/to/android-sdk
export TARGET_APP_PKG=com.example.targetapp

The Android™ packaging flow in scripts/build.py requires the Android™ NDK toolchain for the native build and Gradle 8.4 or later with ANDROID_HOME set for APK generation. The Android™ SDK installation pointed to by ANDROID_HOME should include build-tools;34.0.0 and platforms;android-34, or other compatible versions. A typical APK packaging command looks like:

python3 $EMULATION_LAYER_ROOT/scripts/build.py \
    --build-type Android \
    --target-platform android \
    --cmake-toolchain-for-android $NDK/build/cmake/android.toolchain.cmake \
    --install $EMULATION_LAYER_ROOT/apk_install \
    --package-type apk \
    -j $(nproc)

This produces an Android™ project in apk_package/ and Gradle builds the debug APK from there. The layer APK package name is currently com.arm.ai_ml_emulation_layer_for_vulkan.

To enable the packaged layers for a target application, use Android™ GPU debug layer settings:

adb shell settings put global enable_gpu_debug_layers 1
adb shell settings put global gpu_debug_app $TARGET_APP_PKG
adb shell settings put global gpu_debug_layers \
    VK_LAYER_ML_Graph_Emulation:VK_LAYER_ML_Tensor_Emulation
adb shell settings put global gpu_debug_layer_app \
    com.arm.ai_ml_emulation_layer_for_vulkan

If you only want to enable a single layer, the command will likely look like:

adb shell settings put global gpu_debug_layers VK_LAYER_KHRONOS_validation

The layer package must also be visible to the debug app. On Android™ 11 and later, if the target app does not already query the layer package, add a package visibility entry such as:

<queries>
    <package android:name="com.arm.ai_ml_emulation_layer_for_vulkan" />
</queries>

Refer to the Android™ validation layer guide for background on APK packaging, debug layer settings, and package visibility: Use Vulkan validation layers on Android.

Building for Darwin (Experimental)

MoltenVK is required to build and run the ML Emulation Layer for Vulkan® for a Darwin device. The MoltenVK version must have Vulkan® API 1.3 support. In this example we install into a deploy folder and build using the script.

To build the ML Emulation Layer for Vulkan®, run:

python3 ${REPO}/sw/emulation-layer/scripts/build.py --install $SDK_PATH/deploy

Install MoltenVK by following the documentation: https://vulkan.lunarg.com/doc/sdk/1.4.328.1/mac/getting_started.html

Usage on Darwin (Experimental)

We need to link to both the MoltenVK and the ML Emulation Layer for Vulkan® build output, when running on a Darwin device. On Darwin, LD_LIBRARY_PATH is instead DYLD_LIBRARY_PATH.

export PATH=${MOLTEN_VK_PATH}/macOS/bin:${PATH}
export VK_ICD_FILENAMES=${MOLTEN_VK_PATH}/macOS/share/vulkan/icd.d/MoltenVK_icd.json
export DYLD_LIBRARY_PATH=${MOLTEN_VK_PATH}/macOS/lib:${SDK_PATH}/deploy/lib
export VK_LAYER_PATH=${REPO}/deploy/share/vulkan/explicit_layer.d
export VK_INSTANCE_LAYERS=VK_LAYER_ML_Graph_Emulation:VK_LAYER_ML_Tensor_Emulation

Cross compilation for AArch64 on x86-64 (Experimental)

The shader pre-compilation step requires a glslang compiler. There are three ways to accomplish this when cross-compiling:

  1. Provide a custom glslang executable. You can direct CMake to a custom glslang executable file using the GLSLANG_EXECUTABLE option. First, build glslang inside its repo. When the repository is initialized using the repo manifest, the glslang source is checked out in <repo_root>/dependencies/glslang/ For building glslang, see Building (CMake).

  2. Install glslang to the system. Under cross compilation, when no custom glslang executable is provided, it will be searched from the system using CMake’s find_package. On Ubuntu, you can install it with sudo apt install glslang-tools or from the source code following the previously mentioned documentation. Note that we require version > 15.4.0, which may not yet be available in Ubuntu’s official package repositories.

  3. Disable shader pre-compilation. This can be done by adding the flag --disable-precompile-shaders to the build script command. By doing so, the shaders will be compiled at runtime.

An example build flow using the option 1 would be:

First, build the glslang standalone under <repo_root>/dependencies/glslang/:

cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_BINARIES=ON -DENABLE_OPT=OFF -DBUILD_SHARED_LIBS=OFF

cmake --build build --target glslang-standalone

After building, the binary will be at <repo_root>/dependencies/glslang/build/StandAlone/glslang. Then run the following under <repo_root>/sw/emulation-layer/:

cmake -B build \
   -DCMAKE_TOOLCHAIN_FILE=${REPO}/sw/emulation-layer/cmake/toolchain/linux-aarch64-gcc.cmake \
   -DGLSLANG_PATH=${REPO}/dependencies/glslang \
   -DSPIRV_CROSS_PATH=${REPO}/dependencies/SPIRV-Cross \
   -DSPIRV_HEADERS_PATH=${REPO}/dependencies/SPIRV-Headers \
   -DSPIRV_TOOLS_PATH=${REPO}/dependencies/SPIRV-Tools \
   -DVULKAN_HEADERS_PATH=${REPO}/dependencies/Vulkan-Headers \
   -DGLSLANG_EXECUTABLE=${REPO}/dependencies/glslang/build/StandAlone/glslang

cmake --build build

Vulkan® Layer Documentation

For more information about using layers, see the Vulkan® Layer Documentation.

Troubleshooting

All zero output from AMD GPUs on Linux

Some workloads may cause silent GPU crashes due to timeout errors. You can check for related kernel messages with the following command:

dmesg | grep -i amdgpu

To change the timeout, follow these steps (applies if your system uses GRUB as the bootloader):

  1. Edit the GRUB configuration file:

    sudo nano /etc/default/grub
    
  2. Add or modify the GRUB_CMDLINE_LINUX line to include a longer timeout value in milliseconds:

    GRUB_CMDLINE_LINUX="quiet splash amdgpu.lockup_timeout=20000"
    
  3. Update the GRUB configuration:

    sudo update-grub
    
  4. Reboot the system:

    sudo reboot
    

PyPI

The ML Emulation Layer for Vulkan® is available on PyPI as the ai-ml-emulation-layer-for-vulkan package.

Install:

pip install ai-ml-emulation-layer-for-vulkan