Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/19008
Note: Links to docs will display an error until the docs builds have been completed. ❌ 3 New Failures, 2 Unrelated FailuresAs of commit 909b931 with merge base 8ed6e85 ( NEW FAILURES - The following jobs have failed:
BROKEN TRUNK - The following jobs failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
|
@claude review |
|
Claude finished @lucylq's task in 1m 14s —— View job Review of PR #19008
This is a well-motivated defensive fix. All ~30 node-definition functions are Macro designThe
The Windows compatibility fix (vs. the prior PR #18804) is the avoidance of GCC/Clang statement-expression extensions ( One minor observationThe macro introduces a leading-underscore identifier Completeness checkI verified all 34
No SummaryLooks good. The change is mechanical, consistent, and addresses a real crash risk on map lookup failure in |
There was a problem hiding this comment.
Pull request overview
Prevents std::terminate() in XNNPACK graph compilation by replacing unchecked std::unordered_map::at() lookups (which can throw inside noexcept node-definition functions) with a checked remap-id lookup that returns an Error instead. This improves robustness and Windows/MSVC compatibility for malformed or unexpected serialized graphs.
Changes:
- Added a
REMAP_IDhelper macro to safely look up remapped tensor IDs and returnError::Internalwhen missing. - Replaced
remapped_ids.at(...)usages across many node-definition helpers (convert/conv/pooling/unary/binary/etc.) with the checked lookup. - Updated generic unary/binary node-definition helpers to use the new safe remapping path.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Clang, and GCC (no statement-expression extension). | ||
| #define REMAP_ID(map, key, out_var) \ | ||
| uint32_t out_var = 0; \ | ||
| { \ | ||
| const auto _et_remap_it = (map).find(key); \ | ||
| ET_CHECK_OR_RETURN_ERROR( \ | ||
| _et_remap_it != (map).end(), \ | ||
| Internal, \ | ||
| "Remapped id not found for key %u", \ | ||
| static_cast<unsigned>(key)); \ | ||
| out_var = _et_remap_it->second; \ | ||
| } |
There was a problem hiding this comment.
REMAP_ID is a macro that expands to multiple statements and evaluates key (and map) more than once. That makes it easy to misuse later (e.g., as the body of an if without braces, or with a non-trivial key expression), and it can also lead to duplicate evaluation costs/side effects. Consider capturing key/map into temporaries inside the macro, or replacing this with a small static inline helper (returning Error and writing to an out-param) and using ET_CHECK_OK_OR_RETURN_ERROR(...) at call sites for type-safety and single evaluation.
| // Clang, and GCC (no statement-expression extension). | |
| #define REMAP_ID(map, key, out_var) \ | |
| uint32_t out_var = 0; \ | |
| { \ | |
| const auto _et_remap_it = (map).find(key); \ | |
| ET_CHECK_OR_RETURN_ERROR( \ | |
| _et_remap_it != (map).end(), \ | |
| Internal, \ | |
| "Remapped id not found for key %u", \ | |
| static_cast<unsigned>(key)); \ | |
| out_var = _et_remap_it->second; \ | |
| } | |
| // Clang, and GCC (no statement-expression extension). Evaluates `map` and | |
| // `key` exactly once and expands to a single declaration statement. | |
| #define REMAP_ID(map, key, out_var) \ | |
| uint32_t out_var = [&]() -> uint32_t { \ | |
| auto&& _et_remap_map = (map); \ | |
| auto _et_remap_key = (key); \ | |
| const auto _et_remap_it = _et_remap_map.find(_et_remap_key); \ | |
| ET_CHECK_OR_RETURN_ERROR( \ | |
| _et_remap_it != _et_remap_map.end(), \ | |
| Internal, \ | |
| "Remapped id not found for key %u", \ | |
| static_cast<unsigned>(_et_remap_key)); \ | |
| return _et_remap_it->second; \ | |
| }() |
Introduce remapId function that checks error instead of std::unordered_map::at(), which throws std::out_of_range in noexcept functions causing std::terminate(). Applied across all ~30 node-definition functions in XNNCompiler.
retake #18804, for windows compatibility