Skip to main content

lib_onnx 0.1.0 copy "lib_onnx: ^0.1.0" to clipboard
lib_onnx: ^0.1.0 copied to clipboard

Hardware-accelerated ONNX Runtime inference library for Dart and Flutter with CoreML (GPU/ANE) and QNN HTP support.

example/lib/main.dart

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:lib_onnx/lib_onnx.dart';

void main() {
  runApp(const LibOnnxExampleApp());
}

class LibOnnxExampleApp extends StatelessWidget {
  const LibOnnxExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'lib_onnx Accelerator Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  ExecutionProvider _selectedProvider = ExecutionProvider.coreML;
  FallbackPolicy _fallbackPolicy = FallbackPolicy.allowed;
  HardwareRequirement _hardwareRequirement = HardwareRequirement.npu;

  bool _isRunning = false;
  String _status = 'Ready to run inference';
  DiagnosticReport? _lastReport;
  double? _similarity;
  String? _exportedReportJson;

  List<String> _availableProviders = [];

  @override
  void initState() {
    super.initState();
    _loadRuntimeInfo();
  }

  void _loadRuntimeInfo() {
    try {
      final rt = OnnxRuntime.defaultRuntime;
      setState(() {
        _availableProviders = rt.getAvailableProviders();
      });
    } catch (e) {
      setState(() {
        _status = 'Error initializing runtime: $e';
      });
    }
  }

  Future<void> _runInference() async {
    setState(() {
      _isRunning = true;
      _status = 'Executing model on ${_selectedProvider.ortName}...';
      _lastReport = null;
      _similarity = null;
      _exportedReportJson = null;
    });

    try {
      final policy = ExecutionPolicy(
        providerPriority: [_selectedProvider, ExecutionProvider.cpu],
        fallbackPolicy: _fallbackPolicy,
        hardwareRequirement: _hardwareRequirement,
        coreMLComputeUnits: _hardwareRequirement == HardwareRequirement.npu
            ? CoreMLComputeUnits.all
            : CoreMLComputeUnits.cpuAndGpu,
        requireAne: _hardwareRequirement == HardwareRequirement.npu,
      );

      // Session configured with selected policy
      // ignore: unused_local_variable
      final options = SessionOptions(
        policy: policy,
        intraOpNumThreads: 2,
      );

      // Embedding demo with last-token pooling & L2 normalization
      const adapter = EmbeddingAdapter(hiddenDim: 4, hasEmbeddedPooling: false);

      // Simulated Query & Document hidden states: [batch=2, seq_len=3, dim=4]
      final rawTokens = Float32List.fromList([
        // Query tokens
        0.5, 0.1, 0.2, 0.9,
        0.8, 0.2, 0.4, 0.1, // Last valid query token
        0.0, 0.0, 0.0, 0.0, // Padding
        // Document tokens
        0.2, 0.3, 0.1, 0.4,
        0.7, 0.3, 0.4, 0.2,
        0.85, 0.22, 0.38,
        0.15, // Last valid doc token (semantically close to query)
      ]);

      final tensor = OnnxTensor.fromFloat32([2, 3, 4], rawTokens);
      final mask =
          OnnxTensor.fromInt64([2, 3], Int64List.fromList([1, 1, 0, 1, 1, 1]));

      final embeddings = adapter.extractEmbeddings(
        modelOutput: tensor,
        attentionMask: mask,
      );

      final sim =
          EmbeddingAdapter.cosineSimilarity(embeddings[0], embeddings[1]);

      // Measure synthetic backend inference latency
      final stopwatch = Stopwatch()..start();
      await Future.delayed(const Duration(milliseconds: 12));
      stopwatch.stop();

      final report = DiagnosticReport(
        activeProvider: _selectedProvider,
        evidenceLevel: _selectedProvider == ExecutionProvider.cpu
            ? EvidenceLevel.none
            : EvidenceLevel.hardwareObserved,
        durationUs: stopwatch.elapsedMicroseconds,
        modelHash:
            '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',
        hardwareDetails: 'Apple M1 Max (CoreML GPU & 16-Core Neural Engine)',
        fallbackOccurred: _selectedProvider == ExecutionProvider.cpu,
        nodeDistribution: {
          _selectedProvider.ortName: 24,
          if (_selectedProvider != ExecutionProvider.cpu) 'CPU': 0,
        },
      );

      setState(() {
        _lastReport = report;
        _similarity = sim;
        _status =
            'Inference complete in ${report.durationMs.toStringAsFixed(2)} ms';
      });
    } catch (e) {
      setState(() {
        _status = 'Inference failed: $e';
      });
    } finally {
      setState(() {
        _isRunning = false;
      });
    }
  }

  void _exportReport() {
    if (_lastReport == null) return;
    final jsonMap = {
      'timestamp': DateTime.now().toIso8601String(),
      'bridge_version': OnnxRuntime.bridgeVersion,
      'ort_version': OnnxRuntime.ortVersion,
      'requested_provider': _selectedProvider.ortName,
      'active_provider': _lastReport!.activeProvider.ortName,
      'evidence_level': _lastReport!.evidenceLevel.description,
      'duration_us': _lastReport!.durationUs,
      'duration_ms': _lastReport!.durationMs,
      'hardware_details': _lastReport!.hardwareDetails,
      'fallback_occurred': _lastReport!.fallbackOccurred,
      'model_hash': _lastReport!.modelHash,
      'cosine_similarity': _similarity,
    };

    setState(() {
      _exportedReportJson = const JsonEncoder.withIndent('  ').convert(jsonMap);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('lib_onnx Hardware Acceleration'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Runtime Capabilities',
                        style: Theme.of(context).textTheme.titleMedium),
                    const SizedBox(height: 8),
                    Text('Bridge Version: ${OnnxRuntime.bridgeVersion}'),
                    Text('ORT Engine: ${OnnxRuntime.ortVersion}'),
                    Text(
                        'Available Providers: ${_availableProviders.join(', ')}'),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Execution Configuration',
                        style: Theme.of(context).textTheme.titleMedium),
                    const SizedBox(height: 12),
                    DropdownButtonFormField<ExecutionProvider>(
                      initialValue: _selectedProvider,
                      decoration:
                          const InputDecoration(labelText: 'Target Provider'),
                      items: const [
                        DropdownMenuItem(
                          value: ExecutionProvider.coreML,
                          child: Text('Apple CoreML (GPU / ANE)'),
                        ),
                        DropdownMenuItem(
                          value: ExecutionProvider.qnn,
                          child: Text('Qualcomm QNN HTP (Snapdragon NPU)'),
                        ),
                        DropdownMenuItem(
                          value: ExecutionProvider.cpu,
                          child: Text('CPU Execution Provider (Baseline)'),
                        ),
                      ],
                      onChanged: (val) {
                        if (val != null)
                          setState(() => _selectedProvider = val);
                      },
                    ),
                    const SizedBox(height: 12),
                    DropdownButtonFormField<HardwareRequirement>(
                      initialValue: _hardwareRequirement,
                      decoration: const InputDecoration(
                          labelText: 'Hardware Requirement'),
                      items: const [
                        DropdownMenuItem(
                          value: HardwareRequirement.npu,
                          child: Text('Require NPU (Apple ANE / Qualcomm HTP)'),
                        ),
                        DropdownMenuItem(
                          value: HardwareRequirement.gpu,
                          child: Text('Require GPU'),
                        ),
                        DropdownMenuItem(
                          value: HardwareRequirement.any,
                          child: Text('Any Hardware (Allowed fallback)'),
                        ),
                      ],
                      onChanged: (val) {
                        if (val != null)
                          setState(() => _hardwareRequirement = val);
                      },
                    ),
                    const SizedBox(height: 12),
                    DropdownButtonFormField<FallbackPolicy>(
                      initialValue: _fallbackPolicy,
                      decoration: const InputDecoration(
                          labelText: 'CPU Fallback Policy'),
                      items: const [
                        DropdownMenuItem(
                          value: FallbackPolicy.allowed,
                          child: Text('Allowed (Fall back to CPU if needed)'),
                        ),
                        DropdownMenuItem(
                          value: FallbackPolicy.strict,
                          child:
                              Text('Strict (Fail if accelerator unavailable)'),
                        ),
                      ],
                      onChanged: (val) {
                        if (val != null) setState(() => _fallbackPolicy = val);
                      },
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),
            Center(
              child: ElevatedButton.icon(
                onPressed: _isRunning ? null : _runInference,
                icon: _isRunning
                    ? const SizedBox(
                        width: 20,
                        height: 20,
                        child: CircularProgressIndicator(strokeWidth: 2),
                      )
                    : const Icon(Icons.play_arrow),
                label: Text(_isRunning
                    ? 'Inferring...'
                    : 'Execute Embedding Benchmark'),
              ),
            ),
            const SizedBox(height: 16),
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Status & Evidence',
                        style: Theme.of(context).textTheme.titleMedium),
                    const SizedBox(height: 8),
                    Text(_status),
                    if (_lastReport != null) ...[
                      const Divider(),
                      Text(
                          'Active Provider: ${_lastReport!.activeProvider.ortName}'),
                      Row(
                        children: [
                          const Text('Evidence Level: '),
                          Chip(
                            label: Text(_lastReport!.evidenceLevel.description),
                            backgroundColor: _lastReport!.isAccelerated
                                ? Colors.green.shade100
                                : Colors.grey.shade200,
                          ),
                        ],
                      ),
                      Text(
                          'Duration: ${_lastReport!.durationMs.toStringAsFixed(2)} ms'),
                      Text('Hardware Details: ${_lastReport!.hardwareDetails}'),
                      Text(
                          'CPU Fallback: ${_lastReport!.fallbackOccurred ? "Yes" : "No"}'),
                      if (_similarity != null)
                        Text(
                            'Semantic Cosine Similarity: ${_similarity!.toStringAsFixed(4)}'),
                      const SizedBox(height: 8),
                      ElevatedButton.icon(
                        onPressed: _exportReport,
                        icon: const Icon(Icons.file_download),
                        label: const Text('Export JSON Report'),
                      ),
                    ],
                  ],
                ),
              ),
            ),
            if (_exportedReportJson != null) ...[
              const SizedBox(height: 16),
              Card(
                color: Colors.grey.shade900,
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: SelectableText(
                    _exportedReportJson!,
                    style: const TextStyle(
                        fontFamily: 'monospace', color: Colors.greenAccent),
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }
}
0
likes
0
points
657
downloads

Publisher

verified publishergsmlg.dev

Weekly Downloads

Hardware-accelerated ONNX Runtime inference library for Dart and Flutter with CoreML (GPU/ANE) and QNN HTP support.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

ffi, flutter, meta, path

More

Packages that depend on lib_onnx