core/ndstrides: define ndarray with strides

This commit is contained in:
lyken 2024-08-20 11:38:05 +08:00
parent 9d8cc0c59d
commit f090b3b4d2
No known key found for this signature in database
GPG Key ID: 3BD5FC6AC8325DD8
5 changed files with 114 additions and 9 deletions

View File

@ -1,4 +1,5 @@
#include <irrt/exception.hpp>
#include <irrt/int_types.hpp>
#include <irrt/math_util.hpp>
#include <irrt/original.hpp>
#include <irrt/ndarray/def.hpp>
#include <irrt/original.hpp>

View File

@ -0,0 +1,47 @@
#pragma once
#include <irrt/int_types.hpp>
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 <typename SizeT> 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

View File

@ -1,7 +1,7 @@
use crate::{
codegen::classes::{ListType, NDArrayType, ProxyType, RangeType},
codegen::classes::{ListType, ProxyType, RangeType},
symbol_resolver::{StaticValue, SymbolResolver},
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys, TopLevelContext, TopLevelDef},
toplevel::{helper::PrimDef, TopLevelContext, TopLevelDef},
typecheck::{
type_inferencer::{CodeLocation, PrimitiveStore},
typedef::{CallId, FuncArg, Type, TypeEnum, Unifier},
@ -24,7 +24,9 @@ use inkwell::{
AddressSpace, IntPredicate, OptimizationLevel,
};
use itertools::Itertools;
use model::*;
use nac3parser::ast::{Location, Stmt, StrRef};
use object::ndarray::NDArray;
use parking_lot::{Condvar, Mutex};
use std::collections::{HashMap, HashSet};
use std::sync::{
@ -491,12 +493,7 @@ fn get_llvm_type<'ctx, G: CodeGenerator + ?Sized>(
}
TObj { obj_id, .. } if *obj_id == PrimDef::NDArray.id() => {
let (dtype, _) = unpack_ndarray_var_tys(unifier, ty);
let element_type = get_llvm_type(
ctx, module, generator, unifier, top_level, type_cache, dtype,
);
NDArrayType::new(generator, ctx, element_type).as_base_type().into()
Ptr(Struct(NDArray)).get_type(generator, ctx).as_basic_type_enum()
}
_ => unreachable!(

View File

@ -1 +1,2 @@
pub mod any;
pub mod ndarray;

View File

@ -0,0 +1,59 @@
use crate::{
codegen::{model::*, CodeGenContext, CodeGenerator},
toplevel::{helper::extract_ndims, numpy::unpack_ndarray_var_tys},
typecheck::typedef::Type,
};
use super::any::AnyObject;
/// Fields of [`NDArray`]
pub struct NDArrayFields<'ctx, F: FieldTraversal<'ctx>> {
pub data: F::Out<Ptr<Int<Byte>>>,
pub itemsize: F::Out<Int<SizeT>>,
pub ndims: F::Out<Int<SizeT>>,
pub shape: F::Out<Ptr<Int<SizeT>>>,
pub strides: F::Out<Ptr<Int<SizeT>>>,
}
/// A strided ndarray in NAC3.
///
/// See IRRT implementation for details about its fields.
#[derive(Debug, Clone, Copy, Default)]
pub struct NDArray;
impl<'ctx> StructKind<'ctx> for NDArray {
type Fields<F: FieldTraversal<'ctx>> = NDArrayFields<'ctx, F>;
fn traverse_fields<F: FieldTraversal<'ctx>>(&self, traversal: &mut F) -> Self::Fields<F> {
Self::Fields {
data: traversal.add_auto("data"),
itemsize: traversal.add_auto("itemsize"),
ndims: traversal.add_auto("ndims"),
shape: traversal.add_auto("shape"),
strides: traversal.add_auto("strides"),
}
}
}
/// A NAC3 Python ndarray object.
#[derive(Debug, Clone, Copy)]
pub struct NDArrayObject<'ctx> {
pub dtype: Type,
pub ndims: u64,
pub instance: Instance<'ctx, Ptr<Struct<NDArray>>>,
}
impl<'ctx> NDArrayObject<'ctx> {
/// Attempt to convert an [`AnyObject`] into an [`NDArrayObject`].
pub fn from_object<G: CodeGenerator + ?Sized>(
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
object: AnyObject<'ctx>,
) -> NDArrayObject<'ctx> {
let (dtype, ndims) = unpack_ndarray_var_tys(&mut ctx.unifier, object.ty);
let ndims = extract_ndims(&ctx.unifier, ndims);
let value = Ptr(Struct(NDArray)).check_value(generator, ctx.ctx, object.value).unwrap();
NDArrayObject { dtype, ndims, instance: value }
}
}