Fix Neureka#188
Conversation
d0ed93d to
5081593
Compare
…te conv layers - in parser, weights are contrained to have 3 dimensions. That is correct for PW only. DW and Dense require 4 dimensions. The fix allows weights with 4 dimensions for DW and Dense. - in tiler, again only 3-dim weights for PW is supported. Add support for 4-dim weights for DW and Dense. - in test-runner, arguments for neureka are ignored. Add support for `enable-3x3` and `neureka-wmem` arguments.
…the bias is coherent with requantshift add vector
The flag avoid that aliases of input/output (such as a no-op reshape view) is deallocated
…totally supported
📝 WalkthroughWalkthroughThis PR removes the experimental ChangesNeureka 3x3 fix and depthwise lowering
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
Deeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.py (1)
103-109: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRedundant
elif depthwisebranch — collapse it.With the depthwise transpose removed earlier in
_weightEncode, theelif depthwiseandelsebranches now return an identical expression, so thedepthwiseflag no longer changes the produced layout. The branch (and possibly thedepthwiseparameter itself, if all callers can drop it) can be simplified.♻️ Proposed simplification
if height == 1 and width == 1: # (cout, cinMajor, Weight Bandwidth Bytes) return weight.reshape(cout, cinMajor, weightBandwidthBytes) - elif depthwise: - return weight.reshape(cout, cinMajor, bits, weightBandwidthBytes) - else: - return weight.reshape(cout, cinMajor, bits, weightBandwidthBytes) + return weight.reshape(cout, cinMajor, bits, weightBandwidthBytes)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Deeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.py` around lines 103 - 109, The `reshapeWeight` logic in `Passes.py` has a redundant `elif depthwise` branch because it returns the same layout as the `else` case. Simplify the conditional so the `depthwise` flag no longer affects the returned `weight.reshape(...)` result, and update the surrounding `_weightEncode`/`reshapeWeight` flow to remove `depthwise` entirely if no callers still need it.Deeploy/Targets/Neureka/Engine.py (1)
38-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueVerify that GVSOC logging should be unconditionally enabled at init.
neureka_gvsoc_log_activate(..., NEUREKA_GVSOC_LOG_LEVEL_ALL, ...)is now emitted into the standard init code for every Neureka deployment.LOG_LEVEL_ALLis very verbose and this appears to be a debug/tracing aid; enabling it unconditionally can drown simulation logs and slow runs. Consider gating it behind a debug/profiling flag if it isn't meant to be always-on.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Deeploy/Targets/Neureka/Engine.py` around lines 38 - 42, The Neureka init snippet in _neurekaInitCode always enables gvsoc logging with NEUREKA_GVSOC_LOG_LEVEL_ALL, which should not be unconditionally turned on in normal deployments. Update the init path in Engine.py so neureka_gvsoc_log_activate is only emitted when a debug/profiling flag or similar opt-in is enabled, while keeping neureka_nnx_init and the device setup unchanged. Use the existing _neurekaInitCode generation point to make the logging conditional.Deeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.py (1)
234-235: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
cubeis unused in this loop.Since the DW weight is loaded in full per tile,
cubeis no longer referenced; iterate overinputLoadScheduledirectly for clarity.♻️ Optional cleanup
- for cube, load in zip(outputCubes, inputLoadSchedule): - load['weight'] = HyperRectangle((0,) * len(weightShape), tuple(weightShape)) + for load in inputLoadSchedule: + load['weight'] = HyperRectangle((0,) * len(weightShape), tuple(weightShape))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Deeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.py` around lines 234 - 235, The loop in NeurekaDepthwiseConstraint is carrying an unused `cube` variable, since the DW weight is loaded in full per tile and only `inputLoadSchedule` is needed. Update the iteration in the relevant weight-loading block to loop directly over `inputLoadSchedule`, keeping the `load['weight'] = HyperRectangle(...)` assignment unchanged and removing the unused `cube` binding for clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Deeploy/Targets/Neureka/Parsers.py`:
- Around line 109-119: Update the Neureka parser methods so they always return
the expected (NetworkContext, bool) tuple instead of a bare False. In
NeurekaDWConv2DParser.parseNodeCtxt, NeurekaPWConv2DParser.parseNodeCtxt, and
NeurekaDenseConv2DParser.parseNodeCtxt, make both failure paths (the
super().parseNodeCtxt call returning false and the weight-shape validation
failure) return the current context together with False, matching the
Tuple[NetworkContext, bool] contract used by the base parser and RQS parser.
Keep the successful return as (newCtxt, True) and ensure callers can safely
unpack the result.
---
Nitpick comments:
In `@Deeploy/Targets/Neureka/Engine.py`:
- Around line 38-42: The Neureka init snippet in _neurekaInitCode always enables
gvsoc logging with NEUREKA_GVSOC_LOG_LEVEL_ALL, which should not be
unconditionally turned on in normal deployments. Update the init path in
Engine.py so neureka_gvsoc_log_activate is only emitted when a debug/profiling
flag or similar opt-in is enabled, while keeping neureka_nnx_init and the device
setup unchanged. Use the existing _neurekaInitCode generation point to make the
logging conditional.
In `@Deeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.py`:
- Around line 234-235: The loop in NeurekaDepthwiseConstraint is carrying an
unused `cube` variable, since the DW weight is loaded in full per tile and only
`inputLoadSchedule` is needed. Update the iteration in the relevant
weight-loading block to loop directly over `inputLoadSchedule`, keeping the
`load['weight'] = HyperRectangle(...)` assignment unchanged and removing the
unused `cube` binding for clarity.
In `@Deeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.py`:
- Around line 103-109: The `reshapeWeight` logic in `Passes.py` has a redundant
`elif depthwise` branch because it returns the same layout as the `else` case.
Simplify the conditional so the `depthwise` flag no longer affects the returned
`weight.reshape(...)` result, and update the surrounding
`_weightEncode`/`reshapeWeight` flow to remove `depthwise` entirely if no
callers still need it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4e9e3fa4-4260-4a98-9c31-0218ebe4ba82
📒 Files selected for processing (21)
CHANGELOG.mdDeeploy/CommonExtensions/OptimizationPasses/TopologyOptimizationPasses/LoweringOptimizationPasses.pyDeeploy/DeeployTypes.pyDeeploy/Targets/Neureka/Deployer.pyDeeploy/Targets/Neureka/Engine.pyDeeploy/Targets/Neureka/Parsers.pyDeeploy/Targets/Neureka/Templates/ConvTemplate.pyDeeploy/Targets/Neureka/TileConstraints/NeurekaDenseConstraint.pyDeeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.pyDeeploy/Targets/Neureka/TileConstraints/NeurekaPointwiseConstraint.pyDeeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.pyDeeploy/Targets/PULPOpen/TopologyOptimizationPasses/Passes.pyDeeployTest/Tests/Kernels/Integer/Conv/DW_3x3_RQ/inputs.npzDeeployTest/Tests/Kernels/Integer/Conv/DW_3x3_RQ/network.onnxDeeployTest/Tests/Kernels/Integer/Conv/DW_3x3_RQ/outputs.npzDeeployTest/Tests/Kernels/Integer/Conv/Regular_3x3_RQ/inputs.npzDeeployTest/Tests/Kernels/Integer/Conv/Regular_3x3_RQ/network.onnxDeeployTest/Tests/Kernels/Integer/Conv/Regular_3x3_RQ/outputs.npzDeeployTest/testMVP.pyDeeployTest/testUtils/deeployRunner.pyDeeployTest/test_siracusa_neureka_tiled_config.py
💤 Files with no reviewable changes (1)
- DeeployTest/testMVP.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Deeploy/Targets/Neureka/Engine.py (1)
41-41: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider removing the commented-out GVSOC log line.
The commented-out
neureka_gvsoc_log_activate(...)call is dead code in the generated init string. If it's kept intentionally for easy debug toggling, a brief comment explaining that would help future readers.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Deeploy/Targets/Neureka/Engine.py` at line 41, Remove the commented-out neureka_gvsoc_log_activate call from the init string, or if you want to keep it for debug toggling, replace it with a brief explanatory comment so the intent is clear. Update the Neureka engine initialization logic in Engine.py around the generated init string to avoid leaving dead code in the output.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@Deeploy/Targets/Neureka/Engine.py`:
- Line 41: Remove the commented-out neureka_gvsoc_log_activate call from the
init string, or if you want to keep it for debug toggling, replace it with a
brief explanatory comment so the intent is clear. Update the Neureka engine
initialization logic in Engine.py around the generated init string to avoid
leaving dead code in the output.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0934c17d-b027-42c9-83a5-2d1681520b68
📒 Files selected for processing (4)
Deeploy/Targets/Neureka/Engine.pyDeeploy/Targets/Neureka/Parsers.pyDeeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.pyDeeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.py
🚧 Files skipped from review as they are similar to previous changes (3)
- Deeploy/Targets/Neureka/TileConstraints/NeurekaDepthwiseConstraint.py
- Deeploy/Targets/Neureka/TopologyOptimizationPasses/Passes.py
- Deeploy/Targets/Neureka/Parsers.py
Current implementation of Neureka has a few bugs that need to be fixed. This PR wants to fix those bugs and provide some test to check the functionality. Most changes are related to the tiler for Dense and DW Convolutions.
Added
NeurekaNCHWtoNHWCDwConvPasswhich apply the weight layout depending on the engine.Changed
NeurekaReshapePointwiseConvolutionPass_requantized_gemm_to_pw_fun, add a guard onmulandaddshapes to check if they are consistent with PW output channels.Fixed
_merge_conv_rq_funlowering pass (which mergesConvandRequantShiftintoRequantConv) to make the Engine color be inherited fromConvinstead ofRequantShift._createIOBindings, set_live = Trueon network input and output buffers. They are externally allocated and effectively reserved for the whole inference (mirroringConstantBuffer, which already hardcodes_live = True). This makeshas_live_aliases()correctly see them as live, so any buffer aliasing a network I/O tensor is no longer deallocated while the I/O tensor is still in use.has_live_aliases():visited = set(self.name)built a set of the name's characters instead of{self.name}PR Merge Checklist
develcommit and pointing todevel.CHANGELOG.mdfile has been updated.