-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add bilinear interpolation support (upsample_bilinear2d) #3237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@ivarflakstad Request for review, thank you so much |
ivarflakstad
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! We definitely need this and it is on my todo list so thank you :)
I'll do a detailed review at some later point, but for now I'll only give feedback on the tests.
Because overall I don't think the they are quite strict enough wrt the functionality they are checking.
Maybe you could get some expected values from pytorch and assert that they match the results from candle?
For the tests that specifically only verify correct output dims I think they could be merged into a single test with several cases.
Does that sound reasonable to you?
@ivarflakstad I have expanded the test cases again by adding more PyTorch numerical comparison verification, and tested them on both the metal and CUDA backends. The results are as follows. File: Metal Running tests/bilinear_tests.rs (/Users/spensercai/Dev/candle_dev/candle/target/debug/deps/bilinear_tests-0a37c0f4e1ce3b04)
running 24 tests
test bilinear_output_dimensions_cpu ... ok
test bilinear_pytorch_multi_channel_cpu ... ok
test bilinear_align_corners_difference_cpu ... ok
test bilinear_pytorch_2x_upscale_cpu ... ok
test bilinear_pytorch_align_corners_true_cpu ... ok
test bilinear_pytorch_downscale_cpu ... ok
test bilinear_identity_cpu ... ok
test bilinear_pytorch_non_square_exact_cpu ... ok
test bilinear_pytorch_scale_factor_cpu ... ok
test bilinear_pytorch_tiny_1x1_to_3x3_cpu ... ok
test bilinear_pytorch_tiny_1x2_to_3x6_cpu ... ok
test bilinear_pytorch_large_64x64_to_128x128_cpu ... ok
test bilinear_identity_metal ... ok
test bilinear_output_dimensions_metal ... ok
test bilinear_pytorch_non_square_exact_metal ... ok
test bilinear_pytorch_downscale_metal ... ok
test bilinear_pytorch_large_64x64_to_128x128_metal ... ok
test bilinear_pytorch_tiny_1x1_to_3x3_metal ... ok
test bilinear_pytorch_align_corners_true_metal ... ok
test bilinear_pytorch_tiny_1x2_to_3x6_metal ... ok
test bilinear_pytorch_2x_upscale_metal ... ok
test bilinear_pytorch_multi_channel_metal ... ok
test bilinear_align_corners_difference_metal ... ok
test bilinear_pytorch_scale_factor_metal ... ok
test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06sCUDA Finished `test` profile [unoptimized + debuginfo] target(s) in 0.45s
Running tests/bilinear_tests.rs (target/debug/deps/bilinear_tests-72e19a9c1fdd7dc5)
running 24 tests
test bilinear_align_corners_difference_cpu ... ok
test bilinear_identity_cpu ... ok
test bilinear_pytorch_2x_upscale_cpu ... ok
test bilinear_output_dimensions_cpu ... ok
test bilinear_pytorch_align_corners_true_cpu ... ok
test bilinear_pytorch_downscale_cpu ... ok
test bilinear_pytorch_multi_channel_cpu ... ok
test bilinear_pytorch_non_square_exact_cpu ... ok
test bilinear_pytorch_scale_factor_cpu ... ok
test bilinear_pytorch_tiny_1x1_to_3x3_cpu ... ok
test bilinear_pytorch_tiny_1x2_to_3x6_cpu ... ok
test bilinear_pytorch_large_64x64_to_128x128_cpu ... ok
test bilinear_pytorch_multi_channel_gpu ... ok
test bilinear_pytorch_large_64x64_to_128x128_gpu ... ok
test bilinear_output_dimensions_gpu ... ok
test bilinear_pytorch_tiny_1x2_to_3x6_gpu ... ok
test bilinear_pytorch_downscale_gpu ... ok
test bilinear_pytorch_align_corners_true_gpu ... ok
test bilinear_align_corners_difference_gpu ... ok
test bilinear_identity_gpu ... ok
test bilinear_pytorch_2x_upscale_gpu ... ok
test bilinear_pytorch_scale_factor_gpu ... ok
test bilinear_pytorch_non_square_exact_gpu ... ok
test bilinear_pytorch_tiny_1x1_to_3x3_gpu ... ok
test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s |


Summary
This PR adds bilinear interpolation support to Candle, implementing
upsample_bilinear2dandupsample_bilinear2d_with_scalemethods for theTensortype.Motivation
Many modern neural networks require bilinear interpolation for vision tasks, including:
Currently, Candle only supports nearest-neighbor interpolation (
upsample_nearest1d,upsample_nearest2d). This PR fills that gap with a PyTorch-compatible bilinear interpolation implementation.Implementation
API
Two new public methods on
Tensor:Features
✅ CPU Backend - Full implementation with optimized performance
✅ CUDA Backend - Complete GPU acceleration support
✅ Metal Backend - Apple Silicon optimized implementation
✅ PyTorch Compatibility - Exact numerical equivalence
✅ Comprehensive Testing
Files Modified
Core Implementation:
candle-core/src/op.rs- Added UpsampleBilinear2D operationcandle-core/src/tensor.rs- Added public API methods with documentationcandle-core/src/storage.rs- Added storage dispatch layercandle-core/src/backend.rs- Added backend trait methodBackend Implementations:
candle-core/src/cpu_backend/mod.rs- CPU implementation with all dtype supportcandle-kernels/src/conv.cu- CUDA kernel implementationcandle-metal-kernels/src/metal_src/conv.metal- Metal shader implementationcandle-metal-kernels/src/lib.rs- Metal helper functionscandle-metal-kernels/src/kernels/convolution.rs- Metal kernel registrationTesting:
candle-core/tests/interpolate_tests.rs- Comprehensive test suite (new file)Test Result
Metal
Cuda
Breaking Changes
✅ None - this is a new feature addition.