Enable GPU acceleration in UDFs

This article explains how to enable GPU acceleration in custom user defined functions (UDFs).

Introduction

In on-premises installations of Exasol 2025.2 and later you can utilize GPUs to accelerate parallel processing for user defined functions (UDFs) in Exasol clusters. This article explains how to enable and configure GPU acceleration in UDFs, and describes the prerequisites and limitations for its use.

Prerequisites

  • GPU support is only possible in on-premises deployments of Exasol 2025.2 and later.

  • The hosts in the Exasol deployment must have compatible NVIDIA GPUs installed and GPU support must be enabled. For more information, see Install and configure GPU support.

Supported UDF types and functions

  • All UDF types are supported: Scalar/Set and Return/Emits.

  • Only the run callback function and the corresponding initialization and cleanup can use GPU acceleration. For other UDF callback functions the GPU option will be ignored.

Other limitations

You can not use GPU acceleration in the following use cases:

  • inside import_spec and export_spec callback functions

  • inside a dynamic output parameter callback function

  • in virtual schema adapter scripts

Using GPU acceleration with library scripts

The GPU option must only be set in the importing UDF, not in the imported scripts.

When you import other (library) scripts into a UDF, the imported scripts will be able to use GPU acceleration. However, the GPU option must only be set in the importing UDF, not in the imported scripts. Adding the GPU option in the imported scripts will cause a syntax error.

GPU option parameter

To enable GPU support in a UDF, add the option perInstanceRequiredAcceleratorDevices to the UDF definition.

Example:
Copy
--/
CREATE OR REPLACE PYTHON_GPU SCALAR SCRIPT GPU_UDF_EXAMPLE()
RETURNS VARCHAR(20) AS
%perInstanceRequiredAcceleratorDevices GpuNvidia;
...
/

Acceleration options

The perInstanceRequiredAcceleratorDevices option parameter accepts the following option values:

Option value Result
None No accelerator selected or required (implicit default for CPU processing).
GpuNvidia NVIDIA GPU accelerator is required by the UDF.
GpuNividia|None NVIDIA GPU accelerator is preferred, but can fall back to no accelerator (CPU processing).

Acceleration scenarios

The option value indicates to the Exasol system which type of acceleration the UDF requires/prefers. This results in the following possible scenarios:

Disable acceleration – Explicitly disable acceleration (implicit default)

Result: CPU processing is always used.

Example: Standard UDFs without the usage of GPU-enabled software packages.

Enforce acceleration – Require available GPUs for acceleration

Result: GPU acceleration is always used. If no GPUs are available, execution fails.

Example: This can be the case if the used frameworks, software packages, or written code require GPUs.

Prefer acceleration – Allow GPU acceleration with CPU fallback

Result: GPU acceleration is used if GPUs are available. If no GPUs are available, CPU processing is used.

Example: Portable UDF code that may be developed and executed on deployments with and without GPUs.

Script language containers with GPU support

If a UDF definition contains the option for either required or preferred GPU acceleration, the script language container (SLC) that is used for the UDF must be derived from a template flavor that supports acceleration with NVIDIA GPUs. Otherwise, the execution will fail.

Exasol provides script language flavors with NVIDIA CUDA support. For more information, see Exasol Script Language Flavors overview on GitHub.

Lua is not supported.

Examples

The following examples assume that a script language container (SLC) is already deployed in the database and activated with the alias PYTHON_GPU. For more details, see Adding New Packages to Existing Script Languages.

Example 1: UDF with GPU acceleration preferred

The following example represents a GPU-CPU portable Python UDF. This UDF reads and emits the environment variable NVIDIA_VISIBLE_DEVICES, which is correctly forwarded by the database to the UDF if the GPU is available. If no GPU is available, the UDF will return <undefined>.

Copy
--/
CREATE OR REPLACE PYTHON_GPU SCALAR SCRIPT
NVIDIA_ENVIRONMENT_VARIABLES()
EMITS (var_name VARCHAR(1000), var_value VARCHAR(1000)) AS
%perInstanceRequiredAcceleratorDevices GpuNvidia|None;

import os

def run(ctx):
    ctx.emit("NVIDIA_VISIBLE_DEVICES", os.getenv('NVIDIA_VISIBLE_DEVICES', "<undefined>"))
/

SELECT NVIDIA_ENVIRONMENT_VARIABLES();

Example 2: UDF with GPU acceleration enforced

The following example shows a Python UDF enforcing GPU acceleration. This UDF only executes if GPU acceleration is available. This means that it will always return the correct value of the environment variable NVIDIA_VISIBLE_DEVICES, or the execution fails.

Copy
--/
CREATE OR REPLACE PYTHON_GPU SCALAR SCRIPT
NVIDIA_ENVIRONMENT_VARIABLES()
EMITS (var_name VARCHAR(1000), var_value VARCHAR(1000)) AS
%perInstanceRequiredAcceleratorDevices GpuNvidia;

def run(ctx):
    ctx.emit("NVIDIA_VISIBLE_DEVICES", os.getenv('NVIDIA_VISIBLE_DEVICES', "<undefined>"))
/

SELECT NVIDIA_ENVIRONMENT_VARIABLES();

GPU usage across UDF instances

If there are multiple UDF instances of a single UDF call within the same query, all those instances will have access to all (GPU) accelerators. To reduce the risk of running out of GPU memory, we recommend that you use UDF instance limiting to control how many accelerators each instance can use, and that you configure the instance limit based on the number of accelerators and the use case.

Example:

This is the simplest case, where all accelerators are used together by one UDF instance. The perNodeAndCallInstanceLimit parameter is therefore set to 1.

Copy
--/
CREATE OR REPLACE PYTHON_GPU SCALAR SCRIPT GPU_UDF_EXAMPLE()
RETURNS VARCHAR(20) AS
%perNodeAndCallInstanceLimit 1;
%perInstanceRequiredAcceleratorDevices GpuNvidia;
...
/

For more examples, see Exasol AI Lab on GitHub.