Skip to the content.

Custom models: replacing the four models that build a scenario

What it shows

Every other example leaves at least part of the scenario to the default models and registers only what it wants to teach, usually the orchestrator or the mobility model. This one registers the four models that assemble a run before the first event fires, and uses each of them to actually change the scenario, so the two result rows differ everywhere except the workload size:

Model Setter on Simulation Custom class What it changes
Computing nodes generator set_custom_computing_nodes_generator TypeGuaranteeGenerator reserves a device for the type the default split rounds to zero
Topology creator set_custom_topology_creator FullMeshTopologyCreator completes the declared ring of edge data centers into a full mesh
Task generator set_custom_task_generator BurstTaskGenerator lands the whole fleet’s first-minute burst on one instant
Simulation manager set_custom_simulation_manager AuditSimulationManager audits every task by outcome and prints the arrival peak

Each class extends its default, overrides one method, and delegates everything else to super, the same shape as the four setCustom... classes of the Java example. The script launches the identical scenario twice, once with the stock models and once with these four, then prints the two rows side by side.

The four hooks follow the order the framework uses to build a scenario: nodes, then links, then workload, then the event loop.

flowchart LR
    files["settings/<br/>4 device types 39/29/30/2<br/>4 edge DC, ring of 4 links"] --> gen["nodes generator<br/>_allocate_devices<br/>8/6/6/0 becomes 7/6/6/1"]
    gen --> topo["topology creator<br/>create<br/>+4 directed MAN links"]
    topo --> task["task generator<br/>_generate_for_device<br/>burst anchored at t=60 s"]
    task --> run["simulation manager<br/>task_failed, _results_returned<br/>audit and peak lines"]
    classDef custom fill:#cfe8ff,stroke:#333;
    class gen,topo,task,run custom;

The scenario

settings/ holds one small scenario, run twice on the same seed so the only difference is the four models:

Run it

From the repository root, after pip install -e .:

python examples/custom_models/custom_models.py

No-install variant:

PYTHONPATH=src python examples/custom_models/custom_models.py

Optional arguments shrink the run for a quick look: a device count, then the output folder.

PYTHONPATH=src python examples/custom_models/custom_models.py 6 /tmp/custom_models

What to look for

The custom launch prints the four hooks firing:

TypeGuaranteeGenerator - Device type 4 declares 2.0 % of the fleet, a share that rounds to zero: one device reserved from type 1
FullMeshTopologyCreator - Added 4 directed MAN links to complete the full mesh of 4 edge data centers
AuditSimulationManager - audit: 1248 succeeded, 202 failed, 0 not sent (FAILED_DUE_TO_DELAY 202)
AuditSimulationManager - link usage: WAN 17.97 s, MAN 0.00 s, LAN 64.38 s, 0 transfers crossed a MAN link
AuditSimulationManager - busiest instant: 20 tasks arrive together at t=60 s over 1450 generated tasks

Both rows below are the ALL / TRADE_OFF / 20 devices scenario at five simulated minutes and seed 83, measured 2026-10-28 and read from the two CSVs that one run of the script writes. The stock and custom columns share the metrics the run prints for both passes.

Metric Stock models Custom models
Device split over the four types 8, 6, 6, 0 7, 6, 6, 1
Directed MAN links in the graph 8 12
Number of generated tasks 1450 1450
Tasks successfully executed 1250 (86.21 %) 1248 (86.07 %)
Failed due to latency 200 202
Average execution delay (s) 0.1609 0.2075
Network usage, WAN (s) 44.4508, 0.608 82.3452, 17.968
Total network traffic (MB) 1694.02 1613.02
Average CPU usage (%) 0.262 0.38
MAN energy consumption (Wh) 0.0 0.0
Energy of computing nodes (Wh) 39.0373 37.9788
Dead devices, device-death, mobility failures 0, 0, 0 0, 0, 0

Results go to examples/custom_models/output/. The settings clear the output folder before a launch, so the two runs write to separate folders: the custom row owns a timestamped folder under output/, and the stock row goes to output/stock/.

Files

Where to go next