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

Polygon to cells experimental fuzzer #800

Merged

Conversation

isaacbrodsky
Copy link
Collaborator

This adds new fuzzers for the polygonToCellsExperimental function, based on the existing functions. Since #796 (this PR is based on that branch) adds containment modes, this updates the existing fuzzers to exercise those options too.

When I run the fuzzerPolygonToCellsExperimental, I see some runtime errors about misaligned addresses, which doesn't cause an issue on Apple M1 architecture but might indicate trouble on other architectures. When I run fuzzerPolygonToCellsExperimentalNoHoles I get a crash about heap-buffer-overflow around polygonToCellsExperimental polyfill.c:646 (looks like the output exceeds the allocated output buffer in some case?)

@coveralls
Copy link

coveralls commented Nov 16, 2023

Coverage Status

coverage: 98.783% (-0.04%) from 98.825%
when pulling 0b4f284 on isaacbrodsky:polygon-to-cells-experimental-fuzzer
into b355c9d on uber:master.

Copy link
Collaborator

@nrabinowitz nrabinowitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that maxPolygonToCellsSize doesn't allocate enough cells for the new modes in some cases. I've seen similar behavior here in benchmarks - this could be an issue that affects the old polygonToCells as well.

I have a plan for a new maxPolygonToCellsSize algo that I'll try out, this may fix the fuzzer errors.

src/apps/fuzzers/fuzzerPolygonToCells.c Outdated Show resolved Hide resolved
@nrabinowitz
Copy link
Collaborator

I think the/one issue here is polar shapes. When I run all countries, I see differences in output for Antarctica (not sure why I didn't catch this earlier):

image

My new estimator seems to cover this case, though it has other issues I'm still debugging. I haven't had a chance yet to check what the old/new output looks like, though I'd guess that the new output is closer to correct due to better handling of the pole itself.

@nrabinowitz
Copy link
Collaborator

Old polyfill:
image
New polyfill:
image

The new one may be correct, I'd have to import the original polygon to check

@isaacbrodsky
Copy link
Collaborator Author

The new one may be correct, I'd have to import the original polygon to check

Has this polygon been added as a test case to ensure we aren't dropping a lot of cells there?

@nrabinowitz
Copy link
Collaborator

The new one may be correct, I'd have to import the original polygon to check

Has this polygon been added as a test case to ensure we aren't dropping a lot of cells there?

I'd rather add some simplified version, as the Antarctica polygon is too large to be easily added to a test file. I can add a new PR with more tests for this.

@nrabinowitz
Copy link
Collaborator

Still seeing errors here with the new estimator. Is there an easy-ish way to get the input for the failure cases?

@isaacbrodsky
Copy link
Collaborator Author

Here is the hexdump of a new crash case for fuzzerPolygonToCellsExperimental:

$ hexdump ./crash-7bee58752754302154762e5e3a399235e773c80c
0000000 0000 4400 0005 0000 0001 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0009 0000
0000020 0000 0000 0000 0000 0000 9f00 9f9f 9f9f
0000030 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 6069
0000040 6060 6060 6060 9f9f 9f9f 9f9f 9f9f 9f9f
0000050 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
0000090 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 3939 3939
00000a0 3939 3939 3939 3939 0039 0000 0000 0000
00000b0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000180 9f00 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
0000190 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
00001c0 9f9f 9f9f 9f9f 9f2a 9f9f 9f9f 9f9f 9f9f
00001d0 9f9f 9f9f 9f9f 399f 3939 3939 3939 3939
00001e0 3939 3939 0000 0000 0000 0000 0000 0000
00001f0 0000 0000 0000 0000 0000 0000 0000 0000
0000200 0000 0000 0544 0000 0000 0000 0000 0000
0000210 0000 0040 0000 0000 0000 0000 9f9f 9f9f
0000220 9f9f 9f9f 9f9a 9f9f 9f9f 9f9f 9f9f 9f9f
0000230 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
0000260 9f9f 9f9f 9f9f 9f9f 9f9f 399f 3939 3939
0000270 3b39 3939 3939 3939 3939 3939 3939 3939
0000280 3939 3939 3939 3939 3939 3939 3939 3939
0000290 3939 3939 3939 3939 3939 9f38 9f9f 9f9f
00002a0 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
00002c0 9f9f 9f9f 9f9f 9f89 9f9f 9f9f 409f 9f9f
00002d0 9f9f fc9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
00002e0 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
00002f0 9f9f 9f9f 9f9f 0000 0000 0000 0000 0000
0000300 0000 0000 0000 0000 0000 0000 0000 9f9f
0000310 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
0000340 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 009f
0000350 0000 0000 0000 0000 9f9f 9f9f 9f9f 9f9f
0000360 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
0000380 3939 3939 3939 3939 3939 3939 0039 0000
0000390 0000 0000 0800 0000 0000 0000 0000 0000
00003a0 0000 0000 0000 0000 9f9f 9f9f 9f9f 9f9f
00003b0 9fe7 9f9f 9f9f 9f9f 9f9f 0c01 0000 0000
00003c0 0000 0000 0000 0000 9f00 9f9f 9f9f 9f9f
00003d0 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f 9f9f
*
0000430 9f9f 9f9f 9f9f 9f9f 0000 0800 0000 0000
0000440 0000 0000 0000 9f00 9f9f 0000          
000044b

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ isaacbrodsky
❌ Nick Rabinowitz


Nick Rabinowitz seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@isaacbrodsky
Copy link
Collaborator Author

I tried adding an additional check today to recompute the expected array size and bail if the function is about to write past the end of the array. That seems to, at the cost of recomputing the size, avoid any remaining crashes. Unfortunately there is a timeout with some input which is currently failing the test.

@@ -433,7 +433,8 @@ void iterStepPolygonCompact(IterCellsPolygonCompact *iter) {

// Target res: Do a fine-grained check
if (cellRes == iter->_res) {
if (mode == CONTAINMENT_CENTER || mode == CONTAINMENT_OVERLAPPING) {
if (mode == CONTAINMENT_CENTER || mode == CONTAINMENT_OVERLAPPING ||
mode == CONTAINMENT_OVERLAPPING_BBOX) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. These additional checks might get the fuzzer to pass, but they miss the point of CONTAINMENT_OVERLAPPING_BBOX, which is to do a much faster check than CONTAINMENT_OVERLAPPING. The perf impact here is likely significant, since we're going from a fast bbox check to a slow set of polygon-based checks.

Are all of these additional checks needed to make the fuzzer pass? Or can we narrow down to find the check that's actually missed by CONTAINMENT_OVERLAPPING_BBOX?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All but the change around line 511 seem to be necessary to prevent crashes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit that I'm not seeing any significant differences in the benchmarks after this change, assuming I'm running them correctly. I think I'm ok with this to get the new algo out the door, though I'd really like to look through the logic here and understand what's missing in the bbox check - it doesn't make a lot of sense to me conceptually that these would work when the bbox doesn't, so we must be messing up the bbox check in some way.

Copy link
Collaborator

@nrabinowitz nrabinowitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted elsewhere, this seems ok for now, but we should definitely investigate why it's necessary, as the changes to make the fuzzer pass could have significant perf impact.

@@ -692,9 +696,27 @@ void iterDestroyPolygon(IterCellsPolygon *iter) {
H3Error H3_EXPORT(polygonToCellsExperimental)(const GeoPolygon *polygon,
int res, uint32_t flags,
H3Index *out) {
#ifdef H3_POLYGON_TO_CELLS_ASSERT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we comment on how to set this variable? Can we use the TESTONLY macro here instead?

@ajfriend
Copy link
Contributor

The new one may be correct, I'd have to import the original polygon to check

Has this polygon been added as a test case to ensure we aren't dropping a lot of cells there?

I'd rather add some simplified version, as the Antarctica polygon is too large to be easily added to a test file. I can add a new PR with more tests for this.

Do we still need to add a simplified Antartica-like polygon to the tests? I could help with that.

@isaacbrodsky
Copy link
Collaborator Author

I'm overriding the CLA check since the only people with commits in this branch are myself and @nrabinowitz (who may have used an old email address, but has certainly signed the CLA before)

@isaacbrodsky isaacbrodsky merged commit e8b1661 into uber:master Oct 6, 2024
37 of 38 checks passed
@isaacbrodsky isaacbrodsky deleted the polygon-to-cells-experimental-fuzzer branch October 6, 2024 17:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants