Skip to content

ALMIOPEN-2598: Reuse KernDb connections via cached-database mechanism - #11933

Merged
iq136boy merged 4 commits into
developfrom
users/dfeng/reuse-kerndb-cached-connections
Oct 7, 2026
Merged

iq136boy merged 4 commits into
developfrom
users/dfeng/reuse-kerndb-cached-connections

Conversation

@iq136boy

@iq136boy iq136boy commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Fix SQLiteBase::GetCached signature from (path, is_system) to (DbKinds, path, is_system) so the rank<1> SFINAE caching overload in MultiFileDb::GetDbInstance matches, eliminating redundant sqlite3_open/sqlite3_close per LoadBinary/SaveBinary call
  • Switch cached instance storage to unique_ptr<Derived> (matching RamDb pattern) to avoid requiring Derived to be movable
  • Add per-instance std::recursive_mutex with fine-grained locking in each *Unsafe method for thread safety on shared cached instances. For KernDb, the lock covers only the SQLite step so that bz2 decompression and MD5 verification can run concurrently across threads
  • Cache key includes (path, is_system) to prevent read-only/read-write mode conflicts
  • Add EvictCached() to allow tests to release cached connections before temp files are deleted (required for Windows cleanup)
  • Add compile-time static_assert to catch future SFINAE probe drift
  • Add tests for connection reuse, path isolation, and multi-threaded safety (concurrent store + find)
  • Note: SQLitePerfDb also benefits from this caching when MIOPEN_USE_SQLITE_PERFDB=On, since the fix is in the shared SQLiteBase template

Strace benchmark results

Measured filesystem syscalls over 50 iterations of GetDbInstance<KernDb>() + FindRecord() using strace -f -e trace=file, comparing develop (before) vs this branch (after):

Metric Before (develop) After (this PR) Improvement
KernDb file opens (openat on KDB file) 158 8 19.75x fewer
Total openat syscalls 18,261 18,111 -150
Total newfstatat syscalls 19,647 18,495 -1,152
Total file syscalls 38,104 36,701 -1,403
Test execution time (50 iterations) 97ms 11ms ~9x faster

Root cause: On develop, SQLiteBase::GetCached had a 2-arg signature (path, is_system) while GetDbInstance probed for a 3-arg form (DbKinds, path, bool). The SFINAE mismatch caused the rank<1> caching overload to silently fail, so every GetDbInstance<KernDb>() call fell through to rank<0> — constructing a fresh KernDb each time (sqlite3_open, schema creation, PRAGMAs, sqlite3_close). This is especially costly when the KDB resides on a network filesystem (e.g. NFS), as each open/close is a round-trip.

Test plan

  • Existing check_kern_db test passes
  • New check_kern_db_cached_reuse — same path returns same instance
  • New check_kern_db_cached_distinct_paths — different paths return different instances
  • New check_kern_db_cached_thread_safety — 8 threads concurrently store and read back per-thread records
  • Strace benchmark: 19.75x reduction in KernDb file opens, ~9x wall-clock speedup over 50 iterations
  • Compile-time static_assert ensures GetDbInstance<KernDb> returns a reference (caching overload)

JIRA ID : ALMIOPEN-2598

🤖 Generated with Claude Code

@iq136boy
iq136boy requested a review from a team as a code owner September 10, 2026 16:39
@therock-pr-bot

therock-pr-bot Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

therock-pr-bot Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

iq136boy and others added 2 commits September 11, 2026 16:43
SQLiteBase::GetCached had a 2-arg signature (path, is_system) while
MultiFileDb::GetDbInstance probed for a 3-arg form (DbKinds, path, bool).
The SFINAE mismatch caused the rank<1> caching overload to silently fail,
so every LoadBinary/SaveBinary call opened and closed a fresh SQLite
connection (sqlite3_open, schema creation, PRAGMA table_info, sqlite3_close).

- Change GetCached to accept (DbKinds, path, is_system), matching the
  RamDb/ReadonlyRamDb pattern so rank<1> now wins
- Switch internal storage to unique_ptr<Derived> to avoid requiring
  Derived to be movable
- Add per-instance mutex (instance_mutex) to protect concurrent operations
  on shared cached instances
- Wrap all public entry points (FindRecord, StoreRecord, RemoveRecord,
  Remove, Update, Load) with lock_guard before delegating to Unsafe methods
- Add tests for connection reuse, path isolation, and multi-threaded safety

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iq136boy
iq136boy force-pushed the users/dfeng/reuse-kerndb-cached-connections branch from d8ea6b5 to ece2e19 Compare September 11, 2026 16:58
@iq136boy

Copy link
Copy Markdown
Contributor Author

The MIOpen Build Hip Package failure is a known infrastructure issue — not related to this PR's changes.

The error is in an external rocjitsu dependency pulled in at CI build time:

rocm-systems/emulation/rocjitsu/lib/rocjitsu/src/rocjitsu/kmd/linux/simulated_driver.cpp:63:28:
error: variable 'g_default_state' set but not used [-Werror,-Wunused-but-set-global]

This file doesn't exist in the rocm-libraries repo — it comes from an external package. At least two other open PRs (#11934, #11800) are hitting the same failure. PR #12019 removes this check from component CI.

All actual MIOpen builds and GPU tests pass (gfx90a, gfx942, gfx110X on both Linux and Windows).

Comment thread projects/miopen/test/gtest/cache.cpp Resolved
Comment thread projects/miopen/test/gtest/cache.cpp Resolved
Comment thread projects/miopen/test/gtest/cache.cpp Resolved
Comment thread projects/miopen/test/gtest/cache.cpp Resolved
- Narrow lock scope: move locking from SQLiteBase wrappers into *Unsafe
  methods so KernDb::FindRecordUnsafe locks only the SQLite query while
  bz2 decompression and MD5 run concurrently across threads
- Use std::recursive_mutex for safe re-entry (LoadUnsafe→FindRecordUnsafe)
- Key cache on (path, is_system) to prevent read-only/read-write conflicts
- Add EvictCached() so tests can release connections before TempFile cleanup
- Fix std::vector<bool> data race → std::vector<int>
- Add static_assert to catch future SFINAE probe drift at compile time
- Rewrite thread safety test with concurrent StoreRecord + FindRecord
- Update PR description to mention SQLitePerfDb benefits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iq136boy
iq136boy merged commit d2aaf8c into develop Oct 7, 2026
109 checks passed
@iq136boy
iq136boy deleted the users/dfeng/reuse-kerndb-cached-connections branch October 7, 2026 13:58
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

mattwill-amd pushed a commit that referenced this pull request Oct 14, 2026
JIRA ID: ALMIOPEN-2913

## Motivation

Only 5 of the 30 commits that landed against `projects/miopen` since the
3.6.2 version bump (`2d20a8f775e`, #12211) were reflected in
`CHANGELOG.md`. The remaining 25 were reviewed and the 15
externally-visible ones documented, so the ROCm 10.2.0 section
accurately reflects what shipped.

14 entries added (two of the fixes share one entry), plus a
duplicate-heading fix.

### Added
* [Conv] NHWC (channel-last) support in the GEMM convolution solvers,
with new im2col/col2im kernels (#8693)
* [Conv] Cross-architecture AI heuristics for immediate mode
(`MIOPEN_FIND_MODE=2`), extending data-driven selection to Navi (#9680)
* [Conv] Missing 3x3 stride-1 pad-1 tile-28 CK depthwise backward-data
instance — ALMIOPEN-2423 (#11271)

### Changed
* [Conv] `ConvHipConv` held out of the AI perf-config picker until its
model is retrained — ALMIOPEN-2494 (#13337)
* [Conv] CK byte-span gate lifted for forward and backward-data, now
that CK fixes the 32-bit offset overflow itself — ALMIOPEN-2645 (#12396)

### Optimized
* [Conv] `ConvDirectNaiveConv`: per-direction kernel files, float
accumulators, spatial tiling, bfloat16 path — ALMIOPEN-2485/2486 (#7529)
* Kernel cache reuses cached SQLite connections instead of reopening per
load/store — ALMIOPEN-2598 (#11933)

### Resolved Issues
* [Conv] Incorrect backward-weights results from the gfx950 direct
kernel at `waves_q == 1` (missing cross-lane ordering on LDS staging
reuse) — ROCM-31508 (#12406)
* [Conv] Up to 8x slower hipconv `direct`/`direct_l1`/`direct_wgrad`
under ROCm 10.1's full AMDGCN LTO default; fixed with `-fno-offload-lto`
— ROCM-31334 (#12328)
* [Conv] gfx942 multi-node training throughput regression from backward
GEMM on small-batch 1x1 NHWC shapes — ROCM-31155 (#13232)
* [Conv] Invalid CK perf-config entries in the gfx1201 and gfx1100
system databases — ROCM-29026 (#12088, #12117)
* [BatchNorm] JIT compilation failures on non-GFX9 targets; Welford DPP
assembly restricted to GFX9 — ALMIOPEN-2838 (#12889)
* Out-of-bounds write in `miopenLoadSolution` when a serialized solution
carries more than three work dimensions — ROCM-31082 (#12242)
* `uint64_t` typedef conflict between `miopen_cstdint.hpp` and system
`<stdint.h>` on LP64 Linux (#12623)

## Technical Details

Single-file change to `projects/miopen/CHANGELOG.md`.

The 10.2.0 section had **two** `### Resolved Issues` headings. The two
entries under the trailing one (`ConvHipConv` gfx1250 crash/LDS race,
and the perf-db reload config loss) were merged into the first, and the
trailing heading removed — this accounts for the 2 removed bullets in
the diff. Section order is now `Resolved Issues → Added → Changed →
Optimized → Removed`, matching the 3.6.1 section. `Optimized` is new to
this release section.

Already documented, so untouched: #12874 (reduce int32 rejection),
#12000 / #13016 / #13213 (hipconv v0.3.1 / v0.3.2 / v0.4.0), #11761
(gfx803 removal).

## Notes

Deliberately excluded as not externally visible (10 commits):

* **hipDNN convolution forwarding (#12276)** —
`MIOPEN_ENABLE_HIPDNN_WRAPPER` defaults to `OFF`
(`projects/miopen/CMakeLists.txt:162`), so no shipped build compiles the
forwarding code and the runtime `MIOPEN_HIPDNN_FORWARDING` flag has
nothing to enable.
* **Test-only**: #13289 (gfx1250 depthwise test applicability,
ALMIOPEN-2841), #11610 (hipDNN parity harness), #12660 (Jenkins status
post).
* **Internal kernel-math cleanup, generated ISA unchanged**: #13312
(drop direct `__ocml` calls), #13190 (remove broken single-argument
`__half` overloads).
* **Add/revert pairs, net no change**: #12466 + #13066 (gfx1101 Navi
system DBs), #12496 + #12800 (gfx1250 in the dev image arch lists).

## Risk Assessment

Documentation-only change to a single Markdown file; no code, build, or
runtime impact.

**Risk Level: 🟢 Low**

## Test Plan

None required — Markdown-only. Verified that the entry topics are not
already documented elsewhere in the file, that no content was lost when
merging the duplicate heading, and that every new entry maps to a commit
in `2d20a8f775e..origin/develop -- projects/miopen`.

## Test Result

16 bullets added, 2 relocated — 14 net-new entries covering 15 commits.
Duplicate heading removed; section ordering matches 3.6.1.

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants