Time-Domain System Equivalent logoTime-Domain System EquivalentLinear dynamics, solved faster.Discuss Integration

Getting Started

The first runnable path from a fresh checkout to a verified TDSE step loop.

Use this chapter for the shortest trustworthy TDSE bring-up: build a minimal 3-port model from scratch, write one pack, load it into Runtime, and verify a small step loop.

Prerequisite: Complete the Installation chapter first.

This is the first-run chapter referenced elsewhere in the handbook as Hands-On Tutorial.

The tutorial has four steps:

  1. Create the Builder input data — a C program that defines an impulse response and writes a runtime pack.
  2. Compile and run the Builder — produce tutorial.pack.
  3. Run the Runtime step loop — load the pack, create a model, and execute five steps.
  4. Verify the output — confirm the model metadata and step results match expectations.

By the end, you will have exercised the core SDK pipeline: Builder -> pack -> Runtime -> step loop. All code is runnable as-is.

For most installed-package evaluations, this chapter should take about 15-30 minutes. If the installed SDK is already on your machine and the commands below run unchanged, you should end the session with one pack, one successful model create, and one clean create-step-destroy path.

Expected outputs from this chapter:

  • tutorial.pack
  • a successful tdse_model_create(...)
  • five successful runtime steps
  • a clean tdse_model_destroy(...)

Before you start, confirm these are already true:

  • tdse sdk version --json-out - succeeds from the installed package
  • the tiny compile-and-link check from Installation already works
  • you are using the same SDK prefix, compiler family, and library names from Installation

After Hands-On Tutorial, use the Examples Guide to choose the closest runnable reference for your real integration path.

Step 1: Create the Builder Input Data

This program does three things: (1) defines a 3-port impulse response with 4 taps, (2) configures the Builder with shape parameters, and (3) writes a .pack file.

Create tutorial_data.c:

#include <tdse/tdse.h>
#include <tdse_builder.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    const size_t np = 3;
    const size_t nh = 4;
    const double dt = 1e-3;

    /* Identity-like H: h[k] decays with k */
    double h[4 * 3 * 3] = {
        1, 0, 0,  0, 1, 0,  0, 0, 1,       /* h[0]: instantaneous */
        0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2,   /* h[1] */
        0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1,   /* h[2] */
        0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05 /* h[3] */
    };

    /* Uniform tap axis: tau[k] = k * dt */
    double tau[4] = {0.0, 1.0e-3, 2.0e-3, 3.0e-3};

    /* Configure and build */
    tdse_builder_t* b = NULL;
    tdse_builder_options_t opt = tdse_builder_options_init();
    opt.dt = dt;
    opt.nh = nh;
    opt.np = np;
    opt.nq = np;

    if (tdse_builder_create(&b) != TDSE_BUILDER_OK) return 1;

    tdse_h_desc_t h_desc;
    memset(&h_desc, 0, sizeof(h_desc));
    h_desc.struct_size = sizeof(h_desc);
    h_desc.np = (int32_t)np;
    h_desc.nq = (int32_t)np;
    h_desc.nh = (uint64_t)nh;
    h_desc.data = h;
    h_desc.tau = tau; /* optional explicit tau; h must already match that axis */

    if (tdse_builder_configure_ex(b, &opt) != TDSE_BUILDER_OK) return 1;
    if (tdse_builder_apply_h(b, &h_desc) != TDSE_BUILDER_OK) return 1;
    if (tdse_builder_write_pack(b, "tutorial.pack") != TDSE_BUILDER_OK) return 1;

    tdse_builder_destroy(b);
    printf("Pack written to tutorial.pack\n");
    return 0;
}

This is a runnable example: compile it against the SDK headers and libraries.

Step 2: Run the Builder

Compile and run (assuming SDK is installed at /opt/tdse-sdk):

cc tutorial_data.c \
    -I/opt/tdse-sdk/include \
    -L/opt/tdse-sdk/lib \
    -ltdse_builder -lm \
    -o tutorial_build
LD_LIBRARY_PATH=/opt/tdse-sdk/lib ./tutorial_build

Windows (MSVC):

cl tutorial_data.c ^
  /I"C:\tdse-sdk\include" ^
  /link "C:\tdse-sdk\lib\tdse_builder.lib"
tutorial_build.exe

Success: you see Pack written to tutorial.pack.

Step 3: Run the Runtime Step Loop

Create tutorial_run.c:

#include <tdse/tdse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

static int read_file(const char* path, unsigned char** out, size_t* out_len) {
    FILE* f = fopen(path, "rb");
    long sz; size_t n; unsigned char* p;
    if (!f) return 1;
    fseek(f, 0, SEEK_END); sz = ftell(f); fseek(f, 0, SEEK_SET);
    p = (unsigned char*)malloc((size_t)sz);
    n = fread(p, 1, (size_t)sz, f); fclose(f);
    *out = p; *out_len = (size_t)sz;
    return n != (size_t)sz;
}

int main(void) {
    const size_t np = 3;
    const double dt = 1e-3;
    const double t0 = 0.0;
    const size_t nsteps = 5;
    unsigned char* pack = NULL;
    size_t pack_len = 0;
    tdse_model_t* m = NULL;

    if (read_file("tutorial.pack", &pack, &pack_len) != 0) return 1;

    /* Create model with diagnostics */
    tdse_model_create_diagnostics_t diag = tdse_model_create_diagnostics_init();
    tdse_status_t st = tdse_model_create(pack, pack_len, &diag, &m);
    free(pack);
    if (st != TDSE_OK || m == NULL) {
        printf("Create failed: %s (pack_error=%u)\n",
               tdse_status_message(st), diag.pack_error_code);
        return 1;
    }

    /* Log metadata */
    tdse_model_info_t info = tdse_model_info_init();
    tdse_model_info(m, &info);
    printf("Model: np=%zu nq=%zu nh=%zu dt=%.6f\n",
           (size_t)info.np, (size_t)info.nq, (size_t)info.nh, info.dt);

    /* Prime at n = -1 */
    double primary0[3] = {0.0, 0.0, 0.0};
    tdse_step_begin(m, t0 - dt, dt);

    tdse_dense_block_t op_blk;
    memset(&op_blk, 0, sizeof(op_blk));
    double op[9] = {0};
    op_blk.struct_size = sizeof(op_blk);
    op_blk.rows = (int32_t)np; op_blk.cols = (int32_t)np;
    op_blk.ld = (int32_t)np; op_blk.layout = TDSE_LAYOUT_ROW_MAJOR;
    op_blk.data = op;
    tdse_step_op(m, &op_blk);
    tdse_step_commit(m, primary0);

    /* Main step loop */
    double hr[3], ir[3], dr[3], y[3];
    for (size_t n = 0; n < nsteps; ++n) {
        double primary[3] = {sin(0.1*n), cos(0.1*n), 0.5};

        tdse_step_begin(m, t0 + n * dt, dt);
        tdse_step_hr(m, hr);
        tdse_step_ir(m, ir);

        /* Host composes: y = op * primary + hr + ir */
        for (size_t r = 0; r < np; ++r) {
            y[r] = hr[r] + ir[r];
            for (size_t c = 0; c < np; ++c)
                y[r] += op[r * np + c] * primary[c];
        }

        tdse_step_commit(m, primary);
        tdse_step_dr(m, dr);

        printf("step=%zu y=[%+.6f %+.6f %+.6f] dr=[%+.6f %+.6f %+.6f]\n",
               n, y[0], y[1], y[2], dr[0], dr[1], dr[2]);
    }

    /* Bounded shutdown */
    tdse_model_destroy_options_t dopt = tdse_model_destroy_options_init();
    tdse_model_destroy_result_t dres = tdse_model_destroy_result_init();
    dopt.wait_timeout_ms = 250.0;
    st = tdse_model_destroy(m, &dopt, &dres);
    printf("Destroy: %s\n", tdse_status_message(st));
    return st == TDSE_OK ? 0 : 1;
}

Compile and run (assuming SDK is installed at /opt/tdse-sdk):

cc tutorial_run.c \
    -I/opt/tdse-sdk/include \
    -L/opt/tdse-sdk/lib \
    -ltdse -lm \
    -o tutorial_run
LD_LIBRARY_PATH=/opt/tdse-sdk/lib ./tutorial_run

Windows (MSVC):

cl tutorial_run.c ^
  /I"C:\tdse-sdk\include" ^
  /link "C:\tdse-sdk\lib\tdse.lib"
tutorial_run.exe

Step 4: Verify the Output

Expected output:

Model: np=3 nq=3 nh=4 dt=0.001000
step=0 y=[+0.000000 +0.000000 +0.000000] dr=[+... +... +...]
step=1 y=[+... +... +...] dr=[+... +... +...]
step=2 y=[+... +... +...] dr=[+... +... +...]
step=3 y=[+... +... +...] dr=[+... +... +...]
step=4 y=[+... +... +...] dr=[+... +... +...]
Destroy: OK

Success checklist:

  • tdse_model_create returns TDSE_OK and m != NULL
  • tdse_model_info reports np=3, nq=3, nh=4, dt=0.001
  • Every step loop call returns TDSE_OK
  • tdse_model_destroy returns TDSE_OK

If any step fails, see the failure table in Common First-Run Failure Modes and Troubleshooting.

If all four steps succeed, do not add more complexity here. Move directly to Examples Guide and pick the closest real integration path.

After This Tutorial

Once the first run works, do not keep extending this file as your main reference. Switch to the chapter that matches your real starting point:

Your next taskGo here nextWhy
find the closest runnable referenceExamples Guidefastest way to map from Hands-On Tutorial to real code
package real H or IR dataBuilder and Data Contractsproduction Builder checks and handoff rules
wire Runtime into a host simulatorRuntime Lifecycle and Step Executionlifecycle, ownership, and step semantics
convert netlists or RAW dataAdapter Circuitend-to-end circuit workflow
investigate a failureTroubleshootingsymptom-first triage

For a compact mental model, keep these five handoffs in mind:

  1. source data becomes Builder input
  2. Builder writes a .pack
  3. Runtime creates a model from that pack
  4. the host runs prime, trial, and commit
  5. shutdown happens after the step loop is quiescent

Key Patterns

The tutorial above exercises two patterns you will use repeatedly.

The Builder → Runtime pipeline:

create builder → configure → apply H → write pack → create model → step loop → destroy

The step loop (minimal form):

tdse_step_begin(m, t0 - dt, dt);   /* prime at n = -1 */
tdse_step_op(m, &op);
tdse_step_commit(m, primary_minus1);

for (uint64_t n = 0; n < nsteps; ++n) {
  tdse_step_begin(m, t0 + n * dt, dt);
  tdse_step_hr(m, hr);
  tdse_step_ir(m, ir);
  /* host solve: y = op * primary + hr + ir */
  tdse_step_commit(m, primary);
}

Production shutdown: use bounded destroy with an explicit wait budget.

tdse_model_destroy_options_t opt = tdse_model_destroy_options_init();
opt.wait_timeout_ms = 250.0;
tdse_model_destroy(m, &opt, &result);

For the mathematical meaning behind H, IR, hr, ir, and op, see Theory and Concepts.

C++ Wrapper

The C++ wrapper (tdse::Model) follows the same contract. See the Examples Guide for runnable C++ examples.

Common First-Run Failure Modes

When the API bring-up fails, it is usually one of these:

SymptomMost Likely CauseFirst Check
create fails immediatelybad pack bytes or missing diagnostics initcreate_diag, pack validation, pack token
step_ir fails mid-runIR horizon too shortsimulation step index and ir_nsteps
destroy times outanother same-handle API is still activethread ownership and wait budget
INVALID_STATE on drdr queried before commit or during active trial steplifecycle order