Skip to content

SDK Device Plugin Development Guide

[!NOTE] For the latest implementation status, refer to Functional Implementation Status (Remaining Functionality).

Overview

This guide shows the shortest path for adding a new EvoSpikeNet DevicePlugin.

Use cases: - Integrating a new runtime backend (CPU/GPU/NPU/quantum) - Pluginizing model optimization/conversion/deployment logic

Prerequisites

  • Python 3.10+
  • EvoSpikeNet-Core development environment
  • pip install -e . done

Optional dependencies:

# IBM Quantum example
pip install -e ".[quantum]"

# Jetson / EdgeTPU / Loihi
pip install -e ".[jetson]"
pip install -e ".[edge_tpu]"
pip install -e ".[loihi]"

Required interface

A DevicePlugin must implement:

  • get_metadata()
  • initialize()
  • activate()
  • deactivate()
  • get_capabilities()
  • optimize_model()
  • convert_format()
  • deploy_model()

References: - evospikenet/plugins/device_plugin.py - evospikenet/plugins/builtin/device_plugins.py - evospikenet/plugins/builtin/ibm_quantum_plugin.py - evospikenet/plugins/builtin/device_backends/ibm_neurochip_plugin.py

Additional IBM Quantum APIs available in the current implementation:

  • check_runtime_connectivity()
  • run_sampler()
  • run_estimator()

Additional IBM NeuroChip API available in the current implementation:

  • run_simulator()
  • run_northpole()

Additional G-QuAT API available in the current implementation:

  • run_simulator()
  • run_g_quat()

Template and sample

A minimal template is available at:

  • examples/sdk/programs/device_plugin_template.py
  • examples/sdk/programs/ibm_quantum_runtime_demo.py
  • examples/sdk/programs/ibm_neurochip_demo.py
  • examples/sdk/programs/ibm_neurochip_northpole_mock_e2e.py
  • examples/sdk/programs/g_quat_mock_e2e.py
  • examples/sdk/programs/vqe_neuron_layer_demo.py
  • examples/sdk/programs/loihi_brain2loihi_demo.py

What it demonstrates: - minimal CustomDevicePlugin - registration with PluginFactory - conversion/deploy smoke flow

Run:

python examples/sdk/programs/device_plugin_template.py
python examples/sdk/programs/ibm_quantum_runtime_demo.py
python examples/sdk/programs/ibm_neurochip_demo.py
python examples/sdk/programs/ibm_neurochip_northpole_mock_e2e.py
python examples/sdk/programs/g_quat_mock_e2e.py
python examples/sdk/programs/vqe_neuron_layer_demo.py
python examples/sdk/programs/loihi_brain2loihi_demo.py

Recommended stable invocation for the NorthPole mock E2E sample:

PYTHONPATH=. python examples/sdk/programs/ibm_neurochip_northpole_mock_e2e.py

Recommended stable invocation for the G-QuAT mock E2E sample:

PYTHONPATH=. python examples/sdk/programs/g_quat_mock_e2e.py

For synchronization coverage, see PLUGIN_DOC_SYNC_MATRIX.en.md.

For detailed Loihi simulator steps, see SDK_LOIHI_BRAIN2LOIHI_GUIDE.en.md.

Configuration file integration

When operating DevicePlugin through the SDK, use the following config files together:

  • config/device_plugins.yaml: device enable flags, priority, and fallback chain
  • config/settings.yaml: plugin config references and global defaults

Minimal example:

plugins:
    device_plugins:
        config_file: "config/device_plugins.yaml"
        auto_register: true

device_plugins:
    default_device: "gpu"
    priority_list: ["gpu", "cpu", "jetson", "loihi", "edgetpu", "ibm_quantum", "ibm_neurochip"]

Optional environment variables for IBM Runtime:

export QISKIT_IBM_TOKEN=your_token
export QISKIT_IBM_CHANNEL=ibm_quantum
export QISKIT_IBM_INSTANCE=your_hub_group_project
export QISKIT_IBM_BACKEND=ibmq_qasm_simulator

Example for IBM NeuroChip with NorthPole profile:

plugin = IBMNeuroChipPlugin(
    config={
        "target_chip": "northpole",
        "runtime_candidates": ["ibm_northpole", "northpole", "northpole_sdk"],
        "enable_simulator": True,
    }
)
plugin.initialize()
spikes_out = plugin.run_northpole(spikes, steps=2)

Example for G-QuAT runtime:

plugin = GQuATPlugin(
    config={
        "runtime_candidates": ["g_quat", "gquat", "aist_g_quat"],
        "runtime_api_preference": ["run_g_quat", "execute", "run"],
        "enable_simulator": True,
    }
)
plugin.initialize()
spikes_out = plugin.run_g_quat(spikes, steps=2)

NorthPole runtime adapter contract:

  • Adapter implementation: evospikenet/plugins/builtin/device_backends/northpole_runtime_adapter.py

  • Runtime candidate modules may provide one of the following:

    • Module-level function: run_northpole(spikes, steps=...) / run(spikes, steps=...) / execute(spikes, steps=...)
    • Class: NorthPoleRuntime / Runtime / NorthPoleClient / Client
    • Builder function: build_runtime(config=...)
  • Runtime outputs can be either torch.Tensor or a dict containing one of: spikes, output, result, data.

NorthPole execution-state keys from get_capabilities():

  • runtime_bound: whether a callable runtime API has been bound
  • runtime_api: selected API name (run_northpole / run / execute)
  • runtime_error: structured error payload (code / phase / message / detail)
  • runtime_error_message: compatibility short error message

Additional runtime settings for production integration:

  • runtime_api_preference: preferred API order (example: ["execute", "run_northpole"])
  • runtime_class_candidates: class-name priority for runtime instantiation
  • runtime_output_key_preference: key priority for extracting tensor output from dict payloads
  • runtime_init_kwargs: kwargs passed to runtime class constructor
  • runtime_build_kwargs: extra kwargs passed to build_runtime(...)
  • runtime_call_kwargs: extra kwargs passed at runtime API invocation

Example:

plugin = IBMNeuroChipPlugin(
    config={
        "target_chip": "northpole",
        "runtime_candidates": ["ibm_northpole"],
        "runtime_api_preference": ["execute", "run_northpole"],
        "runtime_init_kwargs": {"device_id": 0},
        "runtime_call_kwargs": {"steps": 8, "batch_mode": True},
        "enable_simulator": True,
    }
)

Registering with PluginFactory

from evospikenet.plugin_factory import PluginFactory
from evospikenet.plugins import PluginType

factory = PluginFactory()
plugin = CustomDevicePlugin(config={"target": "cpu", "precision": "fp32"})
plugin.initialize()
plugin.activate()
factory.register_plugin(plugin)

resolved = factory.get_plugin(PluginType.DEVICE, "custom_device")
  • define input types in config_schema
  • expose runtime features via get_capabilities()
  • keep a fallback path when optional deps are absent
  • enforce output format in convert_format()
  • standardize Sampler/Estimator return shapes for runtime plugins
  • test both real-circuit and local fallback paths

Testing checklist

Minimum unit checks: - metadata and PluginType.DEVICE - lifecycle (initialize/activate/deactivate) - capability keys - fallback behavior when deps are unavailable

Reference tests: - tests/unit/test_ibm_quantum_plugin.py - tests/unit/test_ibm_neurochip_plugin.py - tests/unit/test_plugins.py - tests/unit/test_plugin_phase_roadmap.py

CI notes

  • The optional dependency matrix validates mock/import behavior under the ibm_quantum_runtime profile.
  • The northpole_mock profile in the optional dependency matrix runs NorthPole adapter unit/integration tests and executes ibm_neurochip_northpole_mock_e2e.py.
  • The g_quat_mock profile in the optional dependency matrix runs test_g_quat_plugin.py and executes g_quat_mock_e2e.py.
  • When QISKIT_IBM_TOKEN is available in CI, the live connectivity job performs a real runtime connection check.