Skip to content

Commit

Permalink
Add ArraySubset::new_with_ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
LDeakin committed Dec 24, 2023
1 parent 3d590fc commit a3472f4
Show file tree
Hide file tree
Showing 19 changed files with 91 additions and 97 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Adds generic `StoreLocks`, `StoreKeyMutex`, and `StoreKeyMutexGuard` with associated traits and async variants
- Includes `DefaultStoreLocks` and `DisabledStoreLocks` implementations
- Readable and writable stores include a `new_with_locks` method to choose the store lock implementation
- Added `ArraySubset::new_with_ranges`

### Changed
- **Breaking** `ReadableStorageTraits` is no longer a supertrait of `WritableStorageTraits`
Expand Down
10 changes: 5 additions & 5 deletions examples/array_write_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {

// Write a subset spanning multiple chunks, including updating chunks already written
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![3, 3], vec![3, 3]).unwrap(),
&ArraySubset::new_with_ranges(&[3..6, 3..6]),
vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
)?;

// Store elements directly, in this case set the 7th column to 123.0
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![0, 6], vec![8, 1])?,
&ArraySubset::new_with_ranges(&[0..8, 6..7]),
vec![123.0; 8],
)?;

Expand All @@ -90,15 +90,15 @@ fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
// chunk indices
&[1, 1],
// subset within chunk
&ArraySubset::new_with_start_shape(vec![3, 0], vec![1, 4])?,
&ArraySubset::new_with_ranges(&[3..4, 0..4]),
vec![-4.0; 4],
)?;

// Erase a chunk
array.erase_chunk(&[0, 1])?;

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset_ndarray::<f32>(&subset_all)?;
println!("The whole array is:\n{:?}\n", data_all);

Expand All @@ -108,7 +108,7 @@ fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<f32>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{:?}\n", data_4x2);

Expand Down
10 changes: 5 additions & 5 deletions examples/async_array_write_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
// Write a subset spanning multiple chunks, including updating chunks already written
array
.async_store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![3, 3], vec![3, 3]).unwrap(),
&ArraySubset::new_with_ranges(&[3..6, 3..6]),
vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
)
.await?;

// Store elements directly, in this case set the 7th column to 123.0
array
.async_store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![0, 6], vec![8, 1])?,
&ArraySubset::new_with_ranges(&[0..8, 6..7]),
vec![123.0; 8],
)
.await?;
Expand All @@ -102,7 +102,7 @@ async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
// chunk indices
&[1, 1],
// subset within chunk
&ArraySubset::new_with_start_shape(vec![3, 0], vec![1, 4])?,
&ArraySubset::new_with_ranges(&[3..4, 0..4]),
vec![-4.0; 4],
)
.await?;
Expand All @@ -111,7 +111,7 @@ async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
array.async_erase_chunk(&[0, 1]).await?;

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array
.async_retrieve_array_subset_ndarray::<f32>(&subset_all)
.await?;
Expand All @@ -125,7 +125,7 @@ async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array
.async_retrieve_array_subset_ndarray::<f32>(&subset_4x2)
.await?;
Expand Down
4 changes: 2 additions & 2 deletions examples/async_http_array_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn http_array_read() -> Result<(), Box<dyn std::error::Error>> {
);

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array
.async_retrieve_array_subset_ndarray::<f32>(&subset_all)
.await?;
Expand All @@ -48,7 +48,7 @@ async fn http_array_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array
.async_retrieve_array_subset_ndarray::<f32>(&subset_4x2)
.await?;
Expand Down
4 changes: 2 additions & 2 deletions examples/http_array_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn http_array_read() -> Result<(), Box<dyn std::error::Error>> {
);

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset_ndarray::<f32>(&subset_all)?;
println!("The whole array is:\n{:?}\n", data_all);

Expand All @@ -44,7 +44,7 @@ fn http_array_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<f32>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{:?}\n", data_4x2);

Expand Down
8 changes: 4 additions & 4 deletions examples/rectangular_array_write_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn rectangular_array_write_read() -> Result<(), Box<dyn std::error::Error>> {

// Store elements directly, in this case set the 7th column to 123.0
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![0, 6], vec![8, 1])?,
&ArraySubset::new_with_ranges(&[0..8, 6..7]),
vec![123.0; 8],
)?;

Expand All @@ -95,12 +95,12 @@ fn rectangular_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
// chunk indices
&[3, 1],
// subset within chunk
&ArraySubset::new_with_start_shape(vec![1, 0], vec![1, 4])?,
&ArraySubset::new_with_ranges(&[1..2, 0..4]),
vec![-4.0; 4],
)?;

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset_ndarray::<f32>(&subset_all)?;
println!("The whole array is:\n{:?}\n", data_all);

Expand All @@ -110,7 +110,7 @@ fn rectangular_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<f32>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{:?}\n", data_4x2);

Expand Down
6 changes: 3 additions & 3 deletions examples/sharded_array_write_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
})?;

// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?; // the center 4x2 region
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec()); // the center 4x2 region
let data_all = array.retrieve_array_subset_ndarray::<u16>(&subset_all)?;
println!("The whole array is:\n{:?}\n", data_all);

Expand All @@ -104,12 +104,12 @@ fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
println!("Shard [1,0] is:\n{data_shard:?}\n");

// Read an inner chunk from the store
let subset_chunk_1_0 = ArraySubset::new_with_start_shape(vec![4, 0], vec![4, 4])?;
let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
let data_chunk = array.retrieve_array_subset_ndarray::<u16>(&subset_chunk_1_0)?;
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<u16>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{:?}\n", data_4x2);

Expand Down
10 changes: 5 additions & 5 deletions examples/zip_array_write_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ fn write_array_to_storage<TStorage: ReadableWritableStorageTraits>(

// Write a subset spanning multiple chunks, including updating chunks already written
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![3, 3], vec![3, 3]).unwrap(),
&ArraySubset::new_with_ranges(&[3..6, 3..6]),
vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
)?;

// Store elements directly, in this case set the 7th column to 123.0
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![0, 6], vec![8, 1])?,
&ArraySubset::new_with_ranges(&[0..8, 6..7]),
vec![123.0; 8],
)?;

Expand All @@ -80,7 +80,7 @@ fn write_array_to_storage<TStorage: ReadableWritableStorageTraits>(
// chunk indices
&[1, 1],
// subset within chunk
&ArraySubset::new_with_start_shape(vec![3, 0], vec![1, 4])?,
&ArraySubset::new_with_ranges(&[3..4, 0..4]),
vec![-4.0; 4],
)?;

Expand All @@ -91,7 +91,7 @@ fn read_array_from_store<TStorage: ReadableStorageTraits>(
array: Array<TStorage>,
) -> Result<(), Box<dyn std::error::Error>> {
// Read the whole array
let subset_all = ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec())?;
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset_ndarray::<f32>(&subset_all)?;
println!("The whole array is:\n{:?}\n", data_all);

Expand All @@ -101,7 +101,7 @@ fn read_array_from_store<TStorage: ReadableStorageTraits>(
println!("Chunk [1,0] is:\n{data_chunk:?}\n");

// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_start_shape(vec![2, 3], vec![4, 2])?; // the center 4x2 region
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<f32>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{:?}\n", data_4x2);

Expand Down
10 changes: 4 additions & 6 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,13 +706,12 @@ mod tests {

array
.store_array_subset_elements::<f32>(
&ArraySubset::new_with_start_shape(vec![3, 3], vec![3, 3]).unwrap(),
&ArraySubset::new_with_ranges(&[3..6, 3..6]),
vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
)
.unwrap();

let subset_all =
ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec()).unwrap();
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array
.retrieve_array_subset_elements::<f32>(&subset_all)
.unwrap();
Expand Down Expand Up @@ -750,11 +749,10 @@ mod tests {
let mut any_not_equal = false;
for j in 1..10 {
(0..100).into_par_iter().for_each(|i| {
let subset = ArraySubset::new_with_start_shape(vec![i, 0], vec![1, 4]).unwrap();
let subset = ArraySubset::new_with_ranges(&[i..i + 1, 0..4]);
array.store_array_subset(&subset, vec![j; 4]).unwrap();
});
let subset_all =
ArraySubset::new_with_start_shape(vec![0, 0], array.shape().to_vec()).unwrap();
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset(&subset_all).unwrap();
let all_equal = data_all.iter().all_equal_value() == Ok(&j);
if expect_equal {
Expand Down
11 changes: 5 additions & 6 deletions src/array/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,7 @@ mod tests {
#[test]
fn test_array_subset_iterator1() {
let array_shape = vec![2, 2];
let array_subset = ArraySubset::new_with_start_shape(vec![0, 0], vec![2, 1]).unwrap();
let array_subset = ArraySubset::new_with_shape(vec![2, 1]);
let mut iter = array_subset.iter_contiguous_indices(&array_shape).unwrap();

assert_eq!(iter.next().unwrap(), (vec![0, 0], 1));
Expand All @@ -1102,7 +1102,7 @@ mod tests {
#[test]
fn test_array_subset_iterator2() {
let array_shape = vec![2, 2];
let array_subset = ArraySubset::new_with_start_shape(vec![1, 0], vec![1, 2]).unwrap();
let array_subset = ArraySubset::new_with_ranges(&[1..2, 0..2]);
let mut iter = array_subset.iter_contiguous_indices(&array_shape).unwrap();

assert_eq!(iter.next().unwrap(), (vec![1, 0], 2));
Expand All @@ -1112,7 +1112,7 @@ mod tests {
#[test]
fn test_array_subset_iterator3() {
let array_shape = vec![2, 2];
let array_subset = ArraySubset::new_with_start_shape(vec![0, 0], vec![2, 2]).unwrap();
let array_subset = ArraySubset::new_with_shape(vec![2, 2]);
let mut iter = array_subset.iter_contiguous_indices(&array_shape).unwrap();

assert_eq!(iter.next().unwrap(), (vec![0, 0], 4));
Expand All @@ -1122,8 +1122,7 @@ mod tests {
#[test]
fn test_array_subset_iterator4() {
let array_shape = vec![2, 2, 2, 3];
let array_subset =
ArraySubset::new_with_start_shape(vec![0, 0, 0, 0], vec![2, 1, 2, 3]).unwrap();
let array_subset = ArraySubset::new_with_shape(vec![2, 1, 2, 3]);
let mut iter = array_subset.iter_contiguous_indices(&array_shape).unwrap();

assert_eq!(iter.next().unwrap(), (vec![0, 0, 0, 0], 6));
Expand All @@ -1134,7 +1133,7 @@ mod tests {
#[test]
fn test_array_subset_iterator5() {
let array_shape = vec![2, 2, 3];
let array_subset = ArraySubset::new_with_start_shape(vec![0, 0, 1], vec![2, 2, 2]).unwrap();
let array_subset = ArraySubset::new_with_ranges(&[0..2, 0..2, 1..3]);
let mut iter = array_subset.iter_contiguous_indices(&array_shape).unwrap();

assert_eq!(iter.next().unwrap(), (vec![0, 0, 1], 2));
Expand Down
4 changes: 2 additions & 2 deletions src/array/codec/array_to_array/bitround.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ mod tests {

let encoded = codec.encode(bytes.clone(), &array_representation).unwrap();
let decoded_regions = [
ArraySubset::new_with_start_shape(vec![3], vec![2]).unwrap(),
ArraySubset::new_with_start_shape(vec![17], vec![4]).unwrap(),
ArraySubset::new_with_ranges(&[3..5]),
ArraySubset::new_with_ranges(&[17..21]),
];
let input_handle = Box::new(std::io::Cursor::new(encoded));
let bytes_codec = BytesCodec::default();
Expand Down
3 changes: 1 addition & 2 deletions src/array/codec/array_to_bytes/codec_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,7 @@ mod tests {
let codec = CodecChain::from_metadata(&codec_configurations).unwrap();

let encoded = codec.encode(bytes, &array_representation).unwrap();
let decoded_regions =
[ArraySubset::new_with_start_shape(vec![0, 1, 0], vec![2, 1, 1]).unwrap()];
let decoded_regions = [ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1])];
let input_handle = Box::new(std::io::Cursor::new(encoded));
let partial_decoder = codec
.partial_decoder(input_handle, &array_representation)
Expand Down
7 changes: 3 additions & 4 deletions src/array/codec/array_to_bytes/sharding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ mod tests {
let codec = ShardingCodec::new_with_configuration(&codec_configuration).unwrap();

let encoded = codec.encode(bytes, &array_representation).unwrap();
let decoded_regions = [ArraySubset::new_with_start_shape(vec![1, 0], vec![2, 1]).unwrap()];
let decoded_regions = [ArraySubset::new_with_ranges(&[1..3, 0..1])];
let input_handle = Box::new(std::io::Cursor::new(encoded));
let partial_decoder = codec
.partial_decoder(input_handle, &array_representation)
Expand Down Expand Up @@ -305,8 +305,7 @@ mod tests {
let codec = ShardingCodec::new_with_configuration(&codec_configuration).unwrap();

let encoded = codec.encode(bytes, &array_representation).unwrap();
let decoded_regions =
[ArraySubset::new_with_start_shape(vec![1, 0, 0], vec![1, 2, 3]).unwrap()];
let decoded_regions = [ArraySubset::new_with_ranges(&[1..2, 0..2, 0..3])];
let input_handle = Box::new(std::io::Cursor::new(encoded));
let partial_decoder = codec
.partial_decoder(input_handle, &array_representation)
Expand Down Expand Up @@ -337,7 +336,7 @@ mod tests {
let codec = ShardingCodec::new_with_configuration(&codec_configuration).unwrap();

let encoded = codec.encode(bytes, &array_representation).unwrap();
let decoded_regions = [ArraySubset::new_with_start_shape(vec![1, 0], vec![2, 1]).unwrap()];
let decoded_regions = [ArraySubset::new_with_ranges(&[1..3, 0..1])];
let input_handle = Box::new(std::io::Cursor::new(encoded));
let partial_decoder = codec
.partial_decoder(input_handle, &array_representation)
Expand Down
6 changes: 2 additions & 4 deletions src/array/codec/array_to_bytes/zfp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,8 @@ mod tests {

let encoded = codec.encode(bytes.clone(), &array_representation).unwrap();
let decoded_regions = [
ArraySubset::new_with_start_shape((&[0, 0, 0]).to_vec(), (&[1, 2, 3]).to_vec())
.unwrap(),
ArraySubset::new_with_start_shape((&[0, 1, 2]).to_vec(), (&[3, 2, 1]).to_vec())
.unwrap(),
ArraySubset::new_with_shape(vec![1, 2, 3]),
ArraySubset::new_with_ranges(&[0..3, 1..3, 2..3]),
];

let input_handle = Box::new(std::io::Cursor::new(encoded));
Expand Down
14 changes: 6 additions & 8 deletions src/array/codec/bytes_to_bytes/blosc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,12 @@ mod tests {
let codec = BloscCodec::new_with_configuration(&codec_configuration).unwrap();

let encoded = codec.encode(bytes).unwrap();
let decoded_regions: Vec<ByteRange> =
ArraySubset::new_with_start_shape(vec![0, 1, 0], vec![2, 1, 1])
.unwrap()
.byte_ranges(
array_representation.shape(),
array_representation.element_size(),
)
.unwrap();
let decoded_regions: Vec<ByteRange> = ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1])
.byte_ranges(
array_representation.shape(),
array_representation.element_size(),
)
.unwrap();
let input_handle = Box::new(std::io::Cursor::new(encoded));
let partial_decoder = codec
.partial_decoder(input_handle, &bytes_representation)
Expand Down
Loading

0 comments on commit a3472f4

Please sign in to comment.