Documentation
Library manual
Reference for the self-contained C++20 divisible-load scheduling library that powers this portal: what it is for, what it covers, how to build and use it, and how it is licensed. Concepts and notation are defined in the Knowledge base. This manual is a living document and will grow as new problem classes and solvers are added.
HTTP API
The FastAPI layer exposes JSON endpoints at /api/*.
All POST endpoints accept application/json
and return application/json. The response shape mirrors the
CLI --json output exactly, so the same result struct is usable
from a browser, a script, or a CI pipeline.
Compute requests execute one at a time in submission order (a server-side FIFO queue), so a heavy
exact solve cannot starve other requests. By default a POST
simply waits its turn and returns the result, exactly as before. Add
"queue": true to the body to get a job ticket
({"job", "position"}, HTTP 202) back immediately
instead, then poll GET /api/jobs/<id> for the live
queue position and, finally, the result (kept for 10 minutes). When more than 100 jobs are waiting,
submissions return HTTP 429.
Every job carries a wall-clock limit set by the caller's access level: 10 s for anonymous
calls (including plain curl), 120 s for
registered accounts, unlimited for admins. A job that overruns is killed and reports the limit in
its error message. Anonymous callers may keep 1 job waiting at a time; registered accounts 3.
Scripts authenticate exactly like the browser: POST
/api/auth/login returns a session cookie to send with subsequent requests
(curl -c jar … ; curl -b jar …). Accounts are created
on the register page. GET
/api/me reports your tier and effective limits.
Submissions are also capped per source IP address, independent of job length: 20 per hour anonymous, 100 per hour registered, unlimited for admins — abuse protection against scripted submission floods, separate from the per-job time limit above. Exceeding it returns HTTP 429.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/solvers | Return the list of solver names and descriptions available in this build. |
| POST | /api/solve | { instance, solver?, opts? } → schedule with full Gantt timing and lower bound. |
| POST | /api/pareto | { instance, opts? } → time-energy Pareto front (requires an energy model). |
| POST | /api/map | { opts } → isoefficiency or isoenergy 2-D parameter sweep. |
| POST | /api/bench | { solvers?, opts? } → portfolio comparison over random instances. |
| POST | /api/topology | { klass, text } → chain / tree / graph / mapreduce / multilayer load distribution. |
| POST | /api/mlsd | { text, solver? } → multiple-loads (MLSD) schedule. |
| POST | /api/mapreduce-bwidth | { text } → MapReduce under a bisection-width read-channel limit (exact LP, HiGHS build only). |
| POST | /api/skew-static | { text } → reducer partitioning-skew mitigation, fine partitioning + LPT bin-packing. |
| POST | /api/skew-dynamic | { text } → reducer partitioning-skew mitigation, single-shot post-sort rebalancing. |
| POST | /api/reducer-read | { text } → heterogeneous multi-channel reducer read schedule (branch-and-price, HiGHS build only). |
| POST | /api/multisource | { text } → multi-source map-phase schedule, bipartite storage-nodes-to-mappers LP (HiGHS build only). |
| GET | /api/jobs/{id} | Poll a queued job: { status, position } while waiting, then { status: "done", result }. |
| POST | /api/jobs/{id}/cancel | Stop a queued or running job. Owner (same session or IP) or admin only. |
| GET | /api/queue | Queue snapshot: { running, waiting } counts across all compute endpoints. |
POST /api/solve — request
The instance field uses the same JSON schema as the Python
dls.solve() dict. The solver
field defaults to "auto" when omitted.
The opts object is optional; all keys are shown below.
// POST /api/solve { "instance": { "totalLoad": 1000, "processors": [ { "S": 0.1, "C": 0.11, "A": 0.52, "B": 4000 }, { "S": 0.2, "C": 0.21, "A": 0.22, "B": 5000 }, { "S": 0.3, "C": 0.31, "A": 0.32, "B": 1500 } ] }, "solver": "best-rate", "opts": {} }
POST /api/solve — response
// 200 OK — response body { "solver": "best-rate", "lowerBound": 298.51, "solution": { "status": "Feasible", "makespan": 302.14, "energy": 0.0, "sequence": [0, 1, 2], "fragments": [ { "processorId": 0, "loadSize": 417.31, "commStart": 0.10, "commFinish": 46.10, "computeStart": 46.10, "computeFinish": 302.14 }, { "processorId": 1, "loadSize": 332.84, "commStart": 46.10, "commFinish": 116.82, "computeStart": 116.82, "computeFinish": 302.14 }, { "processorId": 2, "loadSize": 249.85, "commStart": 116.82, "commFinish": 193.57, "computeStart": 193.57, "computeFinish": 302.14 } ], "wallTimeSec": 0.000312 } }
Available opts keys
// opts keys accepted by /api/solve (all optional) { "maxInstallments": 5, // search depth / GA installments "deadline": 300.0, // time deadline T (OptV / FPTAS only) "epsilon": 0.05, // FPTAS approximation ε "seed": 42, // RNG seed for GA reproducibility "costLimit": 500.0, // bi-criteria cost cap G "backend": "highs", // LP evaluator: "simplex" | "highs" "allowRepeats": true, // allow a processor to appear more than once "chunk": "gss" // online chunk rule: "gss" | "ssc" }