Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ jobs:
uv pip install --python .venv -e ".[dev]" --torch-backend=auto
- name: Check default dependencies and available compute
run: uv run --no-project --python .venv python scripts/check_install.py
- name: Audit the resolved Python dependencies
if: matrix.os == 'ubuntu-latest'
run: |
uv run --no-project --python .venv python scripts/audit_requirements.py > /tmp/opendpd-audit.txt
uvx pip-audit --strict --no-deps --disable-pip -r /tmp/opendpd-audit.txt
- name: Real browser fallback remains reachable
run: uv run --no-project --python .venv python -m pytest tests/integration/test_launcher_browser_fallback.py -q

Expand All @@ -143,6 +148,9 @@ jobs:
- name: Install
run: npm ci

- name: Audit frontend dependencies
run: npm audit --audit-level=moderate

- name: Generated API types match docs/contracts/openapi.json
run: npm run types:check

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ OpenDPD is a PyTorch framework for power amplifier (PA) modeling and digital pre
## What's new

<!-- --8<-- [start:studio-features] -->
**OpenDPD 2.2.5** adds LaTeX equations with interactive PA parameter highlighting, shared or per-channel OFDMA settings, and **ILC + ILA DPD** with a separate waveform-specific Ideal benchmark. Next-step controls sit above settings, and metric calculation methods have clearer names.
**OpenDPD 2.2.6** adds a **Server load** tab with active sessions, queued/running jobs, CPU, memory and GPU utilization. The top bar shows one exact workspace cleanup timestamp. Stronger request, filesystem and resource limits protect shared compute.

**Signal Generator → PA Library → PA training → DPD training/testing.** Generate a PA input waveform, simulate its output with one of nine Virtual PAs, or upload existing input/output CSV data. Results label synthetic, surrogate and measured evidence and show separate PSD charts at each signal-chain position.

[2.2.5 release notes](https://lab-emi.github.io/OpenDPD/releases/release-notes-2.2.5/) · [Signal Generator](https://lab-emi.github.io/OpenDPD/guides/signal-generator/) · [ILC guide](https://lab-emi.github.io/OpenDPD/guides/ilc-dpd/). Standard presets are engineering stimuli, not conformance waveforms; Wi-Fi 8 is experimental.
[2.2.6 release notes](https://lab-emi.github.io/OpenDPD/releases/release-notes-2.2.6/) · [Signal Generator](https://lab-emi.github.io/OpenDPD/guides/signal-generator/) · [ILC guide](https://lab-emi.github.io/OpenDPD/guides/ilc-dpd/). Standard presets are engineering stimuli, not conformance waveforms; Wi-Fi 8 is experimental.
<!-- --8<-- [end:studio-features] -->

[Feature history](docs/whats-new.md) · [Verified platform status](docs/releases/support-matrix.md)
Expand Down Expand Up @@ -70,7 +70,7 @@ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | ie
mkdir opendpd-lab
cd opendpd-lab
uv venv --python 3.12
uv pip install --python .venv "opendpd==2.2.5" --torch-backend=auto
uv pip install --python .venv "opendpd==2.2.6" --torch-backend=auto
uv run --no-project --python .venv opendpd gui
```

Expand Down
13 changes: 11 additions & 2 deletions deployment/web/GpuContainerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
FROM docker.io/pytorch/pytorch:2.8.0-cuda12.8-cudnn9-runtime@sha256:417bd75df6365104c283ea4c1651fb3530d9eb5a4c2fafa51943cff2a94e6385
FROM docker.io/pytorch/pytorch:2.14.0-cuda13.2-cudnn9-runtime@sha256:773f5f0122b8d6413ff1e47559d98a3a22896434822e2d7752ba8d5b85a363d7
WORKDIR /opt/opendpd
RUN pip install --no-cache-dir numpy scipy pandas matplotlib pillow tqdm rich 'pydantic>=2.5,<3' psutil
# Apply Ubuntu security updates and remove build headers from the runtime.
# Containers use the host kernel; linux-libc-dev is an unused header package.
RUN apt-get update && apt-get upgrade -y && apt-get purge -y linux-libc-dev python3-pip python3-wheel binutils-common libctf-nobfd0 libsframe1 libc-dev-bin && rm -rf /var/lib/apt/lists/*
RUN uv pip install --system --break-system-packages --no-cache --upgrade 'setuptools>=83'
RUN uv venv --system-site-packages --python /usr/bin/python /opt/opendpd-runtime
ENV PATH="/opt/opendpd-runtime/bin:${PATH}"
RUN uv pip install --python /opt/opendpd-runtime --no-cache --upgrade pip setuptools wheel numpy scipy pandas matplotlib pillow tqdm rich 'pydantic>=2.5,<3' psutil
COPY pyproject.toml README.md arguments.py project.py models.py main.py ./
COPY opendpd ./opendpd
COPY backbones ./backbones
Expand All @@ -11,5 +17,8 @@ COPY quant ./quant
COPY datasets ./datasets
COPY dataset ./dataset
RUN pip install --no-cache-dir --no-deps --no-build-isolation . && chmod -R a-w /opt/opendpd
# No package installation is needed in an offline inference/training worker.
# Remove installers and their bundled dependencies after building the app.
RUN uv pip uninstall --python /opt/opendpd-runtime pip && uv pip uninstall --system --break-system-packages pip uv
USER 65532:65532
ENTRYPOINT ["python", "-m", "opendpd.web.gpu_container"]
2 changes: 2 additions & 0 deletions deployment/web/opendpd-gpu.service
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ UMask=0077
LimitCORE=0
MemoryMax=10G
MemorySwapMax=0
CPUQuota=400%
TasksMax=512
# Worker copies exist only in this service's mount namespace. The container's
# read-only image and log-driver=none keep user files out of OCI storage.
TemporaryFileSystem=/run/opendpd-gpu:rw,size=2G,mode=0700,nodev,nosuid,noexec
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ file (S05).
## Sessions

1. The launcher prints `http://127.0.0.1:<port>/bootstrap?token=…`. Opening it
exchanges the one-time token for an `HttpOnly; SameSite=Strict` cookie and
exchanges the launcher secret for an `HttpOnly; SameSite=Strict` cookie and
redirects to `/` so the token never stays in the address bar.
2. `GET /api/v1/session` returns `{authenticated, csrf_token}`. Every
state-changing request (POST) must send `X-OpenDPD-CSRF: <csrf_token>`.
Expand Down
13 changes: 11 additions & 2 deletions docs/architecture/public-studio.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ it terminates remaining requests and workers, then discards its private tmpfs.
The stop timeout is 20 seconds with SIGKILL as the final fallback. This leaves
margin before any session data reaches 24 hours. Sessions do not get a fresh
24 hours when they are accessed or when new files are generated. Late visitors
therefore have a shorter session; the UI displays their exact expiry.
therefore have a shorter session; the persistent top bar displays the exact scheduled cleanup start in UTC, with local time in its tooltip. Active requests can delay individual deletions until the next sweep; the independent reset bounds that delay.

Refreshing a browser or reconnecting within the same tab resumes the existing
session, events and saved plots. Restarting the API or VM discards every session;
Expand Down Expand Up @@ -118,10 +118,11 @@ Cloudflare response header for `/studio/` because a meta CSP cannot enforce it.
| HTTP requests | 120/minute per session, 600/minute per IP; preflight has a separate 600/minute bucket; 8 concurrent globally, 3/session |
| JSON request body | 64 KiB, 10-second receive deadline; no multipart |
| Jobs | 8/session, 12/IP/day, 60/day globally; 2 pending/session |
| Heavy API work | 2 concurrent analyses/generations/exports globally; one workspace mutation at a time; cancellation is exempt |
| Concurrent training/inference | 1 globally across every session, oldest queued experiment first |
| Job runtime | 30 minutes, followed by cancellation and forced termination |
| Public model/training parameters | bounded layers, widths, batches, frames, epochs and threads |
| Storage | 256 MiB/session checked every 15 seconds; **2 GiB hard limit globally** |
| Storage | 256 MiB/session checked every 15 seconds; **2 GiB hard limit globally**; heavy writers reserve capacity before receiving data, retaining 64 MiB free headroom |
| Files/processes | 64 MiB/file, 256 tasks, 4 CPU equivalents, 6 GiB API cgroup RAM |

IPv6 addresses share a /64 rate-limit bucket. IP quotas use an ephemeral HMAC
Expand Down Expand Up @@ -359,3 +360,11 @@ termination and empty host temporary storage before publishing the frontend.
Deploy the reviewed 2.2.4 source consistently to the isolated API, the private GPU agent and its pinned container image, and the `opendpd-site` Pages build. Drain queued/running experiments before replacing the API; retain prior source and image pins for rollback. Restarting the API expires existing temporary sessions. Verify reported versions before the public generation → Virtual PA → paired dataset → CUDA PA/DPD training/testing journey.

Generator records contain input only. The `/pa-library/` routes perform bounded mathematical simulation inside the owning temporary workspace, preserve synthetic provenance and require explicit paired-dataset creation. New PSD `signal_node` fields are display metadata; tenant boundaries, quotas, expiry and numerical metric protocols remain unchanged. Publication-figure and optional GitHub dataset-contribution capabilities keep their existing operator policy.

## 2.2.6 resource status and security update

Authenticated `GET /api/v1/system/status` exposes aggregate session/job counts and cached resource samples. A single background sampler per API process reads CPU/RAM every five seconds; the private GPU agent samples host CPU/RAM and GPU 0 and sends validated telemetry to `POST /_gpu/resources`. That endpoint requires the existing private bridge credential and refuses browser origins. Status reads neither run GPU commands nor disclose process names, IPs, workspace identifiers or dataset details. Job counts are cached across viewers; collection errors produce unknown counts instead of zero. Samples older than 20 seconds are stale.

Workspace POST/PUT operations serialize within a tenant; cancellation remains available. Heavy API work has a separate global admission limit, and temporary-space reservations prevent concurrent writers from spending the same free capacity. Cleanup scans run off the event loop and tolerate files atomically replaced by legitimate writers. Failed cleanup still disables new sessions.

The runtime image pins PyTorch 2.14/CUDA 13.2 by digest, applies Ubuntu updates and removes unused build headers and package installers. Keep the existing network-free, non-root, read-only worker limits. Deploy reviewed source to the API, agent, image and Pages together, with no queued/running jobs at the swap and rollback copies retained. See [load semantics](../guides/server-load.md) and the [2.2.6 security review](../releases/security-review-2.2.6.md).
Loading
Loading