core/ndstrides: implement np_size()

This commit is contained in:
lyken 2024-08-20 16:03:48 +08:00 committed by David Mak
parent c307a483bd
commit e33f74b331
3 changed files with 30 additions and 2 deletions

View File

@ -18,6 +18,7 @@ use crate::{
codegen::{ codegen::{
builtin_fns, builtin_fns,
classes::{ProxyValue, RangeValue}, classes::{ProxyValue, RangeValue},
model::*,
numpy::*, numpy::*,
object::{any::AnyObject, ndarray::NDArrayObject}, object::{any::AnyObject, ndarray::NDArrayObject},
stmt::exn_constructor, stmt::exn_constructor,
@ -513,7 +514,7 @@ impl<'a> BuiltinBuilder<'a> {
| PrimDef::FunNpEye | PrimDef::FunNpEye
| PrimDef::FunNpIdentity => self.build_ndarray_other_factory_function(prim), | PrimDef::FunNpIdentity => self.build_ndarray_other_factory_function(prim),
PrimDef::FunNpShape | PrimDef::FunNpStrides => { PrimDef::FunNpSize | PrimDef::FunNpShape | PrimDef::FunNpStrides => {
self.build_ndarray_property_getter_function(prim) self.build_ndarray_property_getter_function(prim)
} }
@ -1392,7 +1393,10 @@ impl<'a> BuiltinBuilder<'a> {
} }
fn build_ndarray_property_getter_function(&mut self, prim: PrimDef) -> TopLevelDef { fn build_ndarray_property_getter_function(&mut self, prim: PrimDef) -> TopLevelDef {
debug_assert_prim_is_allowed(prim, &[PrimDef::FunNpShape, PrimDef::FunNpStrides]); debug_assert_prim_is_allowed(
prim,
&[PrimDef::FunNpSize, PrimDef::FunNpShape, PrimDef::FunNpStrides],
);
let in_ndarray_ty = self.unifier.get_fresh_var_with_range( let in_ndarray_ty = self.unifier.get_fresh_var_with_range(
&[self.primitives.ndarray], &[self.primitives.ndarray],
@ -1401,6 +1405,27 @@ impl<'a> BuiltinBuilder<'a> {
); );
match prim { match prim {
PrimDef::FunNpSize => create_fn_by_codegen(
self.unifier,
&into_var_map([in_ndarray_ty]),
prim.name(),
self.primitives.int32,
&[(in_ndarray_ty.ty, "a")],
Box::new(|ctx, obj, fun, args, generator| {
assert!(obj.is_none());
assert_eq!(args.len(), 1);
let ndarray_ty = fun.0.args[0].ty;
let ndarray =
args[0].1.clone().to_basic_value_enum(ctx, generator, ndarray_ty)?;
let ndarray = AnyObject { ty: ndarray_ty, value: ndarray };
let ndarray = NDArrayObject::from_object(generator, ctx, ndarray);
let size =
ndarray.size(generator, ctx).truncate_or_bit_cast(generator, ctx, Int32);
Ok(Some(size.value.as_basic_value_enum()))
}),
),
PrimDef::FunNpShape | PrimDef::FunNpStrides => { PrimDef::FunNpShape | PrimDef::FunNpStrides => {
// The function signatures of `np_shape` an `np_size` are the same. // The function signatures of `np_shape` an `np_size` are the same.
// Mixed together for convenience. // Mixed together for convenience.

View File

@ -57,6 +57,7 @@ pub enum PrimDef {
FunNpIdentity, FunNpIdentity,
// NumPy ndarray property getters // NumPy ndarray property getters
FunNpSize,
FunNpShape, FunNpShape,
FunNpStrides, FunNpStrides,
@ -247,6 +248,7 @@ impl PrimDef {
PrimDef::FunNpIdentity => fun("np_identity", None), PrimDef::FunNpIdentity => fun("np_identity", None),
// NumPy NDArray property getters, // NumPy NDArray property getters,
PrimDef::FunNpSize => fun("np_size", None),
PrimDef::FunNpShape => fun("np_shape", None), PrimDef::FunNpShape => fun("np_shape", None),
PrimDef::FunNpStrides => fun("np_strides", None), PrimDef::FunNpStrides => fun("np_strides", None),

View File

@ -180,6 +180,7 @@ def patch(module):
module.np_array = np.array module.np_array = np.array
# NumPy NDArray property getters # NumPy NDArray property getters
module.np_size = np.size
module.np_shape = np.shape module.np_shape = np.shape
module.np_strides = lambda ndarray: ndarray.strides module.np_strides = lambda ndarray: ndarray.strides