diff --git a/nac3core/irrt/irrt/ndarray/def.hpp b/nac3core/irrt/irrt/ndarray/def.hpp new file mode 100644 index 00000000..4b2c1216 --- /dev/null +++ b/nac3core/irrt/irrt/ndarray/def.hpp @@ -0,0 +1,44 @@ +#pragma once + +namespace { +/** + * @brief The NDArray object + * + * The official numpy implementations: https://github.com/numpy/numpy/blob/735a477f0bc2b5b84d0e72d92f224bde78d4e069/doc/source/reference/c-api/types-and-structures.rst + */ +template +struct NDArray { + /** + * @brief The underlying data this `ndarray` is pointing to. + * + * Must be set to `nullptr` to indicate that this NDArray's `data` is uninitialized. + */ + uint8_t* data; + + /** + * @brief The number of bytes of a single element in `data`. + */ + SizeT itemsize; + + /** + * @brief The number of dimensions of this shape. + */ + SizeT ndims; + + /** + * @brief The NDArray shape, with length equal to `ndims`. + * + * Note that it may contain 0. + */ + SizeT* shape; + + /** + * @brief Array strides, with length equal to `ndims` + * + * The stride values are in units of bytes, not number of elements. + * + * Note that `strides` can have negative values. + */ + SizeT* strides; +}; +} // namespace \ No newline at end of file diff --git a/nac3core/irrt/irrt_everything.hpp b/nac3core/irrt/irrt_everything.hpp index fa775263..16ea68e7 100644 --- a/nac3core/irrt/irrt_everything.hpp +++ b/nac3core/irrt/irrt_everything.hpp @@ -4,4 +4,5 @@ #include #include #include +#include #include \ No newline at end of file diff --git a/nac3core/src/codegen/structs/mod.rs b/nac3core/src/codegen/structs/mod.rs index 14b596fb..51c9cab0 100644 --- a/nac3core/src/codegen/structs/mod.rs +++ b/nac3core/src/codegen/structs/mod.rs @@ -1,2 +1,3 @@ pub mod cslice; pub mod exception; +pub mod ndarray; diff --git a/nac3core/src/codegen/structs/ndarray.rs b/nac3core/src/codegen/structs/ndarray.rs new file mode 100644 index 00000000..cf53abb2 --- /dev/null +++ b/nac3core/src/codegen/structs/ndarray.rs @@ -0,0 +1,54 @@ +use crate::codegen::*; + +pub struct NpArrayFields<'ctx> { + pub data: Field>, + pub itemsize: Field>, + pub ndims: Field>, + pub shape: Field>>, + pub strides: Field>>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct NpArray<'ctx> { + pub sizet: SizeTModel<'ctx>, +} + +impl<'ctx> StructKind<'ctx> for NpArray<'ctx> { + type Fields = NpArrayFields<'ctx>; + + fn struct_name(&self) -> &'static str { + "NDArray" + } + + fn build_fields(&self, builder: &mut FieldBuilder<'ctx>) -> Self::Fields { + NpArrayFields { + data: builder.add_field_auto("data"), + itemsize: builder.add_field("itemsize", self.sizet), + ndims: builder.add_field("ndims", self.sizet), + shape: builder.add_field("shape", PointerModel(self.sizet)), + strides: builder.add_field("strides", PointerModel(self.sizet)), + } + } +} + +impl<'ctx> Pointer<'ctx, StructModel>> { + /// Get an [`ArraySlice`] of [`NpArrayFields::shape`] with [`NpArrayFields::ndims`] as its length. + pub fn shape_slice( + &self, + ctx: &CodeGenContext<'ctx, '_>, + ) -> ArraySlice<'ctx, SizeTModel<'ctx>, SizeTModel<'ctx>> { + let ndims = self.gep(ctx, |f| f.ndims).load(ctx, "ndims"); + let shape_base_ptr = self.gep(ctx, |f| f.shape).load(ctx, "shape"); + ArraySlice { num_elements: ndims, pointer: shape_base_ptr } + } + + /// Get an [`ArraySlice`] of [`NpArrayFields::strides`] with [`NpArrayFields::ndims`] as its length. + pub fn strides_slice( + &self, + ctx: &CodeGenContext<'ctx, '_>, + ) -> ArraySlice<'ctx, SizeTModel<'ctx>, SizeTModel<'ctx>> { + let ndims = self.gep(ctx, |f| f.ndims).load(ctx, "ndims"); + let strides_base_ptr = self.gep(ctx, |f| f.strides).load(ctx, "strides"); + ArraySlice { num_elements: ndims, pointer: strides_base_ptr } + } +}