Skip to main content

rknn_runtime/
error.rs

1//! Error types for RKNN operations.
2
3use std::fmt;
4
5/// Everything that can go wrong when using RKNN.
6///
7/// Most variants carry the RKNN error code (a negative `i32`).
8/// The RKNN SDK doesn't document specific codes, but common ones are:
9/// - `-1` - generic failure
10/// - `-2` - invalid parameter
11/// - `-3` - device not found
12///
13/// # Example
14///
15/// ```rust,no_run
16/// use rknn_runtime::{RknnModel, Error};
17///
18/// match RknnModel::load("model.rknn") {
19///     Ok(model) => println!("Loaded!"),
20///     Err(Error::LibraryNotFound(path)) => {
21///         eprintln!("RKNN library not found at: {}", path);
22///         eprintln!("Make sure librknnmrt.so is installed on the device.");
23///     }
24///     Err(e) => eprintln!("Error: {}", e),
25/// }
26/// ```
27#[derive(Debug)]
28pub enum Error {
29    /// `librknnmrt.so` could not be loaded. Contains the attempted path.
30    LibraryNotFound(String),
31    /// A required function was not found in the loaded library.
32    SymbolNotFound(String),
33    /// `rknn_init()` failed. The model file may be corrupt or incompatible.
34    InitFailed(i32),
35    /// `rknn_query()` failed when reading tensor metadata.
36    QueryFailed(i32),
37    /// `rknn_run()` failed during inference.
38    InferenceFailed(i32),
39    /// NPU memory allocation returned null.
40    MemAllocFailed,
41    /// `rknn_mem_sync()` failed. Cache sync between NPU and CPU did not complete.
42    MemSyncFailed(i32),
43    /// `rknn_set_io_mem()` failed when binding a memory buffer to a tensor.
44    SetIoMemFailed(i32),
45    /// The model data is empty or invalid.
46    InvalidModel,
47    /// Output index is out of range.
48    InvalidIndex {
49        /// The index that was requested.
50        requested: usize,
51        /// How many outputs the model actually has.
52        available: usize,
53    },
54    /// Tensor format or shape does not match what was expected.
55    InvalidFormat {
56        /// What was expected (e.g. "NC1HWC2").
57        expected: &'static str,
58        /// What was actually found.
59        got: String,
60    },
61    /// File I/O error (e.g. model file not found).
62    IoError(std::io::Error),
63}
64
65/// Just display the error message.
66impl fmt::Display for Error {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        match self {
69            Error::LibraryNotFound(path) => {
70                write!(f, "failed to load library: {}", path)
71            }
72            Error::SymbolNotFound(name) => {
73                write!(f, "symbol not found: {}", name)
74            }
75            Error::InitFailed(code) => {
76                write!(f, "rknn_init failed (code {})", code)
77            }
78            Error::QueryFailed(code) => {
79                write!(f, "rknn_query failed (code {})", code)
80            }
81            Error::InferenceFailed(code) => {
82                write!(f, "rknn_run failed (code {})", code)
83            }
84            Error::MemAllocFailed => {
85                write!(f, "rknn_create_mem returned null")
86            }
87            Error::MemSyncFailed(code) => {
88                write!(f, "rknn_mem_sync failed (code {})", code)
89            }
90            Error::SetIoMemFailed(code) => {
91                write!(f, "rknn_set_io_mem failed (code {})", code)
92            }
93            Error::InvalidFormat { expected, got } => {
94                write!(f, "expected {} format, got {}", expected, got)
95            }
96            Error::InvalidModel => write!(f, "invalid or empty model data"),
97            Error::InvalidIndex {
98                requested,
99                available,
100            } => {
101                write!(
102                    f,
103                    "output index {} out of range (have {})",
104                    requested, available
105                )
106            }
107            Error::IoError(e) => write!(f, "I/O error: {}", e),
108        }
109    }
110}
111
112/// Allow chaining
113impl std::error::Error for Error {
114    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
115        match self {
116            Error::IoError(e) => Some(e),
117            _ => None,
118        }
119    }
120}
121
122/// Convert std::io::Error into crate's Error type.
123impl From<std::io::Error> for Error {
124    fn from(e: std::io::Error) -> Self {
125        Error::IoError(e)
126    }
127}