Add EDSR x4 super-resolution sample (CompiledModel GPU) - #212
Open
john-rocky wants to merge 4 commits into
Open
Conversation
EDSR (CVPR 2017 winner, eugenesiow/edsr-base via super-image, Apache-2.0) upscales a low-res image 4x with sharp detail, running fully on the LiteRT CompiledModel GPU at ~23 ms/frame on a Pixel 8a. Tiny at 7.7 MB, so the model is bundled in assets. EDSR is a pure CNN, but its PixelShuffle upsampler lowers to rank-5/6 reshapes the Mali delegate rejects (the classic super-resolution wall). Exact fix: PixelShuffle(r) equals a fixed-weight ConvTranspose2d(stride=r) -> ZeroStuffConvT2d. Result 68/68 nodes, 1 partition; device corr 0.999946. CPU-exact vs PyTorch (corr 1.0). Input [1,3,128,128] RGB /255, output [1,3,512,512] 0-1. Sample at compiled_model_api/super_resolution/edsr_kotlin_gpu (android app + conversion scripts), with a deterministic bundled-image bicubic-vs-EDSR demo.
… conversion script, copyright 2026
Wrap every line in the conversion scripts to the 80-column limit of the Google Python Style Guide and add Args/Returns sections to the module-level function docstrings. No behavior changes.
Restructure the EDSR x4 sample from a single View-based MainActivity into the
canonical Compose + MVVM shape, matching the sibling samples.
- MainActivity.kt is now a thin ComponentActivity that hosts ApplicationTheme
and SuperResolutionScreen, wires the ViewModel via viewModels {...}, and adds
a PickVisualMedia gallery picker.
- MainViewModel.kt owns the Upscaler helper, confines model creation and every
upscale() call to Dispatchers.Default.limitedParallelism(1) (the helper reuses
native in/out buffers), runs the bundled test_image.jpg on startup, and wraps
the assets-backed load in try/catch surfacing the throwable as errorMessage.
- The old Activity's render math moves verbatim: EDSR x4 via Upscaler.upscale()
plus a bicubic x4 baseline (Bitmap.createScaledBitmap to HR), both shown with
the same '... ms . 128 -> 512' status the old UI displayed.
- Added UiState, ImageUtils (decodeAssetBitmap / loadOrientedBitmap), view/
(SuperResolutionScreen, Theme, Color), res/values (strings, themes, colors);
all UI strings live in strings.xml.
- Adopt the shared version catalog (gradle/libs.versions.toml) and root
build.gradle.kts from the sibling samples; app keeps assets loading (no
install_to_device.sh) and LiteRT stays pinned at 2.1.5.
The inference helper Upscaler.kt is unchanged (byte-identical).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
EDSR (CVPR 2017 winner, eugenesiow/edsr-base via super-image, Apache-2.0) performs ×4 single-image super-resolution, running fully on the LiteRT
CompiledModelGPU at ~23 ms/frame on a Pixel 8a. Tiny at 7.7 MB (bundled in assets).EDSR is a pure CNN, but its PixelShuffle upsampler lowers to rank-5/6 reshapes the Mali delegate rejects (the classic super-resolution wall). Exact fix: PixelShuffle(r) ≡ a fixed-weight
ConvTranspose2d(stride=r)→ ZeroStuffConvT2d. Result: 68/68 nodes on the delegate, 1 partition; device corr 0.999946. CPU-exact vs PyTorch (corr 1.0). Input[1,3,128,128]RGB /255, output[1,3,512,512]0–1.Model: litert-community/EDSR-x4-LiteRT.
Sample at
compiled_model_api/super_resolution/edsr_kotlin_gpu(android app + conversion scripts), with a deterministic bundled-image bicubic-vs-EDSR demo.