-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add benchmark with ci #365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
e5d7c59
feat: Add benchmark suite for core JAM components
xlc f1bb694
fix
xlc aa75190
disable jemalloc
xlc 8dd3735
improve review
xlc 8ef34fd
benchmark ci
qiweiii 139bc7c
add tests
qiweiii 8b2c4c3
fix benchmark ci
qiweiii 83f3f35
fix benchmark ci
qiweiii 3bec457
fix benchmark ci
qiweiii f3948a1
fix benchmark ci
qiweiii a3f8821
fix benchmark ci
qiweiii e9b7423
fix benchmark ci
qiweiii File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import Benchmark | ||
| import Blockchain | ||
| import Codec | ||
| import Foundation | ||
| import JAMTests | ||
| import Utils | ||
|
|
||
| @inline(__always) private func w3f(_ path: String, ext: String = "bin") -> [Testcase] { | ||
| (try? JAMBenchSupport.w3fTestcases(at: path, ext: ext)) ?? [] | ||
| } | ||
|
|
||
| // Simple sync runner for async operations (Swift 6-safe) | ||
| private final class _UnsafeBox<T>: @unchecked Sendable { var value: T? } | ||
| @inline(__always) private func blockOn<T>(_ work: @escaping @Sendable () async -> T) -> T { | ||
| let g = DispatchGroup(); g.enter() | ||
| let box = _UnsafeBox<T>() | ||
| Task.detached { box.value = await work(); g.leave() } | ||
| g.wait() | ||
| return box.value! | ||
| } | ||
|
|
||
| let benchmarks: @Sendable () -> Void = { | ||
| // W3F Erasure (full): encode + reconstruct | ||
| struct ErasureCodingTestcase: Codable { let data: Data; let shards: [Data] } | ||
| let erasureCases = w3f("erasure/full") | ||
| if !erasureCases.isEmpty { | ||
| let cfg = TestVariants.full.config | ||
| let basicSize = cfg.value.erasureCodedPieceSize | ||
| let recoveryCount = cfg.value.totalNumberOfValidators | ||
| let originalCount = basicSize / 2 | ||
| Benchmark("w3f.erasure.full.encode+reconstruct") { _ in | ||
| for c in erasureCases { | ||
| if let t = try? JamDecoder.decode(ErasureCodingTestcase.self, from: c.data, withConfig: cfg), | ||
| let shards = try? ErasureCoding.chunk(data: t.data, basicSize: basicSize, recoveryCount: recoveryCount) | ||
| { | ||
| let typed = shards.enumerated().map { ErasureCoding.Shard(data: $0.element, index: UInt32($0.offset)) } | ||
| _ = try? ErasureCoding.reconstruct( | ||
| shards: Array(typed.prefix(originalCount)), | ||
| basicSize: basicSize, | ||
| originalCount: originalCount, | ||
| recoveryCount: recoveryCount | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // W3F Shuffle (JSON + compute) | ||
| struct ShuffleTestCase: Codable { let input: Int; let entropy: String; let output: [Int] } | ||
| if let data = try? JAMBenchSupport.w3fFile(at: "shuffle/shuffle_tests", ext: "json"), | ||
| let tests = try? JSONDecoder().decode([ShuffleTestCase].self, from: data), | ||
| !tests.isEmpty | ||
| { | ||
| Benchmark("w3f.shuffle") { _ in | ||
| for t in tests { | ||
| var input = Array(0 ..< t.input) | ||
| if let e = Data32(fromHexString: t.entropy) { input.shuffle(randomness: e); blackHole(input) } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // JamTestnet traces (full): decode + touch roots | ||
| let tracePaths = ["traces/fallback", "traces/safrole", "traces/storage", "traces/preimages"] | ||
| let traces = tracePaths.flatMap { w3f($0) } | ||
| if !traces.isEmpty { | ||
| Benchmark("w3f.jamtestnet.apply.full") { benchmark in | ||
| for _ in benchmark.scaledIterations { | ||
| for c in traces { | ||
| let tc = try! JamTestnet.decodeTestcase(c, config: TestVariants.full.config) | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Run full STF apply and touch resulting state root | ||
| let result = blockOn { | ||
| await (try? JamTestnet.runSTF(tc, config: TestVariants.full.config)) | ||
| } | ||
| switch result { | ||
| case let .success(stateRef): | ||
| let root = blockOn { await stateRef.value.stateRoot } | ||
| blackHole(root) | ||
| default: | ||
| blackHole(c.description) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // RecentHistory STF (full): updatePartial + update | ||
| struct ReportedWorkPackage: Codable { let hash: Data32; let exportsRoot: Data32 } | ||
| struct RecentHistoryInput: Codable { | ||
| let headerHash: Data32; let parentStateRoot: Data32; let accumulateRoot: Data32; let workPackages: [ReportedWorkPackage] | ||
| } | ||
| struct RecentHistoryTestcase: Codable { let input: RecentHistoryInput; let preState: RecentHistory; let postState: RecentHistory } | ||
| let historyCases = w3f("stf/history/full") | ||
| if !historyCases.isEmpty { | ||
| let cfg = TestVariants.full.config | ||
| Benchmark("w3f.history.full.update") { _ in | ||
| for c in historyCases { | ||
| let tc = try! JamDecoder.decode(RecentHistoryTestcase.self, from: c.data, withConfig: cfg) | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| var state = tc.preState | ||
| state.updatePartial(parentStateRoot: tc.input.parentStateRoot) | ||
| let lookup = Dictionary(uniqueKeysWithValues: tc.input.workPackages.map { ($0.hash, $0.exportsRoot) }) | ||
| state.update(headerHash: tc.input.headerHash, accumulateRoot: tc.input.accumulateRoot, lookup: lookup) | ||
| blackHole(state) | ||
| } | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import Foundation | ||
|
|
||
| // Public helpers to expose W3F testcases for external benchmark targets. | ||
| public enum JAMBenchSupport { | ||
| // Loads W3F testcases from the embedded resources within the JAMTests module. | ||
| public static func w3fTestcases(at path: String, ext: String = "bin") throws -> [Testcase] { | ||
| try TestLoader.getTestcases(path: path, extension: ext, src: .w3f) | ||
| } | ||
|
|
||
| // Load a single W3F resource file (e.g. a companion JSON). | ||
| public static func w3fFile(at path: String, ext: String) throws -> Data { | ||
| try TestLoader.getFile(path: path, extension: ext, src: .w3f) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.