Lua API Reference#

QRMI Lua bindings and available interfaces for developing quantum workflows in Lua.


Generated from the Doxygen comments in lua_qrmi.c. This summarises the full API exposed by the module loaded via require("qrmi"), from a Lua consumer’s point of view (for C-level implementation details, see lua_qrmi.c itself).

The module provides two independent object types:

  • qrmi.resource — a handle to a single quantum resource (created via qrmi.new())

  • qrmi.config — a handle to a qrmi_config.json config file (created via qrmi.load_config()) Completely independent lifecycle from qrmi.resource

Every method follows the same two-value error pattern on failure: (value, ...) on success, (nil, errmsg) on failure (the same convention Lua’s io.open and similar functions use).

Design Notes#

  1. Converting QrmiReturnCode into Lua’s (value, err) pattern Every real API call returns a QrmiReturnCode, so on failure qrmi_get_last_error() is called to fetch a detailed message, returned to Lua as (nil, errmsg). On success, the out-parameter’s value is pushed directly.

  2. String ownership management Any char* heap-allocated on the Rust side (via cbindgen) is freed with qrmi_string_free(). This implementation frees it immediately after copying it into Lua (lua_pushstring), so nothing leaks.

  3. Resource lifecycle and GC QrmiQuantumResource* is an opaque pointer. The userdata holds exactly one, and the __gc metamethod ensures it’s automatically released and freed even if the caller forgets to do so explicitly.


Module functions#

qrmi.new(resource_id, resource_type)#

Creates a quantum resource handle.

Argument

Type

Description

resource_id

string

e.g. "ibm_kingston"

resource_type

string

Canonical name from qrmi_config_resource_type_to_str(). One of the values below

Valid values for resource_type: ibm-quantum-system / ibm-quantum-compute-service / pasqal-cloud / pasqal-local / alice-bob-felis / iqm-server

Returns: on success, resource (a qrmi.resource); on failure, nil, err

local resource, err = qrmi.new("ibm_kingston", "ibm-quantum-compute-service")

qrmi.new_from_config(resource_id, resource_type, config)#

Create a quantum resource handle from an explicit config map. Wraps qrmi_resource_new_from_config().

Argument

Type

Description

resource_id

string

The resource identifier, e.g. "ibm_kingston".

resource_type

string

The canonical hyphenated resource type name. Accepts the same values as qrmi.new().

config

table

A string-to-string config map. The required and optional keys depend on the resource type. They use the same names as the environment variables, without the {resource_id}_ prefix, e.g. QRMI_WARDEN_URL or QRMI_IBM_QCS_SESSION_ID. See the from_config() doc comments in the QRMI Rust crate for details.

Returns: on success, resource (qrmi.resource userdata); on failure, nil, err.

local resource, err = qrmi.new_from_config("ibm_kingston", "ibm-quantum-compute-service", {
  QRMI_IBM_QCS_ENDPOINT = "...",
  QRMI_IBM_QCS_IAM_ENDPOINT = "...",
  QRMI_IBM_QCS_IAM_APIKEY = "...",
  QRMI_IBM_QCS_SERVICE_CRN = "...",
})
if not resource then
  error(err)
end

qrmi.load_config(filename)#

Loads a qrmi_config.json file. Entirely independent from qrmi.resource.

Returns: on success, config (a qrmi.config); on failure, nil, err

local config, err = qrmi.load_config("/etc/slurm/qrmi_config.json")

qrmi.resource methods#

resource:is_accessible()#

Deprecated since version 0.25.0: Use resource:status() instead.

Checks whether the device is reachable.

Returns: on success, accessible (boolean); on failure, nil, err

resource:status()#

Fetch detailed status information as a Lua table.

Returns: on success, a table with the fields described below; on failure, nil, err.

Field

Type

Description

status

string

One of "online", "offline", or "paused".

status_reason

string or nil

The vendor-specific status reason.

busy

boolean or nil

true if the resource is currently busy.

healthy

boolean or nil

true if the resource is currently healthy.

pending_job_count

integer or nil

The number of jobs pending in the queue.

capacity

table or nil

Slot capacity information, with the two fields below.

capacity.available_slots

integer

The number of slots currently available to be acquired.

capacity.max_slots

integer

The maximum number of slots the resource supports.

local st, err = resource:status()
if not st then
  error(err)
end
print(st.status)             -- "online" | "offline" | "paused"
print(st.status_reason)      -- string or nil
print(st.busy)               -- boolean or nil
print(st.healthy)            -- boolean or nil
print(st.pending_job_count)  -- integer or nil
if st.capacity then
  print(st.capacity.available_slots, st.capacity.max_slots)
end

resource:id()#

Fetches the resource’s identifier (the same resource_id passed to qrmi.new()).

Returns: on success, id (string); on failure, nil, err

resource:type()#

Fetches the resource’s type. Returns the canonical hyphenated string (the same form accepted by qrmi.new()) rather than the raw enum value.

Returns: on success, type (string, e.g. "ibm-quantum-system"); on failure, nil, err

resource:acquire()#

Acquires exclusive access to the resource. The returned token is also cached internally, so a later release() call with no arguments, or the __gc finalizer, can release it automatically.

If a token from an earlier, unreleased acquire() is still held, it is properly released via qrmi_resource_release() before acquiring a new one.

Returns: on success, token (string); on failure, nil, err

local token, err = resource:acquire()

resource:release([token])#

Releases a previously acquired resource. If token is omitted, the token cached from the last acquire() call is used automatically.

Returns: on success, ok (boolean, always true); on failure, nil, err

resource:release()          -- uses the cached token automatically
resource:release(token)     -- explicit token

resource:task_start(payload)#

Starts a task. payload is a Lua table mirroring the C API’s QrmiPayload tagged union: the table’s single key names the payload variant, and its value is a sub-table holding that variant’s fields. Four variants are currently supported:

Qiskit Primitive (IBM)

resource:task_start({
    qiskit_primitive = {
        program_id = "estimator",   -- "estimator" or "sampler"
        input = json_str,           -- Qiskit Primitive input (JSON string)
    }
})

IQM Server

resource:task_start({
    iqm_server = {
        iqmjson = json_str,          -- IQM JSON request body
        job_type = "circuit",        -- "circuit" / "run" / "sweep"
        use_timeslot = false,        -- optional, defaults to false
        tag = "my-job",              -- optional, may be nil
    }
})

Pasqal Cloud or Pasqal Local (both use the same pasqal_cloud key, since qrmi.h has only one QRMI_PAYLOAD_PASQAL_CLOUD tag)

resource:task_start({
    pasqal_cloud = {
        sequence = pulser_sequence_str,  -- Pulser sequence
        job_runs = 100,                  -- number of runs
    }
})

Alice & Bob Felis

resource:task_start({
    alice_bob_felis = {
        human_qir = qir_str,          -- human-readable QIR input
        input_params = json_str,      -- input parameters (JSON format)
    }
})

Returns: on success, task_id (string); on failure, nil, err

resource:task_status(task_id)#

Fetches a task’s current status.

Returns: on success, status (string: "queued" / "running" / "completed" / "failed" / "cancelled"); on failure, nil, err

Recommended usage (poll until a terminal status is reached):

local terminal = { completed = true, failed = true, cancelled = true }
local status = resource:task_status(task_id)
while status and not terminal[status] do
    os.execute("sleep 1")
    status = resource:task_status(task_id)
end

resource:task_result(task_id)#

Fetches a completed task’s result.

Returns: on success, result_json (string); on failure, nil, err

resource:task_logs(task_id)#

Fetches a task’s log messages.

Returns: on success, logs (string); on failure, nil, err

resource:task_stop(task_id)#

Stops a running task.

Returns: on success, ok (boolean, always true); on failure, nil, err

resource:metadata()#

Fetches the resource’s metadata as a Lua table (combines qrmi_resource_metadata + qrmi_resource_metadata_keys + qrmi_resource_metadata_value into a single call).

Returns: on success, metadata (table, string → string); on failure, nil, err

local meta = resource:metadata()
print(meta.backend_name, meta.n_qubits)

resource:target()#

Fetches the device’s target information.

Returns: on success, target_json (string); on failure, nil, err

resource:free()#

Explicitly releases and frees the resource (auto-releases first if still acquired). Also happens automatically via __gc if not called explicitly, but calling it explicitly is recommended.

Returns: nothing


qrmi.config methods#

Independent from qrmi.resource.

config:resource_def(resource_id)#

Looks up a resource’s definition in the config file.

Returns: on success, def (table); on failure, nil, err

Structure of def:

{
    name = "ibm_kingston",
    type = "ibm-quantum-compute-service",
    is_dynamic = false,
    environments = {
        QRMI_IBM_QRS_ENDPOINT = "...",
        QRMI_IBM_QRS_IAM_ENDPOINT = "...",
    },
}

config:free()#

Explicitly frees the config. Also auto-frees via __gc.

Returns: nothing


Common error-handling pattern#

Every method returns (nil, errmsg) on failure:

local val, err = resource:some_method()
if not val then
    print("failed:", err)
end

Calling a method on a resource or config that has already been free()d raises a Lua error (via error()) rather than returning the usual value pair:

local ok, err = pcall(function() resource:is_accessible() end)
-- ok = false, err = "qrmi resource already freed"

Not yet implemented (room for extension)#

  • QrmiResourceProvider / qrmi_provider_new() — resource discovery / least-busy selection

  • Redirecting logs to Lua via qrmi_log_callback_set()