Chunk vertices in BFS parallel iteration for dynamic load balancing - #405
Chunk vertices in BFS parallel iteration for dynamic load balancing#405calewis wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the parallel BFS implementation in search/Bfs.cc to chunk vertices into small, fixed-size tasks for dynamic load balancing across worker threads. While this improves performance, indexing into the visitors array using the thread_id from the dispatch queue introduces a potential out-of-bounds access if the queue's thread count diverges from thread_count_. It is recommended to size visitors using dispatch_queue_->getThreadCount() and add an assertion to verify that thread_id is within bounds.
33b8f9c to
b599d79
Compare
|
@dsengupta0628 I don't think the test failures are from my changes but from updating the regression tests to use bazel value. BUT I'm not 100% sure about that, the tests do all pass locally (bazel build) and I can't see how these changes would cause minor QOR differences. How should we proceed? |
The best way would be to file an OpenROAD PR that bumps sta pointer to this change's commit and let the CI run there. There Bazel build based tests run, so if this is QoR neutral, regressions should pass. It is guaranteed to pick your change only in sta as there has been no commit after the latest sta master 8/14 upstream code merge- on top of which your change is built. |
I can do that but needing to open a dummy PR in another project seems like a poor experience for anyone trying to submit PRs to this repo. |
Why would it be a dummy PR? This change would need to propagate to OpenROAD anyways, so the src/sta pointer needs to have this change too for OpenROAD to be able to see that. But yes, not having Bazel build based regression testing here is a limitation for immediate review - please note this is a fairly new repo and upstream does not have any Bazel build based testing anyways. Plus the OpenROAD already has the capability- so we never face any issues trying to resolve Bazel/cmake discrepancies typically. |
|
Dummy was the wrong term, sorry. My frustration is that this is a clunky way to run the tests, shouldn't this repo be able to test itself effectively? Here is the OR PR The-OpenROAD-Project/OpenROAD#11243 |
I hear ya'! Let me see if we can somehow get this resolved so that the tests can be run seamlessly. |
|
@dsengupta0628 looks like the upstream PR passed. |
|
Do I need to do anything else? |
dsengupta0628
left a comment
There was a problem hiding this comment.
We merge upstream OpenSTA regularly, so please keep the diff to upstream code as small as possible and isolate the new logic in a marked block.
- Please drop the visit() comment rewrite, the #include , and the visitors sizing change - I dont think that is needed for the feature and each is a guaranteed conflict if upstream touches those lines.
- Move the chunked dispatch into a new BfsIterator::visitLevelChunked() (declaration in Bfs.hh, definition at the end of the BfsIterator section in Bfs.cc), both wrapped in // ---- OpenROAD fork: BFS chunked dispatch (begin/end) ---- markers. Replace only the body of the existing else branch in visitParallel with one marked call.
- Keep upstream's vertex_count < thread_count fallback unless measurements say otherwise; if you need the 3-chunk threshold, put it inside the helper.
|
Recommended shape: Principle: upstream lines stay byte-identical; fork logic lives in a marked, self-contained block, called from one marked line. include/sta/Bfs.hh — inside class BfsIterator, protected section: search/Bfs.cc — in visitParallel, replace only the body of the existing else branch: and add the implementation at the end of the BfsIterator section (before //// + BfsFwdIterator), fully wrapped: |
Yes please :) I added the comment below. |
Dispatch fixed-size chunks (8 vertices per task) instead of one contiguous slice per thread, so threads that finish early pick up more work. Chunk size vs. runtime is U-shaped; 8 is the smallest size at the bottom of the curve. report_checks on a 32-core machine (min of 5 runs): - gcd_sky130hd, 32 threads: 1845 us -> 1255 us (-32%) - gcd_sky130hd, 8 threads: 1254 us -> 1117 us (-11%) - aes_nangate45 (~17k inst): neutral; single-threaded path unchanged. To keep upstream merges clean, the fork logic lives in a new BfsIterator::visitLevelChunked() wrapped in "OpenROAD fork: BFS chunked dispatch" markers, called from one marked line in visitParallel's existing else branch. All other upstream lines are byte-identical. This is a stop-gap until the upstream BFS rework lands; on merge conflict take upstream and drop it. Signed-off-by: Drew <cannada@google.com>
17a3cc8 to
65bd9df
Compare
Bump OpenSTA submodule pointer to 65bd9df5f7846015313734d08a5a6367df79453c, the squashed revision of The-OpenROAD-Project/OpenSTA#405 after review, to re-run OpenROAD CI and verify QoR neutrality. Signed-off-by: Drew Lewis <cannada@google.com>
|
I updated the OR main repo test pr as well to make sure those pass. The-OpenROAD-Project/OpenROAD#11243 |
Dispatch fixed-size chunks (8 vertices per task) in
BfsIterator::visitParallelinstead of one large contiguous slice per thread. Small chunks let threads that finish early pick up more work, and passing the level vertices to tasks by reference removes a per-task copy of the whole vector.These changes can be thrown out in future upstream merges if there are conflicts. This code is a minor improvement, meant to help out a bit until future upstream bfs improvements land.
OpenSTA measurements
report_checkson a 32-core machine (min of 5 runs):ORFS validation (OpenROAD master, base vs. this branch,
NUM_CORES=8)Every stage
.odbis byte-identical (sha1) between the two binaries; flow wall time is neutral.STA micro-benchmark on the final ORFS databases