1use oxicuda_backend::BackendError;
4
5#[derive(Debug, thiserror::Error)]
7pub enum RocmError {
8 #[error("ROCm/HIP requires Linux")]
10 UnsupportedPlatform,
11
12 #[error("HIP library not found: {0}")]
14 LibraryNotFound(String),
15
16 #[error("HIP error code {0}: {1}")]
18 HipError(i32, String),
19
20 #[error("no AMD GPU found")]
22 NoSuitableDevice,
23
24 #[error("out of device memory")]
26 OutOfMemory,
27
28 #[error("not initialized")]
30 NotInitialized,
31
32 #[error("unsupported: {0}")]
34 Unsupported(String),
35
36 #[error("invalid argument: {0}")]
38 InvalidArgument(String),
39
40 #[error("device error: {0}")]
42 DeviceError(String),
43}
44
45pub type RocmResult<T> = Result<T, RocmError>;
47
48impl From<RocmError> for BackendError {
49 fn from(e: RocmError) -> Self {
50 match e {
51 RocmError::UnsupportedPlatform => {
52 BackendError::DeviceError("ROCm/HIP requires Linux".into())
53 }
54 RocmError::LibraryNotFound(s) => {
55 BackendError::DeviceError(format!("HIP library not found: {s}"))
56 }
57 RocmError::HipError(code, msg) => {
58 BackendError::DeviceError(format!("hip({code}): {msg}"))
59 }
60 RocmError::NoSuitableDevice => BackendError::DeviceError("no AMD GPU found".into()),
61 RocmError::OutOfMemory => BackendError::OutOfMemory,
62 RocmError::NotInitialized => BackendError::NotInitialized,
63 RocmError::Unsupported(s) => BackendError::Unsupported(s),
64 RocmError::InvalidArgument(s) => BackendError::InvalidArgument(s),
65 RocmError::DeviceError(s) => BackendError::DeviceError(s),
66 }
67 }
68}
69
70#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn rocm_error_display() {
78 assert_eq!(
79 RocmError::UnsupportedPlatform.to_string(),
80 "ROCm/HIP requires Linux"
81 );
82 assert_eq!(
83 RocmError::LibraryNotFound("libamdhip64.so".into()).to_string(),
84 "HIP library not found: libamdhip64.so"
85 );
86 assert_eq!(
87 RocmError::HipError(1, "invalid device".into()).to_string(),
88 "HIP error code 1: invalid device"
89 );
90 assert_eq!(RocmError::NoSuitableDevice.to_string(), "no AMD GPU found");
91 assert_eq!(RocmError::OutOfMemory.to_string(), "out of device memory");
92 assert_eq!(RocmError::NotInitialized.to_string(), "not initialized");
93 assert_eq!(
94 RocmError::Unsupported("gemm".into()).to_string(),
95 "unsupported: gemm"
96 );
97 assert_eq!(
98 RocmError::InvalidArgument("bad ptr".into()).to_string(),
99 "invalid argument: bad ptr"
100 );
101 assert_eq!(
102 RocmError::DeviceError("kernel launch failed".into()).to_string(),
103 "device error: kernel launch failed"
104 );
105 }
106
107 #[test]
108 fn backend_error_from_rocm_error() {
109 let e = BackendError::from(RocmError::OutOfMemory);
110 assert_eq!(e, BackendError::OutOfMemory);
111
112 let e = BackendError::from(RocmError::NotInitialized);
113 assert_eq!(e, BackendError::NotInitialized);
114
115 let e = BackendError::from(RocmError::Unsupported("foo".into()));
116 assert_eq!(e, BackendError::Unsupported("foo".into()));
117
118 let e = BackendError::from(RocmError::InvalidArgument("bar".into()));
119 assert_eq!(e, BackendError::InvalidArgument("bar".into()));
120
121 let e = BackendError::from(RocmError::UnsupportedPlatform);
122 assert!(matches!(e, BackendError::DeviceError(_)));
123
124 let e = BackendError::from(RocmError::LibraryNotFound("x".into()));
125 assert!(matches!(e, BackendError::DeviceError(_)));
126
127 let e = BackendError::from(RocmError::HipError(42, "something".into()));
128 assert!(matches!(e, BackendError::DeviceError(_)));
129
130 let e = BackendError::from(RocmError::NoSuitableDevice);
131 assert!(matches!(e, BackendError::DeviceError(_)));
132
133 let e = BackendError::from(RocmError::DeviceError("boom".into()));
134 assert!(matches!(e, BackendError::DeviceError(_)));
135 }
136}