From 157b1871166b9a92157d7e2d8eddff618c8f64c6 Mon Sep 17 00:00:00 2001 From: "John K. Luebs" Date: Wed, 30 Oct 2024 17:07:53 -0500 Subject: [PATCH] Attempt Swift 5.9 compatibility. --- Package.resolved | 3 +- Package.swift | 6 +-- Sources/PFFFT/FFT.swift | 27 +++++++---- Tests/PFFFTTests/PFFFTTests.swift | 79 ++++++++++++++++--------------- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/Package.resolved b/Package.resolved index 4948396..57cbb8b 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,4 @@ { - "originHash" : "d50b9049eb671b1ad14bc8ba592c78735f9e357a6b59835343af6e20e8be4701", "pins" : [ { "identity" : "swift-numerics", @@ -11,5 +10,5 @@ } } ], - "version" : 3 + "version" : 2 } diff --git a/Package.swift b/Package.swift index 8c69197..68e3db6 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -22,12 +22,12 @@ let package = Package( .define("PFFFT_SCALVEC_ENABLED", to: "1"), .define("_USE_MATH_DEFINES"), .define("NDEBUG"), - .unsafeFlags(["-O3"]), ] ), .target( name: "PFFFT", - dependencies: ["PFFFTLib", .product(name: "Numerics", package: "swift-numerics")] + dependencies: ["PFFFTLib", .product(name: "Numerics", package: "swift-numerics")], + swiftSettings: [.enableExperimentalFeature("AccessLevelOnImport")] ), .testTarget( name: "PFFFTTests", diff --git a/Sources/PFFFT/FFT.swift b/Sources/PFFFT/FFT.swift index 5f13957..4f0f916 100644 --- a/Sources/PFFFT/FFT.swift +++ b/Sources/PFFFT/FFT.swift @@ -159,14 +159,20 @@ public struct FFT: ~Copyable { let ptr: OpaquePointer let n: Int - let work: Buffer? + let work: Buffer let setup: Setup public init(setup: Setup) { self.setup = setup ptr = setup.ptr n = setup.n - work = n > 4096 ? Buffer(capacity: T.self == ComplexType.self ? 2 * n : n) : nil + + let workCapacity = if n > 4096 { + T.self == ComplexType.self ? 2 * n : n + } else { + 0 + } + work = Buffer(capacity: workCapacity) } /// Initialize the FFT implementation with the given size and type. @@ -202,10 +208,11 @@ public struct FFT: ~Copyable { } @inline(__always) - func toAddress(_ work: borrowing Buffer?) -> UnsafeMutablePointer? { - switch work { - case let .some(b): return b.baseAddress - case .none: return nil + var workPtr: UnsafeMutablePointer? { + if work.count > 0 { + return work.baseAddress + } else { + return nil } } @@ -271,12 +278,12 @@ public struct FFT: ~Copyable { /// - sign: The direction of the FFT. public func forward(signal: borrowing Buffer, spectrum: borrowing Buffer) { checkFftBufferCounts(signal: signal, spectrum: spectrum) - ScalarType.pffftTransformOrdered(ptr, rebind(signal), rebind(spectrum), toAddress(work), .forward) + ScalarType.pffftTransformOrdered(ptr, rebind(signal), rebind(spectrum), workPtr, .forward) } public func inverse(spectrum: borrowing Buffer, signal: borrowing Buffer) { checkFftBufferCounts(signal: signal, spectrum: spectrum) - ScalarType.pffftTransformOrdered(ptr, rebind(spectrum), rebind(signal), toAddress(work), .backward) + ScalarType.pffftTransformOrdered(ptr, rebind(spectrum), rebind(signal), workPtr, .backward) } /// Perform a forward FFT on the input buffer, with implementation defined order. @@ -290,12 +297,12 @@ public struct FFT: ~Copyable { /// - sign: The direction of the FFT. public func forwardToInternalLayout(signal: borrowing Buffer, spectrum: borrowing Buffer) { checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum) - ScalarType.pffftTransform(ptr, rebind(signal), spectrum.baseAddress, toAddress(work), .forward) + ScalarType.pffftTransform(ptr, rebind(signal), spectrum.baseAddress, workPtr, .forward) } public func inverseFromInternalLayout(spectrum: borrowing Buffer, signal: borrowing Buffer) { checkFftInternalLayoutBufferCounts(signal: signal, spectrum: spectrum) - ScalarType.pffftTransform(ptr, spectrum.baseAddress, rebind(signal), toAddress(work), .backward) + ScalarType.pffftTransform(ptr, spectrum.baseAddress, rebind(signal), workPtr, .backward) } public func reorder(spectrum: borrowing Buffer, output: borrowing Buffer) { diff --git a/Tests/PFFFTTests/PFFFTTests.swift b/Tests/PFFFTTests/PFFFTTests.swift index b72e04f..f7c54b2 100644 --- a/Tests/PFFFTTests/PFFFTTests.swift +++ b/Tests/PFFFTTests/PFFFTTests.swift @@ -1,50 +1,51 @@ -import Testing import ComplexModule @testable import PFFFT +import XCTest -@Test func fftFloat() async throws { +final class FFTTests: XCTestCase { + func testFftFloat() throws { + let fft = try FFT>(n: 16) + let signal = fft.makeSignalBuffer() + let spectrum = fft.makeSpectrumBuffer() - let fft = try FFT>(n: 16) - let signal = fft.makeSignalBuffer() - let spectrum = fft.makeSpectrumBuffer() + signal.mapInPlace { i, v in + v = Complex(Float(i) + 1.0, Float(i) - 2.0) + } - signal.mutateEach { (i, v) in - v = Complex(Float(i) + 1.0, Float(i) - 2.0) - } + fft.forward(signal: signal, spectrum: spectrum) - fft.forward(signal: signal, spectrum: spectrum) + let result = spectrum.map { $0 } + let expected: [Complex] = [ + .init(136.0, 88.0), + .init(-48.218716, 32.218716), + .init(-27.31371, 11.313708), + .init(-19.972847, 3.972846), + .init(-16.0, 0.0), + .init(-13.345428, -2.6545706), + .init(-11.313709, -4.6862917), + .init(-9.591298, -6.408703), + .init(-8.0, -8.0), + .init(-6.408703, -9.591298), + .init(-4.6862917, -11.313708), + .init(-2.6545706, -13.345429), + .init(0.0, -16.0), + .init(3.972845, -19.972847), + .init(11.313707, -27.31371), + .init(32.218716, -48.218716), + ] + for (r, e) in zip(result, expected) { + XCTAssert(r.isApproximatelyEqual(to: e)) + } - let result = spectrum.map { $0 } - let expected: [Complex] = [ - .init(136.0, 88.0), - .init(-48.218716, 32.218716), - .init(-27.31371, 11.313708), - .init(-19.972847, 3.972846), - .init(-16.0, 0.0), - .init(-13.345428, -2.6545706), - .init(-11.313709, -4.6862917), - .init(-9.591298, -6.408703), - .init(-8.0, -8.0), - .init(-6.408703, -9.591298), - .init(-4.6862917, -11.313708), - .init(-2.6545706, -13.345429), - .init(0.0, -16.0), - .init(3.972845, -19.972847), - .init(11.313707, -27.31371), - .init(32.218716, -48.218716), - ] - zip(result, expected).forEach { r, e in - #expect(r.isApproximatelyEqual(to: e)) - } + fft.inverse(spectrum: spectrum, signal: signal) - fft.inverse(spectrum: spectrum, signal: signal) + let signalResult = signal.map { $0 } + let signalExpected = (0 ..< 16).map { i in + Complex(Float(i) + 1.0, Float(i) - 2.0) * 16 + } - let signalResult = signal.map { $0 } - let signalExpected = (0..<16).map { i in - Complex(Float(i) + 1.0, Float(i) - 2.0) * 16 - } - - zip(signalResult, signalExpected).forEach { r, e in - #expect(r.isApproximatelyEqual(to: e)) + for (r, e) in zip(signalResult, signalExpected) { + XCTAssert(r.isApproximatelyEqual(to: e)) + } } }