hurray_ffi/field/
layout.rs1use hurray_core::layout::{LayoutDescriptor, TiledLayout};
8
9use super::{HurrayDescriptorField, U64Source};
10use crate::status::{
11 HurrayStatus, HURRAY_ERR_FIELD_NOT_APPLICABLE, HURRAY_ERR_FIELD_NOT_PRESENT,
12 HURRAY_ERR_INDEX_OUT_OF_BOUNDS,
13};
14
15pub const HURRAY_LAYOUT_FIELD_STRIDED_STRIDES: HurrayDescriptorField = 0x0001_0300;
19
20pub const HURRAY_LAYOUT_FIELD_TILED_TILE_SHAPE: HurrayDescriptorField = 0x0001_0400;
22
23pub const HURRAY_LAYOUT_FIELD_TILED_OUTER_LAYOUT: HurrayDescriptorField = 0x0001_0401;
25
26pub const HURRAY_LAYOUT_FIELD_TILED_INNER_LAYOUT: HurrayDescriptorField = 0x0001_0402;
28
29pub const HURRAY_LAYOUT_FIELD_TILED_OUTER_STRIDES: HurrayDescriptorField = 0x0001_0403;
31
32pub const HURRAY_LAYOUT_FIELD_TILED_INNER_STRIDES: HurrayDescriptorField = 0x0001_0404;
34
35pub const HURRAY_LAYOUT_FIELD_TILED_DEPTH: HurrayDescriptorField = 0x0001_0405;
37
38pub const HURRAY_LAYOUT_FIELD_MORTON_BITS: HurrayDescriptorField = 0x0001_0500;
40
41pub const HURRAY_LAYOUT_FIELD_COO_NNZ: HurrayDescriptorField = 0x0001_0600;
43
44pub const HURRAY_LAYOUT_FIELD_COO_IS_SORTED: HurrayDescriptorField = 0x0001_0601;
46
47pub const HURRAY_LAYOUT_FIELD_CSR_NNZ: HurrayDescriptorField = 0x0001_0700;
49
50pub const HURRAY_LAYOUT_FIELD_CSC_NNZ: HurrayDescriptorField = 0x0001_0800;
52
53pub const HURRAY_LAYOUT_FIELD_CSF_NNZ: HurrayDescriptorField = 0x0001_0900;
55
56pub const HURRAY_LAYOUT_FIELD_CSF_MODE_ORDER: HurrayDescriptorField = 0x0001_0901;
58
59pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_PAGE_SIZE: HurrayDescriptorField = 0x0001_0A00;
61
62pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_NUM_PAGES: HurrayDescriptorField = 0x0001_0A01;
64
65pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_PAGED_AXIS: HurrayDescriptorField = 0x0001_0A02;
67
68pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_NUM_SEQS: HurrayDescriptorField = 0x0001_0A03;
70
71pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_KV_ROLE: HurrayDescriptorField = 0x0001_0A04;
73
74pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_LAYER_INDEX: HurrayDescriptorField = 0x0001_0A05;
76
77pub const HURRAY_LAYOUT_FIELD_BLOCK_PAGED_INDEX_TYPE: HurrayDescriptorField = 0x0001_0A06;
79
80pub const HURRAY_LAYOUT_FIELD_COMPOSITE_RULE: HurrayDescriptorField = 0x0001_0B00;
82
83pub const HURRAY_LAYOUT_FIELD_COMPOSITE_COMBINE_OP: HurrayDescriptorField = 0x0001_0B01;
85
86pub const HURRAY_LAYOUT_FIELD_COMPOSITE_MEMBER_COUNT: HurrayDescriptorField = 0x0001_0B02;
88
89pub const HURRAY_LAYOUT_FIELD_HILBERT_ORDER: HurrayDescriptorField = 0x0001_4000;
91
92pub const HURRAY_LAYOUT_FIELD_HILBERT_RANK: HurrayDescriptorField = 0x0001_4001;
94
95fn tiled_at_level(root: &TiledLayout, level: u32) -> Result<&TiledLayout, HurrayStatus> {
99 let mut current = root;
100 for _ in 0..level {
101 current = match current.inner_tiled.as_deref() {
102 Some(inner) => inner,
103 None => return Err(HURRAY_ERR_INDEX_OUT_OF_BOUNDS),
104 };
105 }
106 Ok(current)
107}
108
109fn tiled_depth(tile: &TiledLayout) -> u64 {
111 let mut depth = 1;
112 let mut current = tile;
113 while let Some(inner) = current.inner_tiled.as_deref() {
114 depth += 1;
115 current = inner;
116 }
117 depth
118}
119
120fn check_level(layout: &LayoutDescriptor, level: u32) -> Result<(), HurrayStatus> {
126 if level != 0 && !matches!(layout, LayoutDescriptor::Tiled(_)) {
127 return Err(HURRAY_ERR_INDEX_OUT_OF_BOUNDS);
128 }
129 Ok(())
130}
131
132pub(super) fn u64_scalar(
137 layout: &LayoutDescriptor,
138 field: HurrayDescriptorField,
139 level: u32,
140) -> Result<u64, HurrayStatus> {
141 check_level(layout, level)?;
142
143 match (field, layout) {
144 (HURRAY_LAYOUT_FIELD_TILED_OUTER_LAYOUT, LayoutDescriptor::Tiled(root)) => {
146 Ok(tiled_at_level(root, level)?.outer_layout as u64)
147 }
148 (HURRAY_LAYOUT_FIELD_TILED_INNER_LAYOUT, LayoutDescriptor::Tiled(root)) => {
149 Ok(tiled_at_level(root, level)?.inner_layout as u64)
150 }
151 (HURRAY_LAYOUT_FIELD_TILED_DEPTH, LayoutDescriptor::Tiled(root)) => {
152 Ok(tiled_depth(tiled_at_level(root, level)?))
153 }
154
155 (HURRAY_LAYOUT_FIELD_COO_NNZ, LayoutDescriptor::Coo(l)) => Ok(l.nnz),
157 (HURRAY_LAYOUT_FIELD_COO_IS_SORTED, LayoutDescriptor::Coo(l)) => Ok(l.is_sorted as u64),
158 (HURRAY_LAYOUT_FIELD_CSR_NNZ, LayoutDescriptor::Csr(l)) => Ok(l.nnz),
159 (HURRAY_LAYOUT_FIELD_CSC_NNZ, LayoutDescriptor::Csc(l)) => Ok(l.nnz),
160 (HURRAY_LAYOUT_FIELD_CSF_NNZ, LayoutDescriptor::Csf(l)) => Ok(l.nnz),
161
162 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_PAGE_SIZE, LayoutDescriptor::BlockPaged(l)) => {
164 Ok(l.page_size as u64)
165 }
166 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_NUM_PAGES, LayoutDescriptor::BlockPaged(l)) => {
167 Ok(l.num_pages)
168 }
169 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_PAGED_AXIS, LayoutDescriptor::BlockPaged(l)) => {
170 Ok(l.paged_axis as u64)
171 }
172 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_NUM_SEQS, LayoutDescriptor::BlockPaged(l)) => {
173 Ok(l.num_seqs as u64)
174 }
175 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_KV_ROLE, LayoutDescriptor::BlockPaged(l)) => {
176 Ok(l.kv_role.wire_byte() as u64)
177 }
178 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_LAYER_INDEX, LayoutDescriptor::BlockPaged(l)) => l
179 .layer_index
180 .map(u64::from)
181 .ok_or(HURRAY_ERR_FIELD_NOT_PRESENT),
182 (HURRAY_LAYOUT_FIELD_BLOCK_PAGED_INDEX_TYPE, LayoutDescriptor::BlockPaged(l)) => {
183 Ok(l.block_table_index_type.wire_byte() as u64)
184 }
185
186 (HURRAY_LAYOUT_FIELD_COMPOSITE_RULE, LayoutDescriptor::Composite(l)) => {
188 Ok(l.rule.rule_byte() as u64)
189 }
190 (HURRAY_LAYOUT_FIELD_COMPOSITE_COMBINE_OP, LayoutDescriptor::Composite(l)) => {
191 Ok(l.rule.combine_op_byte() as u64)
192 }
193 (HURRAY_LAYOUT_FIELD_COMPOSITE_MEMBER_COUNT, LayoutDescriptor::Composite(l)) => {
194 Ok(l.member_count as u64)
195 }
196
197 (HURRAY_LAYOUT_FIELD_HILBERT_ORDER, LayoutDescriptor::Hilbert(l)) => {
199 Ok(l.hilbert_order as u64)
200 }
201 (HURRAY_LAYOUT_FIELD_HILBERT_RANK, LayoutDescriptor::Hilbert(l)) => {
202 Ok(l.hilbert_rank as u64)
203 }
204
205 _ => Err(HURRAY_ERR_FIELD_NOT_APPLICABLE),
206 }
207}
208
209pub(super) fn u64_array<'a>(
211 layout: &'a LayoutDescriptor,
212 field: HurrayDescriptorField,
213 level: u32,
214) -> Result<U64Source<'a>, HurrayStatus> {
215 check_level(layout, level)?;
216
217 match (field, layout) {
218 (HURRAY_LAYOUT_FIELD_TILED_TILE_SHAPE, LayoutDescriptor::Tiled(root)) => {
219 Ok(U64Source::Direct(&tiled_at_level(root, level)?.tile_shape))
220 }
221 (HURRAY_LAYOUT_FIELD_MORTON_BITS, LayoutDescriptor::Morton(l)) => {
222 Ok(U64Source::Widened(&l.morton_bits))
223 }
224 (HURRAY_LAYOUT_FIELD_CSF_MODE_ORDER, LayoutDescriptor::Csf(l)) => {
225 Ok(U64Source::Widened(&l.mode_order))
226 }
227 _ => Err(HURRAY_ERR_FIELD_NOT_APPLICABLE),
228 }
229}
230
231pub(super) fn i64_array(
233 layout: &LayoutDescriptor,
234 field: HurrayDescriptorField,
235 level: u32,
236) -> Result<&[i64], HurrayStatus> {
237 check_level(layout, level)?;
238
239 match (field, layout) {
240 (HURRAY_LAYOUT_FIELD_STRIDED_STRIDES, LayoutDescriptor::Strided(l)) => Ok(&l.strides),
241 (HURRAY_LAYOUT_FIELD_TILED_OUTER_STRIDES, LayoutDescriptor::Tiled(root)) => {
242 match tiled_at_level(root, level)?.outer_strides.as_ref() {
243 Some(s) => Ok(&s.strides),
244 None => Err(HURRAY_ERR_FIELD_NOT_PRESENT),
245 }
246 }
247 (HURRAY_LAYOUT_FIELD_TILED_INNER_STRIDES, LayoutDescriptor::Tiled(root)) => {
248 match tiled_at_level(root, level)?.inner_strides.as_ref() {
249 Some(s) => Ok(&s.strides),
250 None => Err(HURRAY_ERR_FIELD_NOT_PRESENT),
251 }
252 }
253 _ => Err(HURRAY_ERR_FIELD_NOT_APPLICABLE),
254 }
255}