LUPINE is a GPU over IP bridge allowing GPUs on remote machines to be attached to CPU-only machines.
2,426
stars
568
commits
C++
primary language
Sep 15, 2026
updated
LUPINE is a GPU over IP bridge allowing GPUs on remote machines to be attached to CPU-only machines.
Use the published GHCR images. The examples below pin CUDA 13.3.1 on
Ubuntu 24.04; other published tags use the same
cuda-<cuda-version>-ubuntu<ubuntu-version> format.
Run the server on the GPU machine:
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Run the client pointing at that server:
docker run --rm -it \
-e LUPINE_SERVER=<server>:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
nvidia-smi
Example output from a real run against a remote RTX 4090:
Mon May 18 15:40:46 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.288.01 Driver Version: 590.48.01 CUDA Version: 13.1 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 On | Off |
| 30% 52C P8 22W / 450W | 8MiB / 24564MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+
Inside the client container, LD_LIBRARY_PATH=/opt/lupine/lib is already set,
so CUDA driver users pick up the LUPINE libcuda.so.1 shim and NVML users such
as nvidia-smi pick up the LUPINE libnvidia-ml.so.1 shim automatically.
Linux servers built with CUDA and NVML expose Prometheus metrics on the RPC port without monitoring-specific configuration:
curl http://<server>:14833/metrics
The endpoint reports host GPU memory capacity, memory use and utilization,
plus memory and utilization for each connected client process. It also exports
the mapping between client identity, the Lupine connection child, and the host
PID reported by NVML. Values are collected when /metrics is requested, so
the server does no background NVML polling.
Client metadata is optional. Servers advertise support during the HTTP/2 handshake, and clients skip the report when that capability is absent.
Each production server executable embeds the matching Linux, macOS, and
Windows client objects for amd64 and arm64; there is no client-bundle directory
to deploy beside it. Python clients fetch the current object from
/.well-known/lupine/client/v1/<os>/<arch>, verify its strong ETag, content
digest, manifest, and file hashes, and cache it locally. The selected ETag is
also asserted when the RPC connection opens, closing the race between
discovery and a server upgrade. LUPINE_LIBDIR remains an explicit local
override for development.
Linux client objects target the manylinux2014 ABI (glibc 2.17) and statically include their private C++, HTTP/2, and TLS dependencies. They therefore work on newer glibc distributions, including Ubuntu 22.04, without requiring host copies of libstdc++, nghttp2, or OpenSSL.
On Linux, SIGTERM stops the server from accepting connections, asks every
connection child to finish its in-flight CUDA calls, and waits for those
children to exit. This graceful drain happens in the open-source server with
no extra runtime dependency.
Each connection child looks for liblupinecr.so.0, then liblupinecr.so, and
uses the versioned provider ABI in
checkpoint_provider.h. A missing or incompatible
provider is a no-op; the server still drains and exits normally. The provider
is loaded before the child's first CUDA call so it can observe RM/UVM activity
needed to discover allocations.
Set LUPINE_SESSION in the client to attach a stable connection identifier.
The optional provider receives that identifier to restore the connection
before its first CUDA RPC and checkpoint it after shutdown has drained. For an
unkeyed connection, restore is skipped and checkpoint receives a null
identifier. Providers own storage configuration, file layout, and any fallback
policy for unkeyed connections; Lupine does not select a checkpoint directory.
LUPINE_CHECKPOINT_LIBRARY can override the provider library path for a
private deployment.
Each client/server connection is a single long-lived TCP stream. Long-running workloads sit idle for long stretches (between training steps, during host-side data loading, inside long kernels), and stateful middleboxes — cloud load balancers, NAT gateways, conntrack tables, firewalls — silently reap idle flows far sooner than the kernel's default 2-hour keepalive. The next RPC then fails fatally. Lupine keeps these connections alive and resilient without retrying RPCs (which would break CUDA semantics):
RPC request and response bodies require content-encoding: lz4. Compression
is applied transparently as one LZ4 frame per HTTP/2 body; peers do not
negotiate or fall back to another encoding.
Socket buffer sizes are left to the OS, which auto-tunes on modern kernels.
Set LUPINE_TRACE on the client, server, or both to enable trace logging.
LUPINE_TRACE=0 or an unset value disables tracing. LUPINE_TRACE=1 writes
trace output to stdout, LUPINE_TRACE=2 writes it to stderr, and any other
non-empty value is treated as a file path opened in append mode.
# trace to stdout
LUPINE_TRACE=1 ./your_cuda_program
# trace to stderr
LUPINE_TRACE=2 ./server
# trace to a file
LUPINE_TRACE=/tmp/lupine.trace ./your_cuda_program
The same LUPINE_TRACE variable controls both client and server tracing;
LUPINE_SERVER_TRACE is no longer used.
printf ForwardingLUPINE inspects uploaded PTX and cubin symbol data for vprintf, the CUDA device
printf implementation. Until an image that may use device stdout is loaded,
synchronization avoids stdout redirection and its process-global lock, allowing
independent RPC lanes to synchronize concurrently. Fully opaque compressed
fatbins are treated conservatively as potentially using device stdout.
After a device-output-capable image is loaded, context, stream, and event
synchronization captures server fd 1 and forwards the bounded CUDA printf
buffer to the client's stdout. Capture remains process-global so output from
concurrent synchronization lanes is not misattributed.
The client accepts a comma-separated LUPINE_SERVER list. Devices are exposed as
one local ordinal list in server order: all GPUs from the first server, then all
GPUs from the next server, and so on.
Run a server on each GPU machine:
# on gpu-host-a
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
# on gpu-host-b
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Point the client at both servers:
docker run --rm --network host \
-e LUPINE_SERVER=gpu-host-a:14833,gpu-host-b:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
nvidia-smi -L
Expected output lists both remote GPUs:
GPU 0: NVIDIA GeForce RTX 4090 (UUID: GPU-...)
GPU 1: NVIDIA GeForce RTX 4090 (UUID: GPU-...)
CUDA driver applications use the same LUPINE_SERVER value:
docker run --rm --network host \
-e LUPINE_SERVER=gpu-host-a:14833,gpu-host-b:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
./your_cuda_program
Cross-server device-to-device and peer (cuMemcpyDtoD / cuMemcpyPeer) copies are
supported: when the source and destination live on different servers, the client
transparently stages the data through itself (device->host on one server, then
host->device on the other). Direct server-to-server transfers that avoid that
client hop, cross-server peer-access enablement, and cuMemcpy3DPeer are not
implemented yet.
Same-server operations route by handle ownership.
Prefix an endpoint with https:// when the Lupine server is behind a
TLS-terminating proxy. Both CUDA applications and NVML tools such as
nvidia-smi use the scheme and verify the proxy certificate against the
system trust store. HTTPS defaults to port 443; plain and http:// endpoints
default to port 14833.
For a specific CUDA version:
docker pull ghcr.io/lupinemachines/lupine-client:cuda-12.4.1-ubuntu22.04
docker pull ghcr.io/lupinemachines/lupine-server:cuda-12.4.1-ubuntu22.04
Client images contain the CUDA driver, CUDA runtime, cuBLAS, cuBLASLt, cuFFT, cuDNN, NVML, and HIP shims, their runtime dependencies,
and nvidia-smi. They are based on Ubuntu and contain neither the CUDA nor ROCm
SDK. The -slim tags remain available as compatibility aliases with the same
SDK-free contents, for example
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04-slim.
The server image is also based on Ubuntu. It installs the CUDA compatibility runtime and, on amd64, the ROCm HIP runtime so one image can serve either NVIDIA or AMD GPUs; the older separate HIP server Dockerfile is no longer needed.
This path derives a small PyTorch client image from the published LUPINE client
image and runs the microgpt_train test against a remote GPU. It is
intentionally explicit so it is easy to see which side is the CPU-only client
and which side owns the GPU.
Create a PyTorch client Dockerfile in the repo root:
# Dockerfile.pytorch-lupine
FROM ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN pip3 install --break-system-packages \
--index-url https://download.pytorch.org/whl/cu132 \
torch
COPY test/pytorch_lupine_tests.py /opt/lupine/test/pytorch_lupine_tests.py
ENV LD_LIBRARY_PATH=/opt/lupine/lib:${LD_LIBRARY_PATH}
CMD ["python3", "/opt/lupine/test/pytorch_lupine_tests.py", "microgpt_train"]
Build it:
docker build -f Dockerfile.pytorch-lupine -t lupine-pytorch:cuda-13.3 .
Run the server on the GPU machine:
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Run the PyTorch client from the CPU-only machine:
docker run --rm \
-e LUPINE_SERVER=<server>:14833 \
lupine-pytorch:cuda-13.3
Expected success looks like:
microgpt first_loss=... last_loss=...
microgpt_train: PASS
Building the binaries requires running codegen first. The repository provides a containerized runner so local development and CI use the same CUDA and HIP headers, Python, parser, and formatter versions. Docker is the only host dependency.
./codegen/run.sh
Ensure there are no errors in the output of the codegen.
cmake -S . -B build
cmake --build build
CMake builds the CUDA driver shim at build/libcuda.so.1, the CUDA runtime shim
at build/libcudart.so.<major>, the cuBLAS, cuBLASLt and cuFFT shims at
build/libcublas.so.<major>, build/libcublasLt.so.<major> and
build/libcufft.so.<major> (when the toolkit's library headers are present),
the cuDNN shim at build/libcudnn.so.9 (when cuDNN 9 headers are found beside
the toolkit's or through -DLUPINE_CUDNN_INCLUDE_DIR=<dir>), the NVML shim at
build/libnvidia-ml.so.1, the HIP shim at build/libamdhip64.so.1, and the
server at build/lupine_driver_server. The runtime and library shims cover
their whole APIs: they forward cuda*, cublas*, cublasLt*, cufft* and
cudnn* calls on the driver shim's connections, so all of them must come from
the same build. The server loads the machine's libcudnn.so.9 by name.
Redistributable server builds pass LUPINE_CLIENT_BUNDLE_INPUT with staged
native client directories. CMake deterministically assembles all six platform
routes and links them into lupine_driver_server. The Docker server target
requires that generated registry, so a server image cannot be produced without
the clients.
The Lupine server must be running before initiating client commands.
./local.sh server
If successful, the server will start:
Server listening on port 14833...
For local development, preload the built libcuda.so.1 before executing CUDA
commands. The published client image sets LD_LIBRARY_PATH for you instead.
Once the server above is running:
# update to your desired IP/port
export LUPINE_SERVER=<server>:14833
LD_PRELOAD=./build/libcuda.so.1 python3 -c "import torch; print(torch.cuda.is_available())"
# or
LD_PRELOAD=./build/libcuda.so.1 nvidia-smi
You can also use the local shell script to run your commands.
./local.sh run
This project is inspired by some existing proprietary solutions:
C++
52.2%
C
22.5%
Cuda
12.5%
Python
7.2%
Shell
2.3%
CMake
1.8%
HIP
1.1%
LUPINE is a GPU over IP bridge allowing GPUs on remote machines to be attached to CPU-only machines.
2,426
stars
568
commits
C++
primary language
Sep 15, 2026
updated
LUPINE is a GPU over IP bridge allowing GPUs on remote machines to be attached to CPU-only machines.
Use the published GHCR images. The examples below pin CUDA 13.3.1 on
Ubuntu 24.04; other published tags use the same
cuda-<cuda-version>-ubuntu<ubuntu-version> format.
Run the server on the GPU machine:
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Run the client pointing at that server:
docker run --rm -it \
-e LUPINE_SERVER=<server>:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
nvidia-smi
Example output from a real run against a remote RTX 4090:
Mon May 18 15:40:46 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.288.01 Driver Version: 590.48.01 CUDA Version: 13.1 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 On | Off |
| 30% 52C P8 22W / 450W | 8MiB / 24564MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+
Inside the client container, LD_LIBRARY_PATH=/opt/lupine/lib is already set,
so CUDA driver users pick up the LUPINE libcuda.so.1 shim and NVML users such
as nvidia-smi pick up the LUPINE libnvidia-ml.so.1 shim automatically.
Linux servers built with CUDA and NVML expose Prometheus metrics on the RPC port without monitoring-specific configuration:
curl http://<server>:14833/metrics
The endpoint reports host GPU memory capacity, memory use and utilization,
plus memory and utilization for each connected client process. It also exports
the mapping between client identity, the Lupine connection child, and the host
PID reported by NVML. Values are collected when /metrics is requested, so
the server does no background NVML polling.
Client metadata is optional. Servers advertise support during the HTTP/2 handshake, and clients skip the report when that capability is absent.
Each production server executable embeds the matching Linux, macOS, and
Windows client objects for amd64 and arm64; there is no client-bundle directory
to deploy beside it. Python clients fetch the current object from
/.well-known/lupine/client/v1/<os>/<arch>, verify its strong ETag, content
digest, manifest, and file hashes, and cache it locally. The selected ETag is
also asserted when the RPC connection opens, closing the race between
discovery and a server upgrade. LUPINE_LIBDIR remains an explicit local
override for development.
Linux client objects target the manylinux2014 ABI (glibc 2.17) and statically include their private C++, HTTP/2, and TLS dependencies. They therefore work on newer glibc distributions, including Ubuntu 22.04, without requiring host copies of libstdc++, nghttp2, or OpenSSL.
On Linux, SIGTERM stops the server from accepting connections, asks every
connection child to finish its in-flight CUDA calls, and waits for those
children to exit. This graceful drain happens in the open-source server with
no extra runtime dependency.
Each connection child looks for liblupinecr.so.0, then liblupinecr.so, and
uses the versioned provider ABI in
checkpoint_provider.h. A missing or incompatible
provider is a no-op; the server still drains and exits normally. The provider
is loaded before the child's first CUDA call so it can observe RM/UVM activity
needed to discover allocations.
Set LUPINE_SESSION in the client to attach a stable connection identifier.
The optional provider receives that identifier to restore the connection
before its first CUDA RPC and checkpoint it after shutdown has drained. For an
unkeyed connection, restore is skipped and checkpoint receives a null
identifier. Providers own storage configuration, file layout, and any fallback
policy for unkeyed connections; Lupine does not select a checkpoint directory.
LUPINE_CHECKPOINT_LIBRARY can override the provider library path for a
private deployment.
Each client/server connection is a single long-lived TCP stream. Long-running workloads sit idle for long stretches (between training steps, during host-side data loading, inside long kernels), and stateful middleboxes — cloud load balancers, NAT gateways, conntrack tables, firewalls — silently reap idle flows far sooner than the kernel's default 2-hour keepalive. The next RPC then fails fatally. Lupine keeps these connections alive and resilient without retrying RPCs (which would break CUDA semantics):
RPC request and response bodies require content-encoding: lz4. Compression
is applied transparently as one LZ4 frame per HTTP/2 body; peers do not
negotiate or fall back to another encoding.
Socket buffer sizes are left to the OS, which auto-tunes on modern kernels.
Set LUPINE_TRACE on the client, server, or both to enable trace logging.
LUPINE_TRACE=0 or an unset value disables tracing. LUPINE_TRACE=1 writes
trace output to stdout, LUPINE_TRACE=2 writes it to stderr, and any other
non-empty value is treated as a file path opened in append mode.
# trace to stdout
LUPINE_TRACE=1 ./your_cuda_program
# trace to stderr
LUPINE_TRACE=2 ./server
# trace to a file
LUPINE_TRACE=/tmp/lupine.trace ./your_cuda_program
The same LUPINE_TRACE variable controls both client and server tracing;
LUPINE_SERVER_TRACE is no longer used.
printf ForwardingLUPINE inspects uploaded PTX and cubin symbol data for vprintf, the CUDA device
printf implementation. Until an image that may use device stdout is loaded,
synchronization avoids stdout redirection and its process-global lock, allowing
independent RPC lanes to synchronize concurrently. Fully opaque compressed
fatbins are treated conservatively as potentially using device stdout.
After a device-output-capable image is loaded, context, stream, and event
synchronization captures server fd 1 and forwards the bounded CUDA printf
buffer to the client's stdout. Capture remains process-global so output from
concurrent synchronization lanes is not misattributed.
The client accepts a comma-separated LUPINE_SERVER list. Devices are exposed as
one local ordinal list in server order: all GPUs from the first server, then all
GPUs from the next server, and so on.
Run a server on each GPU machine:
# on gpu-host-a
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
# on gpu-host-b
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Point the client at both servers:
docker run --rm --network host \
-e LUPINE_SERVER=gpu-host-a:14833,gpu-host-b:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
nvidia-smi -L
Expected output lists both remote GPUs:
GPU 0: NVIDIA GeForce RTX 4090 (UUID: GPU-...)
GPU 1: NVIDIA GeForce RTX 4090 (UUID: GPU-...)
CUDA driver applications use the same LUPINE_SERVER value:
docker run --rm --network host \
-e LUPINE_SERVER=gpu-host-a:14833,gpu-host-b:14833 \
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04 \
./your_cuda_program
Cross-server device-to-device and peer (cuMemcpyDtoD / cuMemcpyPeer) copies are
supported: when the source and destination live on different servers, the client
transparently stages the data through itself (device->host on one server, then
host->device on the other). Direct server-to-server transfers that avoid that
client hop, cross-server peer-access enablement, and cuMemcpy3DPeer are not
implemented yet.
Same-server operations route by handle ownership.
Prefix an endpoint with https:// when the Lupine server is behind a
TLS-terminating proxy. Both CUDA applications and NVML tools such as
nvidia-smi use the scheme and verify the proxy certificate against the
system trust store. HTTPS defaults to port 443; plain and http:// endpoints
default to port 14833.
For a specific CUDA version:
docker pull ghcr.io/lupinemachines/lupine-client:cuda-12.4.1-ubuntu22.04
docker pull ghcr.io/lupinemachines/lupine-server:cuda-12.4.1-ubuntu22.04
Client images contain the CUDA driver, CUDA runtime, cuBLAS, cuBLASLt, cuFFT, cuDNN, NVML, and HIP shims, their runtime dependencies,
and nvidia-smi. They are based on Ubuntu and contain neither the CUDA nor ROCm
SDK. The -slim tags remain available as compatibility aliases with the same
SDK-free contents, for example
ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04-slim.
The server image is also based on Ubuntu. It installs the CUDA compatibility runtime and, on amd64, the ROCm HIP runtime so one image can serve either NVIDIA or AMD GPUs; the older separate HIP server Dockerfile is no longer needed.
This path derives a small PyTorch client image from the published LUPINE client
image and runs the microgpt_train test against a remote GPU. It is
intentionally explicit so it is easy to see which side is the CPU-only client
and which side owns the GPU.
Create a PyTorch client Dockerfile in the repo root:
# Dockerfile.pytorch-lupine
FROM ghcr.io/lupinemachines/lupine-client:cuda-13.3.1-ubuntu24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN pip3 install --break-system-packages \
--index-url https://download.pytorch.org/whl/cu132 \
torch
COPY test/pytorch_lupine_tests.py /opt/lupine/test/pytorch_lupine_tests.py
ENV LD_LIBRARY_PATH=/opt/lupine/lib:${LD_LIBRARY_PATH}
CMD ["python3", "/opt/lupine/test/pytorch_lupine_tests.py", "microgpt_train"]
Build it:
docker build -f Dockerfile.pytorch-lupine -t lupine-pytorch:cuda-13.3 .
Run the server on the GPU machine:
docker run --rm --gpus all -p 14833:14833 \
ghcr.io/lupinemachines/lupine-server:cuda-13.3.1-ubuntu24.04
Run the PyTorch client from the CPU-only machine:
docker run --rm \
-e LUPINE_SERVER=<server>:14833 \
lupine-pytorch:cuda-13.3
Expected success looks like:
microgpt first_loss=... last_loss=...
microgpt_train: PASS
Building the binaries requires running codegen first. The repository provides a containerized runner so local development and CI use the same CUDA and HIP headers, Python, parser, and formatter versions. Docker is the only host dependency.
./codegen/run.sh
Ensure there are no errors in the output of the codegen.
cmake -S . -B build
cmake --build build
CMake builds the CUDA driver shim at build/libcuda.so.1, the CUDA runtime shim
at build/libcudart.so.<major>, the cuBLAS, cuBLASLt and cuFFT shims at
build/libcublas.so.<major>, build/libcublasLt.so.<major> and
build/libcufft.so.<major> (when the toolkit's library headers are present),
the cuDNN shim at build/libcudnn.so.9 (when cuDNN 9 headers are found beside
the toolkit's or through -DLUPINE_CUDNN_INCLUDE_DIR=<dir>), the NVML shim at
build/libnvidia-ml.so.1, the HIP shim at build/libamdhip64.so.1, and the
server at build/lupine_driver_server. The runtime and library shims cover
their whole APIs: they forward cuda*, cublas*, cublasLt*, cufft* and
cudnn* calls on the driver shim's connections, so all of them must come from
the same build. The server loads the machine's libcudnn.so.9 by name.
Redistributable server builds pass LUPINE_CLIENT_BUNDLE_INPUT with staged
native client directories. CMake deterministically assembles all six platform
routes and links them into lupine_driver_server. The Docker server target
requires that generated registry, so a server image cannot be produced without
the clients.
The Lupine server must be running before initiating client commands.
./local.sh server
If successful, the server will start:
Server listening on port 14833...
For local development, preload the built libcuda.so.1 before executing CUDA
commands. The published client image sets LD_LIBRARY_PATH for you instead.
Once the server above is running:
# update to your desired IP/port
export LUPINE_SERVER=<server>:14833
LD_PRELOAD=./build/libcuda.so.1 python3 -c "import torch; print(torch.cuda.is_available())"
# or
LD_PRELOAD=./build/libcuda.so.1 nvidia-smi
You can also use the local shell script to run your commands.
./local.sh run
This project is inspired by some existing proprietary solutions:
C++
52.2%
C
22.5%
Cuda
12.5%
Python
7.2%
Shell
2.3%
CMake
1.8%
HIP
1.1%