Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
Status: In Progress
Development

Successfully merging a pull request may close this issue.

2 participants