added driver vertex levelization#327
Conversation
Signed-off-by: Cho Moon <cmoon@precisioninno.com>
Signed-off-by: Cho Moon <cmoon@precisioninno.com>
|
Hi @precisionmoon I was looking at OpenSTA PRs and came across this one. I have some comments regarding this change (got reviewed by AI)
Sta is explicitly documented as a FACADE (see Sta.hh:98): Adding Levelize* levelize() const { return levelize_; } leaks the internal component. Instead, add a delegating method on Sta: // In Sta.hh public section: // In Sta.cc: This keeps the facade intact and doesn't require callers to know about Levelize at all. -- The sort comparator is: std::sort is not stable. Vertices at the same level will appear in arbitrary order, which can vary between runs. This is inconsistent with the existing codebase pattern — see Levelize.cc:258-259 where sortedRootsWithFanout() uses VertexNameLess(network_) for determinism, and findCycleBackEdges() at line 308-309 does the same. If any consumer iterates this for delay calculation or reporting, results could be non-reproducible. Fix by either:
The clear() method sets drvr_vertices_level_valid_ = false but doesn't clear levelized_drvr_vertices_. Every other container in clear() is explicitly cleared (roots_.clear(), loops_.clear(), loop_edges_.clear()). The cached vector should be too: This also avoids holding stale/dangling pointers between a clear() and the next rebuild.
After deleteVertexBefore(vertex), the vertex is about to be destroyed, but levelized_drvr_vertices_ may still contain the pointer. The flag is set false, so levelizedDrvrVertices() would rebuild before returning — but the raw vector member is accessible to subclasses (it's protected). At minimum, also clear the vector:
In invalid(), the drvr_vertices_level_valid_ = false is inside the if (levelized_) guard. This is technically correct today because drvr_vertices_level_valid_ can only be true when levelized_ is true — the only path that sets it true (levelizeDrvrVertices()) goes through ensureLevelized() first, which guarantees levelized_ == true. However, this makes the correctness non-obvious and dependent on call ordering across multiple methods. Consider moving it outside the guard:
levelizeDrvrVertices() iterates all vertices, filtering for drivers. On large designs this could cause multiple vector reallocations. A reserve() based on a fraction of total vertex count would help: |
|
DESCRIPTION This PR adds a way to get all driver vertices from the timing graph, sorted by their level (topological depth), with lazy caching. What it adds One new data structure — a cached VertexSeq (std::vector<Vertex*>) of driver vertices sorted by level, plus a bool dirty flag. Two new methods on Levelize:
Cache invalidation — sets drvr_vertices_level_valid_ = false in every method that can change the graph structure or vertex levels: clear(), invalid(), deleteVertexBefore(), relevelizeFrom(), One new accessor on Sta — Levelize* levelize() const to let external code reach the Levelize object and call levelizedDrvrVertices(). What it does NOT do
In plain terms Before this PR, if you wanted all driver pins in topological order, you'd have to walk the entire graph, filter for drivers, and sort them yourself — every time. This PR does that once and caches the result, |
dsengupta0628
left a comment
There was a problem hiding this comment.
Added in detailed comment section
Signed-off-by: Cho Moon <cmoon@precisioninno.com>
…roject#327 Signed-off-by: James Cherry <cherry@parallaxsw.com>
…vr_level_to_dbsta Revert driver-vertex levelization (PR #327): move to OpenROAD/dbSta
No description provided.