# 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](./quickstart/gpu-env.md) and [Install KDB-X and the GPU Module](./quickstart/kdb-env.md).

> **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
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
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
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
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
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
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
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
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.

> **Note — 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
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
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
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
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](reference.md#select) for details.
>
### Prerequisite

Move data to the GPU before running queries.
```q
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
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](./quickstart/quickstart.md).

## 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
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
q).gpu.aj[`time;Trade;Quote]
```

### Two column as-of join

Join `Trade` and `Quote` on `sym` and `time`:
```q
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
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
q).gpu.xasc[`time] Trade
```

### Sort by size and timestamp

Sort `Trade` by `size` and `time` in ascending order:
```q
q).gpu.xasc[`size`time] Trade
```

## Next steps

- Refer to the [GPU Reference](./reference.md) for a full API reference.
- Visit [Troubleshooting Errors](./troubleshooting-errors.md) if you encounter issues.
- Check the [GPU Release Notes](./release-notes/changelog.md) for version history and fixes.
