Send Feedback
Skip to content

GPU Examples

This page covers practical examples for using the GPU module in KDB-X.

These examples progress from basic data movement to more advanced GPU operations including queries, joins, and sorting. Each example is self-contained and includes the setup code needed to run it. The examples assume KDB-X is installed with a GPU-enabled license and the environment is configured as described in GPU Setup and Install KDB-X and the GPU Module.

Note

Most GPU operations require inputs to be on-device. Use .gpu.to to move all columns to the GPU, or .gpu.xto to move selected columns only – this creates a mixed-residency table, where some columns are on the GPU and others remain on the host.

Example 1: Move data to and from the GPU

Learn how to move lists, tables, and dictionaries between host and device.

Prerequisite

This example uses in-memory data on the host.

q)tableExample:([] x:`a`b`c;y:1 2 3)
q)dictExample :flip tableExample
q)listExample :tableExample`y 

Move data to device .gpu.to

Use these details in your KDB-X session:

q).gpu:use`kx.gpu
q).gpu.to tableExample
+`x`y!(foreign;foreign)
q).gpu.to dictExample
x| foreign
y| foreign
q).gpu.to listExample
foreign

Move data from device .gpu.from

Run a full round‑trip transfer between the CPU and GPU:

q).gpu:use`kx.gpu
q)tableExample ~ .gpu.from .gpu.to tableExample
1b
q)dictExample ~ .gpu.from .gpu.to dictExample
1b
q)listExample ~ .gpu.from .gpu.to listExample
1b

Move selected columns to device with .gpu.xto

Build a mixed residency table:

q).gpu:use`kx.gpu
q).gpu.xto[`x] tableExample
+`x`y!(foreign;1 2 3)

Inspect the table metadata to confirm mixed residency:

q).gpu.meta .gpu.xto[`x] tableExample
c| t f a r
-| ---------
x| s     gpu
y| j     cpu

Example 2: Append data on the GPU

Append GPU-resident and host-resident data while preserving mixed residency.

Prerequisite

This example uses a mixed-residency table.

q).gpu:use`kx.gpu
q)tableExample: .gpu.xto[`y] ([] x:`a`b`c;y:1 2 3)

Append another batch .gpu.append

Append a second table to the existing one:

q)T:.gpu.append[tableExample;tableExample]
q)T
+`x`y!(`a`b`c`a`b`c;foreign)
q).gpu.from T
x y
---
a 1
b 2
c 3
a 1
b 2
c 3

Append additional rows that are still on the host:

q)T:.gpu.append[tableExample;([]x:`d;y:enlist 5)]
q)T
+`x`y!(`a`b`c`d;foreign)
q).gpu.from T
x y
---
a 1
b 2
c 3
d 5

Example 3: Attributes on the GPU

Build on-device hash maps for accelerated data access.

Currently, only the g (grouped) attribute is supported, and it is used to enable efficient as‑of joins.

Prerequisite

This example uses a mixed-residency table.

q).gpu:use`kx.gpu
q)tableExample: .gpu.xto[`x`y] ([] x:`a`b`c;y:`g#1 2 3;z:4 5 6)

Group attributes are preserved on the GPU

Inspect the object metadata with .gpu.meta; the g (grouped) attribute is preserved on the GPU.

q).gpu.meta tableExample
c| t f a r
-| ---------
x| s     gpu
y| j   g gpu
z| j     cpu

Apply an additional g (grouped) attribute to the x column using .gpu.xgroup:

q).gpu.meta .gpu.xgroup[`x] tableExample
c| t f a r
-| ---------
x| s   g gpu
y| j   g gpu
z| j     cpu

Appending new rows preserves the g (grouped) attribute:

q).gpu.meta .gpu.append[tableExample;([]x:`a`a;y:2 3;z:6 7)]
c| t f a r
-| ---------
x| s   g gpu
y| j   g gpu
z| j     cpu

Example 4: Queries on the GPU

The GPU module supports a subset of qSQL statements executed directly on the GPU. The module provides a one-to-one mapping from standard functional selects to GPU equivalents, replacing ?[t;c;b;a] with .gpu.select[T;c;b;a], where T is an on-device copy of an in-memory table t.

Note

This release has limited select statement support. Refer to the reference for details.

Prerequisite

Move data to the GPU before running queries.

q).gpu:use`kx.gpu  / load the module
q)N:10000000
q)trade:([]time:.z.d+N?0D;sym:N?`3;price:N?1f;size:1+N?100)
q)Trade:.gpu.to trade
q)Trade
+`time`sym`price`size!(foreign;foreign;foreign;foreign)

Run a VWAP on the GPU

VWAP calculations run faster on the GPU because it can use many threads in parallel:

q)5#`sym xasc .gpu.from .gpu.select[Trade;();([sym:`sym]);enlist[`vwap]!enlist (%;(sum;(*;`size;`price));(sum;`size))]
sym vwap
-------------
aaa 0.4888454
aab 0.5023713
aac 0.496366
aad 0.5038354
aae 0.5059297
For a CPU vs. GPU timing comparison, refer to the GPU Quickstart.

Example 5: As-of joins

Run as-of joins directly on the GPU.

Prerequisite

Move data to the GPU before running joins.

Note

The GPU module supports joins on:

  • a single time column (time)
  • two columns (sym and time), where sym has the g (grouped) attribute
q).gpu:use`kx.gpu  / load the module
q)M:10*N:10000000
q)trade:([]time:.z.d+N?0D;sym:N?`3;price:N?1f;size:1+N?100)
q)quote:([]time:asc .z.d+M?0D;sym:`g#M?`3;bid:M?1f;ask:M?1f)
q)(Trade;Quote):.gpu.xto[`time`sym] each (trade;quote)

One column as-of join

Join Trade and Quote on time:

q).gpu.aj[`time;Trade;Quote]

Two column as-of join

Join Trade and Quote on sym and time:

q).gpu.aj[`sym`time;Trade;Quote]

Example 6: Sorting

Sort GPU-resident tables by one or more columns.

Prerequisite

Move data to the GPU before sorting.

q).gpu:use`kx.gpu  / load the module
q)N:10000000
q)trade:([]time:.z.d+N?0D;sym:N?`3;price:N?1f;size:1+N?100)
q)Trade:.gpu.to trade

Sort by timestamp

Sort Trade by time in ascending order:

q).gpu.xasc[`time] Trade

Sort by size and timestamp

Sort Trade by size and time in ascending order:

q).gpu.xasc[`size`time] Trade

Next steps