Skip to content

Commit 96c602d

Browse files
authored
Use native Swift APIs (#24)
1 parent 0bfb510 commit 96c602d

File tree

5 files changed

+17
-125
lines changed

5 files changed

+17
-125
lines changed

mv3/apple/ExecuTorchDemo/ExecuTorchDemo.xcodeproj/project.pbxproj

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
032C01A72AC22B16002955E1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C018D2AC22B16002955E1 /* ContentView.swift */; };
1313
032C01B72AC329B6002955E1 /* CustomViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C01B62AC329B6002955E1 /* CustomViews.swift */; };
1414
032C01B92AC32ADF002955E1 /* CameraController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C01B82AC32ADF002955E1 /* CameraController.swift */; };
15-
032C01E82AC34B60002955E1 /* MobileNetClassifier.mm in Sources */ = {isa = PBXBuildFile; fileRef = 032C01902AC22B16002955E1 /* MobileNetClassifier.mm */; };
1615
032C01EC2AC34CAC002955E1 /* libMobileNetClassifier.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 032C01CB2AC34632002955E1 /* libMobileNetClassifier.a */; platformFilter = ios; };
1716
032C02032AC47CFB002955E1 /* mv3_xnnpack_fp32.pte in Resources */ = {isa = PBXBuildFile; fileRef = 032C01FC2AC47CFB002955E1 /* mv3_xnnpack_fp32.pte */; };
1817
032C02082AC47CFB002955E1 /* imagenet_classes.txt in Resources */ = {isa = PBXBuildFile; fileRef = 032C02012AC47CFB002955E1 /* imagenet_classes.txt */; };
@@ -95,9 +94,6 @@
9594
032C018A2AC22B16002955E1 /* MobileNetClassifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MobileNetClassifier.swift; sourceTree = "<group>"; };
9695
032C018B2AC22B16002955E1 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
9796
032C018D2AC22B16002955E1 /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
98-
032C018E2AC22B16002955E1 /* MobileNet-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MobileNet-Bridging-Header.h"; sourceTree = "<group>"; };
99-
032C01902AC22B16002955E1 /* MobileNetClassifier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MobileNetClassifier.mm; sourceTree = "<group>"; };
100-
032C01912AC22B16002955E1 /* MobileNetClassifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MobileNetClassifier.h; sourceTree = "<group>"; };
10197
032C01B62AC329B6002955E1 /* CustomViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomViews.swift; sourceTree = "<group>"; };
10298
032C01B82AC32ADF002955E1 /* CameraController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraController.swift; sourceTree = "<group>"; };
10399
032C01CB2AC34632002955E1 /* libMobileNetClassifier.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMobileNetClassifier.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -216,9 +212,6 @@
216212
children = (
217213
03C818132AC6707F0084CC29 /* Test */,
218214
032C018A2AC22B16002955E1 /* MobileNetClassifier.swift */,
219-
032C018E2AC22B16002955E1 /* MobileNet-Bridging-Header.h */,
220-
032C01912AC22B16002955E1 /* MobileNetClassifier.h */,
221-
032C01902AC22B16002955E1 /* MobileNetClassifier.mm */,
222215
);
223216
path = MobileNet;
224217
sourceTree = "<group>";
@@ -463,7 +456,6 @@
463456
buildActionMask = 2147483647;
464457
files = (
465458
03C818252AC75E580084CC29 /* MobileNetClassifier.swift in Sources */,
466-
032C01E82AC34B60002955E1 /* MobileNetClassifier.mm in Sources */,
467459
);
468460
runOnlyForDeploymentPostprocessing = 0;
469461
};
@@ -691,7 +683,6 @@
691683
buildSettings = {
692684
PRODUCT_NAME = "$(TARGET_NAME)";
693685
SKIP_INSTALL = YES;
694-
SWIFT_OBJC_BRIDGING_HEADER = "ExecuTorchDemo/Sources/MobileNet/MobileNet-Bridging-Header.h";
695686
};
696687
name = Debug;
697688
};
@@ -700,7 +691,6 @@
700691
buildSettings = {
701692
PRODUCT_NAME = "$(TARGET_NAME)";
702693
SKIP_INSTALL = YES;
703-
SWIFT_OBJC_BRIDGING_HEADER = "ExecuTorchDemo/Sources/MobileNet/MobileNet-Bridging-Header.h";
704694
};
705695
name = Release;
706696
};
@@ -806,7 +796,7 @@
806796
isa = XCRemoteSwiftPackageReference;
807797
repositoryURL = "https://github.com/pytorch/executorch";
808798
requirement = {
809-
branch = "swiftpm-0.6.0";
799+
branch = "swiftpm-0.7.0.20250523";
810800
kind = branch;
811801
};
812802
};

mv3/apple/ExecuTorchDemo/ExecuTorchDemo/Sources/MobileNet/MobileNet-Bridging-Header.h

Lines changed: 0 additions & 9 deletions
This file was deleted.

mv3/apple/ExecuTorchDemo/ExecuTorchDemo/Sources/MobileNet/MobileNetClassifier.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

mv3/apple/ExecuTorchDemo/ExecuTorchDemo/Sources/MobileNet/MobileNetClassifier.mm

Lines changed: 0 additions & 60 deletions
This file was deleted.

mv3/apple/ExecuTorchDemo/ExecuTorchDemo/Sources/MobileNet/MobileNetClassifier.swift

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import UIKit
1313
import os.log
1414

1515
public enum MobileNetClassifierError: Error {
16-
case inputPointer
16+
case inference
1717
case rawData
1818
case transform
1919

2020
var localizedDescription: String {
2121
switch self {
22-
case .inputPointer:
23-
return "Cannot get the input pointer base address"
22+
case .inference:
23+
return "Cannot recognize the image"
2424
case .rawData:
2525
return "Cannot get the pixel data from the image"
2626
case .transform:
@@ -35,15 +35,15 @@ public class MobileNetClassifier: ImageClassification {
3535
private static let resizeSize: CGFloat = 256
3636
private static let cropSize: CGFloat = 224
3737

38-
private var mobileNetClassifier: ETMobileNetClassifier
38+
private var module: Module
3939
private var labels: [String] = []
4040
private var rawDataBuffer: [UInt8]
4141
private var normalizedBuffer: [Float]
4242

4343
public init?(modelFilePath: String, labelsFilePath: String) throws {
4444
labels = try String(contentsOfFile: labelsFilePath, encoding: .utf8)
4545
.components(separatedBy: .newlines)
46-
mobileNetClassifier = ETMobileNetClassifier(filePath: modelFilePath)
46+
module = Module(filePath: modelFilePath)
4747
rawDataBuffer = [UInt8](repeating: 0, count: Int(Self.cropSize * Self.cropSize) * 4)
4848
normalizedBuffer = [Float](repeating: 0, count: rawDataBuffer.count / 4 * 3)
4949

@@ -59,22 +59,18 @@ public class MobileNetClassifier: ImageClassification {
5959
}
6060

6161
public func classify(image: UIImage) throws -> [Classification] {
62-
var input = try normalize(rawData(from: transformed(image)))
63-
var output = [Float](repeating: 0, count: labels.count)
64-
65-
try input.withUnsafeMutableBufferPointer { inputPointer in
66-
guard let inputPointerBaseAddress = inputPointer.baseAddress else {
67-
throw MobileNetClassifierError.inputPointer
68-
}
69-
try mobileNetClassifier.classify(
70-
withInput: inputPointerBaseAddress,
71-
output: &output,
72-
outputSize: labels.count)
62+
let input = try normalize(rawData(from: transformed(image))).withUnsafeBytes {
63+
Tensor(bytes: $0.baseAddress!, shape: [1, 3, 224, 224], dataType: .float)
64+
}
65+
guard let output = try module.forward(input).first?.tensor?.withUnsafeBytes([Float].init)
66+
else {
67+
throw MobileNetClassifierError.inference
7368
}
74-
return softmax(output).enumerated().sorted(by: { $0.element > $1.element })
75-
.compactMap { (index, probability) -> Classification? in
76-
guard index < labels.count else { return nil }
77-
return Classification(label: labels[index], confidence: probability)
69+
return softmax(output)
70+
.enumerated()
71+
.sorted(by: { $0.element > $1.element })
72+
.compactMap { index, probability in
73+
index < labels.count ? Classification(label: labels[index], confidence: probability) : nil
7874
}
7975
}
8076

0 commit comments

Comments
 (0)