Skip to content

Commit 45b7743

Browse files
committed
[benchmark] Add the ability for a benchmark to specify that it does not run on specific platforms.
Today, one can not completely disable a benchmark depending on the platform without changing the source of main.swift. We would like to be able to disable benchmarks locally in a benchmark's file without needing to modify the rest of the infrastructure. The closest that one can get to such behavior is to just conditionally compile out the file locally. But one still will have the test run. This commit adds support for not-running the benchmark on specific platforms. This in combination with conditional compilation of benchmark bodies, allows us to not have to comment out module's in main.swift or have to conditionally compile testinfo. rdar://40541972
1 parent ba9cc17 commit 45b7743

File tree

2 files changed

+83
-12
lines changed

2 files changed

+83
-12
lines changed

benchmark/utils/DriverUtils.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct Test {
6363
}
6464

6565
/// The "main routine" of the benchmark.
66-
var runFunction: (Int) -> () {
66+
var runFunction: ((Int) -> ())? {
6767
return benchInfo.runFunction
6868
}
6969

@@ -358,9 +358,19 @@ class SampleRunner {
358358
}
359359

360360
/// Invoke the benchmark entry point and return the run time in milliseconds.
361-
func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
361+
func runBench(_ test: Test, _ c: TestConfig) -> BenchResults? {
362362
var samples = [UInt64](repeating: 0, count: c.numSamples)
363363

364+
// Before we do anything, check that we actually have a function to
365+
// run. If we don't it is because the benchmark is not supported on
366+
// the platform and we should skip it.
367+
guard let testFn = test.runFunction else {
368+
if c.verbose {
369+
print("Skipping unsupported benchmark \(test.name)!")
370+
}
371+
return nil
372+
}
373+
364374
if c.verbose {
365375
print("Running \(test.name) for \(c.numSamples) samples.")
366376
}
@@ -373,7 +383,7 @@ func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
373383
var elapsed_time : UInt64 = 0
374384
if c.fixedNumIters == 0 {
375385
test.setUpFunction?()
376-
elapsed_time = sampler.run(test.name, fn: test.runFunction, num_iters: 1)
386+
elapsed_time = sampler.run(test.name, fn: testFn, num_iters: 1)
377387
test.tearDownFunction?()
378388

379389
if elapsed_time > 0 {
@@ -395,7 +405,7 @@ func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
395405
print(" Measuring with scale \(scale).")
396406
}
397407
test.setUpFunction?()
398-
elapsed_time = sampler.run(test.name, fn: test.runFunction, num_iters: scale)
408+
elapsed_time = sampler.run(test.name, fn: testFn, num_iters: scale)
399409
test.tearDownFunction?()
400410
} else {
401411
scale = 1
@@ -442,7 +452,11 @@ func runBenchmarks(_ c: TestConfig) {
442452
sumBenchResults.sampleCount = 0
443453

444454
for t in c.tests {
445-
let results = runBench(t, c)
455+
guard let results = runBench(t, c) else {
456+
print("\(t.index)\(c.delim)\(t.name)\(c.delim)Unsupported")
457+
fflush(stdout)
458+
continue
459+
}
446460
print("\(t.index)\(c.delim)\(t.name)\(c.delim)\(results.description)")
447461
fflush(stdout)
448462

benchmark/utils/TestsUtils.swift

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,91 @@ public enum BenchmarkCategory : String {
7070
case skip
7171
}
7272

73+
public struct BenchmarkPlatformSet : OptionSet {
74+
public let rawValue: Int
75+
76+
public init(rawValue: Int) {
77+
self.rawValue = rawValue
78+
}
79+
80+
public static let darwin = BenchmarkPlatformSet(rawValue: 1 << 0)
81+
public static let linux = BenchmarkPlatformSet(rawValue: 1 << 1)
82+
83+
public static var currentPlatform: BenchmarkPlatformSet {
84+
#if os(Linux)
85+
return .linux
86+
#else
87+
return .darwin
88+
#endif
89+
}
90+
91+
public static var allPlatforms: BenchmarkPlatformSet {
92+
return [.darwin, .linux]
93+
}
94+
}
95+
7396
public struct BenchmarkInfo {
7497
/// The name of the benchmark that should be displayed by the harness.
7598
public var name: String
7699

100+
/// Shadow static variable for runFunction.
101+
private var _runFunction: (Int) -> ()
102+
77103
/// A function that invokes the specific benchmark routine.
78-
public var runFunction: (Int) -> ()
104+
public var runFunction: ((Int) -> ())? {
105+
if !shouldRun {
106+
return nil
107+
}
108+
return _runFunction
109+
}
79110

80111
/// A set of category tags that describe this benchmark. This is used by the
81112
/// harness to allow for easy slicing of the set of benchmarks along tag
82113
/// boundaries, e.x.: run all string benchmarks or ref count benchmarks, etc.
83114
public var tags: [BenchmarkCategory]
84115

116+
/// The platforms that this benchmark supports. This is an OptionSet.
117+
private var unsupportedPlatforms: BenchmarkPlatformSet
118+
119+
/// Shadow variable for setUpFunction.
120+
private var _setUpFunction: (() -> ())?
121+
85122
/// An optional function that if non-null is run before benchmark samples
86123
/// are timed.
87-
public var setUpFunction: (() -> ())?
124+
public var setUpFunction : (() -> ())? {
125+
if !shouldRun {
126+
return nil
127+
}
128+
return _setUpFunction
129+
}
130+
131+
/// Shadow static variable for computed property tearDownFunction.
132+
private var _tearDownFunction: (() -> ())?
88133

89134
/// An optional function that if non-null is run immediately after a sample is
90135
/// taken.
91-
public var tearDownFunction: (() -> ())?
136+
public var tearDownFunction: (() -> ())? {
137+
if !shouldRun {
138+
return nil
139+
}
140+
return _tearDownFunction
141+
}
92142

93143
public init(name: String, runFunction: @escaping (Int) -> (), tags: [BenchmarkCategory],
94144
setUpFunction: (() -> ())? = nil,
95-
tearDownFunction: (() -> ())? = nil) {
145+
tearDownFunction: (() -> ())? = nil,
146+
unsupportedPlatforms: BenchmarkPlatformSet = []) {
96147
self.name = name
97-
self.runFunction = runFunction
148+
self._runFunction = runFunction
98149
self.tags = tags
99-
self.setUpFunction = setUpFunction
100-
self.tearDownFunction = tearDownFunction
150+
self._setUpFunction = setUpFunction
151+
self._tearDownFunction = tearDownFunction
152+
self.unsupportedPlatforms = unsupportedPlatforms
153+
}
154+
155+
/// Returns true if this benchmark should be run on the current platform.
156+
var shouldRun: Bool {
157+
return !unsupportedPlatforms.contains(.currentPlatform)
101158
}
102159
}
103160

0 commit comments

Comments
 (0)