Skip to content

Commit 013dcb1

Browse files
authored
Merge pull request #300 from bluss/maint
Various cleanups
2 parents 0e45ce1 + f46938f commit 013dcb1

File tree

13 files changed

+186
-52
lines changed

13 files changed

+186
-52
lines changed

benches/bench1.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,33 @@ fn add_2d_f32_regular(bench: &mut test::Bencher)
583583
});
584584
}
585585

586+
const ADD3DSZ: usize = 16;
587+
588+
#[bench]
589+
fn add_3d_strided(bench: &mut test::Bencher)
590+
{
591+
let mut a = Array::<i32, _>::zeros((ADD3DSZ, ADD3DSZ, ADD3DSZ * 2));
592+
let mut a = a.slice_mut(s![.., .., ..;2]);
593+
let b = Array::<i32, _>::zeros(a.dim());
594+
let bv = b.view();
595+
bench.iter(|| {
596+
a += &bv;
597+
});
598+
}
599+
600+
#[bench]
601+
fn add_3d_strided_dyn(bench: &mut test::Bencher)
602+
{
603+
let mut a = Array::<i32, _>::zeros(&[ADD3DSZ, ADD3DSZ, ADD3DSZ * 2][..]);
604+
let mut a = a.slice_mut(s![.., .., ..;2]);
605+
let b = Array::<i32, _>::zeros(a.dim());
606+
let bv = b.view();
607+
bench.iter(|| {
608+
a += &bv;
609+
});
610+
}
611+
612+
586613
const ADD1D_SIZE: usize = 64 * 64;
587614

588615
#[bench]

benches/iter.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,35 @@ fn vector_sum_3_zip_unchecked(bench: &mut Bencher)
202202
}
203203
});
204204
}
205+
206+
// index iterator size
207+
const ISZ: usize = 16;
208+
209+
#[bench]
210+
fn indexed_iter_3d_ix3(bench: &mut Bencher) {
211+
let mut a = Array::<f64, _>::zeros((ISZ, ISZ, ISZ));
212+
for ((i, j, k), elt) in a.indexed_iter_mut() {
213+
*elt = (i + 100 * j + 10000 * k) as _;
214+
}
215+
216+
bench.iter(|| {
217+
for (i, &elt) in a.indexed_iter() {
218+
assert!(a[i] == elt);
219+
}
220+
})
221+
}
222+
223+
#[bench]
224+
fn indexed_iter_3d_dyn(bench: &mut Bencher) {
225+
let mut a = Array::<f64, _>::zeros((ISZ, ISZ, ISZ));
226+
for ((i, j, k), elt) in a.indexed_iter_mut() {
227+
*elt = (i + 100 * j + 10000 * k) as _;
228+
}
229+
let a = a.into_shape(&[ISZ; 3][..]).unwrap();
230+
231+
bench.iter(|| {
232+
for (i, &elt) in a.indexed_iter() {
233+
assert!(a[i] == elt);
234+
}
235+
})
236+
}

src/aliases.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ pub type Ix6 = Dim<[Ix; 6]>;
7171
/// // We can index into a, b using fixed size arrays:
7272
/// a[[0, 0, 0, 0]] = 0.;
7373
/// b[[0, 2, 3]] = a[[0, 0, 2, 3]];
74-
///
75-
/// // Note: It will panic at runtime if the number of indices given does
74+
/// // Note: indexing will panic at runtime if the number of indices given does
7675
/// // not match the array.
7776
///
7877
/// // We can keep them in the same vector because both the arrays have

src/arraytraits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix1>
230230
fn from(slice: &'a Slice) -> Self {
231231
let xs = slice.as_ref();
232232
unsafe {
233-
Self::new_(xs.as_ptr(), Ix1(xs.len()), Ix1(1))
233+
Self::from_shape_ptr(xs.len(), xs.as_ptr())
234234
}
235235
}
236236
}
@@ -256,7 +256,7 @@ impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>
256256
fn from(slice: &'a mut Slice) -> Self {
257257
let xs = slice.as_mut();
258258
unsafe {
259-
Self::new_(xs.as_mut_ptr(), Ix1(xs.len()), Ix1(1))
259+
Self::from_shape_ptr(xs.len(), xs.as_mut_ptr())
260260
}
261261
}
262262
}

src/data_traits.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use {
1515
ArrayBase,
1616
Dimension,
1717
ViewRepr,
18+
OwnedRepr,
19+
OwnedRcRepr,
1820
};
1921

2022
/// Array representation trait.
@@ -68,15 +70,15 @@ pub unsafe trait DataClone : Data {
6870
}
6971
}
7072

71-
unsafe impl<A> Data for Rc<Vec<A>> {
73+
unsafe impl<A> Data for OwnedRcRepr<A> {
7274
type Elem = A;
7375
fn _data_slice(&self) -> &[A] {
7476
self
7577
}
7678
}
7779

7880
// NOTE: Copy on write
79-
unsafe impl<A> DataMut for Rc<Vec<A>>
81+
unsafe impl<A> DataMut for OwnedRcRepr<A>
8082
where A: Clone
8183
{
8284
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
@@ -112,23 +114,23 @@ unsafe impl<A> DataMut for Rc<Vec<A>>
112114
}
113115
}
114116

115-
unsafe impl<A> DataClone for Rc<Vec<A>> {
117+
unsafe impl<A> DataClone for OwnedRcRepr<A> {
116118
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
117119
// pointer is preserved
118120
(self.clone(), ptr)
119121
}
120122
}
121123

122-
unsafe impl<A> Data for Vec<A> {
124+
unsafe impl<A> Data for OwnedRepr<A> {
123125
type Elem = A;
124126
fn _data_slice(&self) -> &[A] {
125127
self
126128
}
127129
}
128130

129-
unsafe impl<A> DataMut for Vec<A> { }
131+
unsafe impl<A> DataMut for OwnedRepr<A> { }
130132

131-
unsafe impl<A> DataClone for Vec<A>
133+
unsafe impl<A> DataClone for OwnedRepr<A>
132134
where A: Clone
133135
{
134136
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
@@ -185,7 +187,7 @@ pub unsafe trait DataOwned : Data {
185187
#[doc(hidden)]
186188
fn new(elements: Vec<Self::Elem>) -> Self;
187189
#[doc(hidden)]
188-
fn into_shared(self) -> Rc<Vec<Self::Elem>>;
190+
fn into_shared(self) -> OwnedRcRepr<Self::Elem>;
189191
}
190192

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

198-
unsafe impl<A> DataShared for Rc<Vec<A>> {}
200+
unsafe impl<A> DataShared for OwnedRcRepr<A> {}
199201
unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
200202

201-
unsafe impl<A> DataOwned for Vec<A> {
203+
unsafe impl<A> DataOwned for OwnedRepr<A> {
202204
fn new(elements: Vec<A>) -> Self {
203205
elements
204206
}
205-
fn into_shared(self) -> Rc<Vec<A>> {
207+
fn into_shared(self) -> OwnedRcRepr<A> {
206208
Rc::new(self)
207209
}
208210
}
209211

210-
unsafe impl<A> DataOwned for Rc<Vec<A>> {
212+
unsafe impl<A> DataOwned for OwnedRcRepr<A> {
211213
fn new(elements: Vec<A>) -> Self {
212214
Rc::new(elements)
213215
}
214-
fn into_shared(self) -> Rc<Vec<A>> {
216+
fn into_shared(self) -> OwnedRcRepr<A> {
215217
self
216218
}
217219
}

src/dimension/dimension_trait.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
113113
{
114114
let mut it = strides.slice_mut().iter_mut().rev();
115115
// Set first element to 1
116-
for rs in it.by_ref() {
116+
while let Some(rs) = it.next() {
117117
*rs = 1;
118118
break;
119119
}
@@ -134,12 +134,12 @@ pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
134134
{
135135
let mut it = strides.slice_mut().iter_mut();
136136
// Set first element to 1
137-
for rs in it.by_ref() {
137+
while let Some(rs) = it.next() {
138138
*rs = 1;
139139
break;
140140
}
141141
let mut cum_prod = 1;
142-
for (rs, dim) in it.zip(self.slice().iter()) {
142+
for (rs, dim) in it.zip(self.slice()) {
143143
cum_prod *= *dim;
144144
*rs = cum_prod;
145145
}
@@ -558,30 +558,6 @@ unsafe impl Dimension for Dim<[Ix; 2]> {
558558
}
559559
}
560560

561-
#[inline]
562-
fn is_contiguous(dim: &Self, strides: &Self) -> bool {
563-
let defaults = dim.default_strides();
564-
if strides.equal(&defaults) {
565-
return true;
566-
}
567-
568-
if dim.ndim() == 1 { return false; }
569-
let order = strides._fastest_varying_stride_order();
570-
let strides = strides.slice();
571-
572-
// FIXME: Negative strides
573-
let dim_slice = dim.slice();
574-
let mut cstride = 1;
575-
for &i in order.slice() {
576-
// a dimension of length 1 can have unequal strides
577-
if dim_slice[i] != 1 && strides[i] != cstride {
578-
return false;
579-
}
580-
cstride *= dim_slice[i];
581-
}
582-
true
583-
}
584-
585561
#[inline]
586562
fn first_index(&self) -> Option<Self> {
587563
let m = get!(self, 0);
@@ -683,6 +659,26 @@ unsafe impl Dimension for Dim<[Ix; 3]> {
683659
stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u)
684660
}
685661

662+
/// Return stride offset for this dimension and index.
663+
#[inline]
664+
fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize>
665+
{
666+
let m = get!(self, 0);
667+
let n = get!(self, 1);
668+
let l = get!(self, 2);
669+
let i = get!(index, 0);
670+
let j = get!(index, 1);
671+
let k = get!(index, 2);
672+
let s = get!(strides, 0);
673+
let t = get!(strides, 1);
674+
let u = get!(strides, 2);
675+
if i < m && j < n && k < l {
676+
Some(stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u))
677+
} else {
678+
None
679+
}
680+
}
681+
686682
#[inline]
687683
fn _fastest_varying_stride_order(&self) -> Self {
688684
let mut stride = *self;

src/dimension/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ fn stride_offset_checked_arithmetic<D>(dim: &D, strides: &D, index: &D)
139139
}
140140

141141
/// Stride offset checked general version (slices)
142+
#[inline]
142143
pub fn stride_offset_checked(dim: &[Ix], strides: &[Ix], index: &[Ix]) -> Option<isize> {
143144
if index.len() != dim.len() {
144145
return None;

src/free_functions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub fn rcarr1<A: Clone>(xs: &[A]) -> RcArray<A, Ix1> {
6868

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

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

src/impl_owned_array.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
use std::rc::Rc;
33

44
use imp_prelude::*;
5+
use {
6+
OwnedRepr,
7+
OwnedRcRepr,
8+
};
59

6-
impl<A, D> ArrayBase<Vec<A>, D>
10+
impl<A, D> ArrayBase<OwnedRepr<A>, D>
711
where D: Dimension
812
{
913
/// Return a vector of the elements in the array, in the way they are
@@ -17,7 +21,7 @@ impl<A, D> ArrayBase<Vec<A>, D>
1721
}
1822

1923
// RcArray
20-
impl<A, D> ArrayBase<Rc<Vec<A>>, D>
24+
impl<A, D> ArrayBase<OwnedRcRepr<A>, D>
2125
where A: Clone,
2226
D: Dimension
2327
{

src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ pub struct ArrayBase<S, D>
504504
/// An array where the data has shared ownership and is copy on write.
505505
/// It can act as both an owner as the data as well as a shared reference (view
506506
/// like).
507-
pub type RcArray<A, D> = ArrayBase<Rc<Vec<A>>, D>;
507+
pub type RcArray<A, D> = ArrayBase<OwnedRcRepr<A>, D>;
508508

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

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

550+
/// Array's representation.
551+
type OwnedRepr<A> = Vec<A>;
552+
553+
/// RcArray's representation.
554+
type OwnedRcRepr<A> = Rc<Vec<A>>;
555+
550556
/// Array view’s representation.
551557
#[derive(Copy, Clone)]
552558
// This is just a marker type, to carry the lifetime parameter.

src/numeric/impl_numeric.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use numeric_util;
1515

1616
use {
1717
LinalgScalar,
18+
FoldWhile,
19+
Zip,
1820
};
1921

2022
/// Numerical methods for arrays.
@@ -124,8 +126,20 @@ impl<A, S, D> ArrayBase<S, D>
124126
S2: Data<Elem=A>,
125127
E: Dimension,
126128
{
127-
let rhs_broadcast = rhs.broadcast_unwrap(self.raw_dim());
128-
self.iter().zip(rhs_broadcast.iter()).all(|(x, y)| (*x - *y).abs() <= tol)
129+
let result =
130+
Zip::from(self)
131+
.and(rhs.broadcast_unwrap(self.raw_dim()))
132+
.fold_while((), |_, x, y| {
133+
if (*x - *y).abs() <= tol {
134+
FoldWhile::Continue(())
135+
} else {
136+
FoldWhile::Done(())
137+
}
138+
});
139+
match result {
140+
FoldWhile::Continue(_) => true,
141+
FoldWhile::Done(_) => false,
142+
}
129143
}
130144
}
131145

0 commit comments

Comments
 (0)