Skip to content

AFDEAPAC/topogen

Repository files navigation

Topology Generator

An AI-fabric topology planner: given a switch capability model, a scale (compute nodes and NICs/GPUs per node), and constraints (subscription, link speeds, tiers), it computes a feasible Clos / rail-optimized fabric, validates it, and renders / exports it. It also ships an AMD MI3XX reference "advisor" that recommends a design from a GPU count.

Topology Generator — settings panel and 3D topology viewer

Architecture

The code is layered so the planning engine is fully headless (usable from the browser and a CLI), and the viewers are independent components that render purely from the engine's output model.

src/
  core/                 # headless engine (no DOM) — the Input->Output calculator
    types.ts            # contracts: SwitchSpec, TopologyInput, TopologyModel, Kpis,
                        #            FabricGraph, ValidationReport, Advisor, Viewer
    engine.ts           # generate(input) -> model, port math, builders, KPIs, AMD data
    validate.ts         # validate(model) -> ValidationReport (radix, coverage, cabling...)
    advisors/           # Advisor plugin registry
      amdReference.ts   #   AMD MI3XX reference design advisor
      index.ts          #   listAdvisors() / getAdvisor(id)
    index.ts            # public barrel
  exporters/
    format.ts           # pure toDot / toSlurmConf (no DOM) — reused by the CLI
    dom.ts              # browser download / print-to-PDF
    index.ts
  viewers/              # independent components; consume ONLY a TopologyModel
    viewer2d.ts         # createViewer2D() {mount,update,destroy} + renderModelSvg()
    viewer3d.ts         # createViewer3D() (WebGL, model-driven)
    index.ts
  ui/
    store.ts            # tiny observable store + connectViewer() (auto-render seam)
  cli/
    index.ts            # topogen CLI
  topology.js / renderer.js / exporters.js / flow3d.js / main.js
                        # back-compat barrels + the live browser controller

Data flow:

TopologyInput --> core.generate() --> TopologyModel --> validate() --> ValidationReport
                                            |
                     +----------------------+----------------------+
                     v                      v                      v
                 Viewer2D               Viewer3D             exporters (DOT/Slurm/SVG/JSON)

Advisor.recommend({gpus, variant, family}) maps a GPU count to a partial TopologyInput (plus matched reference metadata) that is fed to generate().

Contracts

The rigorous Input/Output shapes live in src/core/types.ts. A new switch only needs to provide a SwitchSpec (id, asic, kind, radixBySpeed, and — for DDC NCPs — a fixed nifPorts/fabricPorts split) to be planned with.

Validator

validate(model) returns a ValidationReport { ok, checks[], errors[], warnings[] } covering: leaf radix feasibility, spine fan-in vs radix, endpoint coverage, cable-count consistency, switch-count consistency, connectivity, and oversubscription advisories. The engine attaches it as model.report.

CLI

npm run cli -- --leaf as9817_64d --topology fat2 --nodes 64 --gpn 8 \
               --down 400 --up 800 --blocking 0.862 --formats dot,slurm,svg,json --out ./out
npm run cli -- --advisor amd-mi3xx --gpus 2048 --variant tree --family sched --out ./out

Writes the requested formats, prints the validation report, and exits non-zero if the design is infeasible.

Quick start (Docker)

Requires Docker or Podman. The app listens on port 8778 by default; override with PORT=<port> if that port is busy.

make dev    # hot-reload dev server — http://localhost:8778
make build  # build production image (nginx + static dist/)
make up     # run production container in background
make run    # build + run production container in foreground
make stop   # stop running containers
make logs   # follow production container logs

make dev mounts the repo into a Node 20 container, runs npm install, then npm run dev with --host 0.0.0.0. Source edits on the host are picked up by Vite without rebuilding the image.

make build runs a multi-stage Dockerfile: Vite builds dist/, then nginx serves it. make up / make run expose the app at http://localhost:8778.

GitHub Pages

Pushes to main run .github/workflows/pages.yml: npm cinpm run build (with BASE_PATH=/<repo>/) → deploy dist/ to GitHub Pages.

One-time setup in the repo on GitHub:

  1. Settings → Pages → Build and deployment → SourceGitHub Actions
  2. After the first successful workflow run, the site is live at
    https://<org-or-user>.github.io/topogen/

Local preview of the Pages build:

BASE_PATH=/topogen/ npm run build && npm run preview

Scripts (npm)

  • npm run dev / npm run build — Vite web app (same as inside make dev / the Docker build stage).
  • npm test — Node test runner (via tsx); includes golden characterization tests.
  • npm run typechecktsc --noEmit.
  • npm run golden — regenerate test/fixtures/golden.json (only when a change is intended).

Offline note: Three.js is vendored at src/vendor/three.module.js and loaded locally (no CDN). The container harness scripts/run.sh runs any npm script in a Node container when npm is unavailable on the host.

Notes / staged work

  • The engine (core/engine.ts) carries a transitional // @ts-nocheck; contracts in types.ts are strict. Fine-grained decomposition of the engine and removal of @ts-nocheck is staged.
  • main.js remains the live browser controller (UX unchanged). The ui/store.ts observable is in place for incremental migration of panels/viewers onto it.

Releases

Packages

Contributors

Languages