docs: cross-container CUDA IPC requires both --ipc и --pid namespace share
Реальный тест на 192.168.88.98 (1920x1080 HEVC, 25fps) показал: для отдельных consumer-container'ов недостаточно ipc=container:X — нужен также pid=container:X, иначе cudaIpcOpenEventHandle падает с invalid device context. CUDA driver валидирует IPC peer через /proc/<pid>/... E2E на реальной камере проверен: publisher (отдельный контейнер) -> consumer (docker exec): 250 frames, 0 gaps publisher (отдельный контейнер) -> consumer (отдельный с pid+ipc): 200, 0 gaps Обновлено: - docs/integration.md compose snippet, verification, troubleshooting section - docker-compose.example.yml — добавлен pid: container:cuframes-cam-test - README.md quickstart — добавлен --pid в docker run subscriber Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,9 @@ docker run -d --name cuframes-cam --runtime=nvidia --ipc=shareable \
|
|||||||
--rtsp 'rtsp://user:pass@cam/stream' --key cam1 --ring 6
|
--rtsp 'rtsp://user:pass@cam/stream' --key cam1 --ring 6
|
||||||
|
|
||||||
# Subscriber: получает декодированные frames zero-copy
|
# Subscriber: получает декодированные frames zero-copy
|
||||||
docker run --rm --runtime=nvidia --ipc=container:cuframes-cam \
|
# (для cross-container CUDA IPC нужны и --ipc, и --pid — см. docs/integration.md)
|
||||||
|
docker run --rm --runtime=nvidia \
|
||||||
|
--ipc=container:cuframes-cam --pid=container:cuframes-cam \
|
||||||
-v /run/cuframes:/run/cuframes:ro \
|
-v /run/cuframes:/run/cuframes:ro \
|
||||||
gx/cuframes:0.1 \
|
gx/cuframes:0.1 \
|
||||||
/usr/local/bin/sub_count --key cam1 --max-frames 100
|
/usr/local/bin/sub_count --key cam1 --max-frames 100
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
NVIDIA_VISIBLE_DEVICES: all
|
NVIDIA_VISIBLE_DEVICES: all
|
||||||
NVIDIA_DRIVER_CAPABILITIES: compute,video,utility
|
NVIDIA_DRIVER_CAPABILITIES: compute,video,utility
|
||||||
# CRITICAL: ipc namespace должен совпадать с publisher'ом
|
# CRITICAL: обa namespace должны совпадать с publisher'ом —
|
||||||
|
# ipc нужен для /dev/shm, pid нужен для CUDA driver IPC validation
|
||||||
|
# (без pid: cudaIpcOpenEventHandle падает с "invalid device context")
|
||||||
ipc: "container:cuframes-cam-test"
|
ipc: "container:cuframes-cam-test"
|
||||||
|
pid: "container:cuframes-cam-test"
|
||||||
volumes:
|
volumes:
|
||||||
- cuframes_sock:/run/cuframes:ro
|
- cuframes_sock:/run/cuframes:ro
|
||||||
command:
|
command:
|
||||||
|
|||||||
+27
-7
@@ -78,8 +78,9 @@ services:
|
|||||||
image: gx/cctv-processor:cuda
|
image: gx/cctv-processor:cuda
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
runtime: nvidia
|
runtime: nvidia
|
||||||
# CRITICAL: --ipc=container:cuframes-cam-parking для shared CUDA context
|
# CRITICAL: shared IPC + PID namespace с publisher'ом (см. ниже)
|
||||||
ipc: container:cuframes-cam-parking
|
ipc: container:cuframes-cam-parking
|
||||||
|
pid: container:cuframes-cam-parking
|
||||||
volumes:
|
volumes:
|
||||||
- cuframes_sock:/run/cuframes:ro
|
- cuframes_sock:/run/cuframes:ro
|
||||||
environment:
|
environment:
|
||||||
@@ -90,9 +91,16 @@ volumes:
|
|||||||
cuframes_sock:
|
cuframes_sock:
|
||||||
```
|
```
|
||||||
|
|
||||||
**Важно**: все consumer'ы должны использовать **тот же** `ipc:` namespace, что
|
**Важно — оба флага обязательны** для cross-container CUDA IPC:
|
||||||
и publisher (через `ipc: container:<publisher_container>`). Это нужно для того,
|
|
||||||
чтобы cudaIpcOpenMemHandle / cudaIpcOpenEventHandle работали корректно.
|
| Флаг | Зачем |
|
||||||
|
|---|---|
|
||||||
|
| `ipc: container:<publisher>` | shared `/dev/shm` (нужен для `shm_open` под header/sockets) |
|
||||||
|
| `pid: container:<publisher>` | CUDA driver валидирует IPC peer через `/proc/<pid>/...`; без этого `cudaIpcOpenEventHandle` падает с `invalid device context` |
|
||||||
|
|
||||||
|
Альтернативы:
|
||||||
|
- Запускать consumer внутри того же container'а через `docker exec` (наследует все namespaces) — удобно для отладки.
|
||||||
|
- `--ipc=host --pid=host` — убирает namespacing вообще, но ослабляет изоляцию (не рекомендуется в production).
|
||||||
|
|
||||||
### Изменения в cctv-processor
|
### Изменения в cctv-processor
|
||||||
|
|
||||||
@@ -198,9 +206,11 @@ Engage с upstream Frigate чтобы добавить custom Source-type ("cufr
|
|||||||
ls -la /run/cuframes/cam-parking.sock
|
ls -la /run/cuframes/cam-parking.sock
|
||||||
ls -la /dev/shm/cuframes-cam-parking
|
ls -la /dev/shm/cuframes-cam-parking
|
||||||
|
|
||||||
# 2. Контейнеры в одном IPC namespace
|
# 2. Контейнеры в одном IPC и PID namespace
|
||||||
docker inspect cuframes-cam-parking cctv-backend -f '{{.HostConfig.IpcMode}}'
|
docker inspect cuframes-cam-parking cctv-backend \
|
||||||
# Должно быть "shareable" для publisher и "container:cuframes-cam-parking" для consumer
|
-f '{{.Name}} ipc={{.HostConfig.IpcMode}} pid={{.HostConfig.PidMode}}'
|
||||||
|
# Publisher: ipc=shareable pid=(default)
|
||||||
|
# Consumer: ipc=container:cuframes-cam-parking pid=container:cuframes-cam-parking
|
||||||
|
|
||||||
# 3. Subscriber connect успешен
|
# 3. Subscriber connect успешен
|
||||||
docker exec cctv-backend /usr/local/bin/sub_count --key cam-parking --max-frames 10
|
docker exec cctv-backend /usr/local/bin/sub_count --key cam-parking --max-frames 10
|
||||||
@@ -222,6 +232,16 @@ Subscriber не нашёл publisher. Причины:
|
|||||||
- cuframes_sock:/run/cuframes:ro` в consumer'е
|
- cuframes_sock:/run/cuframes:ro` в consumer'е
|
||||||
- IPC namespace не совпадает — см. checklist пункт 2
|
- IPC namespace не совпадает — см. checklist пункт 2
|
||||||
|
|
||||||
|
### `cudaIpcOpenEventHandle: invalid device context`
|
||||||
|
Проявляется в **отдельном** consumer-container'е после успешного handshake (socket
|
||||||
|
открыт, header валиден, но open event handle не проходит).
|
||||||
|
|
||||||
|
Причина: CUDA driver валидирует sender'а IPC peer'а через `/proc`. Если PID
|
||||||
|
namespace не совпадает, sender невидим — context считается невалидным.
|
||||||
|
|
||||||
|
Fix: добавить `pid: container:<publisher>` в consumer's compose service (рядом
|
||||||
|
с `ipc: container:<publisher>`). Проверено на CUDA 13.0 + driver 555+.
|
||||||
|
|
||||||
### `cudaIpcOpenMemHandle returned 'invalid device pointer'`
|
### `cudaIpcOpenMemHandle returned 'invalid device pointer'`
|
||||||
- Контейнеры в РАЗНЫХ ipc namespace — должны быть в одном (через
|
- Контейнеры в РАЗНЫХ ipc namespace — должны быть в одном (через
|
||||||
`ipc: container:<publisher>` или общий `ipc: shareable`)
|
`ipc: container:<publisher>` или общий `ipc: shareable`)
|
||||||
|
|||||||
Reference in New Issue
Block a user