Update mpas_kd_tree.F to break ties on equidistant queries#630
Update mpas_kd_tree.F to break ties on equidistant queries#630mgduda merged 1 commit intoMPAS-Dev:developfrom
Conversation
|
I have added an additional test to the |
|
It seems like having a module variable, |
There was a problem hiding this comment.
Is this assignment necessary? L.240 should guarantee that the l.h.s here is the same as the r.h.s.
There was a problem hiding this comment.
You're correct! Good point!
There was a problem hiding this comment.
Should we remove this assignment?
There was a problem hiding this comment.
Yes, looks like I missed it in the last update.
Ah that is right. I forgot that I'll update it to use |
5a47873 to
baa0e30
Compare
There was a problem hiding this comment.
In my opinion, it's a little awkward to have a cycle statement here. Wouldn't the following loop without a cycle statement work?
do i = 1, size(p1 % point(:))
if (p1 % point(i) < p2 % point(i)) then
tie = -1
return
else if (p1 % point(i) > p2 % point(i)) then
tie = 1
return
end if
end do There was a problem hiding this comment.
Also, I'm not sure whether the loop as written (with the cycle statement) works as expected. For example, if I define two points:
p1 % point(:) = [1.0, 1.0, 0.0]
p2 % point(:) = [0.0, 0.0, 1.0] the break_tie function returns -1 (i.e., p1 < p2), which isn't what I was expecting. However, it could be that I've misunderstood the expected behavior. Ultimately, as long as the function works deterministically, we should be fine; but, it's always nice when the function behavior matches what most people would intuitively expect.
There was a problem hiding this comment.
@mgduda I think the portion of code is also a bit awkward, particularly I don't like the double if statements. I like your implementation better and I'll switch it over to that.
Too your second comment, I think -1 was being returned as there were a few return statements missing. When I wrote my unit test, I wrote a test and figured it was enough, but in the back of my mind I knew I needed a few more, and it appears that thought was right, so I'll add a few more tests to make sure we've got good coverage.
|
There are a couple of places where the commit messages or code comments make references to interior/exterior cells, or to different MPI tasks, and I think the problem that this PR is addressing is not inherently tied to either of these. For example, a serial program could construct two different kd-trees that share points and be affected by the issue of searches in one tree or the other returning different "nearest" points. As such, I'd suggest we keep the descriptions general. |
That sounds great. Thanks for the note on this. I was actually wondering how exactly the commit message should be worded. I agree, I'll update it to be more generalized. |
baa0e30 to
26b4a27
Compare
|
Okay, @mgduda. I have updated the comparison loop (so that it no longer contains |
|
The commit message mentions 'closet' in a couple of places; I think this should be 'closest'. Also, in the commit message, it's stated that "the resulting 'closet' point (from mpas_kd_search) would be the last if (current_distance < distance) then
distance = current_distance
res => kdtree |
26b4a27 to
c652356
Compare
That's embarrassing! Thanks for the catch.
You are correct! I was wrong. I just checked with my small toy program and it point chosen (originally) on equidistant queries is the first point encountered. I have just pushed an update that fixes the spelling mistakes and the above error. |
|
@MiCurry Other than one other minor typo, I think this PR is ready to be merged. Since we have the opportunity to easily do so, though, it seems worth changing "than" to "then" as noted in the preceding comment. |
Previous to this commit if a query is equidistant from two points of the KD-Tree, the resulting 'closest' point (from mpas_kd_search) would be the first point that the KD-Tree visited in its search. This produces different results across different trees that contain the same ties, but have a different tree structure. This commit adds a function to break these ties, so that different trees will predictively select the same point on equidistant queries.
c652356 to
ddd137d
Compare
|
Okay, @mgduda I have just pushed a fix for that typo, so we should be good to merge! |
|
@MiCurry It seems GitHub doesn't allow me to add a review if I've already pushed the merge commit. Needless to say, I've approved this PR. |
#3737) Update MPAS framework This PR brings in a new mpas-source submodule with updates to the mpas framework itself, plus changes to the cores supporting the framework update. Some changes are made to the atmosphere core, even though it is not used by E3SM, in order to maintain consistency with the framework. This update includes the following individual branches and PRs, many of which are additions to the makefiles for summit, or optional libraries: * az/azamat/mpas-cmake/mpas-tool-dir (MPAS-Dev/MPAS-Model#629) * init_atmosphere/kd_tree_ties (MPAS-Dev/MPAS-Model#630) * mark-petersen/framework/add_FillValue (MPAS-Dev/MPAS-Model#616) * mark-petersen/framework/add_lapack_option (MPAS-Dev/MPAS-Model#613) * amametjanov/framework/nullify-field-pointers (MPAS-Dev/MPAS-Model#578) * framework/makefile_e3sm (MPAS-Dev/MPAS-Model#603) * xylar/framework/make_shell_bash (MPAS-Dev/MPAS-Model#594) * registry/missing_value (MPAS-Dev/MPAS-Model#562) * pwolfram/updates_make_intel_stack (MPAS-Dev/MPAS-Model#592) * azamat/framework/pgi-cpr-omp-workaround (MPAS-Dev/MPAS-Model#449) * az/framework/e3sm-cmake-qnosmp-typo (MPAS-Dev/MPAS-Model#579) * xylar/compass/add_prerequisite_tag * atmosphere/fix_timekeeping_imports (MPAS-Dev/MPAS-Model#582) * xylar/fix_docs_ci (MPAS-Dev/MPAS-Model#575) * xylar/add_compass_docs (MPAS-Dev/MPAS-Model#472) * philipwjones/framework/summitmake (MPAS-Dev/MPAS-Model#536) * atmosphere/atm_core_cleanup (MPAS-Dev/MPAS-Model#548) * init_atmosphere/parse_geoindex (MPAS-Dev/MPAS-Model#459) * xylar/compass/add_copy_file (MPAS-Dev/MPAS-Model#467) * init_atmosphere/kd_tree (MPAS-Dev/MPAS-Model#438) * init_atmosphere/mpas_stack (MPAS-Dev/MPAS-Model#426) * operators/add_mpas_in_cell (MPAS-Dev/MPAS-Model#400) Fixes #3396 Fixes #3236 [BFB]
Update MPAS framework This PR brings in a new mpas-source submodule with updates to the mpas framework itself, plus changes to the cores supporting the framework update. Some changes are made to the atmosphere core, even though it is not used by E3SM, in order to maintain consistency with the framework. This update includes the following individual branches and PRs, many of which are additions to the makefiles for summit, or optional libraries: * az/azamat/mpas-cmake/mpas-tool-dir (MPAS-Dev/MPAS-Model#629) * init_atmosphere/kd_tree_ties (MPAS-Dev/MPAS-Model#630) * mark-petersen/framework/add_FillValue (MPAS-Dev/MPAS-Model#616) * mark-petersen/framework/add_lapack_option (MPAS-Dev/MPAS-Model#613) * amametjanov/framework/nullify-field-pointers (MPAS-Dev/MPAS-Model#578) * framework/makefile_e3sm (MPAS-Dev/MPAS-Model#603) * xylar/framework/make_shell_bash (MPAS-Dev/MPAS-Model#594) * registry/missing_value (MPAS-Dev/MPAS-Model#562) * pwolfram/updates_make_intel_stack (MPAS-Dev/MPAS-Model#592) * azamat/framework/pgi-cpr-omp-workaround (MPAS-Dev/MPAS-Model#449) * az/framework/e3sm-cmake-qnosmp-typo (MPAS-Dev/MPAS-Model#579) * xylar/compass/add_prerequisite_tag * atmosphere/fix_timekeeping_imports (MPAS-Dev/MPAS-Model#582) * xylar/fix_docs_ci (MPAS-Dev/MPAS-Model#575) * xylar/add_compass_docs (MPAS-Dev/MPAS-Model#472) * philipwjones/framework/summitmake (MPAS-Dev/MPAS-Model#536) * atmosphere/atm_core_cleanup (MPAS-Dev/MPAS-Model#548) * init_atmosphere/parse_geoindex (MPAS-Dev/MPAS-Model#459) * xylar/compass/add_copy_file (MPAS-Dev/MPAS-Model#467) * init_atmosphere/kd_tree (MPAS-Dev/MPAS-Model#438) * init_atmosphere/mpas_stack (MPAS-Dev/MPAS-Model#426) * operators/add_mpas_in_cell (MPAS-Dev/MPAS-Model#400) Fixes #3396 Fixes #3236 [BFB]
Previous to this commit if a query in is equidistant from two points of the KD-Tree, the resulting 'closet' point (from mpas_kd_search) would be the last point that the KD-Tree visited in its search.
This is fine for single processors, but if two tasks share the same point (along the boundary of two decompositions) they each can decide that a single query lies closer to two different points. For the static field interpolation this would mean that a single data value can be counted twice, which produces differences static-fields across task counts.
This commit breaks these ties so that each task will choose the same node that a query belongs too.