The portfolio data, risk and mean-CVaR optimisation service, prepared for students who run it on their own DGX Spark without root, Docker or Tailscale. - deploy/apptainer/qc.sh: install, start/stop/status/logs, cli/api/python, data import/export and Yahoo setup/update. cuOpt and quantcore run as two Apptainer instances of the user and talk over 127.0.0.1; the API and the test bench listen on 127.0.0.1 only. Builds quantcore.sif without root, or falls back to a plain Python image plus a virtualenv when the Spark allows no unprivileged builds. Detects taken ports and suggests free ones. - deploy/apptainer/quantcore.def + constraints.txt: the image, with the library versions of the verified production container pinned. - cuOpt under Apptainer: NVIDIA's image sets HOME=/opt/cuopt, read-only in a SIF, so the solver died on its first job; qc.sh gives it a writable home. - solvers: a cuOpt that disappears during a solve now falls back to HiGHS instead of answering 500 (requests' ConnectionError escaped the fallback). - client: idempotent GETs retry a dropped keep-alive connection, which made `quantcore-api update --wait` fail when a poll met uvicorn's 5 s timeout. - config: cuOpt defaults to http://127.0.0.1:5000 and `quantcore serve` to 127.0.0.1; the Docker images keep passing their own values. - docs/SPARK_APPTAINER.md: the students' guide; README, USAGE, ARCHITECTURE and SPARK_DEPLOYMENT point to it. Tested on a DGX Spark (GB10, Apptainer 1.5.4, unprivileged user) in both modes: selftest on every endpoint, optimisation on cuOpt, Yahoo update, port conflicts; 139 tests pass in the container against the live cuOpt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
1.2 KiB
YAML
31 lines
1.2 KiB
YAML
# quantcore for a platform team: the JSON API and /docs, no test bench.
|
|
#
|
|
# docker compose -f deploy/docker-compose.students.yml up -d --build
|
|
# curl http://localhost:5001/health
|
|
#
|
|
# The MILP solver is optional. Point QUANTCORE_CUOPT_URL at a cuOpt server if you have one (on a DGX
|
|
# Spark: http://<host>:5000); if it is unreachable, every optimisation falls back to HiGHS on the CPU
|
|
# -- slower on large problems, same model, same answer, and the result says which solver produced it.
|
|
#
|
|
# The data directory is mounted, not baked in: run the setup once (POST /jobs/setup, ~15 min) or copy
|
|
# a prepared ./data next to this file.
|
|
services:
|
|
quantcore:
|
|
build:
|
|
context: ..
|
|
dockerfile: deploy/Dockerfile
|
|
image: quantcore:0.1
|
|
container_name: quantcore
|
|
restart: unless-stopped
|
|
ports: ["5001:5001"]
|
|
environment:
|
|
QUANTCORE_DATA_DIR: /data
|
|
QUANTCORE_CUOPT_URL: ${QUANTCORE_CUOPT_URL:-http://cuopt:5000}
|
|
QUANTCORE_CUOPT_TIME_LIMIT: "300"
|
|
QUANTCORE_ENABLE_UI: "false" # the test bench is not part of the deliverable
|
|
QUANTCORE_LOG_LEVEL: INFO
|
|
OPENBLAS_NUM_THREADS: "4" # small-matrix linear algebra is much slower with all cores
|
|
OMP_NUM_THREADS: "4"
|
|
volumes:
|
|
- ../data:/data
|