-
Notifications
You must be signed in to change notification settings - Fork 38
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
Add example for 2D triangle-point intersection #542
Conversation
I'm deeply confused about the purpose of this PR and its relationship to XGC. In my understanding, XGC would require calling tree traversal individually from each thread, with no collaboration. This PR seems to still assume that there's a place in XGC where all thread are able to launch the search at the same time. I thought that instead the API for I may be missing something here. Also, this PR tries to do too many things simultaneously, and should be split in multiple, like the part touching the core (with the addition of unit testing) and adding an example. |
This is a draft showing my current progress. |
I'm happy to discuss why this approach might or might not work. |
based on the code written in arborx#542
80f824b
to
d7e7f3a
Compare
This should now be in decent shape to be reviewed again. As opposed to the initial approach, we now run a "classical" batched query. |
We only see |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Global comments:
- Template on
MemorySpace
, notDeviceType
- Use
_blah
instead ofblah_
for class member variables - Prefix all views and kernels with
Example::
I'd like to think whether #915 makes this easier. If we construct a hierarchy on triangles, how do we get the performance out of it? Would not having Mapping
stored significantly affect the performance? It seems to do a few calculations, is it worth storing?
ExecutionSpace execution_space; | ||
|
||
std::cout << "Create grid with triangles.\n"; | ||
Triangles<DeviceType> triangles(execution_space); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice if we have a parameter n
in main()
for the number of triangles. Could be constexpr.
ArborX::BasicBoundingVolumeHierarchy< | ||
MemorySpace, ArborX::Details::PairIndexVolume< | ||
ArborX::ExperimentalHyperGeometry::Box<2>>> const | ||
tree(execution_space, triangles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#915 will affect this. We would want to construct the hierarchy based on triangles. However, not sure how mapping plays into this. Ideally, would want to do an intersection of a triangle with a point within ArborX without and extra data. Is that much slower?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be very difficult to derive a variant or adapt once #915 is merged.
std::cout << "BVH tree set up.\n"; | ||
|
||
std::cout << "Create the points used for queries.\n"; | ||
Points<DeviceType> points(execution_space); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provide a parameter with the number of points.
Kokkos::View<int *, MemorySpace> offsets("offsets", n); | ||
Kokkos::View<ArborX::Point *, MemorySpace> coefficients("coefficients", n); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you distinguish whether intersection was found or not? The default values for these views are indistinguishable for the wrong ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Debug
mode we run a full test checking that we detected the expected intersections and get the correct coefficients.
c832b01
to
8b108ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to have NDEBUG (except for the final one checking the results) and print outs removed (print outs may be replaced by leading comments).
I think it would work well if you have them in one of the commits in history to be able to easily restore the code, but they add a bulk to the example. If we want a user to read easily, we want to make it as short as possible.
if (intersects) | ||
{ | ||
_offsets(query_index) = primitive.index; | ||
_coefficients(query_index) = coeffs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we store coefficients? Is that because the problem we consider is interpolation? I don't remember what XGC or the like want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. In my opinion, this is one of the points of this example.
Kokkos::parallel_for( | ||
Kokkos::RangePolicy<ExecutionSpace>(execution_space, 0, n), | ||
KOKKOS_LAMBDA(int i) { | ||
constexpr float eps = 1.e-3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How was this eps chosen? What happens with smaller values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, this was about the magnitude I needed to pass CI.
Here you go! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this seems ok
There's one thing that I'm pretty uncomfortable with in the current version. Suppose, I'm a user that wants to solve this problem. Why should I care about the mapping? What I really want is to have a set of triangles, and a set of points, and get the results. I wouldn't want to be concerned about constructing some mapping, passing it in, or something. Ideally, it would be as simple as
auto bvh = BVH(space, triangles); // for example, a Kokkos::View<Triangle*, MemorySpace>
bvh.query(space, points_intersect, callback); // with callback being called only on the positive match
So I wonder about it. How much performance do we lose if we compute coefficients alpha and beta inside the callback? Is there a way for us to avoid that?
Currently, while it may be efficient, the example's interface is not self contained, and requires a lot of work from the user. I think it is important to keep simple things simple, while allowing the flexibility for a user to get the performance out with some effort.
I also noticed that |
Co-authored-by: Andrey Prokopenko <andrey.prok@gmail.com>
Co-authored-by: Andrey Prokopenko <andrey.prok@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the understanding of major simplification after APIv2 is finalized.
0630794
to
ed51b2e
Compare
I made a crack at what the example would look like in APIv2 (without mapping) here. I think it would be much cleaner and shorter. There's a question of how to not repeat the calculations, though. |
Sure. |
This should be useful for
XGC
. In particular, this pull request separatesTreeTraversal
construction and actually running the search allowing applications to use theTreeTraversal
class in their ownKokkos
kernels.