// Native Core ML benchmark for the hand-written CiteNet builds. // usage: bench import CoreML import Foundation let dir = URL(fileURLWithPath: CommandLine.arguments[1]) let seq = 64 let raw = try Data(contentsOf: dir.appendingPathComponent("bench_codes.f16")) let nCites = raw.count / (seq * 2) func load(_ b: Int, _ units: MLComputeUnits) throws -> MLModel { let cfg = MLModelConfiguration() cfg.computeUnits = units return try MLModel(contentsOf: dir.appendingPathComponent("CiteNet_b\(b).mlmodelc"), configuration: cfg) } func batch(_ b: Int, offset: Int) throws -> MLDictionaryFeatureProvider { let arr = try MLMultiArray(shape: [NSNumber(value: b), 1, 1, NSNumber(value: seq)], dataType: .float16) raw.withUnsafeBytes { src in let dst = arr.dataPointer for i in 0.. UInt64 { DispatchTime.now().uptimeNanoseconds } func pct(_ v: [Double], _ p: Double) -> Double { v.sorted()[min(v.count - 1, Int(Double(v.count) * p))] } let unitsName: [(String, MLComputeUnits)] = [("cpu", .cpuOnly), ("ane", .cpuAndNeuralEngine), ("gpu", .cpuAndGPU)] let only = CommandLine.arguments.count > 2 ? CommandLine.arguments[2] : "all" for b in [1, 32, 512, 2048, 8192] where only == "all" { for (uname, units) in unitsName { if b == 1 && uname == "gpu" { continue } // b1/b32 plans stay on CPU for GPU units if b >= 2048 && uname == "cpu" { continue } let m = try load(b, units) let inputs = try (0..<8).map { try batch(b, offset: $0 * b) } for i in 0..<50 { _ = try m.prediction(from: inputs[i % 8]) } let iters = b == 1 ? 5000 : (b == 32 ? 3000 : max(40, 300_000 / b)) var lat = [Double]() let t0 = now() for i in 0.. %.0f cites/s", parts.joined(separator: " + "), Double(counts.reduce(0, +)) / total)) } try concurrent([("ane", 512, .cpuAndNeuralEngine)], seconds: 3) try concurrent([("gpu", 8192, .cpuAndGPU)], seconds: 3) try concurrent([("ane", 512, .cpuAndNeuralEngine), ("gpu", 8192, .cpuAndGPU)], seconds: 3) try concurrent([("ane", 2048, .cpuAndNeuralEngine), ("gpu", 8192, .cpuAndGPU)], seconds: 3) try concurrent([("ane", 512, .cpuAndNeuralEngine), ("ane", 512, .cpuAndNeuralEngine), ("gpu", 8192, .cpuAndGPU), ("gpu", 8192, .cpuAndGPU)], seconds: 3)