Skip to content

Commit

Permalink
Simplify shape based initializers, add tests for shape based initiali…
Browse files Browse the repository at this point in the history
…zers
  • Loading branch information
MadAlex1997 committed Aug 30, 2024
1 parent fd32e26 commit 540f54f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 135 deletions.
2 changes: 2 additions & 0 deletions numojo/__init__.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ from .core import *
from .math import *
from .math.statistics import stats

alias __version__ = "V0.2"

# Constants
alias pi = core.constants.Constants.pi
alias e = core.constants.Constants.e
Expand Down
184 changes: 56 additions & 128 deletions numojo/core/ndarray.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -653,84 +653,34 @@ struct NDArray[dtype: DType = DType.float64](
# ===-------------------------------------------------------------------===#

# default constructor
@always_inline("nodebug")
fn __init__(
inout self, *shape: Int, random: Bool = False, order: String = "C"
) raises:
"""
NDArray initialization for variadic shape.
Args:
shape: Variadic shape.
random: Set the values randomly.
order: Memory order C or F.
Example:
NDArray[DType.int8](3,2,4)
Returns an zero array with shape 3 x 2 x 4.
"""
self.ndim = shape.__len__()
# I cannot name self.ndshape as self.shape as lsp gives unrecognized variable error
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
# I gotta make coefficients empty, but let's just keep it like for now
self.coefficient = NDArrayStride(shape, offset=0, order=order)
self.datatype = dtype
self.order = order
self.data = DTypePointer[dtype].alloc(self.ndshape.ndsize)
memset_zero(self.data, self.ndshape.ndsize)
if random:
rand[dtype](self.data, self.ndshape.ndsize)

@always_inline("nodebug")
fn __init__(
inout self,
shape: List[Int],
*shape: Int,
fill: Scalar[dtype] = Scalar[dtype](0),
random: Bool = False,
order: String = "C",
) raises:
"""
NDArray initialization for list shape.
NDArray initialization for variadic shape with option to fill.
Args:
shape: List of shape.
random: Set the values randomly.
shape: Variadic shape.
fill: Set all the values to this.
random: Set values randomly.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""
self.ndim = shape.__len__()
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
self.coefficient = NDArrayStride(shape, offset=0, order=order)
self.data = DTypePointer[dtype].alloc(self.ndshape.ndsize)
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
if random:
rand[dtype](self.data, self.ndshape.ndsize)

@always_inline("nodebug")
fn __init__(
inout self,
shape: VariadicList[Int],
random: Bool = False,
order: String = "C",
) raises:
"""
NDArray initialization for variadic shape.
Args:
shape: Variadic List shape.
random: Set the values randomly.
order: Memory order C or F.
if random == True and fill != 0:
raise Error(
"numojo/core/ndarray:NDArray: __init__(*shape, fill, random)):"
" Error if random is true you cannot set a fill value"
)

Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""
self.ndim = shape.__len__()
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
Expand All @@ -741,42 +691,16 @@ struct NDArray[dtype: DType = DType.float64](
self.order = order
if random:
rand[dtype](self.data, self.ndshape.ndsize)

@always_inline("nodebug")
fn __init__(
inout self,
*shape: Int,
fill: Scalar[dtype],
order: String = "C",
) raises:
"""
NDArray initialization for variadic shape with option to fill.
Args:
shape: Variadic shape.
fill: Set all the values to this.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""
self.ndim = shape.__len__()
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
self.coefficient = NDArrayStride(shape, offset=0, order=order)
self.data = DTypePointer[dtype].alloc(self.ndshape.ndsize)
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
for i in range(self.ndshape.ndsize):
self.data[i] = fill
else:
for i in range(self.ndshape.ndsize):
self.data[i] = fill

@always_inline("nodebug")
fn __init__(
inout self,
shape: List[Int],
fill: Scalar[dtype],
fill: Scalar[dtype] = Scalar[dtype](0),
random: Bool = False,
order: String = "C",
) raises:
"""
Expand All @@ -785,12 +709,20 @@ struct NDArray[dtype: DType = DType.float64](
Args:
shape: List of shape.
fill: Set all the values to this.
random: Set values randomly.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""

if random == True and fill != 0:
raise Error(
"numojo/core/ndarray:NDArray: __init__(List[Int], fill,"
" random)): Error if random is true you cannot set a fill value"
)

self.ndim = shape.__len__()
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
Expand All @@ -799,14 +731,18 @@ struct NDArray[dtype: DType = DType.float64](
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
for i in range(self.ndshape.ndsize):
self.data[i] = fill
if random:
rand[dtype](self.data, self.ndshape.ndsize)
else:
for i in range(self.ndshape.ndsize):
self.data[i] = fill

@always_inline("nodebug")
fn __init__(
inout self,
shape: VariadicList[Int],
fill: Scalar[dtype],
fill: Scalar[dtype] = Scalar[dtype](0),
random: Bool = False,
order: String = "C",
) raises:
"""
Expand All @@ -815,12 +751,19 @@ struct NDArray[dtype: DType = DType.float64](
Args:
shape: Variadic List of shape.
fill: Set all the values to this.
random: Set values randomly.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""
if random == True and fill != 0:
raise Error(
"numojo/core/ndarray:NDArray: __init__(VariadicList[Int], fill,"
" random)): Error if random is true you cannot set a fill value"
)

self.ndim = shape.__len__()
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, offset=0, order=order)
Expand All @@ -829,44 +772,18 @@ struct NDArray[dtype: DType = DType.float64](
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
for i in range(self.ndshape.ndsize):
self.data[i] = fill

@always_inline("nodebug")
fn __init__(
inout self,
shape: NDArrayShape,
random: Bool = False,
order: String = "C",
) raises:
"""
NDArray initialization for NDArrayShape.
Args:
shape: Variadic shape.
random: Set all the values randomly.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""
self.ndim = shape.ndlen
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, order=order)
self.coefficient = NDArrayStride(shape, order=order)
self.data = DTypePointer[dtype].alloc(self.ndshape.ndsize)
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
if random:
rand[dtype](self.data, self.ndshape.ndsize)
else:
for i in range(self.ndshape.ndsize):
self.data[i] = fill

@always_inline("nodebug")
fn __init__(
inout self,
shape: NDArrayShape,
fill: Scalar[dtype],
fill: Scalar[dtype] = Scalar[dtype](0),
random: Bool = False,
order: String = "C",
) raises:
"""
Expand All @@ -875,12 +792,20 @@ struct NDArray[dtype: DType = DType.float64](
Args:
shape: Variadic shape.
fill: Set all the the values to this.
random: Set values randomly.
order: Memory order C or F.
Example:
NDArray[DType.float16](VariadicList[Int](3, 2, 4), random=True)
Returns an array with shape 3 x 2 x 4 and randomly values.
"""

if random == True and fill != 0:
raise Error(
"numojo/core/ndarray:NDArray: __init__(NDArrayShape, fill,"
" random)): Error if random is true you cannot set a fill value"
)

self.ndim = shape.ndlen
self.ndshape = NDArrayShape(shape)
self.stride = NDArrayStride(shape, order=order)
Expand All @@ -889,8 +814,11 @@ struct NDArray[dtype: DType = DType.float64](
memset_zero(self.data, self.ndshape.ndsize)
self.datatype = dtype
self.order = order
for i in range(self.ndshape.ndsize):
self.data[i] = fill
if random:
rand[dtype](self.data, self.ndshape.ndsize)
else:
for i in range(self.ndshape.ndsize):
self.data[i] = fill

fn __init__(
inout self,
Expand Down
46 changes: 39 additions & 7 deletions tests/test_array_creation.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@ import numojo as nm
from time import now
from python import Python, PythonObject
from utils_for_test import check, check_is_close
from testing.testing import assert_raises


def test_list_creation_methods():
var np = Python.import_module("numpy")
check(
nm.NDArray(5, 5, 5, fill=5),
np.zeros([5, 5, 5], dtype=np.float64) + 5,
"*shape broken",
)
check(
nm.NDArray(List[Int](5, 5, 5), fill=5),
np.zeros([5, 5, 5], dtype=np.float64) + 5,
"List[int] shape broken",
)
check(
nm.NDArray(VariadicList[Int](5, 5, 5), fill=5),
np.zeros([5, 5, 5], dtype=np.float64) + 5,
"VariadicList[Int] shape broken",
)
check(
nm.NDArray(nm.NDArrayShape(5, 5, 5), fill=5),
np.zeros([5, 5, 5], dtype=np.float64) + 5,
"NDArrayShape shape broken",
)
with assert_raises(
contains="Error if random is true you cannot set a fill value"
):
_ = nm.NDArray(nm.NDArrayShape(5, 5, 5), fill=5, random=True)


def test_arange():
Expand Down Expand Up @@ -91,20 +120,23 @@ def test_eye():


def main():
# var np = Python.import_module("numpy")
# var arr = nm.arange[nm.f64](0, 100)
# arr.reshape(10, 10)
# var np_arr = np.arange(0, 100).reshape(10, 10)
var np = Python.import_module("numpy")
var arr = nm.arange[nm.f64](0, 100)
arr.reshape(10, 10)
var np_arr = np.arange(0, 100).reshape(10, 10)
print(nm.NDArray(5, 5, 5, fill=5).shape())
print(np.zeros([5, 5, 5], dtype=np.float64).fill(5))
# Arange like flat arrays
# check(nm.arange[nm.i64](0,100),np.arange(0,100,dtype=np.int64),"Arange is broken")
# check(nm.linspace[nm.i64](0,100),np.linspace(0,100,dtype=np.float64),"Linspace is broken")
# check_is_close(nm.logspace[nm.i64](0,100,5),np.logspace(0,100,5,dtype=np.float64),"Logspace is broken")
# check_is_close(nm.geomspace[nm.i64](1,100,5),np.geomspace(1,100,5,dtype=np.float64),"Logspace is broken")
# print((arr@arr).to_numpy()-np.matmul(np_arr,np_arr))
print(
nm.matmul_naive[nm.f64](arr, arr).to_numpy()
) # -np.matmul(np_arr,np_arr))
print(np.matmul(np_arr, np_arr))
# print(
# nm.matmul_naive[nm.f64](arr, arr).to_numpy()
# ) # -np.matmul(np_arr,np_arr))
# print(np.matmul(np_arr, np_arr))
# # Basic ND arrays
# print(nm.sin[nm.f64](nm.arange[nm.f64](0,15)))
# print( np.sin(np.arange(0,15, dtype=np.float64)))
Expand Down

0 comments on commit 540f54f

Please sign in to comment.