Skip to content

IPPL doesn't consistently consider striding in indexes #502

@NickvonWit

Description

@NickvonWit

IPPL Indexes support strides. However, a lot of the codebase just assumes stride 1.
This happens all over the place. Even within the class itself. For example:

In /src/Index/Index.hpp:

ippl/src/Index/Index.hpp

Lines 154 to 160 in c2ec8aa

KOKKOS_INLINE_FUNCTION bool Index::touches(const Index& a) const {
return (min() <= a.max()) && (max() >= a.min());
}
KOKKOS_INLINE_FUNCTION bool Index::contains(const Index& a) const {
return (min() <= a.min()) && (max() >= a.max());
}

For example, ⁠Index(0, 10, 2) represents ⁠{0, 2, 4, 6, 8, 10} and ⁠Index(1, 9, 2) represents ⁠{1, 3, 5, 7, 9}. Their ⁠min()/⁠max() ranges overlap ⁠[0,10] vs ⁠[1,9], but they share zero elements. ⁠touches() returns ⁠true and ⁠contains() returns ⁠true, both incorrectly.

ippl/src/Index/Index.hpp

Lines 261 to 269 in c2ec8aa

KOKKOS_INLINE_FUNCTION Index Index::grow(int ncells) const {
Index index;
index.first_m = this->first_m - ncells;
index.length_m = this->length_m + 2 * ncells;
index.stride_m = this->stride_m;
return index;
}

This should multiply ncells by stride before shifting first_m.

In src/Field/BcTypes.hpp:

ippl/src/Field/BcTypes.hpp

Lines 219 to 230 in c2ec8aa

int offset, offsetRecv, matchtag;
if (face & 1) {
// upper face
offset = -domain[d].length();
offsetRecv = nghost;
matchtag = comm.preceding_tag(mpi::tag::BC_PARALLEL_PERIODIC);
} else {
// lower face
offset = domain[d].length();
offsetRecv = -nghost;
matchtag = comm.following_tag(mpi::tag::BC_PARALLEL_PERIODIC);
}

There are many places where calculations break because of the assumption that lenght() == size(). Obviously, using a strided index, this does not hold anymore.

ippl/src/Field/BcTypes.hpp

Lines 255 to 258 in c2ec8aa

for (size_t j = 0; j < Dim; ++j) {
range.lo[j] = overlap[j].first() - nd[j].first() + nghost;
range.hi[j] = overlap[j].last() - nd[j].first() + nghost + 1;
}

Calculations like this should become this:
https://github.com/NickvonWit/ippl/blob/a8c423af24d4f3e2dc15edad512ba38ad0c044ed/src/Field/BcTypes.hpp#L257-L262

for (size_t j = 0; j < Dim; ++j) {
    const int stride = nd[j].stride();

    range.lo[j] = (overlap[j].first() - nd[j].first()) / stride + nghost;
    range.hi[j] = (overlap[j].last() - nd[j].first()) / stride + nghost + 1;
}

There are many other parts of the codebase that have this issue.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions