Interactive Mode
Step-by-step EM simulation workflow with the AODT client
Use Interactive Mode when you want your script to drive an EM simulation step-by-step. Instead of launching a full simulation and waiting for all batches and time steps to complete, the client loads a scenario, queries metadata or positions, computes selected channel impulse response (CIR) results, and copies those results into Python when needed.
For a full run that executes all batches and time steps at once, use Batched Mode instead.
Workflow
The typical Interactive Mode workflow is:
- Create a
dt_client.DigitalTwinClient. - Load a scenario YAML string with
client.start(...). - Inspect the loaded scenario with
client.get_status(). - Query scene state, such as RU positions or UE positions at selected temporal indices.
- Allocate CIR buffers with
client.allocate_cirs_memory(...). - Compute selected CIRs with
client.get_cirs(...). - Retrieve results into NumPy with
client.to_numpy(...)orclient.to_numpy_all_cir(...), then pass them into your own applications for analysis, visualization, or control logic. - Deallocate CIR buffers when finished.
UE position and CIR requests must specify the point in time to evaluate. Scenarios can describe time in two ways:
- Slot-based timeline: the scenario is divided into numbered slots within each batch. Use
SlotIndex(5)to request slot 5, orSlotIndices([0, 1, 2])to request several slots. - Duration/interval timeline: the scenario uses a duration and a fixed interval. AODT turns those into numbered samples. For example,
duration=10andinterval=1gives samples at0s, 1s, 2s, ... 10s; useTimeStepIndex(5)to request the sample at5s.
The examples below use a slot-based timeline. If your YAML uses
duration/interval instead, use TimeStepIndex or TimeStepIndices in the same
places where the examples use SlotIndex or SlotIndices. After
client.start(...), client.get_status() reports which timeline the loaded
scenario is using.
Examples
Single-step interaction
Use example_client.py first when validating a server connection or learning
the basic request flow.
This example shows how to:
- Load a scenario from generated YAML or a YAML file.
- Start server log streaming to
dt_server.log. - Call
client.start(yaml_content)and verify the scenario withclient.get_status(). - Query radio unit (RU) positions and user equipment (UE) positions at selected slots.
- Allocate CIR buffers for selected RUs and UEs.
- Compute CIRs for one temporal index.
- Copy CIR
valuesanddelaysinto NumPy arrays. - Release the CIR allocation.
The core pattern is:
Multi-time-step interaction
Use example_multi_timesteps.py when one client flow needs results for several
slots or time steps.
This example extends the single-step flow by allocating enough CIR memory for multiple temporal indices and computing several slots in one request:
After computation, use client.to_numpy(...) to fetch a specific slot and RU,
or use client.to_numpy_all_cir(allocation) to fetch all computed CIR outputs
as nested dictionaries. The multi-step example also demonstrates angle outputs
and optional client.export_results() for writing computed results to Parquet.
C++ zero-copy access
The Python examples retrieve CIR results into NumPy arrays. For C++ applications, zero-copy access requires a colocated deployment: the client and worker must run on the same GPU host. In that setup, AODT can use CUDA IPC to expose CIR result buffers directly as GPU pointers. This avoids copying large CIR buffers through host memory before passing them into a CUDA or C++ processing pipeline.
Transport is negotiated automatically. Confirm zero-copy mode by checking the client logs for:
The worker logs also report NegotiateDataTransport result: mode=LOCAL_IPC (cuda_ipc). In this mode, FetchBuffer(..., MemoryType::GPU) opens the
worker’s CUDA IPC handle and returns an accessible GPU pointer. If the client is
remote, the same API uses the remote transfer path instead.
See client/examples/example_cir.cpp for a complete C++ example.
API Reference
See the DigitalTwinClient API for client methods such as
start, get_status, allocate_cirs_memory, get_cirs, to_numpy,
to_numpy_all_cir, and export_results.
See the Config Builder API for simulation configuration types, including EM mode and temporal configuration concepts.