import Foundation import Testing @preconcurrency import COnnxRuntime @testable import OnnxRuntimeBindings @_cdecl("SwiftTestRegisterCustomOps") func SwiftTestRegisterCustomOps(_ options: OpaquePointer?, _ api: UnsafePointer?) -> OpaquePointer? { _ = options _ = api return nil } struct SwiftAPITests { @Test func sessionOptionsRetainConfiguredState() throws { let options = try ORTSessionOptions() try options.setIntraOpNumThreads(4) try options.setGraphOptimizationLevel(.extended) try options.setOptimizedModelFilePath("/tmp/model.optimized.onnx") try options.setLogID("session-log") try options.setLogSeverityLevel(.warning) try options.addConfigEntry(key: "session.disable_prepacking", value: "1") #expect(options.intraOpNumThreads == 4) #expect(options.graphOptimizationLevel == .extended) #expect(options.optimizedModelFilePath == "/tmp/model.optimized.onnx") #expect(options.logID == "session-log") #expect(options.logSeverityLevel == .warning) #expect(options.configEntries["session.disable_prepacking"] == "1") #expect(options.executionProviders.isEmpty) } @Test func unsupportedExecutionProviderSurfacesRuntimeError() throws { let options = try ORTSessionOptions() #expect(throws: ORTError.self) { try options.appendExecutionProvider("XNNPACK", providerOptions: ["threads": "2"]) } } @Test func customOpsFunctionPointerRegistrationIsInvoked() throws { let options = try ORTSessionOptions() let functionPointer = unsafeBitCast( SwiftTestRegisterCustomOps as RegisterCustomOpsFn, to: UnsafeMutableRawPointer.self ) try options.registerCustomOps(usingFunctionPointer: functionPointer) #expect(options.customOpRegistrationFunctionPointer == functionPointer) } @Test func runOptionsRetainConfiguredState() throws { let options = try ORTRunOptions() try options.setLogTag("inference") try options.setLogSeverityLevel(.error) try options.addConfigEntry(key: "terminate", value: "0") #expect(options.logTag == "inference") #expect(options.logSeverityLevel == .error) #expect(options.configEntries["terminate"] == "0") } @Test func numericTensorValueExposesTensorInfo() throws { let bytes = NSMutableData(data: Data([0, 0, 128, 63])) let value = try ORTValue(tensorData: bytes, elementType: .float, shape: [1]) let typeInfo = try value.typeInfo() let tensorInfo = try value.tensorTypeAndShapeInfo() let data = try value.tensorData() #expect(typeInfo.type == .tensor) #expect(typeInfo.tensorTypeAndShapeInfo?.elementType == .float) #expect(tensorInfo.elementType == .float) #expect(tensorInfo.shape == [1]) #expect(data.length == bytes.length) #expect(Data(referencing: data) == Data(referencing: bytes)) } @Test func stringTensorValueExposesTensorInfo() throws { let value = try ORTValue(tensorStringData: ["hello", "world"], shape: [2]) let typeInfo = try value.typeInfo() let tensorInfo = try value.tensorTypeAndShapeInfo() let strings = try value.tensorStringData() #expect(typeInfo.type == .tensor) #expect(typeInfo.tensorTypeAndShapeInfo?.elementType == .string) #expect(tensorInfo.elementType == .string) #expect(tensorInfo.shape == [2]) #expect(strings == ["hello", "world"]) } @Test func wrongTensorAccessorThrows() throws { let numeric = try ORTValue(tensorData: NSMutableData(data: Data([0, 0, 0, 0])), elementType: .float, shape: []) let string = try ORTValue(tensorStringData: [], shape: [0]) #expect(throws: ORTError.self) { _ = try numeric.tensorStringData() } #expect(throws: ORTError.self) { _ = try string.tensorData() } } }