Add ObjC/Swift bindings for the ImageProcessor (#20051)#20051
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20051
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 Cancelled JobAs of commit ce4a08f with merge base 502fdbe ( CANCELLED JOB - The following job was cancelled. Please retry:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@metascroy has exported this pull request. If you are a Meta employee, you can view the originating Diff in D106898406. |
This PR needs a
|
|
@claude review this code |
|
Claude finished @metascroy's task in 1m 47s —— View job Code Review: Add ObjC/Swift bindings for the ImageProcessor
Overall: This is a well-structured, clean PR. The API design is thoughtful—good Swift refinements via Detailed FindingsExecuTorchImageProcessor.mm1. auto tensorPtr = std::move(result.get());
return [[ExecuTorchTensor alloc] initWithNativeInstance:&tensorPtr];This is correct: 2. auto* tensorPtr = reinterpret_cast<TensorPtr*>(tensor.nativeInstance);
auto err = process_pixelbuffer_into(*_processor, pixelBuffer, Orientation::UP, **tensorPtr);This is sound— 3. Singleton thread-safety (lines 75-90)
4. Config defensive copy (lines 150-158) Good practice copying the config in ExecuTorch+ImageProcessor.swift5. return Tensor<Float>(anyTensor)Looking at the 6. Convenience init defaults (lines 25-29) The defaults ( ExecuTorchImageProcessor.h7. Good defensive API design—CVPixelBufferRef is a pointer type, and explicitly accepting + handling nil prevents crashes from accidental nil forwarding in ObjC. 8. Minor alignment nit (lines 55-61) The colon alignment on the ImageProcessorTest.swift9. Test coverage is appropriate for a binding layer:
Correctly defers image-processing correctness to the C++ test suite. Build system10. All three build paths updated:
SummaryNo blocking issues. The code is correct, well-tested at the binding boundary, and follows existing patterns. The API surface is clean for both ObjC and Swift consumers. Ship it. |
Summary:
This diff adds ObjC/Swift bindings for the image processor. Only the pixelbuffer variants get ObjC/Swift bindings. The process/process_yuv variants are only accessible from C++ for now.
Example:
```
import ExecuTorch
// Configure once
let config = ImageProcessorConfig(
targetWidth: 224,
targetHeight: 224,
normalization: .imagenet()
)
let processor = ImageProcessor(config: config)
// Process a CVPixelBuffer (BGRA/RGBA/NV12/P010)
let tensor: Tensor<Float> = try processor.process(pixelBuffer)
// Output: [1, 3, 224, 224] Float tensor
// For video (reuse tensor to avoid allocations)
let output = Tensor<Float>([1, 3, 224, 224], Array(repeating: 0, count: 3*224*224))
try processor.process(pixelBuffer, into: output)
```
Differential Revision: D106898406
9399041 to
ed1525d
Compare
Summary:
This diff adds ObjC/Swift bindings for the image processor. Only the pixelbuffer variants get ObjC/Swift bindings. The process/process_yuv variants are only accessible from C++ for now.
Example:
```
import ExecuTorch
// Configure once
let config = ImageProcessorConfig(
targetWidth: 224,
targetHeight: 224,
normalization: .imagenet()
)
let processor = ImageProcessor(config: config)
// Process a CVPixelBuffer (BGRA/RGBA/NV12/P010)
let tensor: Tensor<Float> = try processor.process(pixelBuffer)
// Output: [1, 3, 224, 224] Float tensor
// For video (reuse tensor to avoid allocations)
let output = Tensor<Float>([1, 3, 224, 224], Array(repeating: 0, count: 3*224*224))
try processor.process(pixelBuffer, into: output)
```
Differential Revision: D106898406
|
@claude review this code |
|
Claude finished @metascroy's task in 1m 46s —— View job Code Review: Add ObjC/Swift bindings for the ImageProcessor
Overall: Clean, well-structured PR. Ship it. The binding layer is thin, delegates correctness to C++, and follows existing patterns ( Detailed Findings
|
Summary:
This diff adds ObjC/Swift bindings for the image processor. Only the pixelbuffer variants get ObjC/Swift bindings. The process/process_yuv variants are only accessible from C++ for now.
Example:
```
import ExecuTorch
// Configure once
let config = ImageProcessorConfig(
targetWidth: 224,
targetHeight: 224,
normalization: .imagenet()
)
let processor = ImageProcessor(config: config)
// Process a CVPixelBuffer (BGRA/RGBA/NV12/P010)
let tensor: Tensor<Float> = try processor.process(pixelBuffer)
// Output: [1, 3, 224, 224] Float tensor
// For video (reuse tensor to avoid allocations)
let output = Tensor<Float>([1, 3, 224, 224], Array(repeating: 0, count: 3*224*224))
try processor.process(pixelBuffer, into: output)
```
Differential Revision: D106898406
ed1525d to
ce4a08f
Compare
Summary:
This diff adds ObjC/Swift bindings for the image processor. Only the pixelbuffer variants get ObjC/Swift bindings. The process/process_yuv variants are only accessible from C++ for now.
Example:
Differential Revision: D106898406