Skip to content
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

Slice ModelArrays #735

Open
17 tasks done
timspainNERSC opened this issue Nov 14, 2024 · 7 comments · May be fixed by #736
Open
17 tasks done

Slice ModelArrays #735

timspainNERSC opened this issue Nov 14, 2024 · 7 comments · May be fixed by #736
Assignees
Labels
enhancement New feature or request

Comments

@timspainNERSC
Copy link
Collaborator

timspainNERSC commented Nov 14, 2024

Both advection (#99) and the halo regions needed for MPI (#132) require moving around subsets of ModelArray data. A unified slicing class/library to provide a common interface would be a useful addition to the model.

  • Create a Slice class
  • Create a class to iterate through a Slice
  • Implement basic indexing
  • Implement 'rest of the array' arguments (what would be written as [::2] in Python).
  • Implement reverse steps
  • Throw an exception when passed a step value of zero
  • Implement negative indices
  • Implement iterator equality
  • Implement the standard start and end iterators
    - [ ] Implement the standard rstart and rend iterators
  • Create a class that gives access to a slice of a ModelArray
  • Assign a scalar to a slice of a ModelArray.
  • Assign one slice of a ModelArray to another.
  • Assign a slice of one ModelArray to the entirety of another
  • Assign the entirety of one ModelArray to a slice of another
  • Assign a buffer (standard container?) to a slice
  • Assign a slice to a buffer (standard container?)
  • Doxygen comments
@timspainNERSC timspainNERSC added the enhancement New feature or request label Nov 14, 2024
@timspainNERSC timspainNERSC added this to the 3 Stand-alone model milestone Nov 14, 2024
@timspainNERSC timspainNERSC self-assigned this Nov 14, 2024
@timspainNERSC timspainNERSC moved this from Todo to In Progress in neXtSIM_DG overview Nov 14, 2024
@timspainNERSC
Copy link
Collaborator Author

Currently in progress on the branch slicer.

@TomMelt
Copy link
Contributor

TomMelt commented Nov 14, 2024

maybe 106445222 assertions is a bit overkill.

image

Could we reduce the size/dimensionality of this test case?

Slice elements8d {{{2, 6}, {4, 9}, {6, 12}, {8, 15}, {10, 18}, {12, 21}, {14, 24}, {16, 27}}};
std::vector<size_t> ni = { 7, 12, 13, 16, 30, 30, 30, 30};
Slice::SliceIter iter8d(elements8d, ni);
count = 0;
const size_t expt = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4;
while (!iter8d.isEnd()) {
auto loc = Indexer::deIndexer(ni, iter8d.index());
for (size_t dim = 0; dim < ni.size(); ++dim) {
REQUIRE(loc[dim] >= elements8d.bounds[dim].start);
REQUIRE(loc[dim] < elements8d.bounds[dim].stop);
}
++iter8d;
++count;

@TomMelt
Copy link
Contributor

TomMelt commented Nov 14, 2024

Thanks for sharing this branch @timspainNERSC. This will be super helpful.

I had a quick look and maybe I missed it. Is it possible to get the elements from a 1D slice back as a array/vector? possibly a std::array would be most sensible for my use case.

@timspainNERSC
Copy link
Collaborator Author

maybe 106445222 assertions is a bit overkill.

image

Could we reduce the size/dimensionality of this test case?

Slice elements8d {{{2, 6}, {4, 9}, {6, 12}, {8, 15}, {10, 18}, {12, 21}, {14, 24}, {16, 27}}};
std::vector<size_t> ni = { 7, 12, 13, 16, 30, 30, 30, 30};
Slice::SliceIter iter8d(elements8d, ni);
count = 0;
const size_t expt = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4;
while (!iter8d.isEnd()) {
auto loc = Indexer::deIndexer(ni, iter8d.index());
for (size_t dim = 0; dim < ni.size(); ++dim) {
REQUIRE(loc[dim] >= elements8d.bounds[dim].start);
REQUIRE(loc[dim] < elements8d.bounds[dim].stop);
}
++iter8d;
++count;

😒
I do want a test that examines a high dimensionality array, but I can arrange the test so that there are fewer assertions. I GUESS.

@timspainNERSC
Copy link
Collaborator Author

Thanks for sharing this branch @timspainNERSC. This will be super helpful.

I had a quick look and maybe I missed it. Is it possible to get the elements from a 1D slice back as a array/vector? possibly a std::array would be most sensible for my use case.

Next on the TODO list. I should write that i the issue 🤔

@timspainNERSC
Copy link
Collaborator Author

timspainNERSC commented Nov 15, 2024

maybe 106445222 assertions is a bit overkill.
image
Could we reduce the size/dimensionality of this test case?

Slice elements8d {{{2, 6}, {4, 9}, {6, 12}, {8, 15}, {10, 18}, {12, 21}, {14, 24}, {16, 27}}};
std::vector<size_t> ni = { 7, 12, 13, 16, 30, 30, 30, 30};
Slice::SliceIter iter8d(elements8d, ni);
count = 0;
const size_t expt = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4;
while (!iter8d.isEnd()) {
auto loc = Indexer::deIndexer(ni, iter8d.index());
for (size_t dim = 0; dim < ni.size(); ++dim) {
REQUIRE(loc[dim] >= elements8d.bounds[dim].start);
REQUIRE(loc[dim] < elements8d.bounds[dim].stop);
}
++iter8d;
++count;

😒 I do want a test that examines a high dimensionality array, but I can arrange the test so that there are fewer assertions. I GUESS.

${\textsf{\color{lightblue}[doctest]}}$ doctest version is "2.4.11"
$${\textsf{\color{lightblue}[doctest]}}$$ run with "--help" for options
$${\textsf{\color{dandelion}===============================================================================}}$$
$${\textsf{\color{lightblue}[doctest]}}$$ test cases: 4 | $${\textsf{\color{green} 4 passed}}$$ | $${\textsf{\color{black}0 failed}}$$ | $${\textsf{\color{black}0 skipped}}$$
$${\textsf{\color{lightblue}[doctest] }}$$ assertions: 423 | $${\textsf{\color{green}423 passed}}$$ | $${\textsf{\color{black}0 failed}}$$ |
$${\textsf{\color{lightblue}[doctest]}}$$ Status: $${\textsf{\color{green}SUCCESS!}}$$

but also

             if (!message.empty()) goto end8d;

😎

@timspainNERSC
Copy link
Collaborator Author

timspainNERSC commented Nov 18, 2024

How numpy behaves with a range of positive, 0, negative and absent indices. The test array a has 12 elements, where the value at each index is equal to the index.

Step = 1 (or absent)

stop value start < 0 start = 0 start > 0 (absent)
Large -ve a[-6:-16]=[] a[0:-16]=[] a[6:-16]=[] a[:-16]=[]
-length a[-6:-12]=[] a[0:-12]=[] a[6:-12]=[] a[:-12]=[]
-ve > start a[-6:-8]=[] a[0:-8]=[0,..,3] a[6:-8]=[] a[:-8]=[0,..,3]
-ve < start a[-6:-4]=[6,7] N/A a[6:-4]=[6,7] N/A
0 a[-6:0]=[] a[0:0]=[] a[6:0]=[] a[:0]=[]
+ve < start a[-6:4]=[] N/A a[6:4]=[] N/A
+ve > start a[-6:8]=[6,7] a[0:8]=[0,..,7] a[6:8]=[6,7] a[:8]=[0,..7]
length a[-6:12]=[6,..,11] a[0:12]=[0,..,11] a[6:12]=[6,..,11] a[:12]=[0,..,11]
large +ve a[-6:16]=[6,..,11] a[0:16]=[0,..,11] a[6:16]=[6,..,11] a[:16]=[0,..,11]
absent a[-6:]=[6,..,11] a[0:]=[0,..,11] a[6:]=[6,..,11] a[:]=[0,..,11]

step = 0

Causes an exception to be thrown.

Step = -1

stop value start < 0 start = 0 start > 0 (absent)
Large -ve a[-6:-16:-1]=[6,..,0] a[0:-16:-1]=[0] a[6:-16:-1]=[6,..,0] a[:-16:-1]=[11,..,0]
-length a[-6:-12:-1]=[6,..,1] a[0:-12:-1]=[] a[6:-12:-1]=[6,..,1] a[:-12:-1]=[11,..,1]
-ve > start a[-6:-8:-1]=[6,5] a[0:-8:-1]=[] a[6:-8:-1]=[6,5] a[:-8:-1]=[11,..,5]
-ve < start a[-6:-4:-1]=[] N/A a[6:-4:-1]=[] N/A
0 a[-6:0:-1]=[6,..,1] a[0:0:-1]=[] a[6:0:-1]=[6,..,1] a[:0:-1]=[11,..,1]
+ve < start a[-6:4:-1]=[6,5] N/A a[6:4:-1]=[6,5] N/A
+ve > start a[-6:8-1]=[] a[0:8:-1]=[] a[6:8:-1]=[6,7] a[:8:-1]=[11,..,9]
length a[-6:12:-1]=[] a[0:12:-1]=[] a[6:12:-1]=[] a[:12:-1]=[]
large +ve a[-6:16:-1]=[] a[0:16:-1]=[] a[6:16:-1]=[] a[:16:-1]=[]
absent a[-6::-1]=[6,..,0] a[0::-1]=[0] a[6::-1]=[6,..,0] a[::-1]=[11,..,0]

|step| > 1

Larger step sizes behave as expected, stepping the defined number of values from the same start index.

@timspainNERSC timspainNERSC linked a pull request Nov 18, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: In Progress
Development

Successfully merging a pull request may close this issue.

2 participants