1use thiserror::Error;
2use yscv_tensor::TensorError;
3
4#[derive(Debug, Clone, PartialEq, Eq, Error)]
6pub enum KernelError {
7 #[error(transparent)]
8 Tensor(#[from] TensorError),
9 #[error(
10 "matmul_2d requires rank-2 tensors, got left_rank={left_rank}, right_rank={right_rank}"
11 )]
12 InvalidMatMulRank { left_rank: usize, right_rank: usize },
13 #[error(
14 "matmul_2d shape mismatch: left={left:?}, right={right:?}; expected left[1] == right[0]"
15 )]
16 MatMulShapeMismatch { left: Vec<usize>, right: Vec<usize> },
17 #[error("failed to build cpu thread pool: {message}")]
18 ThreadPoolBuild { message: String },
19 #[error("pool2d_nhwc requires rank-4 tensor [N,H,W,C], got rank={got_rank}")]
20 InvalidPoolRank { got_rank: usize },
21 #[error(
22 "invalid pool2d parameters: kernel=({kernel_h},{kernel_w}), stride=({stride_h},{stride_w}); all values must be > 0"
23 )]
24 InvalidPoolParameters {
25 kernel_h: usize,
26 kernel_w: usize,
27 stride_h: usize,
28 stride_w: usize,
29 },
30 #[error(
31 "pool2d kernel larger than input: input_hw=({input_h},{input_w}), kernel_hw=({kernel_h},{kernel_w})"
32 )]
33 PoolKernelLargerThanInput {
34 input_h: usize,
35 input_w: usize,
36 kernel_h: usize,
37 kernel_w: usize,
38 },
39 #[error(
40 "conv2d_nhwc requires rank-4 input/kernel tensors [N,H,W,C] and [KH,KW,C,OC], got input_rank={input_rank}, kernel_rank={kernel_rank}"
41 )]
42 InvalidConvRank {
43 input_rank: usize,
44 kernel_rank: usize,
45 },
46 #[error(
47 "invalid conv2d parameters: kernel=({kernel_h},{kernel_w}), stride=({stride_h},{stride_w}); all values must be > 0"
48 )]
49 InvalidConvParameters {
50 kernel_h: usize,
51 kernel_w: usize,
52 stride_h: usize,
53 stride_w: usize,
54 },
55 #[error(
56 "conv2d input/kernel channel mismatch: input_channels={input_channels}, kernel_in_channels={kernel_in_channels}"
57 )]
58 ConvChannelMismatch {
59 input_channels: usize,
60 kernel_in_channels: usize,
61 },
62 #[error(
63 "conv2d kernel larger than input: input_hw=({input_h},{input_w}), kernel_hw=({kernel_h},{kernel_w})"
64 )]
65 ConvKernelLargerThanInput {
66 input_h: usize,
67 input_w: usize,
68 kernel_h: usize,
69 kernel_w: usize,
70 },
71 #[error("conv2d bias shape mismatch: bias_shape={bias_shape:?}, expected [{out_channels}]")]
72 ConvBiasShapeMismatch {
73 bias_shape: Vec<usize>,
74 out_channels: usize,
75 },
76 #[error(
77 "depthwise_conv2d_nhwc requires rank-4 input/kernel tensors [N,H,W,C] and [KH,KW,C,depth_multiplier], got input_rank={input_rank}, kernel_rank={kernel_rank}"
78 )]
79 InvalidDepthwiseConvRank {
80 input_rank: usize,
81 kernel_rank: usize,
82 },
83 #[error(
84 "invalid depthwise_conv2d parameters: kernel=({kernel_h},{kernel_w}), stride=({stride_h},{stride_w}); all values must be > 0"
85 )]
86 InvalidDepthwiseConvParameters {
87 kernel_h: usize,
88 kernel_w: usize,
89 stride_h: usize,
90 stride_w: usize,
91 },
92 #[error(
93 "depthwise_conv2d input/kernel channel mismatch: input_channels={input_channels}, kernel_channels={kernel_channels}"
94 )]
95 DepthwiseConvChannelMismatch {
96 input_channels: usize,
97 kernel_channels: usize,
98 },
99 #[error(
100 "depthwise_conv2d kernel larger than input: input_hw=({input_h},{input_w}), kernel_hw=({kernel_h},{kernel_w})"
101 )]
102 DepthwiseConvKernelLargerThanInput {
103 input_h: usize,
104 input_w: usize,
105 kernel_h: usize,
106 kernel_w: usize,
107 },
108 #[error(
109 "depthwise_conv2d bias shape mismatch: bias_shape={bias_shape:?}, expected [{out_channels}]"
110 )]
111 DepthwiseConvBiasShapeMismatch {
112 bias_shape: Vec<usize>,
113 out_channels: usize,
114 },
115 #[error(
116 "separable_conv2d_nhwc pointwise kernel must have shape [1,1,C_in,C_out], got pointwise_shape={pointwise_shape:?}"
117 )]
118 InvalidSeparablePointwiseKernelShape { pointwise_shape: Vec<usize> },
119 #[error("batch_norm2d_nhwc requires rank-4 input tensor [N,H,W,C], got rank={got_rank}")]
120 InvalidBatchNormRank { got_rank: usize },
121 #[error(
122 "batch_norm2d_nhwc parameter `{parameter}` shape mismatch: got {shape:?}, expected [{expected_channels}]"
123 )]
124 BatchNormParameterShapeMismatch {
125 parameter: &'static str,
126 shape: Vec<usize>,
127 expected_channels: usize,
128 },
129 #[error("batch_norm2d_nhwc requires epsilon to be finite and > 0")]
130 InvalidBatchNormEpsilon,
131 #[error(
132 "batch_norm2d_nhwc requires variance[channel] + epsilon > 0, invalid at channel={channel}"
133 )]
134 InvalidBatchNormVariance { channel: usize },
135 #[error("softmax_last_dim requires rank >= 1 tensor, got rank={got_rank}")]
136 InvalidSoftmaxRank { got_rank: usize },
137 #[error("log_softmax_last_dim requires rank >= 1 tensor, got rank={got_rank}")]
138 InvalidLogSoftmaxRank { got_rank: usize },
139 #[error("logsumexp_last_dim requires rank >= 1 tensor, got rank={got_rank}")]
140 InvalidLogSumExpRank { got_rank: usize },
141 #[error("layer_norm_last_dim requires rank >= 1 tensor, got rank={got_rank}")]
142 InvalidLayerNormRank { got_rank: usize },
143 #[error(
144 "layer_norm_last_dim parameter `{parameter}` shape mismatch: got {shape:?}, expected [{expected_features}]"
145 )]
146 LayerNormParameterShapeMismatch {
147 parameter: &'static str,
148 shape: Vec<usize>,
149 expected_features: usize,
150 },
151 #[error("layer_norm_last_dim requires epsilon to be finite and > 0")]
152 InvalidLayerNormEpsilon,
153 #[error(
154 "scaled_dot_product_attention requires rank-2 tensors, got query_rank={query_rank}, key_rank={key_rank}, value_rank={value_rank}"
155 )]
156 InvalidAttentionRank {
157 query_rank: usize,
158 key_rank: usize,
159 value_rank: usize,
160 },
161 #[error("scaled_dot_product_attention d_k mismatch: query d_k={query_dk}, key d_k={key_dk}")]
162 AttentionDkMismatch { query_dk: usize, key_dk: usize },
163 #[error(
164 "scaled_dot_product_attention seq_k mismatch: key seq={key_seq}, value seq={value_seq}"
165 )]
166 AttentionSeqKMismatch { key_seq: usize, value_seq: usize },
167 #[error("scaled_dot_product_attention mask shape mismatch: expected {expected:?}, got {got:?}")]
168 AttentionMaskShapeMismatch {
169 expected: Vec<usize>,
170 got: Vec<usize>,
171 },
172 #[error("group_norm_nhwc requires rank-4 input tensor [N,H,W,C], got rank={got_rank}")]
173 InvalidGroupNormRank { got_rank: usize },
174 #[error(
175 "group_norm_nhwc: channels ({channels}) must be divisible by num_groups ({num_groups})"
176 )]
177 GroupNormChannelGroupMismatch { channels: usize, num_groups: usize },
178 #[error(
179 "group_norm_nhwc parameter `{parameter}` shape mismatch: got {shape:?}, expected [{expected_channels}]"
180 )]
181 GroupNormParameterShapeMismatch {
182 parameter: &'static str,
183 shape: Vec<usize>,
184 expected_channels: usize,
185 },
186 #[error("group_norm_nhwc requires epsilon to be finite and > 0")]
187 InvalidGroupNormEpsilon,
188 #[error("group_norm_nhwc requires num_groups > 0")]
189 InvalidGroupNormNumGroups,
190 #[error("rms_norm_last_dim requires rank >= 1 tensor, got rank={got_rank}")]
191 InvalidRmsNormRank { got_rank: usize },
192 #[error(
193 "rms_norm_last_dim parameter `{parameter}` shape mismatch: got {shape:?}, expected [{expected_features}]"
194 )]
195 RmsNormParameterShapeMismatch {
196 parameter: &'static str,
197 shape: Vec<usize>,
198 expected_features: usize,
199 },
200 #[error("rms_norm_last_dim requires epsilon to be finite and > 0")]
201 InvalidRmsNormEpsilon,
202 #[error(
203 "embedding_lookup requires rank-2 weight tensor [vocab_size, embed_dim], got rank={got_rank}"
204 )]
205 InvalidEmbeddingWeightRank { got_rank: usize },
206 #[error("embedding_lookup index {index} out of bounds for vocab_size={vocab_size}")]
207 EmbeddingIndexOutOfBounds { index: usize, vocab_size: usize },
208 #[error("deformable_conv2d offset shape mismatch: expected {expected:?}, got {got:?}")]
209 DeformableConvOffsetShapeMismatch {
210 expected: Vec<usize>,
211 got: Vec<usize>,
212 },
213 #[error("GPU backend error: {message}")]
214 Gpu { message: String },
215}