Posts

Post not yet marked as solved
6 Replies
0 Views
Is this work entirely CPU bound? No GPU's involved, so I guess so. The app does nothing outside of the machine upon which it runs. Once the database is generated the app just becomes a viewing instrument. This reply is two weeks late because for two weeks the machine was busy generating useless data. lol. (Down from a 300 year estimated compute time, so yay, progress!) We can probably close this thread because I have no need to generate data on unknown machines. Thanks.
Post not yet marked as solved
6 Replies
0 Views
My original intent was flawed, i. e., trying to optimize code using pre-compiler tests would only be useful for those who would be compiling, and not app users. What do you plan to do with that info? My app has nested for-loops sometimes eighteen deep. By strategically placing DispatchQueue's between the outer loops I can keep all my cpu's busy, minimizing compute time. In an app I can Switch() on the ncpu to the appropriate nest for optimization. As one who compiles the code, it's actually easier for me to edit the nests to my machines ncpu. A second flaw in my thought process is that once the data is generated no-one need generate it again. Nevertheless, I love solving mysteries or maybe just pursuing solutions.
Post not yet marked as solved
6 Replies
0 Views
Re-discovered eskimo's "//developer.apple.com/forums/thread/690310". Result: launch(tool: URL(fileURLWithPath: "/usr/sbin/sysctl"), arguments: ["-n", "hw.ncpu" ], completionHandler: { (status, outputData) in let output = String(data: outputData, encoding: .utf8) ?? "" self.ncpu = (output as NSString).integerValue print("done, status: \(status), output: \(self.ncpu)") }) where I had declared ncpu elsewhere in the app. Thank you eskimo!
Post not yet marked as solved
6 Replies
0 Views
I have attempted to use sysctl() to retrieve the count. It prints the correct value to standard out, i.e., the debugger area but Idk how to capture it in swiftui. ".standardOutput" throws something called an "NSConcreteTask", and not the Int() I was expecting. NSConcreteTask has no entry in the "Developer Documentation" of Xcode, so I'm stuck. let getCPUct = Process() getCPUct.executableURL = URL(fileURLWithPath: "/usr/sbin/sysctl") getCPUct.arguments = ["-n", "hw.ncpu" ] do { try getCPUct.run() // throws 6 to standard out if let output = getCPUct.standardOutput as? Int { print("#file:#line cpu count = \(output)") return output } } catch let error as NSError { print("Failed to execute sysctl", error) } return 0 }
Post marked as solved
5 Replies
0 Views
I have migrated my app to SwiftUI and this issue is solved in my post "EnvironmentObject as progressValue in ProgressView()" Thanks As for my apps "nested for-loops" I am pursuing DispatchQueue with multiple cpu's. See my post: "precompiler test for cpu count". My six cpu Mini now requires three months of computations, not a thousand years.
Post marked as solved
3 Replies
0 Views
Found a solution! Search: "quick-start/swiftui/how-to-show-progress-on-a-task-using-progress" Use a Timer to allow ProgressView to update from EnvironmentObject vars. Then you must config your app-file with the proper .environmentObject() app-file: import SwiftUI @main struct test_progressView_EnvObjApp: App { var body: some Scene { WindowGroup { ContentView().environmentObject(Model.init(progressValue: 0.0)) } } } Model-file: import Foundation import SwiftUI class Model: ObservableObject { @Published var t_step : Double @Published var progressValue : Double init (progressValue: Double){ self.t_step = 0.0 self.progressValue = 0.0 } func stepThroughTime() { var when = DispatchTime.now() progressValue = 0.0 let _ = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { timer in DispatchQueue.global().asyncAfter(deadline: when ) { [self] in DispatchQueue.main.async { [self] in if progressValue >= 0.9 { progressValue = 0.0 } else { progressValue = progressValue + 0.1 } } when = when + .seconds(2) } } } } ContentView-file: import SwiftUI struct ContentView: View { @EnvironmentObject var model: Model @State var progressValue = 0.0 let timer = Timer.publish(every: 2.0, on: .main, in: .common).autoconnect() // seconds var body: some View { VStack { Button( action: { model.stepThroughTime() } ) { Text("Search") }.environmentObject(model) ProgressView(value: progressValue ).onReceive(timer) { _ in progressValue = model.progressValue }.padding() .environmentObject(model) }.environmentObject(model) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } Thanks to Claude31 for the DispatchQueue-ProgressValue portion. See my post on the subject.
Post marked as solved
8 Replies
0 Views
I looked into ndjson. It required a library download and had a number of conditions for which it would fail. It turns out that editing and appending to my JSON file was not hard at all, due to the consistency of the JSON encoder. Since eskimo provided the invaluable info that keyed archives don't support appending, I'll credit him. Thank you.
Post marked as solved
8 Replies
0 Views
eskimo, thanks for your reply. Is there no way to to append-to-file piecemeal and then read it again? If being keyed is the roadblock, I really don't need it as my original app stored as JSON text anyway. So, how can I save without being keyed? My understanding was that Apple would soon require "SecureCoding" which in turn required keying.
Post marked as solved
8 Replies
0 Views
func loadFile(_ N: Int) -> classTwo? { /* https://developer.apple.com/forums/thread/115643 OOPer https://www.hackingwithswift.com/read/12/3/fixing-project-10-nscoding */ let fileURL = URL(fileURLWithPath: "~/\" ).appendingPathExtension("gut") let defaults = UserDefaults.standard if let data = defaults.object(forKey: "classTwo") as? Data { if FileManager.default.fileExists(atPath: fileURL.path) { do { if let BA = try? NSKeyedUnarchiver.unarchivedObject(ofClass: classTwo.self, from: data) { return BA } } } } return nil }
Post marked as solved
8 Replies
0 Views
// // save-load-code.swift // exampleClassInClassSecureCoding // import Foundation func saveFile(fileName: String, object: classTwo, ext: String, appendToFile: CFBoolean) { let fileDir = URL(fileURLWithPath: "~/") let fileURL = URL(fileURLWithPath: "~/\(fileName)").appendingPathExtension(ext) if !FileManager.default.fileExists(atPath: fileDir.path) { do { try FileManager.default.createDirectory(atPath: "~/", withIntermediateDirectories: false, attributes: nil) } catch { print(error) } do { let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true) try data.write(to: fileURL ) let defaults = UserDefaults.standard defaults.set(data, forKey: "classTwo") } catch { print(error) } } else if appendToFile == kCFBooleanTrue { do { let fileHandle = try FileHandle(forWritingTo: fileURL ) let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true) try fileHandle.seekToEnd() let buffer = FileHandleBuffer(fileHandle: fileHandle) buffer.size = data.count try buffer.write(data) let defaults = UserDefaults.standard defaults.set(data, forKey: "classTwo") } catch { print(error) } } }
Post marked as solved
8 Replies
0 Views
piecemeal then: func genData() { var myOutput = Array(repeating: [classOne](), count: 16 ) let words:[UInt8] = [ 0b01111100, 0b00111100, 0b00011100, 0b00001100, 0b00001000, 0b00000000 ] for word1 in words { for word2 in words { for word3 in words { let candidate = classOne( a_One: "Nothing", b_One: [word1, word2, word3] ) let bitCount = word1.nonzeroBitCount + word2.nonzeroBitCount + word3.nonzeroBitCount myOutput[bitCount].append(candidate) } } } let dataToSave = classTwo(c_Two: Int(myOutput[15][0].b_One[0]), d_Two: log(Double(myOutput[15][0].b_One.count)), e_Two: myOutput[15]) // just some/any data to save saveFile(fileName: "TestFileSecureCodingExample", object: dataToSave, ext: "test", appendToFile: kCFBooleanFalse) }
Post marked as solved
8 Replies
0 Views
Sorry, I'll try that again. Here are the class declarations. I suspect my problem is in them. class classOne: Equatable, NSSecureCoding, Codable, NSCoding { static var supportsSecureCoding = true var a_One : String var b_One : [UInt8] init(a_One: String?, b_One: [UInt8]?) { self.a_One = a_One ?? String() self.b_One = b_One ?? [UInt8]() } enum CodingKeys: String, CodingKey { case a_One, b_One } static var allowedTopLevelClasses: [AnyClass] { return [NSArray.self, NSString.self] } func encode(with aCoder: NSCoder) { aCoder.encode(a_One, forKey: CodingKeys.a_One.rawValue) aCoder.encode(b_One, forKey: CodingKeys.b_One.rawValue) } required init?(coder aDecoder: NSCoder) { a_One = aDecoder.decodeObject(forKey: CodingKeys.a_One.rawValue) as? String ?? String() b_One = aDecoder.decodeObject(forKey: CodingKeys.b_One.rawValue) as? [UInt8] ?? [UInt8]() } static func == (lhs: classOne, rhs: classOne) -> Bool { // unnecessary but mirrors my more-elaborate code if lhs.a_One == rhs.a_One && lhs.b_One == rhs.b_One { return true } else { return false } } } class classTwo: NSObject, NSSecureCoding, Codable, NSCoding { static var supportsSecureCoding = true var c_Two : Int var d_Two : Double var e_Two : [classOne] init(c_Two: Int, d_Two: Double?, e_Two: [classOne]? ) { self.c_Two = c_Two self.d_Two = d_Two ?? Double() self.e_Two = e_Two ?? [classOne]() } enum CodingKeys: String, CodingKey { case c_Two, d_Two, e_Two } static var allowedTopLevelClasses: [AnyClass] { return [NSArray.self, NSString.self, classOne.self] } func encode(with aCoder: NSCoder) { aCoder.encode(c_Two, forKey: CodingKeys.c_Two.rawValue) aCoder.encode(d_Two, forKey: CodingKeys.d_Two.rawValue) aCoder.encode(e_Two, forKey: CodingKeys.e_Two.rawValue) } required init(coder aDecoder: NSCoder) { c_Two = aDecoder.decodeInteger(forKey: CodingKeys.c_Two.rawValue) d_Two = aDecoder.decodeDouble(forKey: CodingKeys.d_Two.rawValue) e_Two = aDecoder.decodeObject(forKey: CodingKeys.e_Two.rawValue) as? [classOne] ?? [classOne]() } }
Post not yet marked as solved
5 Replies
0 Views
Thanks Claude31. Using the last entry in that link, I could make an array of FileHandleBuffer to handle the one hundred active files. However, it appears I must know the Data:Capacity:size ? Which I don't know.
Post marked as solved
5 Replies
0 Views
FYI. Updated for Xcode 13.3.1 ... let bufferLength = N * MemoryLayout<Float>.size let devices = MTLCopyAllDevices() print("\(#file):\(#line) Possible devices: \(devices)") let device = devices[0] print("\(#file):\(#line) Running compute application on device \(device.name)") print("\(#file):\(#line) Adding vectorA and vectorB into vectorC. Each vector is \(N) floats") let commandQueue = device.makeCommandQueue() let defaultLibrary = device.makeDefaultLibrary() let commandBuffer = commandQueue!.makeCommandBuffer() let kernel = defaultLibrary!.makeFunction(name: "add_kernel") let computePipeLineDescriptor = MTLComputePipelineDescriptor() computePipeLineDescriptor.computeFunction = kernel let computePipelineState = try! await device.makeComputePipelineState(descriptor: computePipeLineDescriptor, options: [] ) // Set up thread groups to be used in commandEncoder let thrdWidth = 3 // FOUND NO REPLACEMENT FOR: computePipelineState.threadExecutionWidth, SO USED INTEGER let thrdsPerGroup = MTLSize(width:thrdWidth,height:1,depth:1) let numThrdgroups = MTLSize(width:(N+thrdWidth)/thrdWidth, height:1, depth:1) // Create input and output vectors, and corresponding metal buffers var vectorA = Array(repeating: Float(0.0), count: N) for (index, _) in vectorA.enumerated() { vectorA[index] = Float(index) } var vectorB = Array(repeating: Float(0.0), count: N) for (index, _) in vectorB.enumerated() { vectorB[index] = Float(index * 2) } var vectorC = Array(repeating: Float(0.0), count: N) let bufferA = device.makeBuffer(bytes: vectorA, length: bufferLength, options: []) let bufferB = device.makeBuffer(bytes: vectorB, length: bufferLength, options: []) let bufferC = device.makeBuffer(bytes: vectorC, length: bufferLength, options: []) // Create Compute Command Encoder and add buffers and thread groups let computeCommandEncoder = commandBuffer!.makeComputeCommandEncoder() computeCommandEncoder!.setBuffer(bufferA, offset: 0, index: 0) computeCommandEncoder!.setBuffer(bufferB, offset: 0, index: 1) computeCommandEncoder!.setBuffer(bufferC, offset: 0, index: 2) computeCommandEncoder!.setComputePipelineState(computePipelineState.0) computeCommandEncoder!.dispatchThreadgroups(numThrdgroups, threadsPerThreadgroup: thrdsPerGroup) // Finalize configuration and start job computeCommandEncoder!.endEncoding() commandBuffer!.commit() // Wait for job to finish commandBuffer!.waitUntilCompleted() // Get output data back into Swift let data = NSData(bytesNoCopy: bufferC!.contents(), length: bufferLength, freeWhenDone: false) data.getBytes(&vectorC, length:bufferLength) print("\(#file):\(#line) vectorA = \(vectorA)") print("\(#file):\(#line) vectorB = \(vectorB)") print("\(#file):\(#line) vectorC = \(vectorC)") exit(0) Note that I found no replacement for thrdWidth declaration and so just inserted an integer.
Post marked as solved
3 Replies
0 Views
Thought you might say that Claude31. The original is too large so I created this example code... import SwiftUI import Combine class model: ObservableObject { @Published var t_step : Double @Published var progressValue : Double init (progressValue: Double){ self.t_step = 0.0 self.progressValue = 0.0 } func stepThroughTime() { let start = 110.0 let end = 234.0 while t_step < end { progressValue = (end - t_step)/(end - start) t_step += 1 } } } struct ContentView: View { @EnvironmentObject var model: model var body: some View { VStack { Button( action: { model.stepThroughTime() } ) { Text("Search") } ProgressView(value: model.progressValue) // NOT A @STATE var... so doesn't work } } }