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.

To use an existing plugin from an HPDBN node, do not recreate the plugin. Connect it with DevicePluginRuntimeAdapter as described in the HPDBN SDK Integration Guide. For node composition and external optimization, see HPDBN Node Architecture and HPDBN External Optimization.

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.