| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Good point — dropped the cast helper and the is_Mul check in 454434b, applying as_long to the section extent directly: sections = ''.join([f'[{ccode(i)}:{ccode(as_long(j))}]'
for i, j in self.sections])The generated code is unchanged: the start bound i is always 0/an offset (left as-is, can't overflow) and the extent j is the size product that as_long promotes to 64-bit, e.g. (long)(size[3])*(long)(size[2])*.... I left i uncast rather than wrapping both bounds, since the overflow site (#2777) is the extent product. |
Sorry, something went wrong.
|
Gentle ping — the review feedback was addressed back in 454434b (dropped the cast helper and the is_Mul check, switched to as_list). The branch is behind main but conflict-free. Happy to do anything further; otherwise this should be ready for another look when you have a moment. |
Sorry, something went wrong.
Codecov Report❌ Patch coverage is 43.75000% with 9 lines in your changes missing coverage. Please review.
@@ Coverage Diff @@
## main #2939 +/- ##
==========================================
- Coverage 83.57% 79.20% -4.38%
==========================================
Files 257 257
Lines 53841 53852 +11
Branches 4609 4611 +2
==========================================
- Hits 44999 42654 -2345
- Misses 8044 10348 +2304
- Partials 798 850 +52
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
|
Just to keep this moving, this PR will need a rebase and failing tests fixing before it can be merged |
Sorry, something went wrong.
|
Rebased onto current main (flattened the old merge commit into the three commits) and fixed the isort failure in devito/symbolics/manipulation.py that was breaking the lint job. CI should be running fresh now. |
Sorry, something went wrong.
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Sorry, something went wrong.
|
Rebased onto current main and fixed the real CI failures: applying as_long unconditionally also rewrote the plain per-dimension extents (they are IndexedPointer leaves too), which churned every non-linearized transfer pragma — that's what broke the openacc codegen tests and the 01_gpu notebook. Restored the product-only guard at the call site (only a product of the 32-bit sizes can overflow) and updated the notebook's reference output for the linearized clauses that legitimately gain the casts. The arm64/MPI failures were infra — apt mirror timeouts while building the docker images. |
Sorry, something went wrong.
|
Heads-up: the CI runs for the rebase are sitting at "awaiting approval" (fork workflow gating), so nothing has actually run on the new head. Could someone approve the runs when convenient? |
Sorry, something went wrong.
When a host-device data transfer is linearized, its array section size is emitted as a product of the Function's per-dimension sizes, e.g. `copyin(u[0:u_vec->size[0]*u_vec->size[1]*u_vec->size[2]*u_vec->size[3]])`. The `size[i]` fields are 32-bit C ints, so for a Function with more than ~2**31 elements the product overflows `int` before it is used as the transfer bound, yielding a bogus size and a corrupt/failed device transfer. Cast each factor of the product to a 64-bit integer so the multiplication is carried out in 64-bit arithmetic. Casting the whole product would be too late (the overflow would already have occurred), so each factor is cast individually. Non-product bounds (a single size, an offset, a constant) cannot overflow and are left untouched, as are non-transfer expressions. Fixes devitocodes#2777
Address review: replace the ad-hoc _avoid_overflow helper with the existing as_long. as_long only substituted plain Symbols (retrieve_symbols), so it was a no-op on the IndexedPointer size factors (vec->size[i]) of a linearized transfer bound; extend it to retrieve_terminals so Indexed/IndexedPointer leaves are cast too. Keep the cast scoped to Mul products in PragmaTransfer so non-linearized multi-dimensional sections are not needlessly upcast.
…nt directly Per review: as_long already walks the expression args, so the cast() helper and its is_Mul check are unnecessary. Apply as_long to the section extent directly. Output is unchanged: the start bound is always 0/an offset (left as-is) and the extent is the size product that as_long promotes to 64-bit.
…tebook Applying as_long unconditionally also rewrote plain per-dimension extents (IndexedPointer leaves), churning every non-linearized transfer pragma and breaking the openacc codegen tests and the 01_gpu notebook. Only a product of 32-bit sizes can overflow int, so restrict the promotion to Mul bounds and update the notebook's reference output for the linearized transfer clauses that legitimately gained the casts.
|
Rebased onto current main and force-pushed (b83821a). The transfer-size change is unchanged; CI is re-running. test_w_data also passes locally on the rebased tree. |
Sorry, something went wrong.
|
The fresh runs after the rebase are sitting at "awaiting approval" (fork workflow gate) — could someone approve them when convenient? Thanks. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Description
Fixes #2777.
When a host↔device data transfer is linearized, its array section size is emitted as a product of the Function's per-dimension sizes, for example:
#pragma acc enter data copyin(u[0:u_vec->size[0]*u_vec->size[1]*u_vec->size[2]*u_vec->size[3]])The u_vec->size[i] fields are 32-bit C ints, so the product size[0]*size[1]*size[2]*size[3] is evaluated in 32-bit arithmetic. For a Function with more than ~2**31 elements (e.g. the reporter's 1295**3 ≈ 2.17e9 points, ~24.5 GB) the product overflows int before it is used as the transfer bound, producing a bogus size (the reporter saw 18446744065653020036) and a corrupt / failed device transfer — independent of index-mode=int64/linearize=True, because those control the kernel index type, not the type of the transfer-clause arithmetic.
As @mloubout noted on the issue, the fix is to perform the size multiplication in 64-bit. This casts each factor of a product section bound to a 64-bit integer:
#pragma acc enter data copyin(u[0:(long)(u_vec->size[0])*(long)(u_vec->size[1])*(long)(u_vec->size[2])*(long)(u_vec->size[3])])Casting the whole product ((long)(a*b*c)) would be too late — the overflow would already have happened in 32-bit — so each factor is cast individually, which forces every multiplication to be 64-bit regardless of operand ordering.
The change lives in PragmaTransfer._generate, so it is scoped to host-device transfer clauses only. Non-product bounds (a single dimension size, an offset, a constant) cannot overflow and are left untouched, addressing the concern that there is "no reason to use long for all of those". Non-transfer expressions (e.g. free-space guards, TMA descriptors) are unaffected.
Reproduction
Before:
After:
Verification