From e5e52d335c58365b6cbd91f9a8a6f9ee9a085bf5 Mon Sep 17 00:00:00 2001 From: Attila Afra Date: Fri, 21 Jun 2024 01:17:07 +0300 Subject: [PATCH 1/3] fix compile error when using old libc++ (e.g. from macOS 12 SDK) --- core/context.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/context.h b/core/context.h index 433bd293..8b99deb7 100644 --- a/core/context.h +++ b/core/context.h @@ -6,8 +6,8 @@ #include "module.h" #include "device_factory.h" #include -#include -#include +#include +#include OIDN_NAMESPACE_BEGIN @@ -116,9 +116,9 @@ OIDN_NAMESPACE_BEGIN std::mutex mutex; bool fullyInited = false; - std::unordered_set initedDeviceTypes; + std::set initedDeviceTypes; ModuleLoader modules; - std::unordered_map> deviceFactories; + std::map> deviceFactories; std::vector> physicalDevices; }; From 21eac4d0e93696517688a4c63bc591c743a1058f Mon Sep 17 00:00:00 2001 From: Attila Afra Date: Sat, 29 Jun 2024 19:15:31 +0300 Subject: [PATCH 2/3] training: add export to ONNX --- training/config.py | 2 +- training/export.py | 157 ++++++++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 66 deletions(-) diff --git a/training/config.py b/training/config.py index a85e7275..3c8f657a 100644 --- a/training/config.py +++ b/training/config.py @@ -165,7 +165,7 @@ def get_default_device(): if cmd in {'export'}: parser.add_argument('target', type=str, nargs='?', - choices=['weights', 'package'], default='weights', + choices=['weights', 'package', 'onnx', 'onnx_noparams'], default='weights', help='what to export') parser.add_argument('--output', '-o', type=str, help='output file') diff --git a/training/export.py b/training/export.py index 73152a3c..9e03d0fb 100755 --- a/training/export.py +++ b/training/export.py @@ -10,81 +10,108 @@ from config import * from util import * +from model import * from result import * import tza def main(): # Parse the command line arguments - cfg = parse_args(description='Exports a training result to the runtime model weights format (TZA).') + cfg = parse_args(description='Exports a trained model to the runtime weights (TZA) or some other format.') print('Result:', cfg.result) - if cfg.target == 'weights': - export_weights(cfg) - elif cfg.target == 'package': - export_package(cfg) - -# Exports the weights to a TZA file -def export_weights(cfg): - # Initialize the PyTorch device - device = init_device(cfg) - - # Load the checkpoint - result_dir = get_result_dir(cfg) - if not os.path.isdir(result_dir): - error('result does not exist') - result_cfg = load_config(result_dir) - checkpoint = load_checkpoint(result_dir, device, cfg.num_epochs) - epoch = checkpoint['epoch'] - model_state = checkpoint['model_state'] - print('Epoch:', epoch) - - # Save the weights to a TZA file - if cfg.output: - output_filename = cfg.output + if cfg.target == 'package': + # Get the output filename + if cfg.output: + output_filename = cfg.output + else: + output_filename = os.path.join(cfg.results_dir, cfg.result) + '.zip' + print('Output:', output_filename) + + # Get the list of files that belong to the result (latest checkpoint only) + result_dir = get_result_dir(cfg) + filenames = [get_config_filename(result_dir)] + filenames.append(get_checkpoint_state_filename(result_dir)) + latest_epoch = get_latest_checkpoint_epoch(result_dir) + filenames.append(get_checkpoint_filename(result_dir, latest_epoch)) + filenames += glob(os.path.join(get_result_log_dir(result_dir), 'events.out.*')) + filenames += glob(os.path.join(result_dir, 'src.*')) + + # Save the ZIP file + save_zip(output_filename, filenames, root_dir=cfg.results_dir) else: - output_filename = os.path.join(result_dir, cfg.result) - if cfg.num_epochs: - output_filename += '_%d' % epoch - output_filename += '.tza' - print('Output:', output_filename) - print() - - with tza.Writer(output_filename) as output_file: - for name, value in model_state.items(): - tensor = value.half() - tensor = tensor.cpu().numpy() - print(name, tensor.shape) - - if name.endswith('.weight') and len(value.shape) == 4: - layout = 'oihw' - elif len(value.shape) == 1: - layout = 'x' + # Initialize the PyTorch device + device = init_device(cfg) + + # Load the result config + result_dir = get_result_dir(cfg) + if not os.path.isdir(result_dir): + error('result does not exist') + result_cfg = load_config(result_dir) + + # Initialize the model + if cfg.target in {'onnx', 'onnx_noparams'}: + model = get_model(result_cfg) + model.to(device) + else: + model = None + + # Load the checkpoint + checkpoint = load_checkpoint(result_dir, device, cfg.num_epochs, model) + epoch = checkpoint['epoch'] + model_state = checkpoint['model_state'] + print('Epoch:', epoch) + + if cfg.target == 'weights': + # Save the weights to a TZA file + if cfg.output: + output_filename = cfg.output else: - error('unknown state value') - - output_file.write(name, tensor, layout) - -# Exports the result directory to a ZIP file -def export_package(cfg): - # Get the output filename - if cfg.output: - output_filename = cfg.output - else: - output_filename = os.path.join(cfg.results_dir, cfg.result) + '.zip' - print('Output:', output_filename) - - # Get the list of files that belong to the result (latest checkpoint only) - result_dir = get_result_dir(cfg) - filenames = [get_config_filename(result_dir)] - filenames.append(get_checkpoint_state_filename(result_dir)) - latest_epoch = get_latest_checkpoint_epoch(result_dir) - filenames.append(get_checkpoint_filename(result_dir, latest_epoch)) - filenames += glob(os.path.join(get_result_log_dir(result_dir), 'events.out.*')) - filenames += glob(os.path.join(result_dir, 'src.*')) - - # Save the ZIP file - save_zip(output_filename, filenames, root_dir=cfg.results_dir) + output_filename = os.path.join(result_dir, cfg.result) + if cfg.num_epochs: + output_filename += '_%d' % epoch + output_filename += '.tza' + print('Output:', output_filename) + print() + + with tza.Writer(output_filename) as output_file: + for name, value in model_state.items(): + tensor = value.half() + tensor = tensor.cpu().numpy() + print(name, tensor.shape) + + if name.endswith('.weight') and len(value.shape) == 4: + layout = 'oihw' + elif len(value.shape) == 1: + layout = 'x' + else: + error('unknown state value') + + output_file.write(name, tensor, layout) + elif cfg.target in {'onnx', 'onnx_noparams'}: + # Export the model to ONNX + if cfg.output: + output_filename = cfg.output + else: + output_filename = os.path.join(result_dir, cfg.result) + if cfg.target != 'onnx_noparams' and cfg.num_epochs: + output_filename += '_%d' % epoch + output_filename += '.onnx' + print('Output:', output_filename) + print() + + W, H = 1920, 1080 + C = len(get_model_channels(result_cfg.features)) + dtype = torch.float32 if device.type == 'cpu' else torch.float16 + input_shape = [1, C, round_up(H, model.alignment), round_up(W, model.alignment)] + input = torch.zeros(input_shape, dtype=dtype, device=device) + model.to(dtype=dtype) + + torch.onnx.export(model, input, output_filename, + opset_version=11, + export_params=(cfg.target != 'onnx_noparams'), + input_names=['input'], + output_names=['output']) if __name__ == '__main__': main() \ No newline at end of file From 068235ba61875a20cb2da9f343f9d55c1f7c24f7 Mon Sep 17 00:00:00 2001 From: kraszkow Date: Tue, 30 Jul 2024 16:12:50 +0200 Subject: [PATCH 3/3] ci: add external continuous integration workflow using GitHub Actions (#103) --- .github/workflows/external.ci.yml | 139 ++++++++++++++++++ .github/workflows/{ci.yml => internal.ci.yml} | 5 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/external.ci.yml rename .github/workflows/{ci.yml => internal.ci.yml} (99%) diff --git a/.github/workflows/external.ci.yml b/.github/workflows/external.ci.yml new file mode 100644 index 00000000..bc4a80ad --- /dev/null +++ b/.github/workflows/external.ci.yml @@ -0,0 +1,139 @@ +## Copyright 2024 Intel Corporation +## SPDX-License-Identifier: Apache-2.0 + +name: Linux + +on: + push: + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + build-cpu-rocky-8: + runs-on: ubuntu-latest + container: + image: rockylinux:8 + + steps: + - name: Install packages + run: | + echo "Installing build dependencies..." + dnf update -y + dnf group install "Development Tools" -y + dnf install -y git-lfs cmake wget tbb-devel + + mkdir /tmp/deps + cd /tmp/deps + + wget https://github.com/ispc/ispc/releases/download/v1.24.0/ispc-v1.24.0-linux.tar.gz + tar -xvf ispc-v1.24.0-linux.tar.gz + echo "PATH=$PATH:`pwd`/ispc-v1.24.0-linux/bin" >> $GITHUB_ENV + + - name: Checkout Repository + uses: actions/checkout@v4 + with: + submodules: true + lfs: true + + - name: Build + run: | + mkdir build + cd build + cmake -D CMAKE_INSTALL_PREFIX=`pwd`/install -D OIDN_INSTALL_DEPENDENCIES=ON -D OIDN_ZIP_MODE=ON .. + make -j$(nproc) install + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: build-cpu-rocky-8 + path: build/install + + + test-cpu-rocky-8: + needs: build-cpu-rocky-8 + runs-on: ubuntu-latest + container: + image: rockylinux:8 + + steps: + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + name: build-cpu-rocky-8 + + - name: Test + run: | + # Adding execution bit to binaries is needed since upload/download GHA is using zip compression + # and it can't preserve files permissions - https://github.com/actions/upload-artifact/issues/38 + chmod +x ./bin/* + + ./bin/oidnTest + ./bin/oidnBenchmark -v 1 + + + build-cpu-ubuntu-2204: + runs-on: ubuntu-latest + container: + image: ubuntu:22.04 + + steps: + - name: Install packages + run: | + echo "Installing build dependencies..." + apt update + apt upgrade -y + apt install build-essential cmake git-lfs wget python3 libtbb2-dev -y + + mkdir /tmp/deps + cd /tmp/deps + + wget https://github.com/ispc/ispc/releases/download/v1.24.0/ispc-v1.24.0-linux.tar.gz + tar -xvf ispc-v1.24.0-linux.tar.gz + echo "PATH=$PATH:`pwd`/ispc-v1.24.0-linux/bin" >> $GITHUB_ENV + + - name: Checkout Repository + uses: actions/checkout@v4 + with: + submodules: true + lfs: true + + - name: Build + run: | + mkdir build + cd build + cmake -D CMAKE_INSTALL_PREFIX=`pwd`/install -D OIDN_INSTALL_DEPENDENCIES=ON -D OIDN_ZIP_MODE=ON .. + make -j`nproc` install + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: build-cpu-ubuntu-2204 + path: build/install + + + test-cpu-ubuntu-2204: + needs: build-cpu-ubuntu-2204 + runs-on: ubuntu-latest + container: + image: ubuntu:22.04 + + steps: + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + name: build-cpu-ubuntu-2204 + + - name: Test + run: | + # Adding execution bit to binaries is needed since upload/download GHA is using zip compression + # and it can't preserve files permissions - https://github.com/actions/upload-artifact/issues/38 + chmod +x ./bin/* + + ./bin/oidnTest + ./bin/oidnBenchmark -v 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/internal.ci.yml similarity index 99% rename from .github/workflows/ci.yml rename to .github/workflows/internal.ci.yml index 315bb318..7347a905 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/internal.ci.yml @@ -1,4 +1,7 @@ -name: CI workflow +## Copyright 2024 Intel Corporation +## SPDX-License-Identifier: Apache-2.0 + +name: (Internal) CI workflow on: push: workflow_dispatch: