Skip to content

Commit f998c70

Browse files
authored
Merge pull request #291 from bluss/whole-chunks-mut
Add .whole_chunks_mut()
2 parents 6559364 + 4445e5a commit f998c70

File tree

12 files changed

+612
-223
lines changed

12 files changed

+612
-223
lines changed

benches/bench1.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,45 @@ fn add_2d_zip_cutout(bench: &mut test::Bencher)
348348
});
349349
}
350350

351+
#[bench]
352+
fn add_2d_cutouts_by_4(bench: &mut test::Bencher)
353+
{
354+
let mut a = Array::<i32, _>::zeros((64 * 1, 64 * 1));
355+
let b = Array::<i32, _>::zeros((64 * 1, 64 * 1));
356+
let chunksz = (4, 4);
357+
bench.iter(|| {
358+
Zip::from(a.whole_chunks_mut(chunksz))
359+
.and(b.whole_chunks(chunksz))
360+
.apply(|mut a, b| a += &b);
361+
});
362+
}
363+
364+
#[bench]
365+
fn add_2d_cutouts_by_16(bench: &mut test::Bencher)
366+
{
367+
let mut a = Array::<i32, _>::zeros((64 * 1, 64 * 1));
368+
let b = Array::<i32, _>::zeros((64 * 1, 64 * 1));
369+
let chunksz = (16, 16);
370+
bench.iter(|| {
371+
Zip::from(a.whole_chunks_mut(chunksz))
372+
.and(b.whole_chunks(chunksz))
373+
.apply(|mut a, b| a += &b);
374+
});
375+
}
376+
377+
#[bench]
378+
fn add_2d_cutouts_by_32(bench: &mut test::Bencher)
379+
{
380+
let mut a = Array::<i32, _>::zeros((64 * 1, 64 * 1));
381+
let b = Array::<i32, _>::zeros((64 * 1, 64 * 1));
382+
let chunksz = (32, 32);
383+
bench.iter(|| {
384+
Zip::from(a.whole_chunks_mut(chunksz))
385+
.and(b.whole_chunks(chunksz))
386+
.apply(|mut a, b| a += &b);
387+
});
388+
}
389+
351390
#[bench]
352391
fn add_2d_broadcast_1_to_2(bench: &mut test::Bencher)
353392
{

benches/chunks.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(test)]
2+
3+
extern crate test;
4+
use test::Bencher;
5+
6+
#[macro_use(azip)]
7+
extern crate ndarray;
8+
use ndarray::prelude::*;
9+
use ndarray::NdProducer;
10+
11+
#[bench]
12+
fn chunk2x2_sum(bench: &mut Bencher)
13+
{
14+
let a = Array::<f32, _>::zeros((256, 256));
15+
let chunksz = (2, 2);
16+
let mut sum = Array::zeros(a.whole_chunks(chunksz).raw_dim());
17+
bench.iter(|| {
18+
azip!(ref a (a.whole_chunks(chunksz)), mut sum in {
19+
*sum = a.iter().sum::<f32>();
20+
});
21+
});
22+
}
23+
24+
#[bench]
25+
fn chunk2x2_scalar_sum(bench: &mut Bencher)
26+
{
27+
let a = Array::<f32, _>::zeros((256, 256));
28+
let chunksz = (2, 2);
29+
let mut sum = Array::zeros(a.whole_chunks(chunksz).raw_dim());
30+
bench.iter(|| {
31+
azip!(ref a (a.whole_chunks(chunksz)), mut sum in {
32+
*sum = a.scalar_sum();
33+
});
34+
});
35+
}

src/arrayformat.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use super::{
1010
ArrayBase,
1111
Data,
1212
Dimension,
13+
NdProducer,
1314
};
1415
use dimension::IntoDimension;
1516

@@ -109,7 +110,8 @@ impl<'a, A: fmt::Debug, S, D: Dimension> fmt::Debug for ArrayBase<S, D>
109110
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110111
// Add extra information for Debug
111112
try!(format_array(self, f, <_>::fmt));
112-
try!(write!(f, " shape={:?}, strides={:?}", self.shape(), self.strides()));
113+
try!(write!(f, " shape={:?}, strides={:?}, layout={:?}",
114+
self.shape(), self.strides(), layout=self.view().layout()));
113115
Ok(())
114116
}
115117
}

src/impl_methods.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use super::zipsl;
2222
use super::ZipExt;
2323
use dimension::IntoDimension;
2424
use dimension::{axes_of, Axes, merge_axes, stride_offset};
25-
use iterators::whole_chunks_of;
2625
use iterators::{
2726
new_inner_iter_smaller,
2827
new_inner_iter_smaller_mut,
28+
whole_chunks_of,
29+
whole_chunks_mut_of,
2930
};
3031

3132
use {
@@ -41,6 +42,7 @@ use {
4142
AxisIter,
4243
AxisIterMut,
4344
WholeChunks,
45+
WholeChunksMut,
4446
};
4547
use stacking::stack;
4648

@@ -619,15 +621,57 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
619621
/// It produces the whole chunks of a given n-dimensional chunk size,
620622
/// skipping the remainder along each dimension that doesn't fit evenly.
621623
///
622-
/// Iterator element is `ArrayView<A, D>`
624+
/// The produced element is a `ArrayView<A, D>` with exactly the dimension
625+
/// `chunk_size`.
623626
///
624-
/// **Panics** if any dimension of `chunk_size` is zero
627+
/// **Panics** if any dimension of `chunk_size` is zero<br>
628+
/// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
629+
/// number of array axes.)
625630
pub fn whole_chunks<E>(&self, chunk_size: E) -> WholeChunks<A, D>
626631
where E: IntoDimension<Dim=D>,
627632
{
628633
whole_chunks_of(self.view(), chunk_size)
629634
}
630635

636+
/// Return a whole chunks producer (and iterable).
637+
///
638+
/// It produces the whole chunks of a given n-dimensional chunk size,
639+
/// skipping the remainder along each dimension that doesn't fit evenly.
640+
///
641+
/// The produced element is a `ArrayViewMut<A, D>` with exactly
642+
/// the dimension `chunk_size`.
643+
///
644+
/// **Panics** if any dimension of `chunk_size` is zero<br>
645+
/// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
646+
/// number of array axes.)
647+
///
648+
/// ```rust
649+
/// use ndarray::Array;
650+
/// use ndarray::arr2;
651+
/// let mut a = Array::zeros((6, 7));
652+
///
653+
/// // Fill each 2 × 2 chunk with the index of where it appeared in iteration
654+
/// for (i, mut chunk) in a.whole_chunks_mut((2, 2)).into_iter().enumerate() {
655+
/// chunk.fill(i);
656+
/// }
657+
///
658+
/// // The resulting array is:
659+
/// assert_eq!(
660+
/// a,
661+
/// arr2(&[[0, 0, 1, 1, 2, 2, 0],
662+
/// [0, 0, 1, 1, 2, 2, 0],
663+
/// [3, 3, 4, 4, 5, 5, 0],
664+
/// [3, 3, 4, 4, 5, 5, 0],
665+
/// [6, 6, 7, 7, 8, 8, 0],
666+
/// [6, 6, 7, 7, 8, 8, 0]]));
667+
/// ```
668+
pub fn whole_chunks_mut<E>(&mut self, chunk_size: E) -> WholeChunksMut<A, D>
669+
where E: IntoDimension<Dim=D>,
670+
S: DataMut
671+
{
672+
whole_chunks_mut_of(self.view_mut(), chunk_size)
673+
}
674+
631675
// Return (length, stride) for diagonal
632676
fn diag_params(&self) -> (Ix, Ixs) {
633677
/* empty shape has len 1 */

src/impl_views.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a A>, D>
7575
ArrayView::new_(ptr, dim, strides)
7676
}
7777

78-
/// Split the array along `axis` and return one view strictly before the
78+
/// Split the array view along `axis` and return one view strictly before the
7979
/// split and one view after the split.
8080
///
8181
/// **Panics** if `axis` or `index` is out of bounds.
@@ -190,7 +190,7 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D>
190190
ArrayViewMut::new_(ptr, dim, strides)
191191
}
192192

193-
/// Split the array along `axis` and return one mutable view strictly
193+
/// Split the array view along `axis` and return one mutable view strictly
194194
/// before the split and one mutable view after the split.
195195
///
196196
/// **Panics** if `axis` or `index` is out of bounds.

0 commit comments

Comments
 (0)