Skip to content

Various cleanups #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 3, 2017
27 changes: 27 additions & 0 deletions benches/bench1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,33 @@ fn add_2d_f32_regular(bench: &mut test::Bencher)
});
}

const ADD3DSZ: usize = 16;

#[bench]
fn add_3d_strided(bench: &mut test::Bencher)
{
let mut a = Array::<i32, _>::zeros((ADD3DSZ, ADD3DSZ, ADD3DSZ * 2));
let mut a = a.slice_mut(s![.., .., ..;2]);
let b = Array::<i32, _>::zeros(a.dim());
let bv = b.view();
bench.iter(|| {
a += &bv;
});
}

#[bench]
fn add_3d_strided_dyn(bench: &mut test::Bencher)
{
let mut a = Array::<i32, _>::zeros(&[ADD3DSZ, ADD3DSZ, ADD3DSZ * 2][..]);
let mut a = a.slice_mut(s![.., .., ..;2]);
let b = Array::<i32, _>::zeros(a.dim());
let bv = b.view();
bench.iter(|| {
a += &bv;
});
}


const ADD1D_SIZE: usize = 64 * 64;

#[bench]
Expand Down
32 changes: 32 additions & 0 deletions benches/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,35 @@ fn vector_sum_3_zip_unchecked(bench: &mut Bencher)
}
});
}

// index iterator size
const ISZ: usize = 16;

#[bench]
fn indexed_iter_3d_ix3(bench: &mut Bencher) {
let mut a = Array::<f64, _>::zeros((ISZ, ISZ, ISZ));
for ((i, j, k), elt) in a.indexed_iter_mut() {
*elt = (i + 100 * j + 10000 * k) as _;
}

bench.iter(|| {
for (i, &elt) in a.indexed_iter() {
assert!(a[i] == elt);
}
})
}

#[bench]
fn indexed_iter_3d_dyn(bench: &mut Bencher) {
let mut a = Array::<f64, _>::zeros((ISZ, ISZ, ISZ));
for ((i, j, k), elt) in a.indexed_iter_mut() {
*elt = (i + 100 * j + 10000 * k) as _;
}
let a = a.into_shape(&[ISZ; 3][..]).unwrap();

bench.iter(|| {
for (i, &elt) in a.indexed_iter() {
assert!(a[i] == elt);
}
})
}
3 changes: 1 addition & 2 deletions src/aliases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ pub type Ix6 = Dim<[Ix; 6]>;
/// // We can index into a, b using fixed size arrays:
/// a[[0, 0, 0, 0]] = 0.;
/// b[[0, 2, 3]] = a[[0, 0, 2, 3]];
///
/// // Note: It will panic at runtime if the number of indices given does
/// // Note: indexing will panic at runtime if the number of indices given does
/// // not match the array.
///
/// // We can keep them in the same vector because both the arrays have
Expand Down
4 changes: 2 additions & 2 deletions src/arraytraits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix1>
fn from(slice: &'a Slice) -> Self {
let xs = slice.as_ref();
unsafe {
Self::new_(xs.as_ptr(), Ix1(xs.len()), Ix1(1))
Self::from_shape_ptr(xs.len(), xs.as_ptr())
}
}
}
Expand All @@ -256,7 +256,7 @@ impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>
fn from(slice: &'a mut Slice) -> Self {
let xs = slice.as_mut();
unsafe {
Self::new_(xs.as_mut_ptr(), Ix1(xs.len()), Ix1(1))
Self::from_shape_ptr(xs.len(), xs.as_mut_ptr())
}
}
}
Expand Down
26 changes: 14 additions & 12 deletions src/data_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use {
ArrayBase,
Dimension,
ViewRepr,
OwnedRepr,
OwnedRcRepr,
};

/// Array representation trait.
Expand Down Expand Up @@ -68,15 +70,15 @@ pub unsafe trait DataClone : Data {
}
}

unsafe impl<A> Data for Rc<Vec<A>> {
unsafe impl<A> Data for OwnedRcRepr<A> {
type Elem = A;
fn _data_slice(&self) -> &[A] {
self
}
}

// NOTE: Copy on write
unsafe impl<A> DataMut for Rc<Vec<A>>
unsafe impl<A> DataMut for OwnedRcRepr<A>
where A: Clone
{
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
Expand Down Expand Up @@ -112,23 +114,23 @@ unsafe impl<A> DataMut for Rc<Vec<A>>
}
}

unsafe impl<A> DataClone for Rc<Vec<A>> {
unsafe impl<A> DataClone for OwnedRcRepr<A> {
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
// pointer is preserved
(self.clone(), ptr)
}
}

unsafe impl<A> Data for Vec<A> {
unsafe impl<A> Data for OwnedRepr<A> {
type Elem = A;
fn _data_slice(&self) -> &[A] {
self
}
}

unsafe impl<A> DataMut for Vec<A> { }
unsafe impl<A> DataMut for OwnedRepr<A> { }

unsafe impl<A> DataClone for Vec<A>
unsafe impl<A> DataClone for OwnedRepr<A>
where A: Clone
{
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
Expand Down Expand Up @@ -185,7 +187,7 @@ pub unsafe trait DataOwned : Data {
#[doc(hidden)]
fn new(elements: Vec<Self::Elem>) -> Self;
#[doc(hidden)]
fn into_shared(self) -> Rc<Vec<Self::Elem>>;
fn into_shared(self) -> OwnedRcRepr<Self::Elem>;
}

/// Array representation trait.
Expand All @@ -195,23 +197,23 @@ pub unsafe trait DataOwned : Data {
/// ***Internal trait, see `Data`.***
pub unsafe trait DataShared : Clone + DataClone { }

unsafe impl<A> DataShared for Rc<Vec<A>> {}
unsafe impl<A> DataShared for OwnedRcRepr<A> {}
unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}

unsafe impl<A> DataOwned for Vec<A> {
unsafe impl<A> DataOwned for OwnedRepr<A> {
fn new(elements: Vec<A>) -> Self {
elements
}
fn into_shared(self) -> Rc<Vec<A>> {
fn into_shared(self) -> OwnedRcRepr<A> {
Rc::new(self)
}
}

unsafe impl<A> DataOwned for Rc<Vec<A>> {
unsafe impl<A> DataOwned for OwnedRcRepr<A> {
fn new(elements: Vec<A>) -> Self {
Rc::new(elements)
}
fn into_shared(self) -> Rc<Vec<A>> {
fn into_shared(self) -> OwnedRcRepr<A> {
self
}
}
Expand Down
50 changes: 23 additions & 27 deletions src/dimension/dimension_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
{
let mut it = strides.slice_mut().iter_mut().rev();
// Set first element to 1
for rs in it.by_ref() {
while let Some(rs) = it.next() {
*rs = 1;
break;
}
Expand All @@ -134,12 +134,12 @@ pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
{
let mut it = strides.slice_mut().iter_mut();
// Set first element to 1
for rs in it.by_ref() {
while let Some(rs) = it.next() {
*rs = 1;
break;
}
let mut cum_prod = 1;
for (rs, dim) in it.zip(self.slice().iter()) {
for (rs, dim) in it.zip(self.slice()) {
cum_prod *= *dim;
*rs = cum_prod;
}
Expand Down Expand Up @@ -558,30 +558,6 @@ unsafe impl Dimension for Dim<[Ix; 2]> {
}
}

#[inline]
fn is_contiguous(dim: &Self, strides: &Self) -> bool {
let defaults = dim.default_strides();
if strides.equal(&defaults) {
return true;
}

if dim.ndim() == 1 { return false; }
let order = strides._fastest_varying_stride_order();
let strides = strides.slice();

// FIXME: Negative strides
let dim_slice = dim.slice();
let mut cstride = 1;
for &i in order.slice() {
// a dimension of length 1 can have unequal strides
if dim_slice[i] != 1 && strides[i] != cstride {
return false;
}
cstride *= dim_slice[i];
}
true
}

#[inline]
fn first_index(&self) -> Option<Self> {
let m = get!(self, 0);
Expand Down Expand Up @@ -683,6 +659,26 @@ unsafe impl Dimension for Dim<[Ix; 3]> {
stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u)
}

/// Return stride offset for this dimension and index.
#[inline]
fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize>
{
let m = get!(self, 0);
let n = get!(self, 1);
let l = get!(self, 2);
let i = get!(index, 0);
let j = get!(index, 1);
let k = get!(index, 2);
let s = get!(strides, 0);
let t = get!(strides, 1);
let u = get!(strides, 2);
if i < m && j < n && k < l {
Some(stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u))
} else {
None
}
}

#[inline]
fn _fastest_varying_stride_order(&self) -> Self {
let mut stride = *self;
Expand Down
1 change: 1 addition & 0 deletions src/dimension/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ fn stride_offset_checked_arithmetic<D>(dim: &D, strides: &D, index: &D)
}

/// Stride offset checked general version (slices)
#[inline]
pub fn stride_offset_checked(dim: &[Ix], strides: &[Ix], index: &[Ix]) -> Option<isize> {
if index.len() != dim.len() {
return None;
Expand Down
5 changes: 2 additions & 3 deletions src/free_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn rcarr1<A: Clone>(xs: &[A]) -> RcArray<A, Ix1> {

/// Create a zero-dimensional array view borrowing `x`.
pub fn aview0<A>(x: &A) -> ArrayView0<A> {
unsafe { ArrayView::new_(x, Ix0(), Ix0()) }
unsafe { ArrayView::from_shape_ptr(Ix0(), x) }
}

/// Create a one-dimensional array view with elements borrowing `xs`.
Expand Down Expand Up @@ -98,8 +98,7 @@ pub fn aview2<A, V: FixedInitializer<Elem=A>>(xs: &[V]) -> ArrayView2<A> {
};
let dim = Ix2(rows, cols);
unsafe {
let strides = dim.default_strides();
ArrayView::new_(data.as_ptr(), dim, strides)
ArrayView::from_shape_ptr(dim, data.as_ptr())
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/impl_owned_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
use std::rc::Rc;

use imp_prelude::*;
use {
OwnedRepr,
OwnedRcRepr,
};

impl<A, D> ArrayBase<Vec<A>, D>
impl<A, D> ArrayBase<OwnedRepr<A>, D>
where D: Dimension
{
/// Return a vector of the elements in the array, in the way they are
Expand All @@ -17,7 +21,7 @@ impl<A, D> ArrayBase<Vec<A>, D>
}

// RcArray
impl<A, D> ArrayBase<Rc<Vec<A>>, D>
impl<A, D> ArrayBase<OwnedRcRepr<A>, D>
where A: Clone,
D: Dimension
{
Expand Down
10 changes: 8 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ pub struct ArrayBase<S, D>
/// An array where the data has shared ownership and is copy on write.
/// It can act as both an owner as the data as well as a shared reference (view
/// like).
pub type RcArray<A, D> = ArrayBase<Rc<Vec<A>>, D>;
pub type RcArray<A, D> = ArrayBase<OwnedRcRepr<A>, D>;

/// An array that owns its data uniquely.
///
Expand All @@ -522,7 +522,7 @@ pub type RcArray<A, D> = ArrayBase<Rc<Vec<A>>, D>;
/// [`Array1`](Array1.t.html),
/// [`Array2`](Array2.t.html),
/// [`Array3`](Array3.t.html) and so on.
pub type Array<A, D> = ArrayBase<Vec<A>, D>;
pub type Array<A, D> = ArrayBase<OwnedRepr<A>, D>;

/// A lightweight array view.
///
Expand All @@ -547,6 +547,12 @@ pub type ArrayView<'a, A, D> = ArrayBase<ViewRepr<&'a A>, D>;
/// [ab]: struct.ArrayBase.html
pub type ArrayViewMut<'a, A, D> = ArrayBase<ViewRepr<&'a mut A>, D>;

/// Array's representation.
type OwnedRepr<A> = Vec<A>;

/// RcArray's representation.
type OwnedRcRepr<A> = Rc<Vec<A>>;

/// Array view’s representation.
#[derive(Copy, Clone)]
// This is just a marker type, to carry the lifetime parameter.
Expand Down
18 changes: 16 additions & 2 deletions src/numeric/impl_numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use numeric_util;

use {
LinalgScalar,
FoldWhile,
Zip,
};

/// Numerical methods for arrays.
Expand Down Expand Up @@ -124,8 +126,20 @@ impl<A, S, D> ArrayBase<S, D>
S2: Data<Elem=A>,
E: Dimension,
{
let rhs_broadcast = rhs.broadcast_unwrap(self.raw_dim());
self.iter().zip(rhs_broadcast.iter()).all(|(x, y)| (*x - *y).abs() <= tol)
let result =
Zip::from(self)
.and(rhs.broadcast_unwrap(self.raw_dim()))
.fold_while((), |_, x, y| {
if (*x - *y).abs() <= tol {
FoldWhile::Continue(())
} else {
FoldWhile::Done(())
}
});
match result {
FoldWhile::Continue(_) => true,
FoldWhile::Done(_) => false,
}
}
}

Loading