Skip to content

Commit 2c1f400

Browse files
authored
Merge pull request swiftlang#16953 from gottesmm/pr-06f7b1dfb03e403b21cbd8127a3a4cc7aeabfbf2
[benchmark] Add two low level Radix2CooleyTukey benchmarks.
2 parents 7b317dd + 1124a37 commit 2c1f400

File tree

3 files changed

+261
-0
lines changed

3 files changed

+261
-0
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ set(SWIFT_BENCH_MODULES
125125
single-source/Queue
126126
single-source/RC4
127127
single-source/RGBHistogram
128+
single-source/Radix2CooleyTukey
128129
single-source/RandomShuffle
129130
single-source/RandomValues
130131
single-source/RangeAssignment
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
// Radix2CooleyTukey benchmark
2+
//
3+
// Originally written by @owensd. Used with his permission.
4+
5+
import Foundation
6+
import TestsUtils
7+
8+
public var Radix2CooleyTukey = [
9+
BenchmarkInfo(
10+
name: "Radix2CooleyTukey",
11+
runFunction: run_Radix2CooleyTukey,
12+
tags: [.validation, .algorithm],
13+
setUpFunction: setUpRadix2CooleyTukey,
14+
tearDownFunction: tearDownRadix2CooleyTukey),
15+
BenchmarkInfo(
16+
name: "Radix2CooleyTukeyf",
17+
runFunction: run_Radix2CooleyTukeyf,
18+
tags: [.validation, .algorithm],
19+
setUpFunction: setUpRadix2CooleyTukeyf,
20+
tearDownFunction: tearDownRadix2CooleyTukeyf),
21+
]
22+
23+
//===----------------------------------------------------------------------===//
24+
// Double Benchmark
25+
//===----------------------------------------------------------------------===//
26+
27+
var double_input_real: UnsafeMutablePointer<Double>?
28+
var double_input_imag: UnsafeMutablePointer<Double>?
29+
var double_output_real: UnsafeMutablePointer<Double>?
30+
var double_output_imag: UnsafeMutablePointer<Double>?
31+
var double_temp_real: UnsafeMutablePointer<Double>?
32+
var double_temp_imag: UnsafeMutablePointer<Double>?
33+
34+
let doubleN = 65_536
35+
let doubleSize = { MemoryLayout<Double>.size * doubleN }()
36+
37+
func setUpRadix2CooleyTukey() {
38+
let size = doubleSize
39+
40+
double_input_real = UnsafeMutablePointer<Double>.allocate(capacity: size)
41+
double_input_imag = UnsafeMutablePointer<Double>.allocate(capacity: size)
42+
double_output_real = UnsafeMutablePointer<Double>.allocate(capacity: size)
43+
double_output_imag = UnsafeMutablePointer<Double>.allocate(capacity: size)
44+
double_temp_real = UnsafeMutablePointer<Double>.allocate(capacity: size)
45+
double_temp_imag = UnsafeMutablePointer<Double>.allocate(capacity: size)
46+
}
47+
48+
func tearDownRadix2CooleyTukey() {
49+
double_input_real?.deallocate()
50+
double_input_imag?.deallocate()
51+
double_output_real?.deallocate()
52+
double_output_imag?.deallocate()
53+
double_temp_real?.deallocate()
54+
double_temp_imag?.deallocate()
55+
}
56+
57+
func Radix2CooleyTukey(_ level: Int,
58+
input_real: UnsafeMutablePointer<Double>,
59+
input_imag: UnsafeMutablePointer<Double>,
60+
stride: Int, output_real: UnsafeMutablePointer<Double>,
61+
output_imag: UnsafeMutablePointer<Double>,
62+
temp_real: UnsafeMutablePointer<Double>,
63+
temp_imag: UnsafeMutablePointer<Double>) {
64+
if level == 0 {
65+
output_real[0] = input_real[0];
66+
output_imag[0] = input_imag[0];
67+
return
68+
}
69+
let length = 1 << level
70+
let half = length >> 1
71+
Radix2CooleyTukey(level - 1,
72+
input_real: input_real,
73+
input_imag: input_imag,
74+
stride: stride << 1,
75+
output_real: temp_real,
76+
output_imag: temp_imag,
77+
temp_real: output_real,
78+
temp_imag: output_imag)
79+
Radix2CooleyTukey(level - 1,
80+
input_real: input_real + stride,
81+
input_imag: input_imag + stride,
82+
stride: stride << 1,
83+
output_real: temp_real + half,
84+
output_imag: temp_imag + half,
85+
temp_real: output_real + half,
86+
temp_imag: output_imag + half)
87+
for idx in 0..<half {
88+
let angle = -Double.pi * Double(idx) / Double(half)
89+
let _cos = cos(angle)
90+
let _sin = sin(angle)
91+
output_real[idx] = temp_real[idx] + _cos *
92+
temp_real[idx + half] - _sin * temp_imag[idx + half]
93+
output_imag[idx] = temp_imag[idx] + _cos *
94+
temp_imag[idx + half] + _sin *
95+
temp_real[idx + half]
96+
output_real[idx + half] = temp_real[idx] - _cos *
97+
temp_real[idx + half] + _sin *
98+
temp_imag[idx + half]
99+
output_imag[idx + half] = temp_imag[idx] - _cos *
100+
temp_imag[idx + half] - _sin *
101+
temp_real[idx + half]
102+
}
103+
}
104+
105+
func testDouble(iter: Int) {
106+
let stride = 1
107+
108+
let size = doubleSize
109+
let level = Int(log2(Double(doubleN)))
110+
111+
let input_real = double_input_real._unsafelyUnwrappedUnchecked
112+
let input_imag = double_input_imag._unsafelyUnwrappedUnchecked
113+
let output_real = double_output_real._unsafelyUnwrappedUnchecked
114+
let output_imag = double_output_imag._unsafelyUnwrappedUnchecked
115+
let temp_real = double_temp_real._unsafelyUnwrappedUnchecked
116+
let temp_imag = double_temp_imag._unsafelyUnwrappedUnchecked
117+
118+
for _ in 0..<iter {
119+
memset(UnsafeMutableRawPointer(input_real), 0, size)
120+
memset(UnsafeMutableRawPointer(input_imag), 0, size)
121+
memset(UnsafeMutableRawPointer(output_real), 0, size)
122+
memset(UnsafeMutableRawPointer(output_imag), 0, size)
123+
memset(UnsafeMutableRawPointer(temp_real), 0, size)
124+
memset(UnsafeMutableRawPointer(temp_imag), 0, size)
125+
126+
Radix2CooleyTukey(level,
127+
input_real: input_real,
128+
input_imag: input_imag,
129+
stride: stride,
130+
output_real: output_real,
131+
output_imag: output_imag,
132+
temp_real: temp_real,
133+
temp_imag: temp_imag)
134+
}
135+
}
136+
137+
@inline(never)
138+
public func run_Radix2CooleyTukey(_ N: Int) {
139+
testDouble(iter: N)
140+
}
141+
142+
//===----------------------------------------------------------------------===//
143+
// Float Benchmark
144+
//===----------------------------------------------------------------------===//
145+
146+
let floatN = 65_536
147+
let floatSize = { MemoryLayout<Float>.size * floatN }()
148+
149+
var float_input_real: UnsafeMutablePointer<Float>?
150+
var float_input_imag: UnsafeMutablePointer<Float>?
151+
var float_output_real: UnsafeMutablePointer<Float>?
152+
var float_output_imag: UnsafeMutablePointer<Float>?
153+
var float_temp_real: UnsafeMutablePointer<Float>?
154+
var float_temp_imag: UnsafeMutablePointer<Float>?
155+
156+
func setUpRadix2CooleyTukeyf() {
157+
let size = floatSize
158+
float_input_real = UnsafeMutablePointer<Float>.allocate(capacity: size)
159+
float_input_imag = UnsafeMutablePointer<Float>.allocate(capacity: size)
160+
float_output_real = UnsafeMutablePointer<Float>.allocate(capacity: size)
161+
float_output_imag = UnsafeMutablePointer<Float>.allocate(capacity: size)
162+
float_temp_real = UnsafeMutablePointer<Float>.allocate(capacity: size)
163+
float_temp_imag = UnsafeMutablePointer<Float>.allocate(capacity: size)
164+
}
165+
166+
func tearDownRadix2CooleyTukeyf() {
167+
float_input_real?.deallocate()
168+
float_input_imag?.deallocate()
169+
float_output_real?.deallocate()
170+
float_output_imag?.deallocate()
171+
float_temp_real?.deallocate()
172+
float_temp_imag?.deallocate()
173+
}
174+
175+
func Radix2CooleyTukeyf(_ level: Int,
176+
input_real: UnsafeMutablePointer<Float>,
177+
input_imag: UnsafeMutablePointer<Float>,
178+
stride: Int, output_real: UnsafeMutablePointer<Float>,
179+
output_imag: UnsafeMutablePointer<Float>,
180+
temp_real: UnsafeMutablePointer<Float>,
181+
temp_imag: UnsafeMutablePointer<Float>) {
182+
if level == 0 {
183+
output_real[0] = input_real[0];
184+
output_imag[0] = input_imag[0];
185+
return
186+
}
187+
let length = 1 << level
188+
let half = length >> 1
189+
Radix2CooleyTukeyf(level - 1,
190+
input_real: input_real,
191+
input_imag: input_imag,
192+
stride: stride << 1,
193+
output_real: temp_real,
194+
output_imag: temp_imag,
195+
temp_real: output_real,
196+
temp_imag: output_imag)
197+
Radix2CooleyTukeyf(level - 1,
198+
input_real: input_real + stride,
199+
input_imag: input_imag + stride,
200+
stride: stride << 1,
201+
output_real: temp_real + half,
202+
output_imag: temp_imag + half,
203+
temp_real: output_real + half,
204+
temp_imag: output_imag + half)
205+
for idx in 0..<half {
206+
let angle = -Float.pi * Float(idx) / Float(half)
207+
let _cos = cosf(angle)
208+
let _sin = sinf(angle)
209+
output_real[idx] = temp_real[idx] + _cos *
210+
temp_real[idx + half] - _sin * temp_imag[idx + half]
211+
output_imag[idx] = temp_imag[idx] + _cos *
212+
temp_imag[idx + half] + _sin * temp_real[idx + half]
213+
output_real[idx + half] = temp_real[idx] - _cos *
214+
temp_real[idx + half] + _sin *
215+
temp_imag[idx + half]
216+
output_imag[idx + half] = temp_imag[idx] - _cos *
217+
temp_imag[idx + half] - _sin *
218+
temp_real[idx + half]
219+
}
220+
}
221+
222+
func testFloat(iter: Int) {
223+
let stride = 1
224+
let n = floatN
225+
let size = floatSize
226+
227+
let input_real = float_input_real._unsafelyUnwrappedUnchecked
228+
let input_imag = float_input_imag._unsafelyUnwrappedUnchecked
229+
let output_real = float_output_real._unsafelyUnwrappedUnchecked
230+
let output_imag = float_output_imag._unsafelyUnwrappedUnchecked
231+
let temp_real = float_temp_real._unsafelyUnwrappedUnchecked
232+
let temp_imag = float_temp_imag._unsafelyUnwrappedUnchecked
233+
234+
let level = Int(log2(Float(n)))
235+
236+
for _ in 0..<iter {
237+
memset(UnsafeMutableRawPointer(input_real), 0, size)
238+
memset(UnsafeMutableRawPointer(input_imag), 0, size)
239+
memset(UnsafeMutableRawPointer(output_real), 0, size)
240+
memset(UnsafeMutableRawPointer(output_imag), 0, size)
241+
memset(UnsafeMutableRawPointer(temp_real), 0, size)
242+
memset(UnsafeMutableRawPointer(temp_imag), 0, size)
243+
244+
Radix2CooleyTukeyf(level,
245+
input_real: input_real,
246+
input_imag: input_imag,
247+
stride: stride,
248+
output_real: output_real,
249+
output_imag: output_imag,
250+
temp_real: temp_real,
251+
temp_imag: temp_imag)
252+
}
253+
}
254+
255+
@inline(never)
256+
public func run_Radix2CooleyTukeyf(_ N: Int) {
257+
testFloat(iter: N)
258+
}

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import ProtocolDispatch2
114114
import Queue
115115
import RC4
116116
import RGBHistogram
117+
import Radix2CooleyTukey
117118
import RandomShuffle
118119
import RandomValues
119120
import RangeAssignment
@@ -274,6 +275,7 @@ registerBenchmark(QueueGeneric)
274275
registerBenchmark(QueueConcrete)
275276
registerBenchmark(RC4Test)
276277
registerBenchmark(RGBHistogram)
278+
registerBenchmark(Radix2CooleyTukey)
277279
registerBenchmark(RandomShuffle)
278280
registerBenchmark(RandomValues)
279281
registerBenchmark(RangeAssignment)

0 commit comments

Comments
 (0)