Skip to content
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

C++ sample for ESRGAN #634

Merged
merged 47 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9343cae
wip
jstoecker Aug 17, 2024
9661b87
wip
jstoecker Aug 17, 2024
714269e
wip
jstoecker Aug 17, 2024
8ffaf9e
asdf
jstoecker Aug 17, 2024
5933c34
asdf
jstoecker Aug 17, 2024
be7b0ff
asdf
jstoecker Aug 17, 2024
91f3bbd
asdf
jstoecker Aug 17, 2024
4ecef23
asdf
jstoecker Aug 17, 2024
bcb5f94
asdf
jstoecker Aug 18, 2024
8a8587d
asdf
jstoecker Aug 18, 2024
77e014a
asdf
jstoecker Aug 18, 2024
f5d6743
asdf
jstoecker Aug 18, 2024
b3c2bd1
asdf
jstoecker Aug 18, 2024
dd429dd
asdf
jstoecker Aug 18, 2024
4a57549
asdf
jstoecker Aug 18, 2024
bf94fc6
asdf
jstoecker Aug 18, 2024
0eb3a52
asdf
jstoecker Aug 20, 2024
5e5c232
adsf
jstoecker Aug 20, 2024
01420da
asdf
jstoecker Aug 20, 2024
531be51
asdf
jstoecker Aug 20, 2024
c03b983
asdf
jstoecker Aug 20, 2024
9ffda04
asdf
jstoecker Aug 20, 2024
21747fe
asdf
jstoecker Aug 20, 2024
3f2bb76
asdf
jstoecker Aug 20, 2024
22e6231
asdf
jstoecker Aug 20, 2024
32c400b
asdf
jstoecker Aug 20, 2024
8effdc4
asdf
jstoecker Aug 20, 2024
e3cf8b5
asdf
jstoecker Aug 20, 2024
0a4c5fc
asdf
jstoecker Aug 20, 2024
93daa1a
asdf
jstoecker Aug 20, 2024
418bf8c
asdf
jstoecker Aug 20, 2024
c1ba8e5
fix fp16 buffer sizes
jstoecker Aug 20, 2024
93c790b
remove null terminator from std string
jstoecker Aug 21, 2024
6f43ded
fix null terminator
jstoecker Aug 21, 2024
b3f5a98
hold ref to type info
jstoecker Aug 21, 2024
0eee4c1
use io bindings
jstoecker Aug 21, 2024
53ebdaa
shape tweaks
jstoecker Aug 21, 2024
9aecfc4
remove help cl opt
jstoecker Aug 21, 2024
0360860
download model
jstoecker Aug 21, 2024
cdd7c7d
3p notices
jstoecker Aug 21, 2024
12e6b3d
cmake note
jstoecker Aug 21, 2024
7475b0d
pch and separate translation unit for helpers
jstoecker Aug 21, 2024
9b6122f
cleanup
jstoecker Aug 21, 2024
b2bc7fa
cleanup
jstoecker Aug 21, 2024
261bbc4
cleanup
jstoecker Aug 21, 2024
f73e609
readme update
jstoecker Aug 21, 2024
e877e6d
copyright
jstoecker Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Samples/DirectML_ESRGAN/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
Binary file added Samples/DirectML_ESRGAN/.readme/input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Samples/DirectML_ESRGAN/.readme/output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 128 additions & 0 deletions Samples/DirectML_ESRGAN/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
cmake_minimum_required(VERSION 3.18)
jstoecker marked this conversation as resolved.
Show resolved Hide resolved
project(directml_esrgan VERSION 0.0.0 LANGUAGES CXX)

# To avoid runtime dependency on MSVC runtime DLLs
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)

include(FetchContent)

if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()

set(TARGET_ARCH ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
if(TARGET_ARCH STREQUAL AMD64)
set(TARGET_ARCH x64)
endif()

# -----------------------------------------------------------------------------
# wil - Windows-related helper types/macros
# -----------------------------------------------------------------------------
FetchContent_Declare(
wil
URL https://github.com/microsoft/wil/archive/refs/tags/v1.0.240803.1.zip
URL_HASH SHA256=353D2D7F2ACEA5642689A1BA85213C1AC6816457038B54AC02158B893E0F389F
)

FetchContent_GetProperties(wil)
if(NOT wil_POPULATED)
FetchContent_Populate(wil)
endif()

add_library(wil INTERFACE)
target_include_directories(wil INTERFACE "${wil_SOURCE_DIR}/include")

# -----------------------------------------------------------------------------
# onnxruntime
# -----------------------------------------------------------------------------
FetchContent_Declare(
ort
URL https://www.nuget.org/api/v2/package/Microsoft.ML.OnnxRuntime.DirectML/1.19.0
URL_HASH SHA256=FD4E65EBD23385FD8ED792F0C859D2AA255DC1761D0E5761087568FF255187AC
)

FetchContent_MakeAvailable(ort)

set(ort_bin_dir "${ort_SOURCE_DIR}/runtimes/win-${TARGET_ARCH}/native")

add_library(ort INTERFACE)
target_include_directories(ort INTERFACE "${ort_SOURCE_DIR}/build/native/include")
target_link_libraries(ort INTERFACE "${ort_bin_dir}/onnxruntime.lib")

# -----------------------------------------------------------------------------
# directx-headers - to get the latest DXCore header with GENERIC_ML GUID
# -----------------------------------------------------------------------------
FetchContent_Declare(
dxheaders
GIT_REPOSITORY https://github.com/microsoft/DirectX-Headers
GIT_TAG de28d93dfa9ebf3e473127c1c657e1920a5345ee # v1.613.1
)

FetchContent_MakeAvailable(dxheaders)

set(ort_bin_dir "${ort_SOURCE_DIR}/runtimes/win-${TARGET_ARCH}/native")

add_library(dxheaders INTERFACE)
target_include_directories(dxheaders INTERFACE ${dxheaders_SOURCE_DIR}/include/directx)
target_link_libraries(dxheaders INTERFACE Microsoft::DirectX-Guids)

# -----------------------------------------------------------------------------
# cxxopts - for parsing command line arguments
# -----------------------------------------------------------------------------

FetchContent_Declare(
cxxopts
GIT_REPOSITORY https://github.com/jarro2783/cxxopts
GIT_TAG v3.2.1
)

set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "Set to ON to build examples")
set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "Set to ON to build tests")
set(CXXOPTS_ENABLE_INSTALL OFF CACHE INTERNAL "Generate the install target")
FetchContent_MakeAvailable(cxxopts)

# -----------------------------------------------------------------------------
# directml
# -----------------------------------------------------------------------------
FetchContent_Declare(
dml
URL https://www.nuget.org/api/v2/package/Microsoft.AI.DirectML/1.15.1
URL_HASH SHA256=F43EB3D8B39F588B6CF049EAF1E0EA6006774EB8C93C661A1DE7721E674F7F56
)

FetchContent_MakeAvailable(dml)

set(dml_bin_dir "${dml_SOURCE_DIR}/bin/${TARGET_ARCH}-win")

add_library(dml INTERFACE)
target_include_directories(dml INTERFACE "${dml_SOURCE_DIR}/include")
target_link_libraries(dml INTERFACE "${dml_bin_dir}/directml.lib")

# -----------------------------------------------------------------------------
# main sample source
# -----------------------------------------------------------------------------

FetchContent_Declare(
esrgan_model
URL https://huggingface.co/microsoft/dml-ai-hub-models/resolve/main/esrgan/esrgan.onnx
URL_HASH SHA256=A853CB2585C47CF0C003B23B1129DB1FA21EC0FAA98A9158284F37FF7C94423B
DOWNLOAD_NO_EXTRACT TRUE
)

FetchContent_MakeAvailable(esrgan_model)

add_executable(directml_esrgan main.cpp helpers.cpp)
target_link_libraries(directml_esrgan PRIVATE wil ort dml d3d12 dxcore dxheaders cxxopts)
chrilaMSFT marked this conversation as resolved.
Show resolved Hide resolved
target_compile_features(directml_esrgan PRIVATE cxx_std_20)
target_precompile_headers(directml_esrgan PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pch.h")

add_custom_command(
TARGET directml_esrgan
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ort_bin_dir}/onnxruntime.dll" $<TARGET_FILE_DIR:directml_esrgan>
jstoecker marked this conversation as resolved.
Show resolved Hide resolved
jstoecker marked this conversation as resolved.
Show resolved Hide resolved
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dml_bin_dir}/directml.dll" $<TARGET_FILE_DIR:directml_esrgan>
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dml_bin_dir}/directml.pdb" $<TARGET_FILE_DIR:directml_esrgan>
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${esrgan_model_SOURCE_DIR}/esrgan.onnx" $<TARGET_FILE_DIR:directml_esrgan>
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/zebra.jpg" $<TARGET_FILE_DIR:directml_esrgan>
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdPartyNotices.txt" $<TARGET_FILE_DIR:directml_esrgan>
)
58 changes: 58 additions & 0 deletions Samples/DirectML_ESRGAN/CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"version": 3,
"configurePresets": [
{
"name": "vs2022",
"hidden": true,
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/install"
},
"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }
},
{
"name": "win-x64",
"displayName": "Windows x64",
"inherits": "vs2022",
"architecture": { "value": "x64", "strategy": "set" }
},
{
"name": "win-arm64",
"displayName": "Windows ARM64",
"inherits": "vs2022",
"architecture": { "value": "arm64", "strategy": "set" }
}
],

"buildPresets": [
{
"name": "win-x64-debug",
"displayName": "Debug",
"configurePreset": "win-x64",
"configuration": "Debug",
"nativeToolOptions": ["/m"]
},
{
"name": "win-x64-release",
"displayName": "Release",
"configurePreset": "win-x64",
"configuration": "RelWithDebInfo",
"nativeToolOptions": ["/m"]
},
{
"name": "win-arm64-debug",
"displayName": "Debug",
"configurePreset": "win-arm64",
"configuration": "Debug",
"nativeToolOptions": ["/m"]
},
{
"name": "win-arm64-release",
"displayName": "Release",
"configurePreset": "win-arm64",
"configuration": "RelWithDebInfo",
"nativeToolOptions": ["/m"]
}
]
}
67 changes: 67 additions & 0 deletions Samples/DirectML_ESRGAN/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# DirectML ESRGAN Sample

This sample illustrates DirectML and [ONNX Runtime](https://onnxruntime.ai/docs/execution-providers/DirectML-ExecutionProvider.html) inference of the [ESRGAN](https://github.com/xinntao/ESRGAN) super-resolution model (converted to ONNX by [Qualcomm AI Hub](https://aihub.qualcomm.com/models/esrgan)). While the model is converted from PyTorch using an IHV-specific toolchain, the same ONNX model can run on either GPU or NPU devices across hardware vendors when using DirectML. You may wish to use this sample as a simple template for learning:

- How to build a C++ application that depends a prebuilt release of ONNX Runtime with the DirectML execution provider (EP).
- How to use ONNX Runtime's C++ API to run inference of ONNX models with the DirectML EP. This sample illustrates the simpler path of binding CPU-side tensor data, which is automatically converted to DirectX resources within ONNX Runtime (directly binding of D3D resources is not shown).
- How to enumerate and select a specific DirectX adapter (GPU or NPU) to be used by the DirectML EP.
- How to load and convert image files to NCHW tensors compatible with ONNX Runtime by leveraging WIC, an API built into Windows.

The included variant of the ESRGAN model accepts a 128x128 input image and upscales it by factor of 4X to 512x512. The images below compare the low-resolution input to its high-resolution output.

**[Original Image]** An 900x659 test image ([Grevy's Zebra Stalion by Rainbirder](https://commons.wikimedia.org/wiki/File:Grevy%27s_Zebra_Stallion.jpg), CC BY-SA 2.0 <https://creativecommons.org/licenses/by-sa/2.0>, via Wikimedia Commons).

<img src="zebra.jpg" alt="drawing" height="512"/>

**[Model Input]** The test image cropped and downsampled to 128x128 using a high-quality bicubic filter. When viewing this image in this README it will be upscaled to 512x512 for easier comparison. This image is converted to a NCHW tensor and passed into the model for inference.

<img src=".readme/input.png" alt="drawing" height="512"/>

**[Model Output]** The output NCHW float32 tensor converted back to an image, which reconstructs significantly more detail than a simple bilinear or bicubic filter.

<img src=".readme/output.png" alt="drawing" height="512"/>

## Build

This sample uses [CMake](https://cmake.org/download/) to generate a Visual Studio solution and download external dependencies. The following instructions assume you have installed CMake and it is available on the PATH.

Run CMake to configure and build the sample:

```
> cmake --preset win-<arch>
> cmake --build --preset win-<arch>-<config>
```

- `<arch>` must be one of: `x64`, `arm64`.
- `<config>` must be one of: `<release>`, `<debug>`.

## Run

Running the compiled executable will list all enumerate DX adapters, select a DX adapter (by default the first), then use this adapter to run inference with the model:

```
> cd build/win-<arch>/<config>
> .\directml_esrgan.exe

Adapter[0]: NVIDIA GeForce RTX 4080 (SELECTED)
Adapter[1]: Intel(R) UHD Graphics 770
Adapter[2]: Microsoft Basic Render Driver
Saving cropped/scaled image to input.png
Saving inference results to output.png
```

### NPU Support

You may use the `-a <adapter_substring>` to select a different adapter that contains part of the `<adapter_substring>` in its description. For example, you can run on a compatible<sup>1</sup> NPU using `-a NPU`:

```
> cd build/win-arm64/release
> .\directml_esrgan.exe -a NPU
Adapter[0]: Snapdragon(R) X Elite - X1E78100 - Qualcomm(R) Adreno(TM) GPU
Adapter[1]: Snapdragon(R) X Elite - X1E78100 - Qualcomm(R) Hexagon(TM) NPU (SELECTED)
...
```

You must have Windows 11 24H2 installed to run this sample using an NPU.

<sup>1</sup> Currently, this sample is only supported with the NPU available in Copilot+ PCs with Snapdragon X Series processors. Support for additional NPUs will come soon. To run this sample with the QC NPU you must install driver 30.0.31.250 or newer.
55 changes: 55 additions & 0 deletions Samples/DirectML_ESRGAN/ThirdPartyNotices.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize

This software incorporates third party material from the projects listed below.

- cxxopts: https://github.com/jarro2783/cxxopts
- Half-precision floating-point library (half): http://half.sourceforge.net/

-------------------------------------------------------------------------------
cxxopts
-------------------------------------------------------------------------------
Copyright (c) 2014 Jarryd Beck

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-------------------------------------------------------------------------------
Half-precision floating-point library (half)
-------------------------------------------------------------------------------
The MIT License

Copyright (c) 2012-2019 Christian Rau

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Loading