Post

Replies

Boosts

Views

Activity

Ditto cannot extract ZIP file into filesystem-compressed files
It's quite common for app bundles to be distributed in .zip files, and to be stored on-disk as filesystem-compressed files. However, having them both appears to be an edge case that's broken for at least two major releases! (FB19048357, FB19329524) I'd expect a simple ditto -x -k appbundle.zip ~/Applications (-x: extract, -k: work on a zip file) to work. Instead it spits out countless errors and leaves 0 Byte files in the aftermath 😭 Please fix.
4
0
158
Nov ’25
hdiutil prints invisible characters for its devnode output
This script from man hdiutil no longer works: devnode=$(hdiutil attach -nomount ram://102400) newfs_hfs “$devnode” mount -t hfs “$devnode” /path/to/ramdisk because $devnode contains spaces and tabs!! $ hdiutil attach -nomount ram://1 | xxd 00000000: 2f64 6576 2f64 6973 6b34 2020 2020 2020 /dev/disk4 00000010: 2020 2020 0920 2020 2020 2020 2020 2020 . 00000020: 2020 2020 2020 2020 2020 2020 2020 2020 00000030: 2020 2020 090a # remember to clean up afterwards $ hdiutil detach /dev/disk4 Please properly quote your variables in CI test scripts to catch such regression. It could pass because unquoted expansion of $devnode undergoes word splitting after the variable is substituted, removing the trailing whitespaces. FB20303191
1
0
42
Nov ’25
MPSMatrixRandom SEGFAULTs when ran in an async context
The following minimal snippet SEGFAULTS with SDK 26.0 and 26.1. Won't crash if I remove async from the enclosing function signature - but it's impractical in a real project. import Metal import MetalPerformanceShaders let SEED = UInt64(0x0) typealias T = Float16 /* Why ran in async context? Because global GPU object, and async makeMTLFunction, and async makeMTLComputePipelineState. Nevertheless, can trigger the bug without using global @MainActor let myGPU = MyGPU() */ @main struct CMDLine { static func main() async { let ptr = UnsafeMutablePointer<T>.allocate(capacity: 0) async let future: Void = randomFillOnGPU(ptr, count: 0) print("Main thread is playing around") await future print("Successfully reached the end.") } static func randomFillOnGPU(_ buf: UnsafeMutablePointer<T>, count destbufcount: Int) async { // let (device, queue) = await (myGPU.device, myGPU.commandqueue) let myGPU = MyGPU() let (device, queue) = (myGPU.device, myGPU.commandqueue) // Init MTLBuffer, async let makeFunction, makeComputePipelineState, etc. let tempDataType = MPSDataType.uInt32 let randfiller = MPSMatrixRandomMTGP32(device: device, destinationDataType: tempDataType, seed: Int(bitPattern:UInt(SEED))) print("randomFillOnGPU: successfully created MPSMatrixRandom.") // try await computePipelineState // ^ Crashes before this could return // Or in this minimal case, after randomFillOnGPU() returns // make encoder, set pso, dispatch, commit... } } actor MyGPU { let device : MTLDevice let commandqueue : MTLCommandQueue init() { guard let dev: MTLDevice = MPSGetPreferredDevice(.skipRemovable), let cq = dev.makeCommandQueue(), dev.supportsFamily(.apple6) || dev.supportsFamily(.mac2) else { print("Unable to get Metal Device! Exiting"); exit(EX_UNAVAILABLE) } print("Selected device: \(String(format: "%llX", dev.registryID))") self.device = dev self.commandqueue = cq print("myGPU: initialization complete.") } } See FB20916929. Apparently objc autorelease pool is releasing the wrong address during context switch (across suspension points). I wonder why such obvious case has not been caught before.
0
0
70
Nov ’25
Horrendous Swift overlay of vDSP Fourier Transform functions
I'm very unpleased to have found out the hard way, that vDSP.FFT&amp;lt;T&amp;gt; where T : vDSP_FourierTransformable and its associated vDSP_FourierTransformFunctions, only does real-complex conversion!!! This is horribly misleading - the only hint that it calls vDSP_fft_zrop() (split-complex real-complex out-of-place) under the hood, not vDSP_fft_zop()[1], is "A 1D single- and double-precision fast Fourier transform." - instead of "a single- and double-precision complex fast Fourier transform". Holy ******* ****. Just look at how people miss-call this routine. Poor him, realizing he had to log2n+1 lest only the first half of the array was transformed, not understanding why [2]. And poor me, having taken days investigating why a simple Swift overlay vDSP.FFT.transform may execute at 1.4x the speed of vDSP_fft_zopt(out-of-place with temporary buffer)! [3] [1]: or better, vDSP_fft_zopt with the temp buffer alloc/dealloc taken care of, for us [2]: for real-complex conversion, say real signal of length 16. log2n is 4 no problem, but then the real and imaginary vectors are both length 8. Also, vDSP_fft only works on integer powers of 2, so he had to choose next integer power of 2 (i.e. 1&amp;lt;&amp;lt;(log2n-1)) instead of plain length for his internal arrays. [3]: you guessed it. fft_zrop(log2n-1, ...) vs. fft_zop(log2n, ...). Half the problem size lol. Now we have vDSP.DiscreteFourierTransform, which wraps vDSP_DFT routines and "calls FFT routines when the size allows it", and works too for interleaved complexes. Just go all DFT, right? if let setup_f = try? vDSP.DiscreteFourierTransform(previous: nil, count: 8, direction: .forward, transformType: .complexComplex, ofType: DSPComplex.self) { // Done forward transformation // and scaled the results with 1/N // How about going reverse? if let setup_r = try? vDSP.DiscreteFourierTransform(previous: setup_f, count: 8, direction: .inverse, transformType: .complexComplex, ofType: DSPComplex.self) { // Error: cannot convert vDSP.DiscreteFourierTransform&amp;lt;DSPComplex&amp;gt; to vDSP.DiscreteFourierTransform&amp;lt;Float&amp;gt; // lolz } } This API appeared in macOS 12. 3 years later nobody have ever noticed. I'm at a loss for words.
4
0
141
Jun ’25