From 840212e115f7468fc0968570e9c0b5c860fd1fce Mon Sep 17 00:00:00 2001 From: Weixing Zhang Date: Tue, 7 Dec 2021 12:47:00 -0800 Subject: [PATCH 001/113] Enable OneHot kernel for ROCm EP and add Dockerfile for ROCm 4.3.1 (#9656) * enable OneHot for ROCm EP * add dockerfile for ROCm 4.3.1 Co-authored-by: Weixing Zhang --- .../providers/rocm/rocm_execution_provider.cc | 10 +- .../tools/amdgpu/Dockerfile.rocm4.3.1.pytorch | 172 ++++++++++++++++++ 2 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 orttraining/tools/amdgpu/Dockerfile.rocm4.3.1.pytorch diff --git a/onnxruntime/core/providers/rocm/rocm_execution_provider.cc b/onnxruntime/core/providers/rocm/rocm_execution_provider.cc index 28128bfcf5..33000f4a5f 100644 --- a/onnxruntime/core/providers/rocm/rocm_execution_provider.cc +++ b/onnxruntime/core/providers/rocm/rocm_execution_provider.cc @@ -1711,11 +1711,11 @@ static Status RegisterRocmKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - // BuildKernelCreateInfo, - // BuildKernelCreateInfo, - // BuildKernelCreateInfo, - // BuildKernelCreateInfo, - // BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, diff --git a/orttraining/tools/amdgpu/Dockerfile.rocm4.3.1.pytorch b/orttraining/tools/amdgpu/Dockerfile.rocm4.3.1.pytorch new file mode 100644 index 0000000000..f78b531dca --- /dev/null +++ b/orttraining/tools/amdgpu/Dockerfile.rocm4.3.1.pytorch @@ -0,0 +1,172 @@ +# docker build --network=host --file Dockerfile.rocm4.3.1.pytorch --tag ort:rocm4.3.1-pytorch . + +FROM rocm/pytorch:rocm4.3.1_ubuntu18.04_py3.6_pytorch_1.9.0 + +RUN apt-get -y install gpg-agent +RUN wget -q -O - http://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - +RUN echo 'deb [arch=amd64] http://repo.radeon.com/rocm/apt/4.3.1 xenial main' | tee /etc/apt/sources.list.d/rocm.list + +RUN apt-get -y update +RUN apt-get -y install apt-utils +RUN apt-get -y install build-essential autotools-dev \ + make git curl vim wget rsync jq openssh-server openssh-client sudo \ + iputils-ping net-tools ethtool libcap2 \ + automake autoconf libtool flex doxygen \ + perl lsb-release iproute2 pciutils graphviz \ + bc tar git bash pbzip2 pv bzip2 unzip cabextract \ + g++ gcc \ + && apt-get autoremove + +# sh +RUN rm /bin/sh && ln -s /bin/bash /bin/sh + +# Labels for the docker +LABEL description="This docker sets up the environment to run ORT Training with AMD GPU" + +# CMake +ENV CMAKE_VERSION=3.18.2 +RUN cd /usr/local && \ + wget -q -O - https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz | tar zxf - +ENV PATH=/usr/local/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:${PATH} + +ENV WORKSPACE_DIR=/workspace +RUN mkdir -p $WORKSPACE_DIR +WORKDIR $WORKSPACE_DIR + +ENV OLD_PATH=${PATH} +ENV PATH=/usr/bin:${PATH} +# Infiniband setup, openmpi installed under /usr/mpi/gcc/openmpi-4.0.4rc3 doesn't support multi-thread +ENV MOFED_VERSION=5.1-0.6.6.0 +ENV MOFED_OS=ubuntu18.04 +ENV MOFED_FILENAME=MLNX_OFED_LINUX-${MOFED_VERSION}-${MOFED_OS}-x86_64 +RUN curl -fSsL https://www.mellanox.com/downloads/ofed/MLNX_OFED-${MOFED_VERSION}/${MOFED_FILENAME}.tgz | tar -zxpf - +RUN cd MLNX_OFED_LINUX-${MOFED_VERSION}-${MOFED_OS}-x86_64 && \ + ./mlnxofedinstall --force --user-space-only --without-fw-update --hpc && \ + cd .. && \ + rm -r MLNX_OFED_LINUX-${MOFED_VERSION}-${MOFED_OS}-x86_64 + +ENV PATH=${OLD_PATH} +ENV unset OLD_PATH + +# python env +RUN pip3 install --upgrade setuptools +ARG NUMPY_VERSION=1.18.5 +ARG ONNX_VERSION=1.10.2 +RUN pip3 install --no-cache-dir wheel tqdm boto3 requests six ipdb h5py html2text nltk progressbar pyyaml \ + git+https://github.com/NVIDIA/dllogger \ + numpy==${NUMPY_VERSION} \ + onnx=="${ONNX_VERSION}" + +ENV GITHUB_DIR=$WORKSPACE_DIR/github +RUN mkdir -p $GITHUB_DIR + +# UCX +WORKDIR $GITHUB_DIR +RUN apt-get -y update && apt-get -y --no-install-recommends install libnuma-dev +ARG UCX_VERSION=1.9.0-rc3 +ENV UCX_DIR=$WORKSPACE_DIR/ucx-$UCX_VERSION +RUN git clone https://github.com/openucx/ucx.git \ + && cd ucx \ + && git checkout v$UCX_VERSION \ + && ./autogen.sh \ + && mkdir build \ + && cd build \ + && ../contrib/configure-opt --prefix=$UCX_DIR --without-rocm --without-knem --without-cuda \ + && make -j"$(nproc)" \ + && make install \ + && cd .. \ + && rm -rf build + +# OpenMPI +# note: require --enable-orterun-prefix-by-default for Azure machine learning compute +# note: disable verbs as we use ucx middleware and don't want btl openib warnings +WORKDIR $GITHUB_DIR +ARG OPENMPI_BASEVERSION=4.0 +ARG OPENMPI_VERSION=${OPENMPI_BASEVERSION}.5 +ENV OPENMPI_DIR=$WORKSPACE_DIR/openmpi-${OPENMPI_VERSION} +RUN git clone --recursive https://github.com/open-mpi/ompi.git \ + && cd ompi \ + && git checkout v$OPENMPI_VERSION \ + && ./autogen.pl \ + && mkdir build \ + && cd build \ + && ../configure --prefix=$OPENMPI_DIR --with-ucx=$UCX_DIR --without-verbs \ + --enable-mpirun-prefix-by-default --enable-orterun-prefix-by-default \ + --enable-mca-no-build=btl-uct --disable-mpi-fortran \ + && make -j"$(nproc)" \ + && make install \ + && cd .. \ + && rm -rf build \ + && ldconfig \ + && test -f ${OPENMPI_DIR}/bin/mpic++ + +ENV PATH=$OPENMPI_DIR/bin:${PATH} +ENV LD_LIBRARY_PATH=$OPENMPI_DIR/lib:${LD_LIBRARY_PATH} + +# Create a wrapper for OpenMPI to allow running as root by default +RUN mv $OPENMPI_DIR/bin/mpirun $OPENMPI_DIR/bin/mpirun.real && \ + echo '#!/bin/bash' > $OPENMPI_DIR/bin/mpirun && \ + echo 'mpirun.real --allow-run-as-root "$@"' >> $OPENMPI_DIR/bin/mpirun && \ + chmod a+x $OPENMPI_DIR/bin/mpirun + +# install mpi4py (be sure to link existing /opt/openmpi-xxx) +RUN CC=mpicc MPICC=mpicc pip install mpi4py --no-binary mpi4py + +ARG CACHE_DATA=2021-10-25 + +# ONNX Runtime +WORKDIR $GITHUB_DIR +ENV ORT_DIR=$GITHUB_DIR/onnxruntime +RUN git clone -b wezhan/tnlrv4 --recursive https://github.com/microsoft/onnxruntime.git \ + && cd onnxruntime \ + && python3 tools/ci_build/build.py \ + --cmake_extra_defines ONNXRUNTIME_VERSION=`cat ./VERSION_NUMBER` \ + --build_dir build \ + --config Release \ + --parallel \ + --skip_tests \ + --build_wheel \ + --use_rocm --rocm_version=4.3.1 --rocm_home /opt/rocm \ + --mpi_home $OPENMPI_DIR \ + --nccl_home /opt/rocm \ + --enable_training \ + --enable_training_torch_interop \ + && test -f $ORT_DIR/build/Release/onnxruntime_training_bert \ + && pip install $ORT_DIR/build/Release/dist/*.whl \ + && ldconfig + +RUN pip3 install --no-cache-dir GPUtil azureml azureml-core datasets tokenizers ninja cerberus sympy sacremoses sacrebleu + +RUN pip install transformers==2.10.0 sklearn tensorboardX +RUN pip install --pre torch-ort -f https://download.onnxruntime.ai/torch_ort_nightly.html +RUN python -m torch_ort.configure + +# Enable ssh access without password needed +RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config +RUN sed -i 's/#StrictModes yes/StrictModes no/g' /etc/ssh/sshd_config +RUN sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config +RUN sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config + +# Start or Restart sshd service +ENTRYPOINT service ssh restart && /bin/bash + +# Add model and scripts +ADD model ${WORKSPACE_DIR}/model +ADD script ${WORKSPACE_DIR}/script +RUN chmod a+x ${WORKSPACE_DIR}/script/run_bert.sh + +# add locale en_US.UTF-8 +RUN apt-get install -y locales +RUN locale-gen en_US.UTF-8 + +# Workaround an issue in AMD compiler which generates poor GPU ISA +# when the type of kernel parameter is a structure and “pass-by-value” is used +# ENV HSA_NO_SCRATCH_RECLAIM=1 + +# Distributed training related environment variables +ENV HSA_FORCE_FINE_GRAIN_PCIE=1 +# ENV NCCL_DEBUG=INFO +# ENV RCCL_ALLTOALL_KERNEL_DISABLE=1 +# ENV NCCL_DEBUG_SUBSYS=INIT,COLL + +WORKDIR ${WORKSPACE_DIR}/script From b34b991aea41fc2fdc758fc363db1f167fa3b763 Mon Sep 17 00:00:00 2001 From: Guoyu Wang <62914304+gwang-msft@users.noreply.github.com> Date: Tue, 7 Dec 2021 13:02:05 -0800 Subject: [PATCH 002/113] Improve reduced ops and types build (#9908) * Improve reduceops and types build * minor update * fix test error * fix minimal build break * minor update and add comments * Address CR comments --- .gitignore | 8 + cmake/CMakeLists.txt | 8 +- cmake/onnxruntime_providers.cmake | 9 +- .../contrib_ops/cpu/cpu_contrib_kernels.cc | 182 ++++++++++-------- .../contrib_ops/cuda/cuda_contrib_kernels.cc | 12 ++ .../providers/cpu/cpu_execution_provider.cc | 12 ++ .../providers/cuda/cuda_execution_provider.cc | 12 ++ .../core/providers/op_kernel_type_control.h | 13 ++ onnxruntime/test/shared_lib/test_inference.cc | 3 +- .../training_ops/cpu/cpu_training_kernels.cc | 12 ++ .../cuda/cuda_training_kernels.cc | 12 ++ tools/ci_build/build.py | 3 + tools/ci_build/reduce_op_kernels.py | 85 ++++---- 13 files changed, 242 insertions(+), 129 deletions(-) diff --git a/.gitignore b/.gitignore index d49627f67f..f212e3fd0a 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,11 @@ onnxruntime/python/version_info.py .envrc .psenvrc *.csproj.user +# exclude generated reduced kernel registration and type control +onnxruntime/contrib_ops/cpu/cpu_contrib_kernels_reduced_ops.cc +onnxruntime/core/providers/cpu/cpu_execution_provider_reduced_ops.cc +orttraining/orttraining/training_ops/cpu/cpu_training_kernels_reduced_ops.cc +onnxruntime/contrib_ops/cuda/cuda_contrib_kernels_reduced_ops.cc +onnxruntime/core/providers/cuda/cuda_execution_provider_reduced_ops.cc +orttraining/orttraining/training_ops/cuda/cuda_training_kernels_reduced_ops.cc +onnxruntime/core/providers/op_kernel_type_control_overrides_reduced_types.inc diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 0b09078e0e..b92ea8649e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -117,6 +117,7 @@ cmake_dependent_option(onnxruntime_DISABLE_EXCEPTIONS "Disable exception handlin option(onnxruntime_EXTENDED_MINIMAL_BUILD "onnxruntime_MINIMAL_BUILD with support for execution providers that compile kernels." OFF) option(onnxruntime_MINIMAL_BUILD_CUSTOM_OPS "Add custom operator kernels support to a minimal build." OFF) option(onnxruntime_REDUCED_OPS_BUILD "Reduced set of kernels are registered in build via modification of the kernel registration source files." OFF) +option(onnxruntime_REDUCED_OP_TYPE_SUPPORT "Limit the types individual operators support where possible to further reduce the build size." OFF) option(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS "Don't allow models to load external data" OFF) cmake_dependent_option(onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION "Enable runtime graph optimization of ORT format models. Warning: Not yet ready for general use." @@ -357,8 +358,6 @@ if (onnxruntime_MINIMAL_BUILD) add_compile_definitions(ORT_MINIMAL_BUILD_CUSTOM_OPS) endif() - set(onnxruntime_REDUCED_OPS_BUILD ON) - if (MSVC) # turn on LTO (which adds some compiler flags and turns on LTCG) unless it's a Debug build to minimize binary size if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -402,6 +401,9 @@ endif() if (onnxruntime_REDUCED_OPS_BUILD) add_compile_definitions(REDUCED_OPS_BUILD) + if (onnxruntime_REDUCED_OP_TYPE_SUPPORT) + add_compile_definitions(REDUCED_OP_TYPE_SUPPORT) + endif() endif() if (onnxruntime_DISABLE_EXTERNAL_INITIALIZERS) @@ -1230,7 +1232,7 @@ function(onnxruntime_add_shared_library_module target_name) endif() endfunction() -function(onnxruntime_add_executable target_name) +function(onnxruntime_add_executable target_name) add_executable(${target_name} ${ARGN}) onnxruntime_configure_target(${target_name}) if (onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_BUILD_WEBASSEMBLY) diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index e29dd8f075..cfa128f6b9 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -49,7 +49,12 @@ file(GLOB_RECURSE onnxruntime_rocm_generated_contrib_ops_cu_srcs CONFIGURE_DEPEN file(GLOB onnxruntime_providers_common_srcs CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/*.h" "${ONNXRUNTIME_ROOT}/core/providers/*.cc" - "${ONNXRUNTIME_ROOT}/core/providers/op_kernel_type_control_overrides.inc" + # If we are building with reduced number of kernel registration and types, + # "core/providers/op_kernel_type_control_overrides_reduced_types.inc" + # will be generated with type specifications code. + # For simplicity, we inlcude both .inc files, + # see onnxruntime/core/providers/op_kernel_type_control.h + "${ONNXRUNTIME_ROOT}/core/providers/op_kernel_type_control_overrides*.inc" ) if(onnxruntime_USE_NUPHAR) @@ -655,7 +660,7 @@ if (onnxruntime_USE_OPENVINO) else() list(APPEND OPENVINO_LIB_LIST ${InferenceEngine_LIBRARIES} ${NGRAPH_LIBRARIES} ngraph::onnx_importer ${PYTHON_LIBRARIES}) endif() - + source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_openvino_cc_srcs}) onnxruntime_add_shared_library_module(onnxruntime_providers_openvino ${onnxruntime_providers_openvino_cc_srcs}) onnxruntime_add_include_to_target(onnxruntime_providers_openvino onnxruntime_common onnx) diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc index 33f1b4b454..93e0424701 100644 --- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "contrib_ops/cpu/cpu_contrib_kernels.h" #include "core/graph/constants.h" #include "core/mlas/inc/mlas.h" @@ -145,35 +155,35 @@ Status RegisterNchwcKernels(KernelRegistry& kernel_registry) { Status RegisterQuantizationKernels(KernelRegistry& kernel_registry) { static const BuildKernelCreateInfoFn function_table[] = { - BuildKernelCreateInfo, //default entry to avoid the list become empty after ops-reducing - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, //default entry to avoid the list become empty after ops-reducing + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, #if defined(MLAS_TARGET_ARM_ANY) - BuildKernelCreateInfo, + BuildKernelCreateInfo, #endif - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, }; for (auto& function_table_entry : function_table) { @@ -188,68 +198,68 @@ Status RegisterQuantizationKernels(KernelRegistry& kernel_registry) { Status RegisterCpuContribKernels(KernelRegistry& kernel_registry) { static const BuildKernelCreateInfoFn function_table[] = { - BuildKernelCreateInfo, //default entry to avoid the list become empty after ops-reducing - BuildKernelCreateInfo, + BuildKernelCreateInfo, //default entry to avoid the list become empty after ops-reducing + BuildKernelCreateInfo, - // add more kernels here - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - #if !defined(DISABLE_SPARSE_TENSORS) - BuildKernelCreateInfo, - #endif - BuildKernelCreateInfo, - BuildKernelCreateInfo, // backward compatibility - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + // add more kernels here + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, +#if !defined(DISABLE_SPARSE_TENSORS) + BuildKernelCreateInfo, +#endif + BuildKernelCreateInfo, + BuildKernelCreateInfo, // backward compatibility + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, #ifdef BUILD_MS_EXPERIMENTAL_OPS - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, #endif - // These ops were experimental ops in onnx domain which have been removed now. We add them here as - // contrib ops to main backward compatibility - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + // These ops were experimental ops in onnx domain which have been removed now. We add them here as + // contrib ops to main backward compatibility + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, }; for (auto& function_table_entry : function_table) { @@ -271,3 +281,5 @@ Status RegisterCpuContribKernels(KernelRegistry& kernel_registry) { } // namespace contrib } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc b/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc index 19b226858a..e2be2b8ab4 100644 --- a/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_common.h" @@ -204,3 +214,5 @@ Status RegisterCudaContribKernels(KernelRegistry& kernel_registry) { } // namespace cuda } // namespace contrib } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index 06c23e996c..d865a06578 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "core/providers/cpu/cpu_execution_provider.h" #include "core/framework/op_kernel.h" #include "core/framework/kernel_registry.h" @@ -2054,3 +2064,5 @@ std::unique_ptr CPUExecutionProvider::GetDataTransfer() const { return std::make_unique(); } } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/cuda/cuda_execution_provider.cc b/onnxruntime/core/providers/cuda/cuda_execution_provider.cc index cd5e7ad6b9..c676ff43a2 100755 --- a/onnxruntime/core/providers/cuda/cuda_execution_provider.cc +++ b/onnxruntime/core/providers/cuda/cuda_execution_provider.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_execution_provider.h" #include "core/providers/cuda/cuda_common.h" @@ -2353,3 +2363,5 @@ void CUDAExecutionProvider::RegisterAllocator(std::shared_ptr } } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/op_kernel_type_control.h b/onnxruntime/core/providers/op_kernel_type_control.h index 446666eaa7..5d491d9dc9 100644 --- a/onnxruntime/core/providers/op_kernel_type_control.h +++ b/onnxruntime/core/providers/op_kernel_type_control.h @@ -469,4 +469,17 @@ struct EnabledTypes { #include "core/framework/data_types.h" // for types that might be used in type specifications // all allowed type specifications should be contained in the following file + +// If we are building with reduced number of kernel registration and types +// will be copied to +// , +// where the type specifications code will be inserted, +// This will prevent, +// 1. Accidental commit of the modified +// 2. If the required ops and types config has changed, user has to revert the changes to +// +#ifndef REDUCED_OP_TYPE_SUPPORT #include "core/providers/op_kernel_type_control_overrides.inc" +#else +#include "core/providers/op_kernel_type_control_overrides_reduced_types.inc" +#endif diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 87dd31c74a..4fb80b311c 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -196,7 +196,9 @@ static constexpr PATH_TYPE PYOP_MULTI_MODEL_URI = TSTR("testdata/pyop_2.onnx"); static constexpr PATH_TYPE PYOP_KWARG_MODEL_URI = TSTR("testdata/pyop_3.onnx"); #endif +#ifndef REDUCED_OPS_BUILD static constexpr PATH_TYPE RESIZE_AND_CROP_MODEL_URI = TSTR("testdata/crop_and_resize.onnx"); +#endif class CApiTestWithProvider : public testing::Test, public ::testing::WithParamInterface { }; @@ -1055,7 +1057,6 @@ TEST(CApiTest, io_binding_cuda) { Ort::Value bound_y = Ort::Value::CreateTensor(info_cuda, reinterpret_cast(output_data.get()), expected_y.size(), expected_y_shape.data(), expected_y_shape.size()); - Ort::IoBinding binding(session); binding.BindInput("X", bound_x); binding.BindOutput("Y", bound_y); diff --git a/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc b/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc index 800fd48221..8754305d95 100644 --- a/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc +++ b/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "orttraining/training_ops/cpu/cpu_training_kernels.h" #include "core/graph/constants.h" @@ -234,3 +244,5 @@ Status RegisterCpuTrainingKernels(KernelRegistry& kernel_registry) { } // namespace contrib } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc b/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc index 8d0882f2ee..7d84cb3f30 100644 --- a/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc +++ b/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// If we are building with reduced number of kernel registration, +// this file will be copied to _reduced_ops.cc, +// where the unused kernel registration will be commented out +// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" +// This will prevent, +// 1. Accidental commit of the reduced kernel registration files +// 2. If the required ops config has changed, user has to revert the changes to +// the kernel registration files +#ifndef REDUCED_OPS_BUILD + #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_fwd.h" #include "core/providers/cuda/cuda_pch.h" @@ -458,3 +468,5 @@ Status RegisterCudaTrainingKernels(KernelRegistry& kernel_registry) { } // namespace cuda } // namespace onnxruntime + +#endif // #ifndef REDUCED_OPS_BUILD diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 8a792bb95f..5b0e317a7a 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -777,6 +777,9 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home args.minimal_build or args.use_extensions)) else "OFF"), "-Donnxruntime_REDUCED_OPS_BUILD=" + ("ON" if is_reduced_ops_build(args) else "OFF"), + "-Donnxruntime_REDUCED_OP_TYPE_SUPPORT=" + ( + "ON" if is_reduced_ops_build(args) and args.enable_reduced_operator_type_support + else "OFF"), "-Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=" + ("ON" if args.enable_language_interop_ops else "OFF"), "-Donnxruntime_USE_DML=" + ("ON" if args.use_dml else "OFF"), "-Donnxruntime_USE_WINML=" + ("ON" if args.use_winml else "OFF"), diff --git a/tools/ci_build/reduce_op_kernels.py b/tools/ci_build/reduce_op_kernels.py index 427bb77f7b..ae98907a46 100755 --- a/tools/ci_build/reduce_op_kernels.py +++ b/tools/ci_build/reduce_op_kernels.py @@ -10,6 +10,10 @@ import sys import typing from logger import get_logger +from pathlib import Path + +REDUCED_KERNEL_DEF_SUFFIX = '_reduced_ops' +REDUCED_TYPE_CONTROL_SUFFIX = '_reduced_types' # add the path to /tools/python so we can import the config parsing and type reduction processing script_path = os.path.dirname(os.path.realpath(__file__)) @@ -105,19 +109,27 @@ def _process_provider_registrations( log.info("Processing {}".format(kernel_registration_file)) - backup_path = kernel_registration_file + '~' - shutil.move(kernel_registration_file, backup_path) + old_path = Path(kernel_registration_file) + reduced_path = Path(old_path.parent, f'{old_path.stem}{REDUCED_KERNEL_DEF_SUFFIX}{old_path.suffix}') - # read from backup and overwrite original with commented out lines for any kernels that are not required - with open(kernel_registration_file, 'w') as file_to_write: + # read from original and create the reduced kernel def file (*_reduced_ops.cc), + # with commented out lines for any kernels that are not required + with open(reduced_path, 'w') as file_to_write: processor = _ExcludingRegistrationProcessor(required_ops, op_type_impl_filter, file_to_write) - op_registration_utils.process_kernel_registration_file(backup_path, processor) + op_registration_utils.process_kernel_registration_file(kernel_registration_file, processor) if not processor.ok(): # error should have already been logged so just exit sys.exit(-1) + # enable the contents in the *_reduced_ops.cc + with open(reduced_path, 'r+') as file: + file_content = file.read().replace(r'#ifndef REDUCED_OPS_BUILD', r'#ifdef REDUCED_OPS_BUILD') + + with open(reduced_path, "w") as file_to_write: + file_to_write.write(file_content) + def _insert_type_control_cpp_code(ort_root: str, cpp_lines: typing.Sequence[str]): ''' @@ -125,43 +137,40 @@ def _insert_type_control_cpp_code(ort_root: str, cpp_lines: typing.Sequence[str] :param ort_root: Root of the ONNX Runtime repository :param cpp_lines: The C++ code to insert ''' - if not cpp_lines: - return - - target = os.path.join(ort_root, 'onnxruntime', 'core', 'providers', 'op_kernel_type_control_overrides.inc') - if not os.path.exists(target) or not os.path.isfile(target): + src = os.path.join(ort_root, 'onnxruntime', 'core', 'providers', 'op_kernel_type_control_overrides.inc') + if not os.path.exists(src) or not os.path.isfile(src): log.warning('Could not find {}. Skipping generation of C++ code to reduce the types supported by operators.' - .format(target)) + .format(src)) return - # copy existing content to use as input - src = target + '.tmp' - shutil.copyfile(target, src) + # create a copy of the op_kernel_type_control_overrides.inc even the cpp_lines is empty + src_path = Path(src) + target = Path(src_path.parent, f'{src_path.stem}{REDUCED_TYPE_CONTROL_SUFFIX}{src_path.suffix}') + shutil.copyfile(src, target) - # find the insertion block and replace any existing content in it - inserted = False - with open(src, 'r') as input, open(target, 'w') as output: - inside_insertion_block = False - for line in input.readlines(): - if '@@insertion_point_begin(allowed_types)@@' in line: - inside_insertion_block = True - output.write(line) - [output.write('{}\n'.format(code_line)) for code_line in cpp_lines] - inserted = True - continue - elif inside_insertion_block: - if '@@insertion_point_end(allowed_types)@@' in line: - inside_insertion_block = False - else: - # we ignore any old lines within the insertion block + if cpp_lines: + # find the insertion block and replace any existing content in it + inserted = False + with open(src, 'r') as input, open(target, 'w') as output: + inside_insertion_block = False + for line in input.readlines(): + if '@@insertion_point_begin(allowed_types)@@' in line: + inside_insertion_block = True + output.write(line) + [output.write('{}\n'.format(code_line)) for code_line in cpp_lines] + inserted = True continue + elif inside_insertion_block: + if '@@insertion_point_end(allowed_types)@@' in line: + inside_insertion_block = False + else: + # we ignore any old lines within the insertion block + continue - output.write(line) + output.write(line) - os.remove(src) - - if not inserted: - raise RuntimeError('Insertion point was not found in {}'.format(target)) + if not inserted: + raise RuntimeError('Insertion point was not found in {}'.format(target)) def reduce_ops(config_path: str, enable_type_reduction: bool = False, use_cuda: bool = True): @@ -175,9 +184,9 @@ def reduce_ops(config_path: str, enable_type_reduction: bool = False, use_cuda: _process_provider_registrations(ort_root, use_cuda, required_ops, op_type_impl_filter) - type_control_cpp_code = op_type_impl_filter.get_cpp_entries() if op_type_impl_filter is not None else [] - - _insert_type_control_cpp_code(ort_root, type_control_cpp_code) + if enable_type_reduction: + type_control_cpp_code = op_type_impl_filter.get_cpp_entries() if op_type_impl_filter is not None else [] + _insert_type_control_cpp_code(ort_root, type_control_cpp_code) if __name__ == "__main__": From a7f649db7c28d5d2b532b2b9a2d1a191a90b67f8 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Tue, 7 Dec 2021 17:56:58 -0800 Subject: [PATCH 003/113] Enable proper override using MIMalloc (#9944) Redirect memory allocations to MiMalloc and advance its version to v2.0.3 Refactor for a universal ifdef --- cmake/CMakeLists.txt | 1 + cmake/external/mimalloc | 2 +- cmake/external/mimalloc.cmake | 8 +-- cmake/onnxruntime_common.cmake | 23 ++++-- cmake/onnxruntime_framework.cmake | 5 ++ include/onnxruntime/core/common/common.h | 4 -- .../onnxruntime/core/framework/allocator.h | 21 +----- onnxruntime/core/framework/allocator.cc | 71 +++++++++++++++++-- onnxruntime/core/framework/allocatormgr.cc | 14 ++-- onnxruntime/core/framework/bfc_arena.h | 2 +- onnxruntime/core/framework/error_code.cc | 18 +++-- .../core/framework/mimalloc_allocator.cc | 44 ------------ .../core/framework/mimalloc_allocator.h | 31 -------- .../framework/prepacked_weights_container.cc | 2 +- onnxruntime/core/framework/utils.cc | 24 +------ onnxruntime/core/platform/path_lib.cc | 17 ++--- onnxruntime/core/platform/windows/env.cc | 1 - .../windows/mimalloc/mimalloc_overloads.cc | 7 ++ onnxruntime/core/providers/cpu/containers.h | 19 ----- .../providers/cpu/cpu_execution_provider.h | 9 +-- onnxruntime/core/session/environment.cc | 11 ++- .../python/onnxruntime_pybind_state.cc | 52 -------------- .../python/onnxruntime_pybind_state_common.h | 2 +- onnxruntime/test/framework/allocator_test.cc | 2 +- onnxruntime/test/framework/dummy_allocator.cc | 4 +- .../test/framework/inference_session_test.cc | 8 +-- .../test/framework/session_state_test.cc | 2 +- onnxruntime/test/framework/tensor_test.cc | 2 +- onnxruntime/test/onnx/heap_buffer.cc | 2 +- onnxruntime/test/onnx/heap_buffer.h | 3 +- .../test/optimizer/graph_transform_test.cc | 4 +- onnxruntime/test/perftest/ort_test_session.cc | 7 +- onnxruntime/test/perftest/ort_test_session.h | 10 ++- .../my_allocator.cc | 7 +- onnxruntime/test/util/test_allocator.cc | 4 +- tools/ci_build/build.py | 8 +-- 36 files changed, 168 insertions(+), 283 deletions(-) delete mode 100644 onnxruntime/core/framework/mimalloc_allocator.cc delete mode 100644 onnxruntime/core/framework/mimalloc_allocator.h create mode 100644 onnxruntime/core/platform/windows/mimalloc/mimalloc_overloads.cc diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b92ea8649e..c447093f9f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -97,6 +97,7 @@ option(onnxruntime_ARMNN_RELU_USE_CPU "Use the CPU implementation for the Relu o option(onnxruntime_ARMNN_BN_USE_CPU "Use the CPU implementation for the Batch Normalization operator for the ArmNN EP" ON) option(onnxruntime_ENABLE_INSTRUMENT "Enable Instrument with Event Tracing for Windows (ETW)" OFF) option(onnxruntime_USE_TELEMETRY "Build with Telemetry" OFF) +option(onnxruntime_USE_MIMALLOC "Override new/delete and arena allocator with mimalloc" OFF) #The onnxruntime_PREFER_SYSTEM_LIB is mainly designed for package managers like apt/yum/vcpkg. #Please note, by default Protobuf_USE_STATIC_LIBS is OFF but it's recommended to turn it ON on Windows. You should set it properly when onnxruntime_PREFER_SYSTEM_LIB is ON otherwise you'll hit linkage errors. #If you have already installed protobuf(or the others) in your system at the default system paths(like /usr/include), then it's better to set onnxruntime_PREFER_SYSTEM_LIB ON. Otherwise onnxruntime may see two different protobuf versions and we won't know which one will be used, the worst case could be onnxruntime picked up header files from one of them but the binaries from the other one. diff --git a/cmake/external/mimalloc b/cmake/external/mimalloc index 2d54553b7a..f412df7a2b 160000 --- a/cmake/external/mimalloc +++ b/cmake/external/mimalloc @@ -1 +1 @@ -Subproject commit 2d54553b7a78c7c35620b827e7e5ab2228ecb495 +Subproject commit f412df7a2b64421e1f1d61fde6055a6ea288e8f5 diff --git a/cmake/external/mimalloc.cmake b/cmake/external/mimalloc.cmake index 77ca987b0c..346e04f4d7 100644 --- a/cmake/external/mimalloc.cmake +++ b/cmake/external/mimalloc.cmake @@ -1,15 +1,11 @@ set(mimalloc_root_dir ${PROJECT_SOURCE_DIR}/external/mimalloc) -if(onnxruntime_USE_MIMALLOC_STL_ALLOCATOR) - add_definitions(-DUSE_MIMALLOC_STL_ALLOCATOR) # used in ONNXRuntime -endif() -if(onnxruntime_USE_MIMALLOC_ARENA_ALLOCATOR) - add_definitions(-DUSE_MIMALLOC_ARENA_ALLOCATOR) # used in ONNXRuntime -endif() +add_definitions(-DUSE_MIMALLOC) include_directories(${mimalloc_root_dir}/include) option(MI_OVERRIDE "" OFF) option(MI_BUILD_TESTS "" OFF) +option(MI_DEBUG_FULL "" OFF) add_subdirectory(${mimalloc_root_dir} EXCLUDE_FROM_ALL) set_target_properties(mimalloc-static PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/cmake/onnxruntime_common.cmake b/cmake/onnxruntime_common.cmake index 8425e70df0..c2a0254940 100644 --- a/cmake/onnxruntime_common.cmake +++ b/cmake/onnxruntime_common.cmake @@ -75,6 +75,14 @@ file(GLOB onnxruntime_common_src CONFIGURE_DEPENDS ${onnxruntime_common_src_patterns} ) +# Remove new/delete intercept. To deal with memory leaks +# Use either non-mimalloc build OR use mimalloc built-in features. +if(WIN32 AND onnxruntime_USE_MIMALLOC) + list(REMOVE_ITEM onnxruntime_common_src + "${ONNXRUNTIME_ROOT}/core/platform/windows/debug_alloc.cc" + "${ONNXRUNTIME_ROOT}/core/platform/windows/debug_alloc.h") +endif() + source_group(TREE ${REPO_ROOT} FILES ${onnxruntime_common_src}) onnxruntime_add_static_library(onnxruntime_common ${onnxruntime_common_src}) @@ -83,17 +91,20 @@ if (onnxruntime_USE_TELEMETRY) set_target_properties(onnxruntime_common PROPERTIES COMPILE_FLAGS "/FI${ONNXRUNTIME_INCLUDE_DIR}/core/platform/windows/TraceLoggingConfigPrivate.h") endif() -if (onnxruntime_USE_MIMALLOC_STL_ALLOCATOR OR onnxruntime_USE_MIMALLOC_ARENA_ALLOCATOR) +if (onnxruntime_USE_MIMALLOC) + if(NOT WIN32) + message(FATAL "Currently do not support MIMALLOC in GPU builds") + endif() if(onnxruntime_USE_CUDA OR onnxruntime_USE_OPENVINO) - message(WARNING "Ignoring directive to use mimalloc on unimplemented targets") - elseif (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") - # Some of the non-windows targets see strange runtime failures - message(WARNING "Ignoring request to link to mimalloc - only windows supported") + message(WARNING "Currently do not support MIMALLOC in GPU builds") else() include(external/mimalloc.cmake) list(APPEND onnxruntime_EXTERNAL_LIBRARIES mimalloc-static) list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES mimalloc-static) - target_link_libraries(onnxruntime_common mimalloc-static) + set(onnxruntime_mimalloc_shim_src "${ONNXRUNTIME_ROOT}/core/platform/windows/mimalloc/mimalloc_overloads.cc") + add_library(onnxruntime_mimalloc_shim ${onnxruntime_mimalloc_shim_src}) + target_link_libraries(onnxruntime_mimalloc_shim mimalloc-static) + target_link_libraries(onnxruntime_common onnxruntime_mimalloc_shim) endif() endif() diff --git a/cmake/onnxruntime_framework.cmake b/cmake/onnxruntime_framework.cmake index dee3ff2bda..60f547e395 100644 --- a/cmake/onnxruntime_framework.cmake +++ b/cmake/onnxruntime_framework.cmake @@ -63,6 +63,11 @@ if (onnxruntime_ENABLE_TRAINING) target_include_directories(onnxruntime_framework PRIVATE ${DLPACK_INCLUDE_DIR}) endif() onnxruntime_add_include_to_target(onnxruntime_framework onnxruntime_common onnx onnx_proto ${PROTOBUF_LIB} flatbuffers) + +if (onnxruntime_USE_MIMALLOC) + target_link_libraries(onnxruntime_framework mimalloc-static) +endif() + set_target_properties(onnxruntime_framework PROPERTIES FOLDER "ONNXRuntime") # need onnx to build to create headers that this project includes add_dependencies(onnxruntime_framework ${onnxruntime_EXTERNAL_DEPENDENCIES}) diff --git a/include/onnxruntime/core/common/common.h b/include/onnxruntime/core/common/common.h index 39fd547798..233311596d 100644 --- a/include/onnxruntime/core/common/common.h +++ b/include/onnxruntime/core/common/common.h @@ -36,10 +36,6 @@ #include "core/common/make_string.h" #include "core/common/status.h" -#ifdef USE_MIMALLOC_ARENA_ALLOCATOR -#include -#endif - namespace onnxruntime { using TimePoint = std::chrono::high_resolution_clock::time_point; diff --git a/include/onnxruntime/core/framework/allocator.h b/include/onnxruntime/core/framework/allocator.h index d0a9ccb1b4..0aa6701e7d 100644 --- a/include/onnxruntime/core/framework/allocator.h +++ b/include/onnxruntime/core/framework/allocator.h @@ -183,24 +183,9 @@ class CPUAllocator : public IAllocator { void Free(void* p) override; }; -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) -class MiMallocAllocator : public IAllocator { - public: - explicit MiMallocAllocator(const OrtMemoryInfo& memory_info) : IAllocator(memory_info) {} - MiMallocAllocator() : IAllocator(OrtMemoryInfo(CPU, OrtAllocatorType::OrtDeviceAllocator)) {} - - void* Alloc(size_t size) override; - void Free(void* p) override; -}; - -#endif - -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) -using TAllocator = MiMallocAllocator; -#else -using TAllocator = CPUAllocator; -#endif - using AllocatorPtr = std::shared_ptr; +void* AllocatorDefaultAlloc(size_t size); +void AllocatorDefaultFree(void* p); + } // namespace onnxruntime diff --git a/onnxruntime/core/framework/allocator.cc b/onnxruntime/core/framework/allocator.cc index 9589bc3283..98a8bf4d98 100644 --- a/onnxruntime/core/framework/allocator.cc +++ b/onnxruntime/core/framework/allocator.cc @@ -4,11 +4,16 @@ #include "core/common/safeint.h" #include "core/framework/allocator.h" #include "core/framework/allocatormgr.h" +#include "core/mlas/inc/mlas.h" #include "core/framework/utils.h" #include "core/session/ort_apis.h" #include #include +#if defined(USE_MIMALLOC) +#include +#endif + namespace onnxruntime { // private helper for calculation so SafeInt usage doesn't bleed into the public allocator.h header @@ -34,22 +39,73 @@ bool IAllocator::CalcMemSizeForArrayWithAlignment(size_t nmemb, size_t size, siz return ok; } -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) -void* MiMallocAllocator::Alloc(size_t size) { - return mi_malloc(size); +#ifdef USE_MIMALLOC +void* AllocatorDefaultAlloc(size_t size) { + const size_t alignment = MlasGetPreferredBufferAlignment(); + if (size <= 0) return nullptr; + void* p; +#if defined(_MSC_VER) + p = mi_malloc_aligned(size, alignment); + if (p == nullptr) + ORT_THROW_EX(std::bad_alloc); +#elif defined(_LIBCPP_SGX_CONFIG) + p = mi_memalign(alignment, size); + if (p == nullptr) + ORT_THROW_EX(std::bad_alloc); +#else + int ret = mi_posix_memalign(&p, alignment, size); + if (ret != 0) + ORT_THROW_EX(std::bad_alloc); +#endif + return p; } -void MiMallocAllocator::Free(void* p) { +void AllocatorDefaultFree(void* p) { +#if defined(_MSC_VER) + const size_t alignment = MlasGetPreferredBufferAlignment(); + mi_free_aligned(p, alignment); +#else mi_free(p); -} #endif +} + +#else +void* AllocatorDefaultAlloc(size_t size) { + const size_t alignment = MlasGetPreferredBufferAlignment(); + if (size <= 0) return nullptr; + void* p; +#if _MSC_VER + p = _aligned_malloc(size, alignment); + if (p == nullptr) + ORT_THROW_EX(std::bad_alloc); +#elif defined(_LIBCPP_SGX_CONFIG) + p = memalign(alignment, size); + if (p == nullptr) + ORT_THROW_EX(std::bad_alloc); +#else + int ret = posix_memalign(&p, alignment, size); + if (ret != 0) + ORT_THROW_EX(std::bad_alloc); +#endif + return p; +} + +void AllocatorDefaultFree(void* p) { +#if _MSC_VER + _aligned_free(p); +#else + free(p); +#endif +} + +#endif // USE_MIMALLOC void* CPUAllocator::Alloc(size_t size) { - return utils::DefaultAlloc(size); + return AllocatorDefaultAlloc(size); } void CPUAllocator::Free(void* p) { - utils::DefaultFree(p); + AllocatorDefaultFree(p); } } // namespace onnxruntime @@ -108,3 +164,4 @@ ORT_API_STATUS_IMPL(OrtApis::CompareMemoryInfo, _In_ const OrtMemoryInfo* info1, *out = (*info1 == *info2) ? 0 : -1; return nullptr; } + diff --git a/onnxruntime/core/framework/allocatormgr.cc b/onnxruntime/core/framework/allocatormgr.cc index 125a450726..ade031abcf 100644 --- a/onnxruntime/core/framework/allocatormgr.cc +++ b/onnxruntime/core/framework/allocatormgr.cc @@ -3,7 +3,6 @@ #include "core/framework/allocatormgr.h" #include "core/framework/bfc_arena.h" -#include "core/framework/mimalloc_allocator.h" #include "core/common/logging/logging.h" #include #include @@ -21,7 +20,7 @@ inline int MakeKey(int id, OrtMemType mem_type) { } // namespace AllocatorPtr CreateAllocator(const AllocatorCreationInfo& info) { - auto device_allocator = std::unique_ptr(info.device_alloc_factory(info.device_id)); + auto device_allocator = info.device_alloc_factory(info.device_id); if (info.use_arena) { size_t max_mem = info.arena_cfg.max_mem == 0 ? BFCArena::DEFAULT_MAX_MEM : info.arena_cfg.max_mem; @@ -48,21 +47,16 @@ AllocatorPtr CreateAllocator(const AllocatorCreationInfo& info) { return nullptr; } -#ifdef USE_MIMALLOC_ARENA_ALLOCATOR - return std::shared_ptr( - std::make_unique(max_mem)); -#else - return std::shared_ptr( + return AllocatorPtr( std::make_unique(std::move(device_allocator), max_mem, arena_extend_str, initial_chunk_size_bytes, max_dead_bytes_per_chunk, initial_growth_chunk_size_bytes)); -#endif + } else { + return device_allocator; } - - return AllocatorPtr(std::move(device_allocator)); } // Update allocator in the provider if already present; ignore if not. diff --git a/onnxruntime/core/framework/bfc_arena.h b/onnxruntime/core/framework/bfc_arena.h index f84b9038fb..f38d6b64e0 100644 --- a/onnxruntime/core/framework/bfc_arena.h +++ b/onnxruntime/core/framework/bfc_arena.h @@ -223,7 +223,7 @@ class BFCArena : public IAllocator { AllocationRegion(AllocationRegion&& other) noexcept { Swap(other); } - AllocationRegion& operator=(AllocationRegion&& other) { + AllocationRegion& operator=(AllocationRegion&& other) noexcept { Swap(other); return *this; } diff --git a/onnxruntime/core/framework/error_code.cc b/onnxruntime/core/framework/error_code.cc index 0f805fcb16..0bcad00233 100644 --- a/onnxruntime/core/framework/error_code.cc +++ b/onnxruntime/core/framework/error_code.cc @@ -19,13 +19,23 @@ struct OrtStatus { #pragma warning(disable : 28196) #pragma warning(disable : 6387) #endif + +namespace { +inline OrtStatus* NewStatus(size_t clen) { + auto* buf = new (std::nothrow) uint8_t[sizeof(OrtStatus) + clen]; + if (buf == nullptr) return nullptr; // OOM. What we can do here? abort()? + return new (buf) OrtStatus; +} +} // namespace + //Even we say it may not return NULL, indeed it may. _Check_return_ _Ret_notnull_ OrtStatus* ORT_API_CALL OrtApis::CreateStatus(OrtErrorCode code, _In_z_ const char* msg) NO_EXCEPTION { assert(!(code == 0 && msg != nullptr)); SafeInt clen(nullptr == msg ? 0 : strnlen(msg, onnxruntime::kMaxStrLen)); - OrtStatus* p = reinterpret_cast(::malloc(sizeof(OrtStatus) + clen)); - if (p == nullptr) return nullptr; // OOM. What we can do here? abort()? + OrtStatus* p = NewStatus(clen); + if (p == nullptr) + return nullptr; p->code = code; memcpy(p->msg, msg, clen); p->msg[clen] = '\0'; @@ -37,7 +47,7 @@ _Ret_notnull_ OrtStatus* ToOrtStatus(const Status& st) { if (st.IsOK()) return nullptr; SafeInt clen(st.ErrorMessage().length()); - OrtStatus* p = reinterpret_cast(::malloc(sizeof(OrtStatus) + clen)); + OrtStatus* p = NewStatus(clen); if (p == nullptr) return nullptr; p->code = static_cast(st.Code()); @@ -57,4 +67,4 @@ ORT_API(const char*, OrtApis::GetErrorMessage, _In_ const OrtStatus* status) { return status->msg; } -ORT_API(void, OrtApis::ReleaseStatus, _Frees_ptr_opt_ OrtStatus* value) { ::free(value); } +ORT_API(void, OrtApis::ReleaseStatus, _Frees_ptr_opt_ OrtStatus* value) { delete[] reinterpret_cast(value); } diff --git a/onnxruntime/core/framework/mimalloc_allocator.cc b/onnxruntime/core/framework/mimalloc_allocator.cc deleted file mode 100644 index 17a8855e87..0000000000 --- a/onnxruntime/core/framework/mimalloc_allocator.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) - -#include "mimalloc.h" -#include "core/framework/mimalloc_allocator.h" - -namespace onnxruntime { - -MiMallocAllocator::MiMallocAllocator(size_t total_memory) - : IAllocator(OrtMemoryInfo(CPU, OrtAllocatorType::OrtDeviceAllocator)) { - stats_.bytes_limit = total_memory; -} - -void* MiMallocAllocator::Alloc(size_t size) { -#if (MI_STAT > 1) - stats_.num_allocs++; -#endif - return mi_malloc(size); -} - -void MiMallocAllocator::Free(void* p) { - mi_free(p); -} - -// mimalloc only maintains stats when compiled under debug (which in turn sets MI_STAT) -void MiMallocAllocator::GetStats(AllocatorStats* stats) { -#if (MI_STAT > 1) - auto current_stats = mi_heap_get_default()->tld->stats; - stats_.bytes_in_use = current_stats.malloc.current; - stats_.total_allocated_bytes = current_stats.reserved.current; - stats_.max_bytes_in_use = current_stats.reserved.peak; -#endif - *stats = stats_; -} - -size_t MiMallocAllocator::AllocatedSize(const void* ptr) { - return mi_usable_size(ptr); -} - -} // namespace onnxruntime - -#endif diff --git a/onnxruntime/core/framework/mimalloc_allocator.h b/onnxruntime/core/framework/mimalloc_allocator.h deleted file mode 100644 index f2357e894f..0000000000 --- a/onnxruntime/core/framework/mimalloc_allocator.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) - -#include "core/common/common.h" -#include "core/framework/allocator.h" -#include "onnxruntime_config.h" - -namespace onnxruntime { - -class MiMallocAllocator : public IAllocator { - public: - explicit MiMallocAllocator(size_t total_memory); - - void* Alloc(size_t size) override; - - void Free(void* p) override; - - // mimalloc only maintains stats when compiled under debug, or when MI_STAT >= 2 - void GetStats(AllocatorStats* stats) override; - - size_t AllocatedSize(const void* ptr); - - private: - AllocatorStats stats_; -}; - -} // namespace onnxruntime - -#endif diff --git a/onnxruntime/core/framework/prepacked_weights_container.cc b/onnxruntime/core/framework/prepacked_weights_container.cc index 42cdd3debb..8b6f146dff 100644 --- a/onnxruntime/core/framework/prepacked_weights_container.cc +++ b/onnxruntime/core/framework/prepacked_weights_container.cc @@ -17,7 +17,7 @@ AllocatorPtr PrepackedWeightsContainer::GetOrCreateAllocator(const std::string& if (device_name == CPU) { // TODO: Investigate benefits of using an arena based allocator // For now, we go with a non-arena based allocator - AllocatorCreationInfo device_info{[](int) { return std::make_unique(); }, + AllocatorCreationInfo device_info{[](int) { return std::make_unique(); }, 0, false}; auto allocator = CreateAllocator(device_info); diff --git a/onnxruntime/core/framework/utils.cc b/onnxruntime/core/framework/utils.cc index 2eb64d6603..83adab1de4 100644 --- a/onnxruntime/core/framework/utils.cc +++ b/onnxruntime/core/framework/utils.cc @@ -71,31 +71,11 @@ std::ostream& operator<<(std::ostream& out, const TensorProto& tensor_proto) { namespace onnxruntime { namespace utils { void* DefaultAlloc(size_t size) { - if (size <= 0) return nullptr; - void* p; - size_t alignment = MlasGetPreferredBufferAlignment(); -#if _MSC_VER - p = _aligned_malloc(size, alignment); - if (p == nullptr) - ORT_THROW_EX(std::bad_alloc); -#elif defined(_LIBCPP_SGX_CONFIG) - p = memalign(alignment, size); - if (p == nullptr) - ORT_THROW_EX(std::bad_alloc); -#else - int ret = posix_memalign(&p, alignment, size); - if (ret != 0) - ORT_THROW_EX(std::bad_alloc); -#endif - return p; + return onnxruntime::AllocatorDefaultAlloc(size); } void DefaultFree(void* p) { -#if _MSC_VER - _aligned_free(p); -#else - free(p); -#endif + onnxruntime::AllocatorDefaultFree(p); } void ConstructStrings(void* p_data, int64_t elements) { diff --git a/onnxruntime/core/platform/path_lib.cc b/onnxruntime/core/platform/path_lib.cc index a242b2d4ab..8ac1f7b577 100644 --- a/onnxruntime/core/platform/path_lib.cc +++ b/onnxruntime/core/platform/path_lib.cc @@ -28,6 +28,7 @@ #include #include #include +#include #endif #ifdef _WIN32 @@ -107,24 +108,24 @@ namespace onnxruntime { namespace { -template -struct Freer { - void operator()(T* p) { ::free(p); } -}; - -using MallocdStringPtr = std::unique_ptr >; +inline std::unique_ptr StrDup(const std::string& input) { + auto buf = std::make_unique(input.size() + 1); + strncpy(buf.get(), input.c_str(), input.size()); + buf[input.size()] = 0; + return buf; +} } // namespace common::Status GetDirNameFromFilePath(const std::basic_string& input, std::basic_string& output) { - MallocdStringPtr s{strdup(input.c_str())}; + auto s = StrDup(input); output = dirname(s.get()); return Status::OK(); } std::string GetLastComponent(const std::string& input) { - MallocdStringPtr s{strdup(input.c_str())}; + auto s = StrDup(input); std::string ret = basename(s.get()); return ret; } diff --git a/onnxruntime/core/platform/windows/env.cc b/onnxruntime/core/platform/windows/env.cc index 1f272aa4c6..cb7d733ae2 100644 --- a/onnxruntime/core/platform/windows/env.cc +++ b/onnxruntime/core/platform/windows/env.cc @@ -600,5 +600,4 @@ class WindowsEnv : public Env { Env& Env::Default() { return WindowsEnv::Instance(); } - } // namespace onnxruntime diff --git a/onnxruntime/core/platform/windows/mimalloc/mimalloc_overloads.cc b/onnxruntime/core/platform/windows/mimalloc/mimalloc_overloads.cc new file mode 100644 index 0000000000..e24a1c0492 --- /dev/null +++ b/onnxruntime/core/platform/windows/mimalloc/mimalloc_overloads.cc @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifdef USE_MIMALLOC +// Add definition for new/delete +#include +#endif diff --git a/onnxruntime/core/providers/cpu/containers.h b/onnxruntime/core/providers/cpu/containers.h index 7dcdaee1f5..b551d19ea8 100644 --- a/onnxruntime/core/providers/cpu/containers.h +++ b/onnxruntime/core/providers/cpu/containers.h @@ -3,27 +3,10 @@ #pragma once -#if defined(USE_MIMALLOC_STL_ALLOCATOR) -#include -#else #include "core/framework/ort_stl_allocator.h" -#endif namespace onnxruntime { -#if defined(USE_MIMALLOC_STL_ALLOCATOR) - -template -mi_stl_allocator GetAllocator(const OpKernelContext& context) { - ORT_UNUSED_PARAMETER(context); - return mi_stl_allocator(); -} - -template -using FastAllocVector = std::vector>; - -#else - template OrtStlAllocator GetAllocator(const OpKernelContext& context) { AllocatorPtr allocator; @@ -35,6 +18,4 @@ OrtStlAllocator GetAllocator(const OpKernelContext& context) { template using FastAllocVector = std::vector>; -#endif - } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.h b/onnxruntime/core/providers/cpu/cpu_execution_provider.h index 5d0d6c31a6..9eb11cdbf2 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.h +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.h @@ -29,18 +29,15 @@ class CPUExecutionProvider : public IExecutionProvider { : IExecutionProvider{onnxruntime::kCpuExecutionProvider} { bool create_arena = info.create_arena; -#ifdef USE_JEMALLOC -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) || defined(USE_MIMALLOC_STL_ALLOCATOR) -#error jemalloc and mimalloc should not both be enabled -#endif - //JEMalloc already has memory pool, so just use device allocator. +#if defined(USE_JEMALLOC) || defined(USE_MIMALLOC) + //JEMalloc/mimalloc already have memory pool, so just use device allocator. create_arena = false; #elif !(defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) //Disable Arena allocator for x86_32 build because it may run into infinite loop when integer overflow happens create_arena = false; #endif - AllocatorCreationInfo device_info{[](int) { return std::make_unique(); }, + AllocatorCreationInfo device_info{[](int) { return std::make_unique(); }, 0, create_arena}; InsertAllocator(CreateAllocator(device_info)); diff --git a/onnxruntime/core/session/environment.cc b/onnxruntime/core/session/environment.cc index f9d82b3a5b..54fc2e75eb 100644 --- a/onnxruntime/core/session/environment.cc +++ b/onnxruntime/core/session/environment.cc @@ -115,11 +115,8 @@ Status Environment::CreateAndRegisterAllocator(const OrtMemoryInfo& mem_info, co // determine if arena should be used bool create_arena = mem_info.alloc_type == OrtArenaAllocator; -#ifdef USE_JEMALLOC -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) || defined(USE_MIMALLOC_STL_ALLOCATOR) -#error jemalloc and mimalloc should not both be enabled -#endif - //JEMalloc already has memory pool, so just use device allocator. +#if defined(USE_JEMALLOC) || defined(USE_MIMALLOC) + // We use these allocators instead of the arena create_arena = false; #elif !(defined(__amd64__) || defined(_M_AMD64)) //Disable Arena allocator for x86_32 build because it may run into infinite loop when integer overflow happens @@ -156,13 +153,13 @@ Status Environment::CreateAndRegisterAllocator(const OrtMemoryInfo& mem_info, co OrtArenaCfg l_arena_cfg{max_mem, arena_extend_strategy, initial_chunk_size_bytes, max_dead_bytes_per_chunk, initial_growth_chunk_size_bytes}; AllocatorCreationInfo alloc_creation_info{ - [mem_info](int) { return std::make_unique(mem_info); }, + [mem_info](int) { return std::make_unique(mem_info); }, 0, create_arena, l_arena_cfg}; allocator_ptr = CreateAllocator(alloc_creation_info); } else { - AllocatorCreationInfo alloc_creation_info{[](int) { return std::make_unique(); }, + AllocatorCreationInfo alloc_creation_info{[](int) { return std::make_unique(); }, 0, create_arena}; allocator_ptr = CreateAllocator(alloc_creation_info); } diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc index f4411def79..387d996c98 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.cc +++ b/onnxruntime/python/onnxruntime_pybind_state.cc @@ -1484,62 +1484,10 @@ including arg name, arg type (contains both type and shape).)pbdoc") .export_values(); } -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) -static struct { - PyMemAllocatorEx mem; - PyMemAllocatorEx raw; - PyMemAllocatorEx obj; -} allocators; -#endif - void CreateInferencePybindStateModule(py::module& m) { m.doc() = "pybind11 stateful interface to ONNX runtime"; RegisterExceptions(m); -#if defined(USE_MIMALLOC_ARENA_ALLOCATOR) - PyMemAllocatorEx alloc; - alloc.malloc = [](void* ctx, size_t size) { - ORT_UNUSED_PARAMETER(ctx); - return mi_malloc(size); - }; - - alloc.calloc = [](void* ctx, size_t nelem, size_t elsize) { - ORT_UNUSED_PARAMETER(ctx); - return mi_calloc(nelem, elsize); - }; - - alloc.realloc = [](void* ctx, void* ptr, size_t new_size) { - if (mi_is_in_heap_region(ptr)) { - return mi_realloc(ptr, new_size); - } else { - PyMemAllocatorEx* a = (PyMemAllocatorEx*)ctx; - return a->realloc(ctx, ptr, new_size); - } - }; - - alloc.free = [](void* ctx, void* ptr) { - if (mi_is_in_heap_region(ptr)) { - mi_free(ptr); - } else { - PyMemAllocatorEx* a = (PyMemAllocatorEx*)ctx; - a->free(ctx, ptr); - } - }; - - alloc.ctx = &allocators.raw; - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); - - alloc.ctx = &allocators.mem; - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); - - alloc.ctx = &allocators.obj; - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); - -#endif - // Initialization of the module ([]() -> void { // import_array1() forces a void return value. diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index ca93b1d598..fb286e2ad2 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -303,7 +303,7 @@ inline const PySessionOptions& GetDefaultCPUSessionOptions() { } inline AllocatorPtr& GetAllocator() { - static AllocatorPtr alloc = std::make_shared(); + static AllocatorPtr alloc = std::make_shared(); return alloc; } diff --git a/onnxruntime/test/framework/allocator_test.cc b/onnxruntime/test/framework/allocator_test.cc index 0b197af0fe..c2bd393c55 100644 --- a/onnxruntime/test/framework/allocator_test.cc +++ b/onnxruntime/test/framework/allocator_test.cc @@ -16,7 +16,7 @@ TEST(AllocatorTest, CPUAllocatorTest) { EXPECT_EQ(cpu_arena->Info().id, 0); // arena is disabled for CPUExecutionProvider on x86 and JEMalloc -#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) && !defined(USE_JEMALLOC) +#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) && !defined(USE_JEMALLOC) && !defined(USE_MIMALLOC) EXPECT_EQ(cpu_arena->Info().alloc_type, OrtAllocatorType::OrtArenaAllocator); #else EXPECT_EQ(cpu_arena->Info().alloc_type, OrtAllocatorType::OrtDeviceAllocator); diff --git a/onnxruntime/test/framework/dummy_allocator.cc b/onnxruntime/test/framework/dummy_allocator.cc index ff9be8315f..950f41a8d5 100644 --- a/onnxruntime/test/framework/dummy_allocator.cc +++ b/onnxruntime/test/framework/dummy_allocator.cc @@ -11,11 +11,11 @@ DummyAllocator::DummyAllocator() } void* DummyAllocator::Alloc(size_t size) { - return malloc(size); + return new (std::nothrow) uint8_t[size]; } void DummyAllocator::Free(void* p) { - free(p); + delete[] reinterpret_cast(p); } } // namespace test diff --git a/onnxruntime/test/framework/inference_session_test.cc b/onnxruntime/test/framework/inference_session_test.cc index 23e240a134..f8f1745042 100644 --- a/onnxruntime/test/framework/inference_session_test.cc +++ b/onnxruntime/test/framework/inference_session_test.cc @@ -2544,12 +2544,12 @@ TEST(InferenceSessionTests, AllocatorSharing_EnsureSessionsUseSameOrtCreatedAllo ASSERT_TRUE(st.IsOK()); // create allocator to register with the env bool use_arena = true; -#if !(defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) +#if !(defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) || defined(USE_MIMALLOC) use_arena = false; #endif OrtMemoryInfo mem_info{onnxruntime::CPU, use_arena ? OrtArenaAllocator : OrtDeviceAllocator}; AllocatorCreationInfo device_info{ - [mem_info](int) { return std::make_unique(mem_info); }, + [mem_info](int) { return std::make_unique(mem_info); }, 0, use_arena}; AllocatorPtr allocator_ptr = CreateAllocator(device_info); @@ -2589,12 +2589,12 @@ TEST(InferenceSessionTests, AllocatorSharing_EnsureSessionsDontUseSameOrtCreated ASSERT_TRUE(st.IsOK()); // create allocator to register with the env bool use_arena = true; -#if !(defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) +#if !(defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) || defined(USE_MIMALLOC) use_arena = false; #endif OrtMemoryInfo mem_info{onnxruntime::CPU, use_arena ? OrtArenaAllocator : OrtDeviceAllocator}; AllocatorCreationInfo device_info{ - [mem_info](int) { return std::make_unique(mem_info); }, + [mem_info](int) { return std::make_unique(mem_info); }, 0, use_arena}; AllocatorPtr allocator_ptr = CreateAllocator(device_info); diff --git a/onnxruntime/test/framework/session_state_test.cc b/onnxruntime/test/framework/session_state_test.cc index c75e81cd29..c6d49e7356 100644 --- a/onnxruntime/test/framework/session_state_test.cc +++ b/onnxruntime/test/framework/session_state_test.cc @@ -178,7 +178,7 @@ TEST_P(SessionStateTestP, TestInitializerProcessing) { // if the relevant session option config flag is set // For this test we need to enable the arena-based allocator which is not supported on x86 builds, so // enable this test only on x64 builds -#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) +#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) && !defined(USE_MIMALLOC) TEST(SessionStateTest, TestInitializerMemoryAllocatedUsingNonArenaMemory) { // Part 1: Feature turned ON (i.e.) allocate from non-arena memory { diff --git a/onnxruntime/test/framework/tensor_test.cc b/onnxruntime/test/framework/tensor_test.cc index 503b92d947..c55ae28917 100644 --- a/onnxruntime/test/framework/tensor_test.cc +++ b/onnxruntime/test/framework/tensor_test.cc @@ -139,7 +139,7 @@ TEST(TensorTest, EmptyTensorTest) { EXPECT_EQ(location.id, 0); // arena is disabled for CPUExecutionProvider on x86 and JEMalloc -#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) && !defined(USE_JEMALLOC) +#if (defined(__amd64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(_M_ARM64)) && !defined(USE_JEMALLOC) && !defined(USE_MIMALLOC) EXPECT_EQ(location.alloc_type, OrtAllocatorType::OrtArenaAllocator); #else EXPECT_EQ(location.alloc_type, OrtAllocatorType::OrtDeviceAllocator); diff --git a/onnxruntime/test/onnx/heap_buffer.cc b/onnxruntime/test/onnx/heap_buffer.cc index d09aa18fb9..10ddfa244b 100644 --- a/onnxruntime/test/onnx/heap_buffer.cc +++ b/onnxruntime/test/onnx/heap_buffer.cc @@ -16,7 +16,7 @@ HeapBuffer::~HeapBuffer() { d.Run(); } for (void* p : buffers_) { - free(p); + delete[] reinterpret_cast(p); } } } // namespace test diff --git a/onnxruntime/test/onnx/heap_buffer.h b/onnxruntime/test/onnx/heap_buffer.h index 4bb8ae3c59..37ca6aa615 100644 --- a/onnxruntime/test/onnx/heap_buffer.h +++ b/onnxruntime/test/onnx/heap_buffer.h @@ -7,6 +7,7 @@ #include #include +#include namespace onnxruntime { namespace test { @@ -21,7 +22,7 @@ class HeapBuffer { */ ~HeapBuffer(); void* AllocMemory(size_t size) { - void* p = malloc(size); + void* p = new (std::nothrow) uint8_t[size]; buffers_.push_back(p); return p; } diff --git a/onnxruntime/test/optimizer/graph_transform_test.cc b/onnxruntime/test/optimizer/graph_transform_test.cc index bcb7be6e1a..af7f5739f7 100644 --- a/onnxruntime/test/optimizer/graph_transform_test.cc +++ b/onnxruntime/test/optimizer/graph_transform_test.cc @@ -3005,8 +3005,8 @@ TEST_F(GraphTransformationTests, BiasGeluSwitchedInputOrder) { session_options.graph_optimization_level = level; session_options.session_logid = "OptimizerTests"; InferenceSession session{session_options, GetEnvironment()}; - ASSERT_TRUE(session.Load(model_uri).IsOK()); - ASSERT_TRUE(session.Initialize().IsOK()); + ASSERT_STATUS_OK(session.Load(model_uri)); + ASSERT_STATUS_OK(session.Initialize()); RunOptions run_options; ASSERT_STATUS_OK(session.Run(run_options, feeds, output_names, &fetches)); diff --git a/onnxruntime/test/perftest/ort_test_session.cc b/onnxruntime/test/perftest/ort_test_session.cc index fe724a20c0..551709ea62 100644 --- a/onnxruntime/test/perftest/ort_test_session.cc +++ b/onnxruntime/test/perftest/ort_test_session.cc @@ -29,7 +29,7 @@ std::chrono::duration OnnxRuntimeTestSession::Run() { OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device& rd, const PerformanceTestConfig& performance_test_config, const TestModelInfo& m) - : rand_engine_(rd()), input_names_(m.GetInputCount()), input_length_(m.GetInputCount()) { + : rand_engine_(rd()), input_names_(m.GetInputCount()), input_names_str_(m.GetInputCount()), input_length_(m.GetInputCount()) { Ort::SessionOptions session_options; const std::string& provider_name = performance_test_config.machine_config.provider_type_name; if (provider_name == onnxruntime::kDnnlExecutionProvider) { @@ -438,9 +438,10 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device output_names_raw_ptr[i] = output_names_[i].c_str(); } - size_t input_count = static_cast(m.GetInputCount()); + const size_t input_count = static_cast(m.GetInputCount()); for (size_t i = 0; i != input_count; ++i) { - input_names_[i] = strdup(m.GetInputName(i).c_str()); + input_names_str_[i] = m.GetInputName(i); + input_names_[i] = input_names_str_[i].c_str(); } } diff --git a/onnxruntime/test/perftest/ort_test_session.h b/onnxruntime/test/perftest/ort_test_session.h index d23315fa6b..a844cc58c7 100644 --- a/onnxruntime/test/perftest/ort_test_session.h +++ b/onnxruntime/test/perftest/ort_test_session.h @@ -27,11 +27,8 @@ class OnnxRuntimeTestSession : public TestSession { bool PopulateGeneratedInputTestData(); - ~OnnxRuntimeTestSession() override { - for (char* p : input_names_) { - free(p); - } - } + ~OnnxRuntimeTestSession() = default; + std::chrono::duration Run() override; ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(OnnxRuntimeTestSession); @@ -45,7 +42,8 @@ class OnnxRuntimeTestSession : public TestSession { // The same size with output_names_. // TODO: implement a customized allocator, then we can remove output_names_ to simplify this code std::vector output_names_raw_ptr; - std::vector input_names_; + std::vector input_names_; + std::vector input_names_str_; const int input_length_; }; diff --git a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc index c5f2a8e831..eceb62266c 100644 --- a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc +++ b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "my_allocator.h" +#include namespace onnxruntime { MyEPAllocator::MyEPAllocator(OrtDevice::DeviceId device_id) @@ -10,14 +11,12 @@ MyEPAllocator::MyEPAllocator(OrtDevice::DeviceId device_id) } void* MyEPAllocator::Alloc(size_t size) { - void* device_address = malloc(size); + void* device_address = new (std::nothrow) uint8_t[size]; return device_address; } void MyEPAllocator::Free(void* p) { - if (p) { - free(p); - } + delete[] reinterpret_cast(p); } } // namespace onnxruntime diff --git a/onnxruntime/test/util/test_allocator.cc b/onnxruntime/test/util/test_allocator.cc index a62eae4af4..4418dcf613 100644 --- a/onnxruntime/test/util/test_allocator.cc +++ b/onnxruntime/test/util/test_allocator.cc @@ -19,7 +19,7 @@ MockedOrtAllocator::~MockedOrtAllocator() { void* MockedOrtAllocator::Alloc(size_t size) { constexpr size_t extra_len = sizeof(size_t); memory_inuse.fetch_add(size += extra_len); - void* p = ::malloc(size); + void* p = new (std::nothrow) uint8_t[size]; if (p == nullptr) return p; num_allocations.fetch_add(1); @@ -33,7 +33,7 @@ void MockedOrtAllocator::Free(void* p) { p = (char*)p - extra_len; size_t len = *(size_t*)p; memory_inuse.fetch_sub(len); - return ::free(p); + delete[] reinterpret_cast(p); } const OrtMemoryInfo* MockedOrtAllocator::Info() const { diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 5b0e317a7a..acbeb54aaa 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -388,8 +388,7 @@ def parse_arguments(): "--use_vstest", action='store_true', help="Use use_vstest for running unitests.") parser.add_argument( - "--use_mimalloc", default=['none'], - choices=['none', 'stl', 'arena', 'all'], help="Use mimalloc.") + "--use_mimalloc", action='store_true', help="Use mimalloc allocator") parser.add_argument( "--use_dnnl", action='store_true', help="Build with DNNL.") parser.add_argument( @@ -729,10 +728,7 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home "-DPython_EXECUTABLE=" + sys.executable, "-DPYTHON_EXECUTABLE=" + sys.executable, "-Donnxruntime_ROCM_VERSION=" + (args.rocm_version if args.use_rocm else ""), - "-Donnxruntime_USE_MIMALLOC_STL_ALLOCATOR=" + ( - "ON" if args.use_mimalloc == "stl" or args.use_mimalloc == "all" else "OFF"), - "-Donnxruntime_USE_MIMALLOC_ARENA_ALLOCATOR=" + ( - "ON" if args.use_mimalloc == "arena" or args.use_mimalloc == "all" else "OFF"), + "-Donnxruntime_USE_MIMALLOC=" + ("ON" if args.use_mimalloc else "OFF"), "-Donnxruntime_ENABLE_PYTHON=" + ("ON" if args.enable_pybind else "OFF"), "-Donnxruntime_BUILD_CSHARP=" + ("ON" if args.build_csharp else "OFF"), "-Donnxruntime_BUILD_JAVA=" + ("ON" if args.build_java else "OFF"), From f60a287a64d509ae60c2ce1190effe9e8bdb0f4e Mon Sep 17 00:00:00 2001 From: Yi-Hong Lyu Date: Wed, 8 Dec 2021 20:50:41 +0800 Subject: [PATCH 004/113] Add __x86.get_pc_thunk.bx to avoid dependency (#9955) --- cmake/onnxruntime_mlas.cmake | 10 ++++++ .../core/mlas/lib/x86/x86.get_pc_thunk.S | 34 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S diff --git a/cmake/onnxruntime_mlas.cmake b/cmake/onnxruntime_mlas.cmake index b13f13de8d..12d1e271a9 100644 --- a/cmake/onnxruntime_mlas.cmake +++ b/cmake/onnxruntime_mlas.cmake @@ -355,6 +355,16 @@ else() ${mlas_platform_srcs_sse2} ${mlas_platform_srcs_avx} ) + + # In r23, NDK remove __x86.get_pc_thunk.* from libatomic. Add our own + # implementation to avoid external dependency. + if(ANDROID) + set(mlas_platform_srcs + ${mlas_platform_srcs} + ${MLAS_SRC_DIR}/x86/x86.get_pc_thunk.S + ) + endif() + if(NOT ONNXRUNTIME_MLAS_MULTI_ARCH) set(MLAS_SOURCE_IS_NOT_SET 0) endif() diff --git a/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S b/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S new file mode 100644 index 0000000000..b3c4f6ac8b --- /dev/null +++ b/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S @@ -0,0 +1,34 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the MIT License. + +Module Name: + + x86.get_pc_thunk.S + +Abstract: + + This module implements __x86.get_pc_thunk.* to avoid external dependency. + +--*/ + + +#include "asmmacro.h" + + .intel_syntax noprefix + +/*++ + +Routine Description: + + The routine loads its return address -- which is the address of the + instruction that immediately follows -- into the ebx register. + +--*/ + + FUNCTION_ENTRY __x86.get_pc_thunk.bx + + mov ebx, [esp] + ret From 9e7d52a80169847071ee35a135e9ff97e7dc38fb Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 8 Dec 2021 10:51:46 -0800 Subject: [PATCH 005/113] Update parity_check_helper.py (#9884) --- onnxruntime/python/tools/transformers/parity_check_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/python/tools/transformers/parity_check_helper.py b/onnxruntime/python/tools/transformers/parity_check_helper.py index c83d947138..a444478a80 100644 --- a/onnxruntime/python/tools/transformers/parity_check_helper.py +++ b/onnxruntime/python/tools/transformers/parity_check_helper.py @@ -35,7 +35,7 @@ def environ_setting_nodes(node_name_filter=None, node_type_filter=None): def environ_setting_paths(output_path): # Set dumping values to files as default - os.environ["ORT_DEBUG_NODE_IO_DUMP_DATA_TO_FILES"] = NON_ZERO_VALUE + os.environ["ORT_DEBUG_NODE_IO_DUMP_DATA_DESTINATION"] = "files" os.environ["ORT_DEBUG_NODE_IO_OUTPUT_DIR"] = output_path From fb30e9fdae53c6ca0d4068a5f0656205e953611d Mon Sep 17 00:00:00 2001 From: Patrik Vavercak <56153264+pvavercak@users.noreply.github.com> Date: Wed, 8 Dec 2021 20:44:00 +0100 Subject: [PATCH 006/113] Remove /safeseh link option from non-msvc builds (#9744) (#9935) --- cmake/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c447093f9f..7a43d53c3e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1228,7 +1228,7 @@ function(onnxruntime_add_shared_library_module target_name) endif() onnxruntime_configure_target(${target_name}) - if (onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_BUILD_WEBASSEMBLY) + if (MSVC AND onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_BUILD_WEBASSEMBLY) target_link_options(${target_name} PRIVATE /SAFESEH) endif() endfunction() @@ -1236,7 +1236,7 @@ endfunction() function(onnxruntime_add_executable target_name) add_executable(${target_name} ${ARGN}) onnxruntime_configure_target(${target_name}) - if (onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_BUILD_WEBASSEMBLY) + if (MSVC AND onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_BUILD_WEBASSEMBLY) target_link_options(${target_name} PRIVATE /SAFESEH) endif() endfunction() From 0adeb86bfda43b42b3351519a648a1824cbdbfff Mon Sep 17 00:00:00 2001 From: "Tang, Cheng" Date: Wed, 8 Dec 2021 13:04:29 -0800 Subject: [PATCH 007/113] Fix ortmodule for the pytorch model with ort device (#9927) * add ortmodule and eager mode test * add ortmodule dependency * convert between aten ort tensor and ortvalue * register the EP to ortmodule using ort device information * remove duplicated test * remove useless dependency * handle half precision type for ortmodule outputs * adjust the tensor conversion python code Co-authored-by: Cheng Tang --- .../orttraining/eager/ort_backends.cpp | 19 +++++++ orttraining/orttraining/eager/ort_backends.h | 9 ++++ orttraining/orttraining/eager/ort_eager.cpp | 51 ++++++++++++++----- .../test/linux_only_ortmodule_eager_test.py | 20 +++++++- .../ortmodule/_graph_execution_manager.py | 5 ++ .../training/ortmodule/_training_manager.py | 18 ++++--- .../python/training/ortmodule/_utils.py | 34 ++++++------- .../github/windows/eager/requirements.txt | 1 + 8 files changed, 120 insertions(+), 37 deletions(-) diff --git a/orttraining/orttraining/eager/ort_backends.cpp b/orttraining/orttraining/eager/ort_backends.cpp index d552393514..e14ba9d2a1 100644 --- a/orttraining/orttraining/eager/ort_backends.cpp +++ b/orttraining/orttraining/eager/ort_backends.cpp @@ -56,6 +56,9 @@ onnxruntime::Status ORTBackendsManager::set_device(size_t device_index, const st custom_op_schema_); backends_[device_index] = std::move(invoker); + ProviderInfoMap provider_info; + provider_info[provider_type] = provider_options; + device_ep_info_[device_index] = provider_info; return onnxruntime::Status::OK(); } @@ -66,6 +69,22 @@ OrtDevice ORTBackendsManager::GetOrtDeviceInfo(size_t torch_device_index){ return allocator->Info().device; } +size_t ORTBackendsManager::GetOrtDeviceIndex(const OrtMemoryInfo& ort_memory_info){ + for (auto it = backends_.begin(); it != backends_.end(); ++it){ + //eager mode currently only operate on EP's default memory type + auto allocator = it->second->GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault); + if (allocator->Info() == ort_memory_info) + return it->first; + } + ORT_THROW("Can't find the eager mode ORT device index for target ort tensor"); +} + +const ProviderInfoMap& ORTBackendsManager::GetOrtDeviceProviderInfo(size_t torch_device_index) const { + auto lookup = device_ep_info_.find(torch_device_index); + ORT_ENFORCE(lookup != device_ep_info_.end()); + return lookup->second; +} + onnxruntime::ORTInvoker& ORTBackendsManager::GetInvoker(const at::Device device) { ORT_LOG_FN(device); diff --git a/orttraining/orttraining/eager/ort_backends.h b/orttraining/orttraining/eager/ort_backends.h index 26cc495a61..4f3d885a5e 100644 --- a/orttraining/orttraining/eager/ort_backends.h +++ b/orttraining/orttraining/eager/ort_backends.h @@ -15,6 +15,8 @@ namespace torch_ort { namespace eager { +using ProviderInfoMap = std::unordered_map; + class ORTBackendsManager { public: ORTBackendsManager(const onnxruntime::logging::Logger& logger); @@ -26,12 +28,19 @@ public: OrtDevice GetOrtDeviceInfo(size_t torch_device_index); + size_t GetOrtDeviceIndex(const OrtMemoryInfo& ort_memory_info); + + const ProviderInfoMap& GetOrtDeviceProviderInfo(size_t torch_device_index) const; + private: std::map> backends_; const onnxruntime::logging::Logger& logger_; //custom op schema registry //TODO: we might want to support load custom op schema on the fly onnxruntime::IOnnxRuntimeOpSchemaRegistryList custom_op_schema_ = {}; + + // record the device associated provider information, so ortmodule can restore the ep + std::unordered_map device_ep_info_; }; ORTBackendsManager& GetORTBackendsManager(); diff --git a/orttraining/orttraining/eager/ort_eager.cpp b/orttraining/orttraining/eager/ort_eager.cpp index e3fdc332f1..f679335258 100644 --- a/orttraining/orttraining/eager/ort_eager.cpp +++ b/orttraining/orttraining/eager/ort_eager.cpp @@ -11,6 +11,7 @@ #include "orttraining/core/framework/ortmodule_graph_builder.h" #include "ort_customops.h" #include "torch/csrc/autograd/python_variable.h" +#include "core/framework/tensor.h" namespace onnxruntime{ namespace python{ @@ -18,19 +19,42 @@ namespace python{ using namespace onnxruntime::training; using namespace torch_ort::eager; -py::object ORTTensor_toDLPack(const at::Tensor& data) -{ - OrtValue ort_value = torch_ort::eager::create_ort_value(data); - return py::reinterpret_steal(onnxruntime::training::framework::torch::ToDlpack(ort_value)); +static at::ScalarType aten_scalar_type_from_ort( + onnxruntime::MLDataType dtype) { + if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kFloat; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kDouble; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kHalf; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kBFloat16; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kInt; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kShort; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kLong; + else if (dtype == onnxruntime::DataTypeImpl::GetType()) + return at::kBool; + else + ORT_THROW("Unsupport aten scalar type: ", dtype); } -at::Tensor ORTTensor_FromDLPack(const py::object& dlpack_tensor) +OrtValue ORTTensor_toORTValue(const at::Tensor& data) { - OrtValue ort_value = onnxruntime::training::framework::torch::FromDlpack(dlpack_tensor.ptr(), false); + return torch_ort::eager::create_ort_value(data); +} + +at::Tensor OrtValue_To_ATen_Tensor(OrtValue& ortvalue) +{ + auto& ort_tensor = ortvalue.Get(); + size_t ort_device_idx = torch_ort::eager::GetORTBackendsManager().GetOrtDeviceIndex(ort_tensor.Location()); return torch_ort::eager::aten_tensor_from_ort( - std::move(ort_value), + std::move(ortvalue), at::TensorOptions() - .device(at::Device(at::DeviceType::ORT, 0))); + .device(at::Device(at::DeviceType::ORT, ort_device_idx)) + .dtype(onnxruntime::python::aten_scalar_type_from_ort(ort_tensor.DataType()))); } void addObjectMethodsForEager(py::module& m){ @@ -44,11 +68,11 @@ void addObjectMethodsForEager(py::module& m){ }, py::arg("device_index") = 0); - m.def("ort_to_dlpack", [](at::Tensor data) { - return ORTTensor_toDLPack(data); + m.def("aten_ort_tensor_to_ort_value", [](at::Tensor data) { + return ORTTensor_toORTValue(data); }); - m.def("ort_from_dlpack", [](py::object dlpack_tensor) { - return ORTTensor_FromDLPack(dlpack_tensor); + m.def("to_aten_ort_device_tensor", [](OrtValue& ortvalue) { + return OrtValue_To_ATen_Tensor(ortvalue); }); m.def("set_device", [](size_t device_index, @@ -61,6 +85,9 @@ void addObjectMethodsForEager(py::module& m){ m.def("get_ort_device", [](size_t torch_device_index){ return torch_ort::eager::GetORTBackendsManager().GetOrtDeviceInfo(torch_device_index); }); + m.def("get_ort_device_provider_info", [](size_t torch_device_index){ + return torch_ort::eager::GetORTBackendsManager().GetOrtDeviceProviderInfo(torch_device_index); + }); auto customop_module = m.def_submodule("custom_ops"); torch_ort::eager::GenerateCustomOpsBindings(customop_module); diff --git a/orttraining/orttraining/eager/test/linux_only_ortmodule_eager_test.py b/orttraining/orttraining/eager/test/linux_only_ortmodule_eager_test.py index d6415f1353..8134a116bf 100644 --- a/orttraining/orttraining/eager/test/linux_only_ortmodule_eager_test.py +++ b/orttraining/orttraining/eager/test/linux_only_ortmodule_eager_test.py @@ -25,7 +25,25 @@ class NeuralNet(nn.Module): out = self.fc2(out) return out +class NoOpNet(torch.nn.Module): + def __init__(self): + super(NoOpNet, self).__init__() + self.dummy_weight = torch.nn.Parameter( + torch.ones(128, 128, dtype=torch.float16)) + + def forward(self, input): + return input + class OrtModuleEagerTest(unittest.TestCase): + def test_half_type(self): + model = NoOpNet() + device = torch.device('ort') + model.to(device) + model = ORTModule(model) + input = torch.ones(2,2).to(torch.float16) + y = model(input.to(device)) + assert(y.dtype == torch.float16) + def test_ort_module_and_eager_mode(self): input_size = 784 hidden_size = 500 @@ -67,4 +85,4 @@ class OrtModuleEagerTest(unittest.TestCase): assert torch.allclose(cpu_updated_state[state_tensor], ort_updated_state[state_tensor].cpu(), atol=1e-3) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/orttraining/orttraining/python/training/ortmodule/_graph_execution_manager.py b/orttraining/orttraining/python/training/ortmodule/_graph_execution_manager.py index 874b0c605e..ede9ffb2ab 100644 --- a/orttraining/orttraining/python/training/ortmodule/_graph_execution_manager.py +++ b/orttraining/orttraining/python/training/ortmodule/_graph_execution_manager.py @@ -274,6 +274,11 @@ class GraphExecutionManager(GraphExecutionInterface): elif self._device.type == 'cpu': providers = ["CPUExecutionProvider"] provider_options = [{}] + elif self._device.type == 'ort': + provider_info = C.get_ort_device_provider_info(self._device.index) + assert len(provider_info.keys()) == 1 + providers = list(provider_info.keys()) + provider_options = [provider_info[providers[0]]] session_options = onnxruntime.SessionOptions() session_options.enable_mem_pattern = False diff --git a/orttraining/orttraining/python/training/ortmodule/_training_manager.py b/orttraining/orttraining/python/training/ortmodule/_training_manager.py index a66ed955d4..35f8208114 100644 --- a/orttraining/orttraining/python/training/ortmodule/_training_manager.py +++ b/orttraining/orttraining/python/training/ortmodule/_training_manager.py @@ -47,8 +47,11 @@ class TrainingManager(GraphExecutionManager): forward_inputs = C.OrtValueVector() forward_inputs.reserve(len(inputs)) for input in inputs: - dlp = _utils._torch_tensor_to_dlpack(input) - forward_inputs.push_back(dlp, input.dtype == torch.bool) + if input.device.type == 'ort': + forward_inputs.push_back(C.aten_ort_tensor_to_ort_value(input)) + else: + valid_ort_tensor = _utils._torch_tensor_to_dlpack(input) + forward_inputs.push_back(valid_ort_tensor, input.dtype == torch.bool) forward_outputs = C.OrtValueVector() # Run and return module outputs. @@ -145,7 +148,10 @@ class TrainingManager(GraphExecutionManager): grad_output = torch.tensor(0., device=device, dtype=dtype) elif not grad_output.is_contiguous(): grad_output = grad_output.contiguous() - backward_inputs.push_back(_utils._torch_tensor_to_dlpack(grad_output), + if grad_output.device.type == 'ort': + backward_inputs.push_back(C.aten_ort_tensor_to_ort_value(grad_output)) + else: + backward_inputs.push_back(_utils._torch_tensor_to_dlpack(grad_output), grad_output.dtype is torch.bool) backward_inputs.shrink_to_fit() @@ -163,8 +169,7 @@ class TrainingManager(GraphExecutionManager): for input_name in self._graph_info.user_input_names: # Append to the results the backward output for each input that required grad if input_name in require_grad_names_set: - results.append(_utils._torch_tensor_from_dl_pack( - backward_outputs.dlpack_at(require_grad_names_index), + results.append(_utils._ortvalue_to_torch_tensor( backward_outputs[require_grad_names_index], self._device)) require_grad_names_index += 1 else: @@ -177,8 +182,7 @@ class TrainingManager(GraphExecutionManager): initializer_index = num_user_input_grads for initializer_name in self._graph_info.initializer_names: if initializer_name in self._graph_initializer_names_to_train: - results.append(_utils._torch_tensor_from_dl_pack( - backward_outputs.dlpack_at(initializer_index), + results.append(_utils._ortvalue_to_torch_tensor( backward_outputs[initializer_index], self._device)) initializer_index += 1 else: diff --git a/orttraining/orttraining/python/training/ortmodule/_utils.py b/orttraining/orttraining/python/training/ortmodule/_utils.py index d5bb43951f..131c8fa80c 100644 --- a/orttraining/orttraining/python/training/ortmodule/_utils.py +++ b/orttraining/orttraining/python/training/ortmodule/_utils.py @@ -38,33 +38,33 @@ def _ortvalue_from_torch_tensor(torch_tensor): return C.OrtValue.from_dlpack(to_dlpack(torch_tensor), is_bool_tensor) -def _torch_tensor_from_dl_pack(dlpack, ortvalue, device): - torch_tensor = from_dlpack(dlpack) if device.type != 'ort' else C.ort_from_dlpack(dlpack) +def _torch_tensor_from_dl_pack(dlpack, ortvalue): + torch_tensor = from_dlpack(dlpack) return torch_tensor.to(torch.bool) if ortvalue.data_type() == 'tensor(bool)' else torch_tensor def _ortvalue_to_torch_tensor(ortvalue, device): + if device.type == 'ort': + return C.to_aten_ort_device_tensor(ortvalue) # PyTorch's to_dlpack() uses same config for both torch.bool and torch.uint8, # and convert the config to torch.uint8 tensor duing from_dlpack(). # So we need to convert the torch tensor to torch.bool type if OrtValue is bool tensor. dlpack_tensor = ortvalue.to_dlpack() - return _torch_tensor_from_dl_pack(dlpack_tensor, ortvalue, device) + return _torch_tensor_from_dl_pack(dlpack_tensor, ortvalue) +# convert torch tensor to ort accept tensors, could be dlpack or ortvalue def _torch_tensor_to_dlpack(tensor): - if tensor.device.type == 'ort': - return C.ort_to_dlpack(tensor) - else: - # TODO: Current DLPack doesn't support bool and PyTorch disables converting bool tensor to DLPack in recent commit. - # https://github.com/pytorch/pytorch/blob/7e7be526c9d9179f35084e9cca5b5c5ad5172100/aten/src/ATen/DLConvertor.cpp#L41 - # We need to convert bool tensor to unit8 tensor to workaround this. - # DLPack is discussing how to support bool type, we can remove this workaround once both DLPack - # and PyTorch support bool type. - if not tensor.is_contiguous(): - raise ORTModuleIOError( - "Only contiguous tensors are supported.") - if tensor.dtype == torch.bool and LooseVersion(torch.__version__) >= LooseVersion('1.10.0'): - tensor = tensor.to(torch.uint8) - return to_dlpack(tensor) + # TODO: Current DLPack doesn't support bool and PyTorch disables converting bool tensor to DLPack in recent commit. + # https://github.com/pytorch/pytorch/blob/7e7be526c9d9179f35084e9cca5b5c5ad5172100/aten/src/ATen/DLConvertor.cpp#L41 + # We need to convert bool tensor to unit8 tensor to workaround this. + # DLPack is discussing how to support bool type, we can remove this workaround once both DLPack + # and PyTorch support bool type. + if not tensor.is_contiguous(): + raise ORTModuleIOError( + "Only contiguous tensors are supported.") + if tensor.dtype == torch.bool and LooseVersion(torch.__version__) >= LooseVersion('1.10.0'): + tensor = tensor.to(torch.uint8) + return to_dlpack(tensor) def _check_same_device(device, argument_str, *args): diff --git a/tools/ci_build/github/windows/eager/requirements.txt b/tools/ci_build/github/windows/eager/requirements.txt index 3dbc855e49..557d5efd0b 100644 --- a/tools/ci_build/github/windows/eager/requirements.txt +++ b/tools/ci_build/github/windows/eager/requirements.txt @@ -3,3 +3,4 @@ wheel numpy typing_extensions torch + From 35cf8b8725c41bae7d82f1331fb97cda122a80d7 Mon Sep 17 00:00:00 2001 From: Sunghoon <35605090+hanbitmyths@users.noreply.github.com> Date: Wed, 8 Dec 2021 13:27:31 -0800 Subject: [PATCH 008/113] [js/react_native] npm audit fix (#9876) * add p50 in test * Audit fix for react native Co-authored-by: Yulong Wang --- js/react_native/lib/backend.ts | 2 +- js/react_native/package.json | 2 +- js/react_native/yarn.lock | 3142 ++++++++++++-------------------- 3 files changed, 1192 insertions(+), 1954 deletions(-) diff --git a/js/react_native/lib/backend.ts b/js/react_native/lib/backend.ts index 855d11b3f7..78879792dc 100644 --- a/js/react_native/lib/backend.ts +++ b/js/react_native/lib/backend.ts @@ -58,7 +58,7 @@ class OnnxruntimeSessionHandler implements SessionHandler { this.inputNames = results.inputNames; this.outputNames = results.outputNames; } catch (e) { - throw new Error(`Can't load a model: ${e.message}`); + throw new Error(`Can't load a model: ${(e as Error).message}`); } } diff --git a/js/react_native/package.json b/js/react_native/package.json index 659359d401..eb642c9520 100644 --- a/js/react_native/package.json +++ b/js/react_native/package.json @@ -109,4 +109,4 @@ "buffer": "^6.0.3", "onnxruntime-common": "file:../common" } -} \ No newline at end of file +} diff --git a/js/react_native/yarn.lock b/js/react_native/yarn.lock index 9f1a565593..9d4e55f47e 100644 --- a/js/react_native/yarn.lock +++ b/js/react_native/yarn.lock @@ -2,52 +2,19 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - dependencies: - "@babel/highlight" "^7.12.13" - -"@babel/code-frame@^7.16.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== dependencies: "@babel/highlight" "^7.16.0" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" - integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== - -"@babel/compat-data@^7.16.0": +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.0", "@babel/compat-data@^7.16.4": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== -"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" - integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.14.0" - "@babel/helper-compilation-targets" "^7.13.16" - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helpers" "^7.14.0" - "@babel/parser" "^7.14.0" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.14.0" - "@babel/types" "^7.14.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - -"@babel/core@^7.1.6": +"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== @@ -68,16 +35,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.14.0", "@babel/generator@^7.5.0": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" - integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== - dependencies: - "@babel/types" "^7.14.1" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/generator@^7.16.0": +"@babel/generator@^7.16.0", "@babel/generator@^7.5.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== @@ -86,13 +44,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" - integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-annotate-as-pure@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d" @@ -100,25 +51,15 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" - integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz#f1a686b92da794020c26582eb852e9accd0d7882" + integrity sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ== dependencies: - "@babel/helper-explode-assignable-expression" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/helper-explode-assignable-expression" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" - integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== - dependencies: - "@babel/compat-data" "^7.13.15" - "@babel/helper-validator-option" "^7.12.17" - browserslist "^4.14.5" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.16.0": +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.0", "@babel/helper-compilation-targets@^7.16.3": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA== @@ -128,18 +69,6 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c" - integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.13.12" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-create-class-features-plugin@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b" @@ -152,18 +81,18 @@ "@babel/helper-replace-supers" "^7.16.0" "@babel/helper-split-export-declaration" "^7.16.0" -"@babel/helper-create-regexp-features-plugin@^7.12.13": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" - integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== +"@babel/helper-create-regexp-features-plugin@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff" + integrity sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-annotate-as-pure" "^7.16.0" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1" - integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw== +"@babel/helper-define-polyfill-provider@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" + integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -174,21 +103,12 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.12.13": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" - integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== +"@babel/helper-explode-assignable-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz#753017337a15f46f9c09f674cff10cee9b9d7778" + integrity sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ== dependencies: - "@babel/types" "^7.13.0" - -"@babel/helper-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" - integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== - dependencies: - "@babel/helper-get-function-arity" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/types" "^7.16.0" "@babel/helper-function-name@^7.16.0": version "7.16.0" @@ -199,13 +119,6 @@ "@babel/template" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/helper-get-function-arity@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" - integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-get-function-arity@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" @@ -213,14 +126,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-hoist-variables@^7.13.0": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" - integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== - dependencies: - "@babel/traverse" "^7.13.15" - "@babel/types" "^7.13.16" - "@babel/helper-hoist-variables@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" @@ -228,13 +133,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-member-expression-to-functions@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" - integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== - dependencies: - "@babel/types" "^7.13.12" - "@babel/helper-member-expression-to-functions@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4" @@ -242,34 +140,13 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" - integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== - dependencies: - "@babel/types" "^7.13.12" - -"@babel/helper-module-imports@^7.16.0": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg== dependencies: "@babel/types" "^7.16.0" -"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" - integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== - dependencies: - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-replace-supers" "^7.13.12" - "@babel/helper-simple-access" "^7.13.12" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.14.0" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.14.0" - "@babel/types" "^7.14.0" - "@babel/helper-module-transforms@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5" @@ -284,13 +161,6 @@ "@babel/traverse" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/helper-optimise-call-expression@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" - integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-optimise-call-expression@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" @@ -298,34 +168,19 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" - integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== - -"@babel/helper-plugin-utils@^7.14.5": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-remap-async-to-generator@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" - integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== +"@babel/helper-remap-async-to-generator@^7.16.0", "@babel/helper-remap-async-to-generator@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.4.tgz#5d7902f61349ff6b963e07f06a389ce139fbfe6e" + integrity sha512-vGERmmhR+s7eH5Y/cp8PCVzj4XEjerq8jooMfxFdA5xVtAk9Sh4AQsrWgiErUEBjtGrBtOFKDUcWQFW4/dFwMA== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-wrap-function" "^7.13.0" - "@babel/types" "^7.13.0" - -"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" - integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.12" + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-wrap-function" "^7.16.0" + "@babel/types" "^7.16.0" "@babel/helper-replace-supers@^7.16.0": version "7.16.0" @@ -337,13 +192,6 @@ "@babel/traverse" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/helper-simple-access@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" - integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== - dependencies: - "@babel/types" "^7.13.12" - "@babel/helper-simple-access@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" @@ -351,13 +199,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" - integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" @@ -365,13 +206,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-split-export-declaration@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" - integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-split-export-declaration@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" @@ -379,44 +213,25 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" - integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== - "@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== -"@babel/helper-validator-option@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" - integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== - "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== -"@babel/helper-wrap-function@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" - integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== +"@babel/helper-wrap-function@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz#b3cf318afce774dfe75b86767cd6d68f3482e57c" + integrity sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" - -"@babel/helpers@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" - integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== - dependencies: - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.14.0" - "@babel/types" "^7.14.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" "@babel/helpers@^7.16.0": version "7.16.3" @@ -427,15 +242,6 @@ "@babel/traverse" "^7.16.3" "@babel/types" "^7.16.0" -"@babel/highlight@^7.12.13": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" - integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.0" - chalk "^2.0.0" - js-tokens "^4.0.0" - "@babel/highlight@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" @@ -445,43 +251,37 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.0": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" - integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== - -"@babel/parser@^7.1.6", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" - integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": + version "7.16.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz#2977fca9b212db153c195674e57cfab807733183" + integrity sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.13.15": - version "7.13.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" - integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz#358972eaab006f5eb0826183b0c93cbcaf13e1e2" + integrity sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + +"@babel/plugin-proposal-async-generator-functions@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.4.tgz#e606eb6015fec6fa5978c940f315eae4e300b081" + integrity sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.4" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" - integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" - -"@babel/plugin-proposal-class-properties@^7.1.0": +"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" integrity sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A== @@ -489,63 +289,56 @@ "@babel/helper-create-class-features-plugin" "^7.16.0" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-class-static-block@^7.13.11": - version "7.13.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.13.11.tgz#6fcbba4a962702c17e5371a0c7b39afde186d703" - integrity sha512-fJTdFI4bfnMjvxJyNuaf8i9mVcZ0UhetaGEUHaHV9KEnibLugJkZAtXikR8KcYj+NYmI4DZMS8yQAyg+hvfSqg== +"@babel/plugin-proposal-class-static-block@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz#5296942c564d8144c83eea347d0aa8a0b89170e7" + integrity sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-dynamic-import@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" - integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== +"@babel/plugin-proposal-dynamic-import@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz#783eca61d50526202f9b296095453977e88659f1" + integrity sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.13.tgz#f110284108a9b2b96f01b15b3be9e54c2610a989" - integrity sha512-idIsBT+DGXdOHL82U+8bwX4goHm/z10g8sGGrQroh+HCRcm7mDv/luaGdWJQMTuCX2FsdXS7X0Nyyzp4znAPJA== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.0.tgz#f8a07008ffcb0d3de4945f3eb52022ecc28b56ad" + integrity sha512-kFAhaIbh5qbBwETRNa/cgGmPJ/BicXhIyrZhAkyYhf/Z9LXCTRGO1mvUwczto0Hl1q4YtzP9cRtTKT4wujm38Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-export-default-from" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-export-default-from" "^7.16.0" -"@babel/plugin-proposal-export-namespace-from@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" - integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== +"@babel/plugin-proposal-export-namespace-from@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz#9c01dee40b9d6b847b656aaf4a3976a71740f222" + integrity sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" - integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== +"@babel/plugin-proposal-json-strings@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz#cae35a95ed1d2a7fa29c4dc41540b84a72e9ab25" + integrity sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" - integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== +"@babel/plugin-proposal-logical-assignment-operators@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz#a711b8ceb3ffddd3ef88d3a49e86dbd3cc7db3fd" + integrity sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" - integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz#44e1cce08fe2427482cf446a91bb451528ed0596" integrity sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ== @@ -553,43 +346,34 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" - integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== +"@babel/plugin-proposal-numeric-separator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz#5d418e4fbbf8b9b7d03125d3a52730433a373734" + integrity sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" - integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== +"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz#5fb32f6d924d6e6712810362a60e12a2609872e6" + integrity sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg== dependencies: - "@babel/compat-data" "^7.13.8" - "@babel/helper-compilation-targets" "^7.13.8" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/compat-data" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-parameters" "^7.16.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0", "@babel/plugin-proposal-optional-catch-binding@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" - integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== +"@babel/plugin-proposal-optional-catch-binding@^7.0.0", "@babel/plugin-proposal-optional-catch-binding@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz#5910085811ab4c28b00d6ebffa4ab0274d1e5f16" + integrity sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" - integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.1.0": +"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0" integrity sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg== @@ -598,31 +382,31 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" - integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== +"@babel/plugin-proposal-private-methods@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6" + integrity sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-private-property-in-object@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" - integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== +"@babel/plugin-proposal-private-property-in-object@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz#69e935b2c5c79d2488112d886f0c4e2790fee76f" + integrity sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-create-class-features-plugin" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" - integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== +"@babel/plugin-proposal-unicode-property-regex@^7.16.0", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612" + integrity sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -645,12 +429,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-class-static-block@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" - integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -659,12 +443,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.12.13.tgz#3c807d37efaf0a806f1deb556ccb3b2f562ae9c2" - integrity sha512-gVry0zqoums0hA+EniCYK3gABhjYSLX1dVuwYpPw9DrLNA4/GovXySHVg4FGRsZht09ON/5C2NVx3keq+qqVGQ== +"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.0.tgz#648520667776781f9a0da178f245fff85bc9e36f" + integrity sha512-xllLOdBj77mFSw8s02I+2SSQGHOftbWTlGmagheuNk/gjQsk7IrYsR/EosXVAVpgIUFffLckB/iPRioQYLHSrQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" @@ -673,14 +457,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.12.13", "@babel/plugin-syntax-flow@^7.2.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz#5df9962503c0a9c918381c929d51d4d6949e7e86" - integrity sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-flow@^7.16.0": +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.16.0", "@babel/plugin-syntax-flow@^7.2.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.0.tgz#07427021d093ed77019408221beaf0272bbcfaec" integrity sha512-dH91yCo0RyqfzWgoM5Ji9ir8fQ+uFbt9KHM3d2x4jZOuHS6wNA+CRmRUP/BWCsHG2bjc7A2Way6AvH1eQk0wig== @@ -701,12 +478,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15" - integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g== +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.0.tgz#f9624394317365a9a88c82358d3f8471154698f1" + integrity sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -750,26 +527,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-private-property-in-object@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" - integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" - integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-typescript@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" - integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.16.0": version "7.16.0" @@ -778,95 +548,87 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" - integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== +"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz#951706f8b449c834ed07bd474c0924c944b95a8e" + integrity sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-async-to-generator@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" - integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== +"@babel/plugin-transform-async-to-generator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604" + integrity sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.0" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" - integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== +"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz#c618763233ad02847805abcac4c345ce9de7145d" + integrity sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.14.1": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" - integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== +"@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16" + integrity sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" - integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== +"@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz#54cf5ff0b2242c6573d753cd4bfc7077a8b282f5" + integrity sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-replace-supers" "^7.13.0" - "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0", "@babel/plugin-transform-computed-properties@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" - integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== +"@babel/plugin-transform-computed-properties@^7.0.0", "@babel/plugin-transform-computed-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz#e0c385507d21e1b0b076d66bed6d5231b85110b7" + integrity sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.13.17": - version "7.13.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" - integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== +"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz#ad3d7e74584ad5ea4eadb1e6642146c590dee33c" + integrity sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" - integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== +"@babel/plugin-transform-dotall-regex@^7.16.0", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz#50bab00c1084b6162d0a58a818031cf57798e06f" + integrity sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-duplicate-keys@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" - integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== +"@babel/plugin-transform-duplicate-keys@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz#8bc2e21813e3e89e5e5bf3b60aa5fc458575a176" + integrity sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-exponentiation-operator@^7.0.0", "@babel/plugin-transform-exponentiation-operator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" - integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== +"@babel/plugin-transform-exponentiation-operator@^7.0.0", "@babel/plugin-transform-exponentiation-operator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz#a180cd2881e3533cef9d3901e48dad0fbeff4be4" + integrity sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz#58177a48c209971e8234e99906cb6bd1122addd3" - integrity sha512-EXAGFMJgSX8gxWD7PZtW/P6M+z74jpx3wm/+9pn+c2dOawPpBkUX7BrfyPvo6ZpXbgRIEuwgwDb/MGlKvu2pOg== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-flow" "^7.12.13" - -"@babel/plugin-transform-flow-strip-types@^7.16.0": +"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.0.tgz#edd968dc2041c1b69e451a262e948d6654a79dc2" integrity sha512-vs/F5roOaO/+WxKfp9PkvLsAyj0G+Q0zbFimHm9X2KDgabN2XmNFoAafmeGEYspUlIF9+MvVmyek9UyHiqeG/w== @@ -874,55 +636,45 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-flow" "^7.16.0" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" - integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== +"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz#f7abaced155260e2461359bbc7c7248aca5e6bd2" + integrity sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-function-name@^7.0.0", "@babel/plugin-transform-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" - integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== +"@babel/plugin-transform-function-name@^7.0.0", "@babel/plugin-transform-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz#02e3699c284c6262236599f751065c5d5f1f400e" + integrity sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-literals@^7.0.0", "@babel/plugin-transform-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" - integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== +"@babel/plugin-transform-literals@^7.0.0", "@babel/plugin-transform-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz#79711e670ffceb31bd298229d50f3621f7980cac" + integrity sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" - integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== +"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz#5251b4cce01eaf8314403d21aedb269d79f5e64b" + integrity sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-modules-amd@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" - integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== +"@babel/plugin-transform-modules-amd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz#09abd41e18dcf4fd479c598c1cef7bd39eb1337e" + integrity sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw== dependencies: - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" - integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== - dependencies: - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-simple-access" "^7.13.12" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.1.0": +"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.1.0", "@babel/plugin-transform-modules-commonjs@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz#add58e638c8ddc4875bd9a9ecb5c594613f6c922" integrity sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ== @@ -932,187 +684,178 @@ "@babel/helper-simple-access" "^7.16.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" - integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== +"@babel/plugin-transform-modules-systemjs@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz#a92cf240afeb605f4ca16670453024425e421ea4" + integrity sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg== dependencies: - "@babel/helper-hoist-variables" "^7.13.0" - "@babel/helper-module-transforms" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-identifier" "^7.15.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" - integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== +"@babel/plugin-transform-modules-umd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz#195f26c2ad6d6a391b70880effce18ce625e06a7" + integrity sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg== dependencies: - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" - integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz#d3db61cc5d5b97986559967cd5ea83e5c32096ca" + integrity sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.16.0" -"@babel/plugin-transform-new-target@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" - integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== +"@babel/plugin-transform-new-target@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz#af823ab576f752215a49937779a41ca65825ab35" + integrity sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-object-assign@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.12.13.tgz#d9b9200a69e03403a813e44a933ad9f4bddfd050" - integrity sha512-4QxDMc0lAOkIBSfCrnSGbAJ+4epDBF2XXwcLXuBcG1xl9u7LrktNVD4+LwhL47XuKVPQ7R25e/WdcV+h97HyZA== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.0.tgz#750c726397f1f6402fb1ceffe9d8ff3595c8a0df" + integrity sha512-TftKY6Hxo5Uf/EIoC3BKQyLvlH46tbtK4xub90vzi9+yS8z1+O/52YHyywCZvYeLPOvv//1j3BPokLuHTWPcbg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" - integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== +"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz#fb20d5806dc6491a06296ac14ea8e8d6fedda72b" + integrity sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" - integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.16.0", "@babel/plugin-transform-parameters@^7.16.3": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.3.tgz#fa9e4c874ee5223f891ee6fa8d737f4766d31d15" + integrity sha512-3MaDpJrOXT1MZ/WCmkOFo7EtmVVC8H4EUZVrHvFOsmwkk4lOjQj8rzv8JKUZV4YoQKeoIgk07GO+acPU9IMu/w== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" - integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== +"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz#a95c552189a96a00059f6776dc4e00e3690c78d1" + integrity sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" - integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== +"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.0.tgz#9a0ad8aa8e8790883a7bd2736f66229a58125676" + integrity sha512-FJFdJAqaCpndL+pIf0aeD/qlQwT7QXOvR6Cc8JPvNhKJBi2zc/DPc4g05Y3fbD/0iWAMQFGij4+Xw+4L/BMpTg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-react-jsx-development@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz#f510c0fa7cd7234153539f9a362ced41a5ca1447" - integrity sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ== +"@babel/plugin-transform-react-jsx-development@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.0.tgz#1cb52874678d23ab11d0d16488d54730807303ef" + integrity sha512-qq65iSqBRq0Hr3wq57YG2AmW0H6wgTnIzpffTphrUWUgLCOK+zf1f7G0vuOiXrp7dU1qq+fQBoqZ3wCDAkhFzw== dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.17" + "@babel/plugin-transform-react-jsx" "^7.16.0" "@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz#422d99d122d592acab9c35ea22a6cfd9bf189f60" - integrity sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.0.tgz#09202158abbc716a08330f392bfb98d6b9acfa0c" + integrity sha512-97yCFY+2GvniqOThOSjPor8xUoDiQ0STVWAQMl3pjhJoFVe5DuXDLZCRSZxu9clx+oRCbTiXGgKEG/Yoyo6Y+w== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.13.tgz#051d76126bee5c9a6aa3ba37be2f6c1698856bcb" - integrity sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.0.tgz#d40c959d7803aae38224594585748693e84c0a22" + integrity sha512-8yvbGGrHOeb/oyPc9tzNoe9/lmIjz3HLa9Nc5dMGDyNpGjfFrk8D2KdEq9NRkftZzeoQEW6yPQ29TMZtrLiUUA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.12.17", "@babel/plugin-transform-react-jsx@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz#1df5dfaf0f4b784b43e96da6f28d630e775f68b3" - integrity sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA== +"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.0.tgz#55b797d4960c3de04e07ad1c0476e2bc6a4889f1" + integrity sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/types" "^7.13.12" + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-jsx" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/plugin-transform-react-pure-annotations@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" - integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== +"@babel/plugin-transform-react-pure-annotations@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.0.tgz#23db6ddf558d8abde41b8ad9d59f48ad5532ccab" + integrity sha512-NC/Bj2MG+t8Ef5Pdpo34Ay74X4Rt804h5y81PwOpfPtmAK3i6CizmQqwyBQzIepz1Yt8wNr2Z2L7Lu3qBMfZMA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-regenerator@^7.0.0", "@babel/plugin-transform-regenerator@^7.13.15": - version "7.13.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" - integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== +"@babel/plugin-transform-regenerator@^7.0.0", "@babel/plugin-transform-regenerator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz#eaee422c84b0232d03aea7db99c97deeaf6125a4" + integrity sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" - integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== +"@babel/plugin-transform-reserved-words@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz#fff4b9dcb19e12619394bda172d14f2d04c0379c" + integrity sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-runtime@^7.0.0": - version "7.13.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz#2eddf585dd066b84102517e10a577f24f76a9cd7" - integrity sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA== + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.4.tgz#f9ba3c7034d429c581e1bd41b4952f3db3c2c7e8" + integrity sha512-pru6+yHANMTukMtEZGC4fs7XPwg35v8sj5CIEmE+gEkFljFiVJxEWxx/7ZDkTK+iZRYo1bFXBtfIN95+K3cJ5A== dependencies: - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-plugin-utils" "^7.13.0" - babel-plugin-polyfill-corejs2 "^0.2.0" - babel-plugin-polyfill-corejs3 "^0.2.0" - babel-plugin-polyfill-regenerator "^0.2.0" + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.4.0" + babel-plugin-polyfill-regenerator "^0.3.0" semver "^6.3.0" -"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" - integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== +"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz#090372e3141f7cc324ed70b3daf5379df2fa384d" + integrity sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" - integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== +"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz#d21ca099bbd53ab307a8621e019a7bd0f40cdcfb" + integrity sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" -"@babel/plugin-transform-sticky-regex@^7.0.0", "@babel/plugin-transform-sticky-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" - integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== +"@babel/plugin-transform-sticky-regex@^7.0.0", "@babel/plugin-transform-sticky-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz#c35ea31a02d86be485f6aa510184b677a91738fd" + integrity sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" - integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== +"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz#a8eced3a8e7b8e2d40ec4ec4548a45912630d302" + integrity sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typeof-symbol@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" - integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== +"@babel/plugin-transform-typeof-symbol@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz#8b19a244c6f8c9d668dca6a6f754ad6ead1128f2" + integrity sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typescript@^7.13.0", "@babel/plugin-transform-typescript@^7.5.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" - integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-typescript" "^7.12.13" - -"@babel/plugin-transform-typescript@^7.16.0": +"@babel/plugin-transform-typescript@^7.16.0", "@babel/plugin-transform-typescript@^7.5.0": version "7.16.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz#cc0670b2822b0338355bc1b3d2246a42b8166409" integrity sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg== @@ -1121,49 +864,50 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript" "^7.16.0" -"@babel/plugin-transform-unicode-escapes@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" - integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== +"@babel/plugin-transform-unicode-escapes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz#1a354064b4c45663a32334f46fa0cf6100b5b1f3" + integrity sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-unicode-regex@^7.0.0", "@babel/plugin-transform-unicode-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" - integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== +"@babel/plugin-transform-unicode-regex@^7.0.0", "@babel/plugin-transform-unicode-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz#293b80950177c8c85aede87cef280259fb995402" + integrity sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/preset-env@^7.12.11": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.1.tgz#b55914e2e68885ea03f69600b2d3537e54574a93" - integrity sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ== + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.4.tgz#4f6ec33b2a3fe72d6bfdcdf3859500232563a2e3" + integrity sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA== dependencies: - "@babel/compat-data" "^7.14.0" - "@babel/helper-compilation-targets" "^7.13.16" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" - "@babel/plugin-proposal-async-generator-functions" "^7.13.15" - "@babel/plugin-proposal-class-properties" "^7.13.0" - "@babel/plugin-proposal-class-static-block" "^7.13.11" - "@babel/plugin-proposal-dynamic-import" "^7.13.8" - "@babel/plugin-proposal-export-namespace-from" "^7.12.13" - "@babel/plugin-proposal-json-strings" "^7.13.8" - "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" - "@babel/plugin-proposal-numeric-separator" "^7.12.13" - "@babel/plugin-proposal-object-rest-spread" "^7.13.8" - "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" - "@babel/plugin-proposal-optional-chaining" "^7.13.12" - "@babel/plugin-proposal-private-methods" "^7.13.0" - "@babel/plugin-proposal-private-property-in-object" "^7.14.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.3" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.2" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-async-generator-functions" "^7.16.4" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-class-static-block" "^7.16.0" + "@babel/plugin-proposal-dynamic-import" "^7.16.0" + "@babel/plugin-proposal-export-namespace-from" "^7.16.0" + "@babel/plugin-proposal-json-strings" "^7.16.0" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-object-rest-spread" "^7.16.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-proposal-private-property-in-object" "^7.16.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.0" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.3" @@ -1173,49 +917,49 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.0" - "@babel/plugin-syntax-top-level-await" "^7.12.13" - "@babel/plugin-transform-arrow-functions" "^7.13.0" - "@babel/plugin-transform-async-to-generator" "^7.13.0" - "@babel/plugin-transform-block-scoped-functions" "^7.12.13" - "@babel/plugin-transform-block-scoping" "^7.14.1" - "@babel/plugin-transform-classes" "^7.13.0" - "@babel/plugin-transform-computed-properties" "^7.13.0" - "@babel/plugin-transform-destructuring" "^7.13.17" - "@babel/plugin-transform-dotall-regex" "^7.12.13" - "@babel/plugin-transform-duplicate-keys" "^7.12.13" - "@babel/plugin-transform-exponentiation-operator" "^7.12.13" - "@babel/plugin-transform-for-of" "^7.13.0" - "@babel/plugin-transform-function-name" "^7.12.13" - "@babel/plugin-transform-literals" "^7.12.13" - "@babel/plugin-transform-member-expression-literals" "^7.12.13" - "@babel/plugin-transform-modules-amd" "^7.14.0" - "@babel/plugin-transform-modules-commonjs" "^7.14.0" - "@babel/plugin-transform-modules-systemjs" "^7.13.8" - "@babel/plugin-transform-modules-umd" "^7.14.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" - "@babel/plugin-transform-new-target" "^7.12.13" - "@babel/plugin-transform-object-super" "^7.12.13" - "@babel/plugin-transform-parameters" "^7.13.0" - "@babel/plugin-transform-property-literals" "^7.12.13" - "@babel/plugin-transform-regenerator" "^7.13.15" - "@babel/plugin-transform-reserved-words" "^7.12.13" - "@babel/plugin-transform-shorthand-properties" "^7.12.13" - "@babel/plugin-transform-spread" "^7.13.0" - "@babel/plugin-transform-sticky-regex" "^7.12.13" - "@babel/plugin-transform-template-literals" "^7.13.0" - "@babel/plugin-transform-typeof-symbol" "^7.12.13" - "@babel/plugin-transform-unicode-escapes" "^7.12.13" - "@babel/plugin-transform-unicode-regex" "^7.12.13" - "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.14.1" - babel-plugin-polyfill-corejs2 "^0.2.0" - babel-plugin-polyfill-corejs3 "^0.2.0" - babel-plugin-polyfill-regenerator "^0.2.0" - core-js-compat "^3.9.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.0" + "@babel/plugin-transform-async-to-generator" "^7.16.0" + "@babel/plugin-transform-block-scoped-functions" "^7.16.0" + "@babel/plugin-transform-block-scoping" "^7.16.0" + "@babel/plugin-transform-classes" "^7.16.0" + "@babel/plugin-transform-computed-properties" "^7.16.0" + "@babel/plugin-transform-destructuring" "^7.16.0" + "@babel/plugin-transform-dotall-regex" "^7.16.0" + "@babel/plugin-transform-duplicate-keys" "^7.16.0" + "@babel/plugin-transform-exponentiation-operator" "^7.16.0" + "@babel/plugin-transform-for-of" "^7.16.0" + "@babel/plugin-transform-function-name" "^7.16.0" + "@babel/plugin-transform-literals" "^7.16.0" + "@babel/plugin-transform-member-expression-literals" "^7.16.0" + "@babel/plugin-transform-modules-amd" "^7.16.0" + "@babel/plugin-transform-modules-commonjs" "^7.16.0" + "@babel/plugin-transform-modules-systemjs" "^7.16.0" + "@babel/plugin-transform-modules-umd" "^7.16.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0" + "@babel/plugin-transform-new-target" "^7.16.0" + "@babel/plugin-transform-object-super" "^7.16.0" + "@babel/plugin-transform-parameters" "^7.16.3" + "@babel/plugin-transform-property-literals" "^7.16.0" + "@babel/plugin-transform-regenerator" "^7.16.0" + "@babel/plugin-transform-reserved-words" "^7.16.0" + "@babel/plugin-transform-shorthand-properties" "^7.16.0" + "@babel/plugin-transform-spread" "^7.16.0" + "@babel/plugin-transform-sticky-regex" "^7.16.0" + "@babel/plugin-transform-template-literals" "^7.16.0" + "@babel/plugin-transform-typeof-symbol" "^7.16.0" + "@babel/plugin-transform-unicode-escapes" "^7.16.0" + "@babel/plugin-transform-unicode-regex" "^7.16.0" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.0" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.4.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.19.1" semver "^6.3.0" -"@babel/preset-flow@^7.0.0": +"@babel/preset-flow@^7.0.0", "@babel/preset-flow@^7.12.1": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.16.0.tgz#9f1f6e72714d79460d48058cb5658fc87da7150b" integrity sha512-e5NE1EoPMpoHFkyFkMSj2h9tu7OolARcUHki8mnBv4NiFK9so+UrhbvT9mV99tMJOUEx8BOj67T6dXvGcTeYeQ== @@ -1224,19 +968,10 @@ "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-transform-flow-strip-types" "^7.16.0" -"@babel/preset-flow@^7.12.1": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.13.13.tgz#a61a1c149b3f77589d795287744393444d5cdd9e" - integrity sha512-MDtwtamMifqq3R2mC7l3A3uFalUb3NH5TIBQWjN/epEPlZktcLq4se3J+ivckKrLMGsR7H9LW8+pYuIUN9tsKg== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-transform-flow-strip-types" "^7.13.0" - -"@babel/preset-modules@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1245,18 +980,18 @@ esutils "^2.0.2" "@babel/preset-react@^7.12.10": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.13.13.tgz#fa6895a96c50763fe693f9148568458d5a839761" - integrity sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.0.tgz#f71d3e8dff5218478011df037fad52660ee6d82a" + integrity sha512-d31IFW2bLRB28uL1WoElyro8RH5l6531XfxMtCeCmp6RVAF1uTfxxUA0LH1tXl+psZdwfmIbwoG4U5VwgbhtLw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-transform-react-display-name" "^7.12.13" - "@babel/plugin-transform-react-jsx" "^7.13.12" - "@babel/plugin-transform-react-jsx-development" "^7.12.17" - "@babel/plugin-transform-react-pure-annotations" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-transform-react-display-name" "^7.16.0" + "@babel/plugin-transform-react-jsx" "^7.16.0" + "@babel/plugin-transform-react-jsx-development" "^7.16.0" + "@babel/plugin-transform-react-pure-annotations" "^7.16.0" -"@babel/preset-typescript@^7.1.0": +"@babel/preset-typescript@^7.1.0", "@babel/preset-typescript@^7.12.7": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac" integrity sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg== @@ -1265,19 +1000,10 @@ "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-transform-typescript" "^7.16.0" -"@babel/preset-typescript@^7.12.7": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz#ab107e5f050609d806fbb039bec553b33462c60a" - integrity sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-transform-typescript" "^7.13.0" - "@babel/register@^7.0.0": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.13.16.tgz#ae3ab0b55c8ec28763877383c454f01521d9a53d" - integrity sha512-dh2t11ysujTwByQjXNgJ48QZ2zcXKQVdV8s0TbeMI0flmtGWCdTwK9tJiACHXPLmncm5+ktNn/diojA45JE4jg== + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.16.0.tgz#f5d2aa14df37cf7146b9759f7c53818360f24ec6" + integrity sha512-lzl4yfs0zVXnooeLE0AAfYaT7F3SPA8yB2Bj4W1BiZwLbMS3MZH35ZvCWSRHvneUugwuM+Wsnrj7h0F7UmU3NQ== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" @@ -1286,22 +1012,13 @@ source-map-support "^0.5.16" "@babel/runtime@^7.8.4": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" - integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.0.0", "@babel/template@^7.12.13", "@babel/template@^7.3.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" - integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/parser" "^7.12.13" - "@babel/types" "^7.12.13" - -"@babel/template@^7.16.0": +"@babel/template@^7.0.0", "@babel/template@^7.16.0", "@babel/template@^7.3.3": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== @@ -1310,21 +1027,7 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" - integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.14.0" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.14.0" - "@babel/types" "^7.14.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== @@ -1339,15 +1042,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" - integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== - dependencies: - "@babel/helper-validator-identifier" "^7.14.0" - to-fast-properties "^2.0.0" - -"@babel/types@^7.16.0": +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== @@ -1380,6 +1075,11 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@hutson/parse-repository-url@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" + integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== + "@iarna/toml@2.2.5": version "2.2.5" resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" @@ -1579,127 +1279,127 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@nodelib/fs.scandir@2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" - integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" - integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" - integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" "@octokit/auth-token@^2.4.4": - version "2.4.5" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3" - integrity sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" + integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g== dependencies: "@octokit/types" "^6.0.3" -"@octokit/core@^3.2.3": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.4.0.tgz#b48aa27d755b339fe7550548b340dcc2b513b742" - integrity sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg== +"@octokit/core@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b" + integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw== dependencies: "@octokit/auth-token" "^2.4.4" "@octokit/graphql" "^4.5.8" - "@octokit/request" "^5.4.12" + "@octokit/request" "^5.6.0" "@octokit/request-error" "^2.0.5" "@octokit/types" "^6.0.3" before-after-hook "^2.2.0" universal-user-agent "^6.0.0" "@octokit/endpoint@^6.0.1": - version "6.0.11" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.11.tgz#082adc2aebca6dcefa1fb383f5efb3ed081949d1" - integrity sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ== + version "6.0.12" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" + integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== dependencies: "@octokit/types" "^6.0.3" is-plain-object "^5.0.0" universal-user-agent "^6.0.0" "@octokit/graphql@^4.5.8": - version "4.6.1" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.6.1.tgz#f975486a46c94b7dbe58a0ca751935edc7e32cc9" - integrity sha512-2lYlvf4YTDgZCTXTW4+OX+9WTLFtEUc6hGm4qM1nlZjzxj+arizM4aHWzBVBCxY9glh7GIs0WEuiSgbVzv8cmA== + version "4.8.0" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" + integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== dependencies: - "@octokit/request" "^5.3.0" + "@octokit/request" "^5.6.0" "@octokit/types" "^6.0.3" universal-user-agent "^6.0.0" -"@octokit/openapi-types@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-7.0.0.tgz#0f6992db9854af15eca77d71ab0ec7fad2f20411" - integrity sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw== +"@octokit/openapi-types@^11.2.0": + version "11.2.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-11.2.0.tgz#b38d7fc3736d52a1e96b230c1ccd4a58a2f400a6" + integrity sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA== -"@octokit/plugin-paginate-rest@^2.6.2": - version "2.13.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz#f0f1792230805108762d87906fb02d573b9e070a" - integrity sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg== +"@octokit/plugin-paginate-rest@^2.16.8": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz#32e9c7cab2a374421d3d0de239102287d791bce7" + integrity sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw== dependencies: - "@octokit/types" "^6.11.0" + "@octokit/types" "^6.34.0" -"@octokit/plugin-request-log@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz#70a62be213e1edc04bb8897ee48c311482f9700d" - integrity sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ== +"@octokit/plugin-request-log@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" + integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== -"@octokit/plugin-rest-endpoint-methods@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.0.tgz#cf2cdeb24ea829c31688216a5b165010b61f9a98" - integrity sha512-Jc7CLNUueIshXT+HWt6T+M0sySPjF32mSFQAK7UfAg8qGeRI6OM1GSBxDLwbXjkqy2NVdnqCedJcP1nC785JYg== +"@octokit/plugin-rest-endpoint-methods@^5.12.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz#8c46109021a3412233f6f50d28786f8e552427ba" + integrity sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA== dependencies: - "@octokit/types" "^6.13.0" + "@octokit/types" "^6.34.0" deprecation "^2.3.1" -"@octokit/request-error@^2.0.0", "@octokit/request-error@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.5.tgz#72cc91edc870281ad583a42619256b380c600143" - integrity sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg== +"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" + integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg== dependencies: "@octokit/types" "^6.0.3" deprecation "^2.0.0" once "^1.4.0" -"@octokit/request@^5.3.0", "@octokit/request@^5.4.12": - version "5.4.15" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.15.tgz#829da413dc7dd3aa5e2cdbb1c7d0ebe1f146a128" - integrity sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag== +"@octokit/request@^5.6.0": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.2.tgz#1aa74d5da7b9e04ac60ef232edd9a7438dcf32d8" + integrity sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA== dependencies: "@octokit/endpoint" "^6.0.1" - "@octokit/request-error" "^2.0.0" - "@octokit/types" "^6.7.1" + "@octokit/request-error" "^2.1.0" + "@octokit/types" "^6.16.1" is-plain-object "^5.0.0" node-fetch "^2.6.1" universal-user-agent "^6.0.0" -"@octokit/rest@18.5.2": - version "18.5.2" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.5.2.tgz#0369e554b7076e3749005147be94c661c7a5a74b" - integrity sha512-Kz03XYfKS0yYdi61BkL9/aJ0pP2A/WK5vF/syhu9/kY30J8He3P68hv9GRpn8bULFx2K0A9MEErn4v3QEdbZcw== +"@octokit/rest@18.12.0": + version "18.12.0" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.12.0.tgz#f06bc4952fc87130308d810ca9d00e79f6988881" + integrity sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q== dependencies: - "@octokit/core" "^3.2.3" - "@octokit/plugin-paginate-rest" "^2.6.2" - "@octokit/plugin-request-log" "^1.0.2" - "@octokit/plugin-rest-endpoint-methods" "5.0.0" + "@octokit/core" "^3.5.1" + "@octokit/plugin-paginate-rest" "^2.16.8" + "@octokit/plugin-request-log" "^1.0.4" + "@octokit/plugin-rest-endpoint-methods" "^5.12.0" -"@octokit/types@^6.0.3", "@octokit/types@^6.11.0", "@octokit/types@^6.13.0", "@octokit/types@^6.7.1": - version "6.14.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.14.2.tgz#64c9457f38fb8522bdbba3c8cc814590a2d61bf5" - integrity sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA== +"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.34.0": + version "6.34.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.34.0.tgz#c6021333334d1ecfb5d370a8798162ddf1ae8218" + integrity sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw== dependencies: - "@octokit/openapi-types" "^7.0.0" + "@octokit/openapi-types" "^11.2.0" "@react-native-community/cli-debugger-ui@^5.0.1": version "5.0.1" @@ -1873,9 +1573,9 @@ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@sindresorhus/is@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" - integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== + version "4.2.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.2.0.tgz#667bfc6186ae7c9e0b45a08960c551437176e1ca" + integrity sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw== "@sinonjs/commons@^1.7.0": version "1.8.3" @@ -1899,16 +1599,21 @@ defer-to-connect "^1.0.1" "@szmarczak/http-timer@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" - integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== dependencies: defer-to-connect "^2.0.0" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": - version "7.1.14" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" - integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" + integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1917,31 +1622,31 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" - integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + version "7.6.3" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5" + integrity sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" - integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== dependencies: "@babel/types" "^7.3.0" "@types/cacheable-request@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" - integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" + integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== dependencies: "@types/http-cache-semantics" "*" "@types/keyv" "*" @@ -1949,9 +1654,9 @@ "@types/responselike" "*" "@types/fs-extra@^9.0.11": - version "9.0.11" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.11.tgz#8cc99e103499eab9f347dbc6ca4e99fb8d2c2b87" - integrity sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA== + version "9.0.13" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" + integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== dependencies: "@types/node" "*" @@ -1963,9 +1668,9 @@ "@types/node" "*" "@types/http-cache-semantics@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" - integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" @@ -1980,41 +1685,41 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" - integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^26.0.0": - version "26.0.23" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.23.tgz#a1b7eab3c503b80451d019efb588ec63522ee4e7" - integrity sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA== + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" "@types/keyv@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" - integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.3.tgz#1c9aae32872ec1f20dcdaee89a9f3ba88f465e41" + integrity sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg== dependencies: "@types/node" "*" "@types/minimist@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" - integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "15.0.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.1.tgz#ef34dea0881028d11398be5bf4e856743e3dc35a" - integrity sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA== + version "16.11.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.10.tgz#2e3ad0a680d96367103d3e670d41c2fed3da61ae" + integrity sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA== "@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== "@types/parse-json@^4.0.0": version "4.0.0" @@ -2022,14 +1727,14 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prettier@^2.0.0": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" - integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.2.tgz#4c62fae93eb479660c3bd93f9d24d561597a8281" + integrity sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA== "@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + version "15.7.4" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" + integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== "@types/react-native@0.62.13": version "0.62.13" @@ -2039,18 +1744,18 @@ "@types/react" "*" "@types/react@*": - version "17.0.4" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.4.tgz#a67c6f7a460d2660e950d9ccc1c2f18525c28220" - integrity sha512-onz2BqScSFMoTRdJUZUDD/7xrusM8hBA2Fktk2qgaTYPCgPvWnDEgkrOs8hhPUf2jfcIXkJ5yK6VfYormJS3Jw== + version "17.0.37" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.37.tgz#6884d0aa402605935c397ae689deed115caad959" + integrity sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/react@^16.9.19": - version "16.14.5" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.5.tgz#2c39b5cadefaf4829818f9219e5e093325979f4d" - integrity sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw== + version "16.14.21" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.21.tgz#35199b21a278355ec7a3c40003bd6a334bd4ae4a" + integrity sha512-rY4DzPKK/4aohyWiDRHS2fotN5rhBSK6/rz1X37KzNna9HJyqtaGAbq9fVttrEPWF5ywpfIP1ITL8Xi2QZn6Eg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2064,24 +1769,24 @@ "@types/node" "*" "@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== "@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== "@types/yargs@^15.0.0": - version "15.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" - integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== dependencies: "@types/yargs-parser" "*" @@ -2136,16 +1841,23 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0: - version "8.2.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.2.tgz#c4574e4fea298d6e6ed4b85ab844b06dd59f26d6" - integrity sha512-VrMS8kxT0e7J1EX0p6rI/E0FbfOVcvBpbIqHThFv+f8YrZIlMfVotYcXKVPmTvPW8sW5miJzfUFrrvthUZg8VQ== +acorn@^8.2.4: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -2154,27 +1866,17 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - anser@^1.4.9: version "1.4.10" resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.10.tgz#befa3eddf282684bd03b63dcda3927aef8c2e35b" integrity sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww== ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== dependencies: - string-width "^3.0.0" + string-width "^4.1.0" ansi-escapes@^4.2.1: version "4.3.2" @@ -2197,10 +1899,10 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" @@ -2264,11 +1966,6 @@ array-filter@~0.0.0: resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" @@ -2304,18 +2001,6 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -2338,12 +2023,12 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async-retry@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.1.tgz#139f31f8ddce50c0870b0ba558a6079684aaed55" - integrity sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA== +async-retry@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== dependencies: - retry "0.12.0" + retry "0.13.1" async@0.9.x: version "0.9.2" @@ -2372,16 +2057,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" @@ -2409,14 +2084,14 @@ babel-plugin-dynamic-import-node@^2.3.3: object.assign "^4.1.0" babel-plugin-istanbul@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" - integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" babel-plugin-jest-hoist@^26.6.2: @@ -2429,29 +2104,29 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4" - integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg== +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" + integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== dependencies: "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.0" + "@babel/helper-define-polyfill-provider" "^0.3.0" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2" - integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg== +babel-plugin-polyfill-corejs3@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz#0b571f4cf3d67f911512f5c04842a7b8e8263087" + integrity sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.0" - core-js-compat "^3.9.1" + "@babel/helper-define-polyfill-provider" "^0.3.0" + core-js-compat "^3.18.0" -babel-plugin-polyfill-regenerator@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8" - integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg== +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" + integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.0" + "@babel/helper-define-polyfill-provider" "^0.3.0" babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: version "7.0.0-beta.0" @@ -2477,9 +2152,9 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-top-level-await" "^7.8.3" babel-preset-fbjs@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" - integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== + version "3.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" + integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-object-rest-spread" "^7.0.0" @@ -2540,22 +2215,15 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - before-after-hook@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.1.tgz#73540563558687586b52ed217dad6a802ab1549c" - integrity sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw== + version "2.2.2" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" + integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== -big-integer@^1.6.44: - version "1.6.48" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" - integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== +big-integer@1.6.x: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== bl@^4.1.0: version "4.1.0" @@ -2567,32 +2235,32 @@ bl@^4.1.0: readable-stream "^3.4.0" boxen@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.0.1.tgz#657528bdd3f59a772b8279b831f27ec2c744664b" - integrity sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA== + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== dependencies: ansi-align "^3.0.0" camelcase "^6.2.0" chalk "^4.1.0" cli-boxes "^2.2.1" - string-width "^4.2.0" + string-width "^4.2.2" type-fest "^0.20.2" widest-line "^3.1.0" wrap-ansi "^7.0.0" -bplist-creator@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.8.tgz#56b2a6e79e9aec3fc33bf831d09347d73794e79c" - integrity sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA== +bplist-creator@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.1.0.tgz#018a2d1b587f769e379ef5519103730f8963ba1e" + integrity sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg== dependencies: - stream-buffers "~2.2.0" + stream-buffers "2.2.x" -bplist-parser@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== +bplist-parser@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.3.0.tgz#ba50666370f61bbf94881636cd9f7d23c5286090" + integrity sha512-zgmaRvT6AN1JpPPV+S0a1/FAtoxSreYDccZGIqEMSvZl9DMe70mJ7MFzpxa1X+gHVdkToE2haRUHHMiW1OdejA== dependencies: - big-integer "^1.6.44" + big-integer "1.6.x" brace-expansion@^1.1.7: version "1.1.11" @@ -2630,18 +2298,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6: - version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" - integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== - dependencies: - caniuse-lite "^1.0.30001219" - colorette "^1.2.2" - electron-to-chromium "^1.3.723" - escalade "^3.1.1" - node-releases "^1.1.71" - -browserslist@^4.17.5: +browserslist@^4.16.0, browserslist@^4.17.5, browserslist@^4.18.1: version "4.18.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== @@ -2660,9 +2317,9 @@ bser@2.1.1: node-int64 "^0.4.0" buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer@^5.5.0: version "5.7.1" @@ -2723,17 +2380,17 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" -cacheable-request@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" - integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" http-cache-semantics "^4.0.0" keyv "^4.0.0" lowercase-keys "^2.0.0" - normalize-url "^4.1.0" + normalize-url "^6.0.1" responselike "^2.0.0" call-bind@^1.0.0: @@ -2768,14 +2425,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - camelcase-keys@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" @@ -2785,30 +2434,20 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.0.0, camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -caniuse-lite@^1.0.30001219: - version "1.0.30001221" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001221.tgz#b916721ddf59066cfbe96c5c9a77cf7ae5c52e65" - integrity sha512-b9TOZfND3uGSLjMOrLh8XxSQ41x8mX+9MLJYDM4AAHLfaZHttrLNPrScWjVnBITRZbY5sPpCt7X85n7VSLZ+/g== + version "6.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" + integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== caniuse-lite@^1.0.30001280: - version "1.0.30001282" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz#38c781ee0a90ccfe1fe7fefd00e43f5ffdcb96fd" - integrity sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg== + version "1.0.30001283" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz#8573685bdae4d733ef18f78d44ba0ca5fe9e896b" + integrity sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg== capture-exit@^2.0.0: version "2.0.0" @@ -2817,15 +2456,10 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -2847,14 +2481,6 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -2870,10 +2496,10 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.1.1.tgz#9a32fcefdf7bcdb6f0a7e1c0f8098ec57897b80a" - integrity sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ== +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== cjs-module-lexer@^0.6.0: version "0.6.0" @@ -2915,9 +2541,9 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.0.0, cli-spinners@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" - integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-width@^3.0.0: version "3.0.0" @@ -3005,17 +2631,17 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^1.0.7, colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== +colorette@^1.0.7: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3113,9 +2739,9 @@ connect@^3.6.5: utils-merge "1.0.1" conventional-changelog-angular@^5.0.12: - version "5.0.12" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz#c979b8b921cbfe26402eb3da5bbfda02d865a2b9" - integrity sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw== + version "5.0.13" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" + integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== dependencies: compare-func "^2.0.0" q "^1.5.1" @@ -3135,24 +2761,24 @@ conventional-changelog-codemirror@^2.0.8: q "^1.5.1" conventional-changelog-conventionalcommits@^4.5.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.0.tgz#7fc17211dbca160acf24687bd2fdd5fd767750eb" - integrity sha512-sj9tj3z5cnHaSJCYObA9nISf7eq/YjscLPoq6nmew4SiOjxqL2KRpK20fjnjVbpNDjJ2HR3MoVcWKXwbVvzS0A== + version "4.6.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz#f4c0921937050674e578dc7875f908351ccf4014" + integrity sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw== dependencies: compare-func "^2.0.0" lodash "^4.17.15" q "^1.5.1" conventional-changelog-core@^4.2.1: - version "4.2.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.2.tgz#f0897df6d53b5d63dec36b9442bd45354f8b3ce5" - integrity sha512-7pDpRUiobQDNkwHyJG7k9f6maPo9tfPzkSWbRq97GGiZqisElhnvUZSvyQH20ogfOjntB5aadvv6NNcKL1sReg== + version "4.2.4" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" + integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== dependencies: add-stream "^1.0.0" - conventional-changelog-writer "^4.0.18" + conventional-changelog-writer "^5.0.0" conventional-commits-parser "^3.2.0" dateformat "^3.0.0" - get-pkg-repo "^1.0.0" + get-pkg-repo "^4.0.0" git-raw-commits "^2.0.8" git-remote-origin-url "^2.0.0" git-semver-tags "^4.1.1" @@ -3161,7 +2787,6 @@ conventional-changelog-core@^4.2.1: q "^1.5.1" read-pkg "^3.0.0" read-pkg-up "^3.0.0" - shelljs "^0.8.3" through2 "^4.0.0" conventional-changelog-ember@^2.0.9: @@ -3205,12 +2830,11 @@ conventional-changelog-preset-loader@^2.3.4: resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== -conventional-changelog-writer@^4.0.18: - version "4.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz#1ca7880b75aa28695ad33312a1f2366f4b12659f" - integrity sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw== +conventional-changelog-writer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz#c4042f3f1542f2f41d7d2e0d6cad23aba8df8eec" + integrity sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g== dependencies: - compare-func "^2.0.0" conventional-commits-filter "^2.0.7" dateformat "^3.0.0" handlebars "^4.7.6" @@ -3247,9 +2871,9 @@ conventional-commits-filter@^2.0.7: modify-values "^1.0.0" conventional-commits-parser@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz#ba44f0b3b6588da2ee9fd8da508ebff50d116ce2" - integrity sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA== + version "3.2.3" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz#fc43704698239451e3ef35fd1d8ed644f46bd86e" + integrity sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw== dependencies: JSONStream "^1.0.4" is-text-path "^1.0.1" @@ -3257,7 +2881,6 @@ conventional-commits-parser@^3.2.0: meow "^8.0.0" split2 "^3.0.0" through2 "^4.0.0" - trim-off-newlines "^1.0.0" conventional-recommended-bump@^6.1.0: version "6.1.0" @@ -3274,9 +2897,9 @@ conventional-recommended-bump@^6.1.0: q "^1.5.1" convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -3285,23 +2908,23 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.9.0, core-js-compat@^3.9.1: - version "3.11.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.11.2.tgz#5048e367851cfd2c6c0cb81310757b4da296e385" - integrity sha512-gYhNwu7AJjecNtRrIfyoBabQ3ZG+llfPmg9BifIX8yxIpDyfNLRM73zIjINSm6z3dMdI1nwNC9C7uiy4pIC6cw== +core-js-compat@^3.18.0, core-js-compat@^3.19.1: + version "3.19.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.2.tgz#18066a3404a302433cb0aa8be82dd3d75c76e5c4" + integrity sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.18.1" semver "7.0.0" -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@7.0.0, cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== +cosmiconfig@7.0.1, cosmiconfig@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== dependencies: "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" @@ -3362,29 +2985,15 @@ cssstyle@^2.3.0: cssom "~0.3.6" csstype@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" - integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" + version "3.0.10" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5" + integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA== dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -3400,9 +3009,9 @@ dateformat@^3.0.0: integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== dayjs@^1.8.15: - version "1.10.4" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2" - integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw== + version "1.10.7" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468" + integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -3411,10 +3020,17 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@4.3.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@4, debug@^4.1.0, debug@^4.1.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" @@ -3426,15 +3042,15 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decode-uri-component@^0.2.0: version "0.2.0" @@ -3466,9 +3082,9 @@ deep-extend@^0.6.0: integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^3.2.0: version "3.3.0" @@ -3609,14 +3225,6 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -3629,26 +3237,16 @@ ejs@^3.1.5: dependencies: jake "^10.6.1" -electron-to-chromium@^1.3.723: - version "1.3.725" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.725.tgz#04fc83f9189169aff50f0a00c6b4090b910cba85" - integrity sha512-2BbeAESz7kc6KBzs7WVrMc1BY5waUphk4D4DX5dSQXJhsc3tP5ZFaiyuL0AB7vUKzDYpIeYwTYlEfxyjsGUrhw== - electron-to-chromium@^1.3.896: - version "1.3.902" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.902.tgz#926726705c17f9531be23bda545b819b35da665d" - integrity sha512-zFv5jbtyIr+V9FuT9o439isXbkXQ27mJqZfLXpBKzXugWE8+3RotHbXJlli0/r+Rvdlkut0OOMzeOWLAjH0jCw== + version "1.4.5" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz#912e8fd1645edee2f0f212558f40916eb538b1f9" + integrity sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw== emittery@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3671,7 +3269,7 @@ envinfo@^7.7.2: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -3736,9 +3334,9 @@ esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" @@ -3760,10 +3358,10 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== -execa@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== +execa@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" get-stream "^6.0.0" @@ -3848,11 +3446,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -3876,32 +3469,16 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -3914,9 +3491,9 @@ fast-levenshtein@~2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" @@ -3985,22 +3562,6 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -4029,9 +3590,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flow-parser@0.*: - version "0.165.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.165.0.tgz#327f4c2c6516face02cb2239bb3bf4b4bf0e8fd8" - integrity sha512-s9pW6fqJvYwdc2KfS0R76e2T1tgKpz4TzFyrnaHPdo/nEZbMiQQuB+uqUgg+sSPmHya0UV3Igc3Dy+NxSDN5sg== + version "0.165.1" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.165.1.tgz#e420c560d0c9bd0e546b9f1b79afed37174298c5" + integrity sha512-vz/5MZIePDCZO9FfnRaH398cc+XSwtgoUzR6pC5zbekpk5ttCaXOnxypho+hb0NzUyQNFV+6vpU8joRZ1llrCw== flow-parser@^0.121.0: version "0.121.0" @@ -4043,11 +3604,6 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - form-data@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -4057,13 +3613,13 @@ form-data@4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fragment-cache@^0.2.1: @@ -4145,21 +3701,15 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-pkg-repo@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" - integrity sha1-xztInAbYDMVTbCyFP54FIyBWly0= +get-pkg-repo@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" + integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== dependencies: - hosted-git-info "^2.1.4" - meow "^3.3.0" - normalize-package-data "^2.3.0" - parse-github-repo-url "^1.3.0" + "@hutson/parse-repository-url" "^3.0.0" + hosted-git-info "^4.0.0" through2 "^2.0.0" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + yargs "^16.2.0" get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" @@ -4185,13 +3735,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - gh-got@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-8.1.0.tgz#2378d07ac293f524549c75f8dc6f3604a885ab01" @@ -4227,17 +3770,17 @@ git-semver-tags@^4.1.1: semver "^6.0.0" git-up@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.2.tgz#10c3d731051b366dc19d3df454bfca3f77913a7c" - integrity sha512-kbuvus1dWQB2sSW4cbfTeGpCMd8ge9jx9RKnhXhuJ7tnvT+NIrTVfYZxjtflZddQYcmdOTlkAcjmx7bor+15AQ== + version "4.0.5" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.5.tgz#e7bb70981a37ea2fb8fe049669800a1f9a01d759" + integrity sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA== dependencies: is-ssh "^1.3.0" - parse-url "^5.0.0" + parse-url "^6.0.0" -git-url-parse@11.4.4: - version "11.4.4" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.4.4.tgz#5d747debc2469c17bc385719f7d0427802d83d77" - integrity sha512-Y4o9o7vQngQDIU9IjyCmRJBin5iYjI5u9ZITnddRZpD7dcCFQj2sL2XuMNbLRE4b4B/4ENPsp2Q8P44fjAZ0Pw== +git-url-parse@11.6.0: + version "11.6.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605" + integrity sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g== dependencies: git-up "^4.0.0" @@ -4255,7 +3798,7 @@ github-username@^5.0.1: dependencies: gh-got "^8.1.0" -glob-parent@^5.1.0: +glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -4263,9 +3806,9 @@ glob-parent@^5.1.0: is-glob "^4.0.1" glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -4286,10 +3829,10 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globby@11.0.3, globby@^11.0.1: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== +globby@11.0.4, globby@^11.0.1: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -4298,17 +3841,17 @@ globby@11.0.3, globby@^11.0.1: merge2 "^1.3.0" slash "^3.0.0" -got@11.8.2: - version "11.8.2" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" - integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== +got@11.8.3: + version "11.8.3" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" + integrity sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg== dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" "@types/cacheable-request" "^6.0.1" "@types/responselike" "^1.0.0" cacheable-lookup "^5.0.3" - cacheable-request "^7.0.1" + cacheable-request "^7.0.2" decompress-response "^6.0.0" http2-wrapper "^1.0.0-beta.5.2" lowercase-keys "^2.0.0" @@ -4332,16 +3875,11 @@ got@^9.5.0, got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -4359,19 +3897,6 @@ handlebars@^4.7.6: optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" @@ -4452,7 +3977,7 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hosted-git-info@^4.0.1: +hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== @@ -4487,14 +4012,14 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + "@tootallnate/once" "1" + agent-base "6" + debug "4" http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" @@ -4504,6 +4029,14 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -4527,9 +4060,9 @@ ieee754@^1.1.13, ieee754@^1.2.1: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + version "5.1.9" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" + integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== image-size@^0.6.0: version "0.6.3" @@ -4572,9 +4105,9 @@ import-lazy@^2.1.0: integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + version "3.0.3" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" + integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -4584,13 +4117,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" @@ -4619,21 +4145,22 @@ ini@^1.3.2, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inquirer@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.0.0.tgz#957a46db1abcf0fdd2ab82deb7470e90afc7d0ac" - integrity sha512-ON8pEJPPCdyjxj+cxsYRe6XfCJepTxANdNnTebsTuQgXpRyZRRT9t4dJwjRubgmvn20CLSEnozRUayXyM9VTXA== +inquirer@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" + integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== dependencies: ansi-escapes "^4.2.1" - chalk "^4.1.0" + chalk "^4.1.1" cli-cursor "^3.1.0" cli-width "^3.0.0" external-editor "^3.0.3" figures "^3.0.0" lodash "^4.17.21" mute-stream "0.0.8" + ora "^5.4.1" run-async "^2.4.0" - rxjs "^6.6.6" + rxjs "^7.2.0" string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" @@ -4687,12 +4214,12 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-ci@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" - integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== +is-ci@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== dependencies: - ci-info "^3.1.1" + ci-info "^3.2.0" is-ci@^2.0.0: version "2.0.0" @@ -4701,10 +4228,10 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" - integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== +is-core-module@^2.2.0, is-core-module@^2.5.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== dependencies: has "^1.0.3" @@ -4767,11 +4294,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -4804,9 +4326,9 @@ is-git-repository@^2.0.0: is-absolute "^1.0.0" is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" @@ -4872,7 +4394,7 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-potential-custom-element-name@^1.0.0: +is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== @@ -4885,9 +4407,9 @@ is-relative@^1.0.0: is-unc-path "^1.0.0" is-ssh@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.2.tgz#a4b82ab63d73976fd8263cceee27f99a88bdae2b" - integrity sha512-elEw0/0c2UscLrNG+OAorbP539E3rhliKPg+hDMWN9VwrDXfYK+4PBEykDPfxlYYtQvl84TascnQyobfQLHEhQ== + version "1.3.3" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.3.tgz#7f133285ccd7f2c2c7fc897b771b53d95a2b2c7e" + integrity sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ== dependencies: protocols "^1.1.0" @@ -4897,9 +4419,9 @@ is-stream@^1.1.0: integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-text-path@^1.0.1: version "1.0.1" @@ -4908,7 +4430,7 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -4925,11 +4447,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4940,7 +4457,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.2.0: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -4974,17 +4491,12 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-coverage@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== - -istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: +istanbul-lib-instrument@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== @@ -4994,6 +4506,17 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" +istanbul-lib-instrument@^5.0.4: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -5004,18 +4527,18 @@ istanbul-lib-report@^3.0.0: supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + version "3.0.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384" + integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -5404,9 +4927,9 @@ jest@^26.0.1: jest-cli "^26.6.3" jetifier@^1.6.2, jetifier@^1.6.6: - version "1.6.7" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.7.tgz#0e3f5ca716db03f1c869c9711ce1b7d0a6e5b24a" - integrity sha512-IMVhXwdIxrR7vVq624m8H79IsaLysUYDPI2KC18L3LCc1Tg/KYvNMIkHN3X96XF5fnPVdINBFkFfC3rsPX1yYg== + version "1.6.8" + resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.8.tgz#e88068697875cbda98c32472902c4d3756247798" + integrity sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw== joi@^17.2.1: version "17.4.2" @@ -5432,11 +4955,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - jsc-android@^245459.0.0: version "245459.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" @@ -5468,12 +4986,12 @@ jscodeshift@^0.11.0: write-file-atomic "^2.3.0" jsdom@^16.4.0: - version "16.5.3" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" - integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" cssstyle "^2.3.0" @@ -5481,12 +4999,13 @@ jsdom@^16.4.0: decimal.js "^10.2.1" domexception "^2.0.1" escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" parse5 "6.0.1" - request "^2.88.2" - request-promise-native "^1.0.9" saxes "^5.0.1" symbol-tree "^3.2.4" tough-cookie "^4.0.0" @@ -5496,7 +5015,7 @@ jsdom@^16.4.0: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.4" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -5529,17 +5048,7 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -5584,16 +5093,6 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -5602,9 +5101,9 @@ keyv@^3.0.0: json-buffer "3.0.0" keyv@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" - integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.4.tgz#f040b236ea2b06ed15ed86fbef8407e1a1c8e376" + integrity sha512-vqNHbAc8BBsxk+7QBYLW0Y219rWcClspR6WSeoHYKG5mnsSoOH+BL1pWq02DDCVdvvuUny5rkBlzMRzoqc+GIg== dependencies: json-buffer "3.0.1" @@ -5665,20 +5164,9 @@ levn@~0.3.0: type-check "~0.3.2" lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== load-json-file@^4.0.0: version "4.0.0" @@ -5713,13 +5201,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -5735,7 +5216,7 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: +lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5771,14 +5252,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -5796,10 +5269,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -macos-release@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.4.1.tgz#64033d0ec6a5e6375155a74b1a1eba8e509820ac" - integrity sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg== +macos-release@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.5.0.tgz#067c2c88b5f3fb3c56a375b2ec93826220fa1ff2" + integrity sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g== make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" @@ -5816,27 +5289,27 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - tmpl "1.0.x" + tmpl "1.0.5" map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-obj@^1.0.0, map-obj@^1.0.1: +map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= map-obj@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.1.tgz#e4ea399dbc979ae735c83c863dd31bdf364277b7" - integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" + integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== map-visit@^1.0.0: version "1.0.0" @@ -5845,22 +5318,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -6169,7 +5626,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.2: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -6177,24 +5634,12 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.47.0, "mime-db@>= 1.43.0 < 2": - version "1.47.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" - integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== - -mime-db@1.51.0: +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": version "1.51.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@2.1.30, mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.30" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" - integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== - dependencies: - mime-db "1.47.0" - -mime-types@^2.1.27: +mime-types@2.1.34, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== @@ -6207,9 +5652,9 @@ mime@1.6.0: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== mimic-fn@^1.0.0: version "1.2.0" @@ -6252,7 +5697,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -6329,6 +5774,13 @@ neo-async@^2.5.0, neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +new-github-release-url@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/new-github-release-url/-/new-github-release-url-1.0.0.tgz#493847e6fecce39c247e9d89929be773d2e7f777" + integrity sha512-dle7yf655IMjyFUqn6Nxkb18r4AOAkzRcgcZv6WZ0IqrOH4QCEZ8Sm6I7XX21zvHdBeeMeTkhR9qT2Z0EJDx6A== + dependencies: + type-fest "^0.4.1" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -6347,9 +5799,11 @@ node-dir@^0.1.17: minimatch "^3.0.2" node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + version "2.6.6" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" + integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + dependencies: + whatwg-url "^5.0.0" node-int64@^0.4.0: version "0.4.0" @@ -6373,22 +5827,17 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-releases@^1.1.71: - version "1.1.71" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" - integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== - node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== node-stream-zip@^1.9.1: - version "1.13.3" - resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.13.3.tgz#63235337abebcef408b244b4e28f28961e6e86f0" - integrity sha512-Vv95ug+8Jfug4AxcqNV7TeGEk2antNidj+YBOyP8SS8LTHJmjsE3d9h6L831eJtO8p7jesJ3CDtgkwmLO/wcSw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" + integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== -normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -6399,12 +5848,12 @@ normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package- validate-npm-package-license "^3.0.1" normalize-package-data@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.2.tgz#cae5c410ae2434f9a6c1baa65d5bc3b9366c8699" - integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" + integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== dependencies: hosted-git-info "^4.0.1" - resolve "^1.20.0" + is-core-module "^2.5.0" semver "^7.3.4" validate-npm-package-license "^3.0.1" @@ -6420,15 +5869,15 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== - normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize-url@^6.0.1, normalize-url@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-run-path@^2.0.0: version "2.0.2" @@ -6454,17 +5903,12 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - ob1@0.64.0: version "0.64.0" resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.64.0.tgz#f254a55a53ca395c4f9090e28a85483eac5eba19" integrity sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ== -object-assign@^4.0.1, object-assign@^4.1.1: +object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -6479,9 +5923,9 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.9.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.2.tgz#b6385a3e2b7cae0b5eafcf90cddf85d128767f30" - integrity sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -6548,6 +5992,14 @@ onetime@^5.1.0, onetime@^5.1.2: "onnxruntime-common@file:../common": version "1.10.0" +open@7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + open@^6.2.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" @@ -6572,10 +6024,10 @@ options@>=0.0.5: resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= -ora@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.0.tgz#42eda4855835b9cd14d33864c97a3c95a3f56bf4" - integrity sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg== +ora@5.4.1, ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: bl "^4.1.0" chalk "^4.1.0" @@ -6599,12 +6051,12 @@ ora@^3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" -os-name@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/os-name/-/os-name-4.0.0.tgz#6c05c09c41c15848ea74658d12c9606f0f286599" - integrity sha512-caABzDdJMbtykt7GmSogEat3faTKQhmZf0BS5l/pZGmP0vPWQjXWqOhbLyK+b6j2/DQPmEvYdzLXJXXLJNVDNg== +os-name@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-4.0.1.tgz#32cee7823de85a8897647ba4d76db46bf845e555" + integrity sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw== dependencies: - macos-release "^2.2.0" + macos-release "^2.5.0" windows-release "^4.0.0" os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: @@ -6646,13 +6098,6 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -6674,13 +6119,6 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" @@ -6715,11 +6153,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-github-repo-url@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" - integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= - parse-json@5.2.0, parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -6730,13 +6163,6 @@ parse-json@5.2.0, parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -6755,13 +6181,13 @@ parse-path@^4.0.0: qs "^6.9.4" query-string "^6.13.8" -parse-url@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-5.0.2.tgz#856a3be1fcdf78dc93fc8b3791f169072d898b59" - integrity sha512-Czj+GIit4cdWtxo3ISZCvLiUjErSo0iI3wJ+q9Oi3QuMYTI6OZu+7cewMWZ+C1YAnKhYTk6/TLuhIgCypLthPA== +parse-url@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-6.0.0.tgz#f5dd262a7de9ec00914939220410b66cff09107d" + integrity sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw== dependencies: is-ssh "^1.3.0" - normalize-url "^3.3.0" + normalize-url "^6.1.0" parse-path "^4.0.0" protocols "^1.4.0" @@ -6780,13 +6206,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -6817,15 +6236,6 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -6838,22 +6248,17 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== +picomatch@^2.0.4, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pify@^2.0.0, pify@^2.3.0: +pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -6868,18 +6273,6 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -6901,19 +6294,18 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -plist@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.2.tgz#74bbf011124b90421c22d15779cee60060ba95bc" - integrity sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ== +plist@^3.0.1, plist@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.4.tgz#a62df837e3aed2bb3b735899d510c4f186019cbe" + integrity sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg== dependencies: base64-js "^1.5.1" xmlbuilder "^9.0.7" - xmldom "^0.5.0" pod-install@^0.1.0: - version "0.1.21" - resolved "https://registry.yarnpkg.com/pod-install/-/pod-install-0.1.21.tgz#a731d172f691bb875f7a0e09dc28b3701947645c" - integrity sha512-m3wwcRKY5shcotdCae2jl3ICdZrZtCX7FdqGaUpquvmmgZ+3w0PUL7vVD/bsj1kbCw25qCqrtbn0ekyn9RABfQ== + version "0.1.29" + resolved "https://registry.yarnpkg.com/pod-install/-/pod-install-0.1.29.tgz#43222b5ebe9006ebf13134b25495bcede7de2f7a" + integrity sha512-fSU1bciYWXEvcDFwTKj8gBL8dYNvxPgibxhT5Z4I67AsHXH56uyPk2hE/HiH1pSkQ7ECWMAR1E0HX066T0RZ8Q== posix-character-classes@^0.1.0: version "0.1.1" @@ -6939,9 +6331,9 @@ prepend-http@^2.0.0: integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= prettier@^2.0.5: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + version "2.5.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.0.tgz#a6370e2d4594e093270419d9cc47f7670488f893" + integrity sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg== pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" @@ -6966,9 +6358,9 @@ promise@^8.0.3: asap "~2.0.6" prompts@^2.0.1, prompts@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" - integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" sisteransi "^1.0.5" @@ -6987,7 +6379,7 @@ protocols@^1.1.0, protocols@^1.4.0: resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -7000,7 +6392,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -7024,11 +6416,6 @@ qs@^6.9.4: dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - query-string@^6.13.8: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" @@ -7070,9 +6457,9 @@ rc@^1.2.8: strip-json-comments "~2.0.1" react-devtools-core@^4.6.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.13.0.tgz#fa80ee03b1a975c1d9898e24de841e45a4b22d30" - integrity sha512-KR+0pLw8wTjOVr+9AECe5ctmycaAjbmxN3bbdB0vmlwm0JkxNnKMxDzanf+4V8IuPBQWgm8qdWpbSOqhu1l14g== + version "4.21.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.21.0.tgz#a54c9a0fd7261491e616d6c87d1869e011d8521d" + integrity sha512-clGWwJHV5MHwTwYyKc+7FZHwzdbzrD2/AoZSkicUcr6YLc3Za9a9FaLhccWDHfjQ+ron9yzNhDT6Tv+FiPkD3g== dependencies: shell-quote "^1.6.1" ws "^7" @@ -7178,14 +6565,6 @@ react@16.13.1: object-assign "^4.1.1" prop-types "^15.6.2" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -7203,15 +6582,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -7270,14 +6640,6 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -7286,22 +6648,22 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== dependencies: - regenerate "^1.4.0" + regenerate "^1.4.2" -regenerate@^1.4.0: +regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== regenerator-transform@^0.14.2: version "0.14.5" @@ -7319,16 +6681,16 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexpu-core@^4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" registry-auth-token@^4.0.0: version "4.2.1" @@ -7344,43 +6706,44 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -regjsgen@^0.5.1: +regjsgen@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.6.4: - version "0.6.9" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" - integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== dependencies: jsesc "~0.5.0" release-it@^14.2.2: - version "14.6.1" - resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.6.1.tgz#a04623312d67886b37b8a6d298844ee3e0c7150a" - integrity sha512-noBho2997G3yrm6YvdLJj4Ua2SCFOU7ajCqtvteI3DZtpM1IhiyXSgcn2Q5irq8lTNK0it4eiNq9TSrAWNYDkA== + version "14.11.8" + resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.11.8.tgz#6da25daa93286d832cae4f10008a3bf0c08c2725" + integrity sha512-951DJ0kwjwU7CwGU3BCvRBgLxuJsOPRrZkqx0AsugJdSyPpUdwY9nlU0RAoSKqgh+VTerzecXLIIwgsGIpNxlA== dependencies: "@iarna/toml" "2.2.5" - "@octokit/rest" "18.5.2" - async-retry "1.3.1" - chalk "4.1.0" - cosmiconfig "7.0.0" - debug "4.3.1" + "@octokit/rest" "18.12.0" + async-retry "1.3.3" + chalk "4.1.2" + cosmiconfig "7.0.1" + debug "4.3.2" deprecated-obj "2.0.0" - execa "5.0.0" - find-up "5.0.0" + execa "5.1.1" form-data "4.0.0" - git-url-parse "11.4.4" - globby "11.0.3" - got "11.8.2" + git-url-parse "11.6.0" + globby "11.0.4" + got "11.8.3" import-cwd "3.0.0" - inquirer "8.0.0" - is-ci "3.0.0" + inquirer "8.2.0" + is-ci "3.0.1" lodash "4.17.21" - mime-types "2.1.30" - ora "5.4.0" - os-name "4.0.0" + mime-types "2.1.34" + new-github-release-url "1.0.0" + open "7.4.2" + ora "5.4.1" + os-name "4.0.1" parse-json "5.2.0" semver "7.3.5" shelljs "0.8.4" @@ -7388,7 +6751,7 @@ release-it@^14.2.2: url-join "4.0.1" uuid "8.3.2" yaml "1.10.2" - yargs-parser "20.2.7" + yargs-parser "20.2.9" remove-trailing-separator@^1.0.1: version "1.1.0" @@ -7405,55 +6768,6 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -7465,9 +6779,9 @@ require-main-filename@^2.0.0: integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== resolve-alpn@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28" - integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA== + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== resolve-cwd@^3.0.0: version "3.0.0" @@ -7496,7 +6810,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.18.1, resolve@^1.20.0: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.18.1: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -7539,10 +6853,10 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +retry@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== reusify@^1.0.4: version "1.0.4" @@ -7592,19 +6906,19 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.6.6: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== +rxjs@^7.2.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68" + integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w== dependencies: - tslib "^1.9.0" + tslib "~2.1.0" safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -7616,7 +6930,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -7781,11 +7095,11 @@ shell-quote@1.6.1: jsonify "~0.0.0" shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== -shelljs@0.8.4, shelljs@^0.8.3, shelljs@^0.8.4: +shelljs@0.8.4, shelljs@^0.8.4: version "0.8.4" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== @@ -7809,18 +7123,18 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== simple-plist@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.1.1.tgz#54367ca28bc5996a982c325c1c4a4c1a05f4047c" - integrity sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.3.0.tgz#f451997663eafd8ea6bad353a01caf49ef186d43" + integrity sha512-uYWpeGFtZtVt2NhG4AHgpwx323zxD85x42heMJBan1qAiqqozIlaGrwrEt6kRjXWRWIXsuV1VLCvVmZan2B5dg== dependencies: - bplist-creator "0.0.8" - bplist-parser "0.2.0" - plist "^3.0.1" + bplist-creator "0.1.0" + bplist-parser "0.3.0" + plist "^3.0.4" sisteransi@^1.0.5: version "1.0.5" @@ -7883,9 +7197,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@^0.5.16, source-map-support@^0.5.6: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -7932,9 +7246,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== split-on-first@^1.0.0: version "1.1.0" @@ -7967,25 +7281,10 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - stack-utils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: escape-string-regexp "^2.0.0" @@ -8014,12 +7313,7 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-buffers@~2.2.0: +stream-buffers@2.2.x: version "2.2.0" resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= @@ -8037,23 +7331,14 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" string_decoder@^1.1.1: version "1.3.0" @@ -8069,26 +7354,19 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: +strip-ansi@^5.0.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" + ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" @@ -8110,13 +7388,6 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -8246,7 +7517,7 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmpl@1.0.x: +tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -8298,14 +7569,6 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -8315,49 +7578,32 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= trim-newlines@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" - integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== - -trim-off-newlines@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" - integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= - -tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" + integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== tslib@^2.0.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== type-check@~0.3.2: version "0.3.2" @@ -8386,6 +7632,11 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" + integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== + type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" @@ -8414,9 +7665,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^4.1.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== + version "4.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" + integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== uglify-es@^3.1.9: version "3.3.9" @@ -8427,9 +7678,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.13.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.5.tgz#5d71d6dbba64cf441f32929b1efce7365bb4f113" - integrity sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw== + version "3.14.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" + integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g== ultron@1.0.x: version "1.0.2" @@ -8441,28 +7692,28 @@ unc-path-regex@^0.1.2: resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== union-value@^1.0.0: version "1.0.1" @@ -8529,13 +7780,6 @@ update-notifier@5.1.0: semver-diff "^3.1.1" xdg-basedir "^4.0.0" -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -8586,9 +7830,9 @@ uuid@^3.3.2: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-to-istanbul@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.1.tgz#04bfd1026ba4577de5472df4f5e89af49de5edda" - integrity sha512-p0BB09E5FRjx0ELN6RgusIPsSPhtgexSRcKETybEs6IGOTXJSZqfwxp7r//55nnu0f1AxltY5VvdVqy2vZf9AA== + version "7.1.2" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" + integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -8614,15 +7858,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" @@ -8643,11 +7878,11 @@ w3c-xmlserializer@^2.0.0: xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - makeerror "1.0.x" + makeerror "1.0.12" wcwidth@^1.0.1: version "1.0.1" @@ -8656,6 +7891,11 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -8683,13 +7923,21 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" - integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" - tr46 "^2.0.2" + tr46 "^2.1.0" webidl-conversions "^6.1.0" which-module@^2.0.0: @@ -8792,10 +8040,10 @@ ws@^6.1.4: dependencies: async-limiter "~1.0.0" -ws@^7, ws@^7.4.4: - version "7.4.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" - integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== +ws@^7, ws@^7.4.6: + version "7.5.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" + integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== xcode@^2.0.0: version "2.1.0" @@ -8832,11 +8080,6 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" -xmldom@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.5.0.tgz#193cb96b84aa3486127ea6272c4596354cb4962e" - integrity sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA== - xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -8862,10 +8105,10 @@ yaml@1.10.2, yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@20.2.7, yargs-parser@^20.2.2, yargs-parser@^20.2.3: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== +yargs-parser@20.2.9, yargs-parser@^20.2.2, yargs-parser@^20.2.3: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^18.1.2: version "18.1.3" @@ -8904,8 +8147,3 @@ yargs@^16.2.0: string-width "^4.2.0" y18n "^5.0.5" yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 0c72f1cd5a51fbe79b3755a993912d362eef35f5 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Wed, 8 Dec 2021 14:34:53 -0800 Subject: [PATCH 009/113] add copyright (#9943) (#9970) --- ThirdPartyNotices.txt | 36 ++++++++++++++++ cgmanifests/cgmanifest.json | 10 +++++ .../core/mlas/lib/qdwconv_kernelsize.cpp | 43 +++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 0a0d490cbc..2ff1385a89 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -4741,3 +4741,39 @@ has been taken from other projects or from the open internet. Every line of code can be traced back to its original author, and all of those authors have public domain dedications on file. So the SQLite code base is clean and is uncontaminated with licensed code from other projects. + +_____ + +google/XNNPACK + +BSD License + +For XNNPACK software + +Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. +Copyright 2019 Google LLC + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/cgmanifests/cgmanifest.json b/cgmanifests/cgmanifest.json index ea66f0fbf1..479516e0e4 100644 --- a/cgmanifests/cgmanifest.json +++ b/cgmanifests/cgmanifest.json @@ -493,6 +493,16 @@ "DownloadUrl": "http://security.ubuntu.com/ubuntu/pool/main/s/sqlite3/libsqlite3-dev_3.22.0-1ubuntu0.4_amd64.deb" } } + }, + { + "component": { + "type": "git", + "git": { + "commitHash": "512d44b9aa22690fd7d7e665fcab9bdcb590f118", + "repositoryUrl": "https://github.com/google/XNNPACK.git" + }, + "comments": "xnnpack" + } } ], "Version": 1 diff --git a/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp b/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp index 32a7fcec91..ce53eb3cd4 100644 --- a/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp +++ b/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp @@ -1,3 +1,46 @@ +/*Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. +Copyright 2019 Google LLC + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +==============================================================================*/ +/* Modifications Copyright (c) Microsoft. */ + + +/*++ +Module Name: + + qdwconv_kernelsize.cpp + +Abstract: + + This module implements kernel of the quantized integer depthwise convolution with kernalsize 25. + +--*/ + #include "mlasi.h" #if defined(MLAS_TARGET_ARM64) From 051d0059261c2fca619faf975aca238ef95c6670 Mon Sep 17 00:00:00 2001 From: Nick Kreeger Date: Wed, 8 Dec 2021 16:43:46 -0600 Subject: [PATCH 010/113] Fix build warnings with VS 2022 (#9967) --- onnxruntime/core/common/helper.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/onnxruntime/core/common/helper.cc b/onnxruntime/core/common/helper.cc index 08aaff423f..0c803465f2 100644 --- a/onnxruntime/core/common/helper.cc +++ b/onnxruntime/core/common/helper.cc @@ -26,8 +26,10 @@ std::string ToMBString(const std::wstring& s) { const int len = WideCharToMultiByte(CP_ACP, 0, s.data(), src_len, nullptr, 0, nullptr, nullptr); assert(len > 0); std::string ret(static_cast(len) - 1, '\0'); +#pragma warning(disable: 4189) const int r = WideCharToMultiByte(CP_ACP, 0, s.data(), src_len, (char*)ret.data(), len, nullptr, nullptr); assert(len == r); +#pragma warning(default: 4189) return ret; } @@ -39,8 +41,10 @@ std::wstring ToWideString(const std::string& s) { const int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), src_len, nullptr, 0); assert(len > 0); std::wstring ret(static_cast(len) - 1, '\0'); +#pragma warning(disable: 4189) const int r = MultiByteToWideChar(CP_UTF8, 0, s.data(), src_len, (wchar_t*)ret.data(), len); assert(len == r); +#pragma warning(default: 4189) return ret; } #endif //#ifdef _WIN32 From cd552e1bdad6bb57da0acb13d76dc7ecb4d0be20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Fri, 29 Oct 2021 15:19:13 +0200 Subject: [PATCH 011/113] Add build.py option for disabling memleak checker The memleak checker used by default in Debug configuration does not play nice with embedding static lib of ONNXRuntime into binaries, because other code will not be using the same debug heap, leading to trouble. This makes it easier for outside builders to disable it for their build. --- tools/ci_build/build.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index acbeb54aaa..8ef9038e19 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -341,6 +341,9 @@ def parse_arguments(): help="Specify the minimum version of the target platform " "(e.g. macOS or iOS)" "This is only supported on MacOS") + parser.add_argument( + "--disable_memleak_checker", action='store_true', + help="Disable memory leak checker from Windows build") # WebAssembly build parser.add_argument("--build_wasm", action='store_true', help="Build for WebAssembly") @@ -1120,7 +1123,8 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home "-Donnxruntime_ENABLE_MEMLEAK_CHECKER=" + ("ON" if config.lower() == 'debug' and not args.use_nuphar and not args.use_openvino and not - args.enable_msvc_static_runtime + args.enable_msvc_static_runtime and not + args.disable_memleak_checker else "OFF"), "-DCMAKE_BUILD_TYPE={}".format(config)], cwd=config_build_dir) From bc0f2d173ace7be561c4b828f93fa55574205302 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Wed, 8 Dec 2021 18:13:13 -0800 Subject: [PATCH 012/113] enable s8s8 QDQ fusion on ARM (#9961) * enable s8s8 QDQ fusion on ARM devices --- .../contrib_ops/cpu/cpu_contrib_kernels.cc | 9 +- .../quantization/dynamic_quantize_matmul.cc | 24 +- .../core/optimizer/graph_transformer_utils.cc | 4 +- .../qdq_selector_action_transformer.cc | 26 +- .../qdq_selector_action_transformer.h | 11 + .../selectors_actions/qdq_selectors.cc | 38 ++- .../selectors_actions/qdq_selectors.h | 9 + .../providers/cpu/cpu_execution_provider.cc | 11 +- .../core/providers/cpu/math/matmul_integer.cc | 19 +- .../matmul_integer_to_float_test.cc | 77 +++-- .../test/optimizer/qdq_transformer_test.cc | 307 +++++++++++------- .../providers/cpu/math/matmul_integer_test.cc | 181 +++++++++++ .../kernel_def_hashes/arm_ops.cpu.json | 8 + .../test/testdata/matmul_integer_to_float.py | 21 +- .../matmul_integer_to_float_int8.onnx | 4 +- .../matmul_integer_to_float_int8_bias.onnx | 4 +- .../matmul_integer_to_float_uint8.onnx | 4 +- .../matmul_integer_to_float_uint8_bias.onnx | 4 +- 18 files changed, 555 insertions(+), 206 deletions(-) diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc index 93e0424701..d65e23c7ac 100644 --- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc @@ -79,17 +79,15 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t, QLinearMul); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, QAttention); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, DynamicQuantizeMatMul); -class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, MatMulIntegerToFloat); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, DynamicQuantizeLSTM); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, MatMulIntegerToFloat); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, QLinearConv); #if defined(MLAS_TARGET_ARM_ANY) +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t, MatMulIntegerToFloat); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t_int8_t, QLinearConv); #endif class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t, NhwcMaxPool); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, NhwcMaxPool); -#if defined(MLAS_TARGET_ARM_ANY) -class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t_int8_t, QLinearConv); -#endif class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, QEmbedLayerNormalization); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, QGemm); // ******** End: Quantization ******************* // @@ -174,10 +172,11 @@ Status RegisterQuantizationKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, #if defined(MLAS_TARGET_ARM_ANY) + BuildKernelCreateInfo, BuildKernelCreateInfo, #endif BuildKernelCreateInfo, diff --git a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc index 28fdec63ea..7168cb8663 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "core/common/safeint.h" +#include "core/mlas/inc/mlas.h" #include "core/providers/cpu/math/element_wise_ops.h" #include "core/providers/cpu/math/matmul_helper.h" #include "core/providers/cpu/math/matmul_integer_base.h" @@ -48,6 +49,7 @@ class MatMulIntegerToFloatBase : public MatMulIntegerBase { const TensorShape& a_shape, float a_scale, uint8_t a_zp, + bool a_is_signed, const Tensor* b_tensor, const Tensor* b_scale, const Tensor* b_zp, @@ -59,6 +61,7 @@ Status MatMulIntegerToFloatBase::ComputeCommon(OpKernelContext* ctx, const TensorShape& a_shape, float a_scale, uint8_t a_zp, + bool a_is_signed, const Tensor* b_tensor, const Tensor* b_scale_tensor, const Tensor* b_zp_tensor, @@ -117,6 +120,7 @@ Status MatMulIntegerToFloatBase::ComputeCommon(OpKernelContext* ctx, gemm_shape.M = static_cast(helper.M()); gemm_shape.N = static_cast(helper.N()); gemm_shape.K = static_cast(helper.K()); + gemm_shape.AIsSigned = a_is_signed; gemm_shape.BIsSigned = b_tensor ? b_tensor->IsDataType() : b_is_signed_; const size_t num_gemms = helper.OutputOffsets().size(); @@ -222,6 +226,7 @@ Status DynamicQuantizeMatMul::Compute(OpKernelContext* ctx) const { a->Shape(), a_scale, a_zero_point, + false /*a_is_signed*/, b, is_b_scale_supported ? b_scale_tensor : nullptr, b_zp_tensor, @@ -266,16 +271,17 @@ Status MatMulIntegerToFloat::Compute(OpKernelContext* ctx) const { if (a_zero_point_tensor != nullptr) { ORT_ENFORCE(IsScalarOr1ElementVector(a_zero_point_tensor), "MatMulIntegerToFloat : input a zero point must be a scalar or 1D tensor of size 1. Per-Channel is not supported yet."); - a_zero_point = *a_zero_point_tensor->Data(); + a_zero_point = *(static_cast(a_zero_point_tensor->DataRaw())); } const Tensor* b_zp_tensor = ctx->Input(IN_B_ZERO_POINT); ORT_RETURN_IF_ERROR(ComputeCommon( ctx, - a->Data(), + static_cast(a->DataRaw()), a->Shape(), is_a_scale_scalar ? *a_scale_tensor->template Data() : 1.f, a_zero_point, + a->IsDataType(), b, is_b_scale_supported ? b_scale_tensor : nullptr, b_zp_tensor, @@ -314,5 +320,19 @@ ONNX_OPERATOR_TYPED_KERNEL_EX( .TypeConstraint("T3", DataTypeImpl::GetTensorType()), MatMulIntegerToFloat); +#if defined(MLAS_TARGET_ARM_ANY) +ONNX_OPERATOR_TYPED_KERNEL_EX( + MatMulIntegerToFloat, + kMSDomain, + 1, + int8_t, + kCpuExecutionProvider, + KernelDefBuilder() + .TypeConstraint("T1", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", DataTypeImpl::GetTensorType()) + .TypeConstraint("T3", DataTypeImpl::GetTensorType()), + MatMulIntegerToFloat); +#endif + } // namespace contrib } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/graph_transformer_utils.cc b/onnxruntime/core/optimizer/graph_transformer_utils.cc index 8c63b595c2..f3f5500f8f 100644 --- a/onnxruntime/core/optimizer/graph_transformer_utils.cc +++ b/onnxruntime/core/optimizer/graph_transformer_utils.cc @@ -193,7 +193,9 @@ std::vector> GenerateTransformers( onnxruntime::kArmNNExecutionProvider}; if (!disable_quant_qdq) { - transformers.emplace_back(std::make_unique(cpu_ep)); + if (!QDQIsInt8Allowed()) { + transformers.emplace_back(std::make_unique(cpu_ep)); + } transformers.emplace_back(std::make_unique(cpu_ep)); transformers.emplace_back(std::make_unique()); } diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc index 1c23855ffb..fb1c49e312 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" +#include "core/mlas/inc/mlas.h" #include "core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h" #if !defined(ORT_MINIMAL_BUILD) @@ -44,19 +45,20 @@ void DropQDQNodesRules(SelectorsAndActions& qdq_selectors_and_actions) { #endif } -void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { // 3 nodes. DQ, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"1DQ"}; std::unique_ptr action(new QDQ::UnaryReplaceWithQLinear(kMSDomain)); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::UnarySelector()); + std::unique_ptr selector(new QDQ::UnarySelector(is_int8_allowed)); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"AveragePool", {}}}, std::move(selector), std::move(action)); #else + ORT_UNUSED_PARAMETER(is_int8_allowed); qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); #endif } @@ -99,7 +101,7 @@ void VariadicOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { #endif } -void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { // 4 or 5 Nodes. 0=DQ X, 1=DQ W, 2=DQ B (optional), 3=Conv, 4=Q // Handle the DQ input for the Bias being optional. // Replace Conv with QLinearConv @@ -108,7 +110,7 @@ void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { std::unique_ptr action(new QDQ::ConvReplaceWithQLinear()); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::ConvSelector()); + std::unique_ptr selector(new QDQ::ConvSelector(is_int8_allowed)); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"Conv", {}}}, @@ -116,11 +118,12 @@ void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { std::move(action)); #else + ORT_UNUSED_PARAMETER(is_int8_allowed); qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); #endif } -void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { // 3 or 4 nodes. 2 x DQ for inputs, target, optional Q // Replace with QLinearMatMul if Q found, or MatMulIntegerToFloat if not. // Delete all original nodes. @@ -129,26 +132,27 @@ void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { std::unique_ptr action(new QDQ::MatMulReplaceWithQLinear()); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::MatMulSelector()); + std::unique_ptr selector(new QDQ::MatMulSelector(is_int8_allowed)); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"MatMul", {}}}, std::move(selector), std::move(action)); #else + ORT_UNUSED_PARAMETER(is_int8_allowed); qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); #endif } -SelectorsAndActions CreateSelectorsAndActions() { +SelectorsAndActions CreateSelectorsAndActions(bool is_int8_allowed) { SelectorsAndActions qdq_selectors_and_actions; DropQDQNodesRules(qdq_selectors_and_actions); - UnaryOpQDQRules(qdq_selectors_and_actions); + UnaryOpQDQRules(qdq_selectors_and_actions, is_int8_allowed); BinaryOpQDQRules(qdq_selectors_and_actions); VariadicOpQDQRules(qdq_selectors_and_actions); - ConvQDQRules(qdq_selectors_and_actions); - MatMulQDQRules(qdq_selectors_and_actions); + ConvQDQRules(qdq_selectors_and_actions, is_int8_allowed); + MatMulQDQRules(qdq_selectors_and_actions, is_int8_allowed); return qdq_selectors_and_actions; } @@ -158,7 +162,7 @@ SelectorsAndActions CreateSelectorsAndActions() { QDQSelectorActionTransformer::QDQSelectorActionTransformer(std::optional save_context) : SelectorActionTransformer{ "QDQSelectorActionTransformer", - CreateSelectorsAndActions(), + CreateSelectorsAndActions(QDQIsInt8Allowed()), std::move(save_context)} { } diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h index 3ac91cb470..1ddd4fe560 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h @@ -4,8 +4,19 @@ #pragma once #include "core/optimizer/selectors_actions/selector_action_transformer.h" +#include "core/mlas/inc/mlas.h" namespace onnxruntime { + +inline constexpr bool QDQIsInt8Allowed(){ +#if !defined(MLAS_TARGET_ARM_ANY) + return false; +#else + return true; +#endif +} + + /** Transformer that fuses QDQ and fp32 ops into quantized ops. */ diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc index 4e4eaada8b..ef5ca43840 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc @@ -114,10 +114,8 @@ bool UnarySelector::Check(const GraphViewer& graph_viewer, const Node& node, int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - return ((dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8 || - (int8_allowed_ && dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8))) && - ((dt_output == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8 || - (int8_allowed_ && dt_output == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8))); + return dt_input == dt_output && + (int8_allowed_ || dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8); } bool BinarySelector::Check(const GraphViewer& graph_viewer, @@ -128,7 +126,6 @@ bool BinarySelector::Check(const GraphViewer& graph_viewer, return false; } - // Currently QLinearAdd and QLinearMul only support activation type uint8_t int32_t dt_input_1 = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_input_2 = dq_nodes[1]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); @@ -168,14 +165,20 @@ bool ConvSelector::Check(const GraphViewer& graph_viewer, return false; } - // Currently QLinearConv only support activation type uint8_t and output type uint8_t + // input and output types need to be same int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); + int32_t dt_weight = dq_nodes[1]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - if (dt_input != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8 || - dt_output != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8) { + if (dt_input != dt_output) { return false; } + if(dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { + if(!int8_allowed_ || dt_weight != dt_input) { + return false; + } + } + if (dq_nodes.size() < 3) { // no bias return true; } @@ -196,6 +199,15 @@ bool MatMulSelector::Check(const GraphViewer& graph_viewer, return false; } + int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); + int32_t dt_weight = dq_nodes[1]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); + + if(dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { + if(!int8_allowed_ || dt_weight != dt_input) { + return false; + } + } + // potential match for QLinearMatMul or MatMulIntegerToFloat bool qlinear = !q_nodes.empty(); @@ -206,16 +218,10 @@ bool MatMulSelector::Check(const GraphViewer& graph_viewer, } int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - if (dt_output != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8) { - return false; - } - } else { - // MatMulIntegerToFloat has no Q node, so no call to CheckQDQNodes + return dt_input == dt_output; } - // Currently Quant MatMul only support activation type uint8_t - int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - return (dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8); + return true; } } // namespace QDQ diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h index 7099288423..83b8b41b52 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h @@ -95,19 +95,28 @@ class VariadicSelector : public BaseSelector { // DQ nodes for X, W and optionally B -> node -> Q class ConvSelector : public BaseSelector { public: + ConvSelector(bool int8_allowed = false) : int8_allowed_(int8_allowed) {} + void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const override; private: bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; + + bool int8_allowed_; }; // 2 DQ nodes for input -> node -> optional Q if QLinearMatMul, MatMulIntegerToFloat if not class MatMulSelector : public BaseSelector { + public: + MatMulSelector(bool int8_allowed = false) : int8_allowed_(int8_allowed) {} + + private: bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; + bool int8_allowed_; }; } // namespace QDQ } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index d865a06578..44a34f06f1 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -316,10 +316,11 @@ class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOn class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 12, uint8_t, QuantizeLinear); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 12, int8_t, QuantizeLinear); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, QLinearMatMul); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, uint8_t, MatMulInteger); #if defined(MLAS_TARGET_ARM_ANY) class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int8_t_int8_t, QLinearMatMul); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int8_t, MatMulInteger); #endif -class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, uint8_t, MatMulInteger); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, ConvInteger); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, QLinearConv); #if defined(MLAS_TARGET_ARM_ANY) @@ -1218,11 +1219,13 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, -#if defined(MLAS_TARGET_ARM_ANY) - BuildKernelCreateInfo, -#endif BuildKernelCreateInfo, +#if defined(MLAS_TARGET_ARM_ANY) + BuildKernelCreateInfo, + BuildKernelCreateInfo, +#endif BuildKernelCreateInfo, BuildKernelCreateInfo, #if defined(MLAS_TARGET_ARM_ANY) diff --git a/onnxruntime/core/providers/cpu/math/matmul_integer.cc b/onnxruntime/core/providers/cpu/math/matmul_integer.cc index 242b90d952..8eb935f1a7 100644 --- a/onnxruntime/core/providers/cpu/math/matmul_integer.cc +++ b/onnxruntime/core/providers/cpu/math/matmul_integer.cc @@ -40,6 +40,20 @@ ONNX_OPERATOR_TYPED_KERNEL_EX( .TypeConstraint("T3", DataTypeImpl::GetTensorType()), MatMulInteger); +#if defined(MLAS_TARGET_ARM_ANY) +ONNX_OPERATOR_TYPED_KERNEL_EX( + MatMulInteger, + kOnnxDomain, + 10, + int8_t, + kCpuExecutionProvider, + KernelDefBuilder() + .TypeConstraint("T1", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", DataTypeImpl::GetTensorType()) + .TypeConstraint("T3", DataTypeImpl::GetTensorType()), + MatMulInteger); +#endif + Status MatMulInteger::Compute(OpKernelContext* ctx) const { const auto* a = ctx->Input(IN_A); const auto* b = packed_b_ ? nullptr : ctx->Input(IN_B); @@ -50,7 +64,7 @@ Status MatMulInteger::Compute(OpKernelContext* ctx) const { if (a_zero_point != nullptr) { ORT_ENFORCE(IsScalarOr1ElementVector(a_zero_point), "MatmulInteger : input1 zero point must be a scalar or 1D tensor of size 1"); - a_offset = *a_zero_point->template Data(); + a_offset = *(static_cast(a_zero_point->DataRaw())); } bool is_b_zp_per_column = false; @@ -82,13 +96,14 @@ Status MatMulInteger::Compute(OpKernelContext* ctx) const { if (y->Shape().Size() == 0) return Status::OK(); - const auto* a_data = a->template Data(); + const uint8_t* a_data = static_cast(a->DataRaw()); auto* y_data = y->template MutableData(); MLAS_GEMM_QUANT_SHAPE_PARAMS gemm_shape; gemm_shape.M = static_cast(helper.M()); gemm_shape.N = static_cast(helper.N()); gemm_shape.K = static_cast(helper.K()); + gemm_shape.AIsSigned = a->IsDataType(); gemm_shape.BIsSigned = b_is_signed; const size_t batch_size = helper.OutputOffsets().size(); diff --git a/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc b/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc index a84c5fa77e..19e3d8d765 100644 --- a/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc +++ b/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "core/framework/tensor.h" +#include "core/mlas/inc/mlas.h" #include "core/session/inference_session.h" #include "test/common/tensor_op_test_utils.h" #include "test/framework/test_utils.h" @@ -21,7 +22,7 @@ using namespace std; namespace onnxruntime { namespace test { -template +template void TestMatMulIntegerToFloat(const std::vector& A_dims, std::vector B_dims, const std::string& reference_model, @@ -32,45 +33,51 @@ void TestMatMulIntegerToFloat(const std::vector& A_dims, // create rand inputs RandomValueGenerator random{}; - std::vector A_data; - std::vector tmp_A_data = random.Uniform(A_dims, 0, 255); - std::transform(tmp_A_data.begin(), tmp_A_data.end(), std::back_inserter(A_data), [](int32_t v) -> T { - return static_cast(v); + std::vector A_data; + std::vector tmp_A_data = random.Uniform(A_dims, + std::numeric_limits::lowest(), + std::numeric_limits::max()); + std::transform(tmp_A_data.begin(), tmp_A_data.end(), std::back_inserter(A_data), [](int32_t v) -> WType { + return static_cast(v); }); - std::vector B_data; - std::vector tmp_B_data = random.Uniform(B_dims, std::numeric_limits::min(), std::numeric_limits::max()); - std::transform(tmp_B_data.begin(), tmp_B_data.end(), std::back_inserter(B_data), [](int32_t v) -> T { - return static_cast(v); + std::vector B_data; + std::vector tmp_B_data = random.Uniform(B_dims, + std::numeric_limits::lowest(), + std::numeric_limits::max()); + std::transform(tmp_B_data.begin(), tmp_B_data.end(), std::back_inserter(B_data), [](int32_t v) -> WType { + return static_cast(v); }); std::vector A_scale = random.Uniform(std::array{1}, -0.1f, 0.1f); - std::vector A_zero_point{127}; + std::vector A_zero_point{(std::numeric_limits::lowest() + std::numeric_limits::max() + IType(2)) / 2}; int64_t b_scale_zp_size = per_column ? B_dims.back() : 1; std::vector B_scale = random.Uniform({b_scale_zp_size}, -0.1f, 0.1f); - std::vector B_zero_point(b_scale_zp_size); + std::vector B_zero_point(b_scale_zp_size); std::for_each(B_zero_point.begin(), B_zero_point.end(), - [&random](T& zp) { - zp = static_cast(random.Uniform(std::array{1}, std::numeric_limits::min(), std::numeric_limits::max())[0]); + [&random](WType& zp) { + zp = static_cast(random.Uniform(std::array{1}, + std::numeric_limits::lowest(), + std::numeric_limits::max())[0]); }); std::vector Bias = random.Uniform({B_dims.back()}, -0.1f, 0.1f); OpTester test("MatMulIntegerToFloat", 1, onnxruntime::kMSDomain); - test.AddInput("A", A_dims, A_data); - test.AddInput("B", B_dims, B_data, is_matrix_b_constant); + test.AddInput("A", A_dims, A_data); + test.AddInput("B", B_dims, B_data, is_matrix_b_constant); test.AddInput("a_scale", {1}, A_scale); test.AddInput("b_scale", {b_scale_zp_size}, B_scale); if (has_zp) { - test.AddInput("a_zero_point", {1}, A_zero_point); - test.AddInput("b_zero_point", {b_scale_zp_size}, B_zero_point); + test.AddInput("a_zero_point", {1}, A_zero_point); + test.AddInput("b_zero_point", {b_scale_zp_size}, B_zero_point); } else { - test.AddOptionalInputEdge(); - test.AddOptionalInputEdge(); + test.AddOptionalInputEdge(); + test.AddOptionalInputEdge(); } if (has_bias) { @@ -84,13 +91,13 @@ void TestMatMulIntegerToFloat(const std::vector& A_dims, test.Run(); } -template +template void RunMatMulIntegerToFloatTest(const string& model_path) { std::vector A_dims{4, 128}; std::vector B_dims{128, 128}; std::vector Y_dims{4, 128}; - TestMatMulIntegerToFloat(A_dims, + TestMatMulIntegerToFloat(A_dims, B_dims, model_path, false, /*is_matrix_b_constant*/ @@ -99,7 +106,7 @@ void RunMatMulIntegerToFloatTest(const string& model_path) { HasBias /*has_bias*/ ); - TestMatMulIntegerToFloat(A_dims, + TestMatMulIntegerToFloat(A_dims, B_dims, model_path, true, /*is_matrix_b_constant*/ @@ -108,7 +115,7 @@ void RunMatMulIntegerToFloatTest(const string& model_path) { HasBias /*has_bias*/ ); - TestMatMulIntegerToFloat(A_dims, + TestMatMulIntegerToFloat(A_dims, B_dims, model_path, false, /*is_matrix_b_constant*/ @@ -117,7 +124,7 @@ void RunMatMulIntegerToFloatTest(const string& model_path) { HasBias /*has_bias*/ ); - TestMatMulIntegerToFloat(A_dims, + TestMatMulIntegerToFloat(A_dims, B_dims, model_path, true, /*is_matrix_b_constant*/ @@ -127,16 +134,26 @@ void RunMatMulIntegerToFloatTest(const string& model_path) { ); } -TEST(MatMulIntegerToFloat, HasZeroPoint_NoBias_test) { - RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8.onnx"); - RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_uint8.onnx"); +TEST(MatMulIntegerToFloat, HasZeroPoint_NoBias_test_U8X8) { + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8.onnx"); + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_uint8.onnx"); } -TEST(MatMulIntegerToFloat, NoZeroPoint_HasBias_test) { - RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_bias.onnx"); - RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_uint8_bias.onnx"); +TEST(MatMulIntegerToFloat, NoZeroPoint_HasBias_test_U8X8) { + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_bias.onnx"); + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_uint8_bias.onnx"); } +#if defined(MLAS_TARGET_ARM_ANY) +TEST(MatMulIntegerToFloat, HasZeroPoint_NoBias_test_S8S8) { + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_int8.onnx"); +} + +TEST(MatMulIntegerToFloat, NoZeroPoint_HasBias_test_S8S8) { + RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_int8_bias.onnx"); +} +#endif + TEST(MatMulIntegerToFloat, MatMulInteger_Nuphar) { auto test_case = [&](const std::vector& input_shape, const std::vector& weights_shape, diff --git a/onnxruntime/test/optimizer/qdq_transformer_test.cc b/onnxruntime/test/optimizer/qdq_transformer_test.cc index 6ac7f3c327..9b2bf8eacc 100644 --- a/onnxruntime/test/optimizer/qdq_transformer_test.cc +++ b/onnxruntime/test/optimizer/qdq_transformer_test.cc @@ -99,9 +99,10 @@ void QDQTransformerConvTests() { auto check_conv_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); - if (std::is_same::value && - std::is_same::value && - std::is_same::value) { + if (std::is_same::value && + std::is_same::value && + (std::is_same::value || + QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["QLinearConv"], 1); EXPECT_EQ(op_to_count["QuantizeLinear"], 1); EXPECT_EQ(op_to_count["DequantizeLinear"], 1); @@ -131,25 +132,33 @@ void QDQTransformerConvTests() { test_case({1, 22, 11, 13, 15}, {30, 22, 5, 3, 3}); } -TEST(QDQTransformerTests, Conv) { +TEST(QDQTransformerTests, Conv_U8X8U8) { QDQTransformerConvTests(); QDQTransformerConvTests(); +} +TEST(QDQTransformerTests, Conv_U8X8U8_Bias_Not_i32) { // bias not int32_t QDQTransformerConvTests(); QDQTransformerConvTests(); +} +TEST(QDQTransformerTests, Conv_U8X8S8) { // output not uint8_t QDQTransformerConvTests(); QDQTransformerConvTests(); +} +TEST(QDQTransformerTests, Conv_S8X8U8) { // input not uint8_t QDQTransformerConvTests(); QDQTransformerConvTests(); +} +TEST(QDQTransformerTests, Conv_S8X8S8) { // input not uint8_t and output not uint8_t QDQTransformerConvTests(); - QDQTransformerConvTests(); + QDQTransformerConvTests(); } TEST(QDQTransformerTests, ConvMaxPoolReshape_UInt8) { @@ -214,13 +223,13 @@ TEST(QDQTransformerTests, ConvMaxPoolReshape_Int8) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add QDQ + Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); auto* dq_conv_output = AddQDQNodePair(builder, input_arg, .004f, 1); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(dq_conv_output, dq_w_output, conv_output); // add QDQ + MaxPool @@ -239,7 +248,11 @@ TEST(QDQTransformerTests, ConvMaxPoolReshape_Int8) { builder.AddNode("Reshape", {dq_reshape_output, reshape_shape}, {reshape_output}); // add Q - builder.AddQuantizeLinearNode(reshape_output, .0039f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(reshape_output, .0039f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(reshape_output, .0039f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -289,7 +302,7 @@ void QDQTransformerAveragePoolTests() { auto check_binary_op_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); if (std::is_same::value && - std::is_same::value) { + (QDQIsInt8Allowed() || std::is_same::value)) { EXPECT_EQ(op_to_count["com.microsoft.QLinearAveragePool"], 1); EXPECT_EQ(op_to_count["AveragePool"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 1); @@ -317,15 +330,24 @@ void QDQTransformerAveragePoolTests() { test_case({1, 22, 11, 13, 15}); } -TEST(QDQTransformerTests, AveragePool) { - QDQTransformerAveragePoolTests(); - QDQTransformerAveragePoolTests(); - QDQTransformerAveragePoolTests(); +TEST(QDQTransformerTests, AveragePool_S8S8) { QDQTransformerAveragePoolTests(); } +TEST(QDQTransformerTests, AveragePool_U8U8) { + QDQTransformerAveragePoolTests(); +} + +TEST(QDQTransformerTests, AveragePool_S8U8) { + QDQTransformerAveragePoolTests(); +} + +TEST(QDQTransformerTests, AveragePool_U8S8) { + QDQTransformerAveragePoolTests(); +} + template -void QDQTransformerBinaryOpTests(const std::string& op_type, bool does_input1_support_int8 = true) { +void QDQTransformerBinaryOpTests(const std::string& op_type) { auto test_case = [&](const std::vector& input_shape) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input1_arg = builder.MakeInput(input_shape, -1.f, 1.f); @@ -375,8 +397,7 @@ void QDQTransformerBinaryOpTests(const std::string& op_type, bool does_input1_su auto check_binary_op_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); if (std::is_same::value && - std::is_same::value && - (does_input1_support_int8 || std::is_same::value)) { + std::is_same::value) { EXPECT_EQ(op_to_count["com.microsoft.QLinear" + op_type], 1); EXPECT_EQ(op_to_count[op_type], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 2); @@ -492,7 +513,8 @@ void QDQTransformerMatMulTests(bool has_output_q) { auto op_to_count = CountOpsInGraph(session.GetGraph()); if (has_output_q) { if (std::is_same::value && - std::is_same::value) { + (std::is_same::value || + QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["QLinearMatMul"], 1); EXPECT_EQ(op_to_count["MatMul"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 2); @@ -504,7 +526,8 @@ void QDQTransformerMatMulTests(bool has_output_q) { EXPECT_EQ(op_to_count["DequantizeLinear"], 3); } } else { - if (std::is_same::value) { + if (std::is_same::value || + (QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["com.microsoft.MatMulIntegerToFloat"], 1); EXPECT_EQ(op_to_count["MatMul"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 2); @@ -533,26 +556,43 @@ void QDQTransformerMatMulTests(bool has_output_q) { test_case({1, 22, 11, 13, 15}, {1, 22, 11, 15, 15}); } -TEST(QDQTransformerTests, MatMul) { +TEST(QDQTransformerTests, MatMul_U8U8U8) { QDQTransformerMatMulTests(false); QDQTransformerMatMulTests(true); +} + +TEST(QDQTransformerTests, MatMul_U8S8S8) { + QDQTransformerMatMulTests(false); + QDQTransformerMatMulTests(true); +} + +TEST(QDQTransformerTests, MatMul_U8U8S8) { + QDQTransformerMatMulTests(false); + QDQTransformerMatMulTests(true); +} + +TEST(QDQTransformerTests, MatMul_U8S8U8) { + QDQTransformerMatMulTests(false); + QDQTransformerMatMulTests(true); +} + +TEST(QDQTransformerTests, MatMul_S8S8S8) { QDQTransformerMatMulTests(false); QDQTransformerMatMulTests(true); } -TEST(QDQTransformerTests, MatMul_Have_Different_Types) { - QDQTransformerMatMulTests(false); - QDQTransformerMatMulTests(false); - QDQTransformerMatMulTests(false); - QDQTransformerMatMulTests(false); - QDQTransformerMatMulTests(false); - QDQTransformerMatMulTests(false); +TEST(QDQTransformerTests, MatMul_S8U8U8) { + QDQTransformerMatMulTests(false); + QDQTransformerMatMulTests(true); +} - QDQTransformerMatMulTests(true); - QDQTransformerMatMulTests(true); - QDQTransformerMatMulTests(true); - QDQTransformerMatMulTests(true); +TEST(QDQTransformerTests, MatMul_S8U8S8) { + QDQTransformerMatMulTests(false); QDQTransformerMatMulTests(true); +} + +TEST(QDQTransformerTests, MatMul_S8S8U8) { + QDQTransformerMatMulTests(false); QDQTransformerMatMulTests(true); } @@ -1035,13 +1075,13 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add QDQ + Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); auto* dq_conv_output = AddQDQNodePair(builder, input_arg, .004f, 1); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(dq_conv_output, dq_w_output, conv_output); // add QDQ + AveragePool @@ -1061,8 +1101,13 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8) { // add Q auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1120,8 +1165,14 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8_Fail) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if(QDQIsInt8Allowed()){ + builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } + }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1153,13 +1204,13 @@ TEST(QDQTransformerTests, ConvTranspose_QBackward) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add QDQ + Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); auto* dq_conv_output = AddQDQNodePair(builder, input_arg, .004f, 1); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(dq_conv_output, dq_w_output, conv_output); // add Transpose @@ -1169,8 +1220,13 @@ TEST(QDQTransformerTests, ConvTranspose_QBackward) { // add Q auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(transpose_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(transpose_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(transpose_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1195,13 +1251,13 @@ TEST(QDQTransformerTests, QBackward_MutilpleSteps) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add QDQ + Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); auto* dq_conv_output = AddQDQNodePair(builder, input_arg, .004f, 1); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(dq_conv_output, dq_w_output, conv_output); // add MaxPool @@ -1224,8 +1280,13 @@ TEST(QDQTransformerTests, QBackward_MutilpleSteps) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(transpose_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(transpose_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(transpose_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1252,7 +1313,7 @@ TEST(QDQTransformerTests, ConvTranspose_DQForward) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add QDQ auto* dq_output = AddQDQNodePair(builder, input_arg, .004f, 1); @@ -1265,13 +1326,18 @@ TEST(QDQTransformerTests, ConvTranspose_DQForward) { // add Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(transpose_output, dq_w_output, conv_output); // add Q auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(conv_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(conv_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(conv_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1296,7 +1362,7 @@ TEST(QDQTransformerTests, DQForward_MutilpleSteps) { auto build_test_case = [&](ModelTestBuilder& builder) { auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); auto* output_arg = builder.MakeOutput(); - auto* weight = builder.MakeInitializer(weights_shape, 0, 255); + auto* weight = builder.MakeInitializer(weights_shape, -64, 64); // add Transpose auto* qdq_output = AddQDQNodePair(builder, input_arg, .004f, 1); @@ -1315,7 +1381,7 @@ TEST(QDQTransformerTests, DQForward_MutilpleSteps) { // add Conv auto* dq_w_output = builder.MakeIntermediate(); auto* conv_output = builder.MakeIntermediate(); - builder.AddDequantizeLinearNode(weight, .003f, 118, dq_w_output); + builder.AddDequantizeLinearNode(weight, .003f, -10, dq_w_output); builder.AddConvNode(maxpool_output, dq_w_output, conv_output); // Reshape @@ -1325,8 +1391,13 @@ TEST(QDQTransformerTests, DQForward_MutilpleSteps) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); - builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + if (QDQIsInt8Allowed()) { + builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); + } else { + builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); + builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); + } }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1348,6 +1419,72 @@ TEST(QDQTransformerTests, DQForward_MutilpleSteps) { test_case({1, 13, 13, 23}, {30, 23, 3, 3}, {0, 3, 1, 2}); } +TEST(QDQTransformerTests, Concat) { + auto test_case = [&](const std::vector>& input_shapes, + int64_t axis, + bool has_input_float = false, + bool has_input_int8 = false, + bool has_output_int8 = false) { + auto build_test_case = [&](ModelTestBuilder& builder) { + auto input_count = input_shapes.size(); + std::vector input_args; + std::vector q_input_args; + for (size_t i = 0; i < input_count; i++) { + input_args.push_back(builder.MakeInput(input_shapes[i], -1.f, 1.f)); + if (i == 0 && has_input_float) { + q_input_args.push_back(input_args.back()); + } else if (i == 0 && has_input_int8) { + q_input_args.push_back(AddQDQNodePair(builder, input_args.back(), 0.05f, 1)); + } else { + q_input_args.push_back(AddQDQNodePair(builder, input_args.back(), 0.05f, 128)); + } + } + auto* concat_output = builder.MakeIntermediate(); + Node& concat_node = builder.AddNode("Concat", q_input_args, {concat_output}); + concat_node.AddAttribute("axis", axis); + + auto* q_concat_output = builder.MakeIntermediate(); + if (has_output_int8) { + builder.AddQuantizeLinearNode(concat_output, 0.05f, 1, q_concat_output); + + auto* output_arg = builder.MakeOutput(); + builder.AddDequantizeLinearNode(q_concat_output, 0.05f, 1, output_arg); + } else { + builder.AddQuantizeLinearNode(concat_output, 0.05f, 128, q_concat_output); + + auto* output_arg = builder.MakeOutput(); + builder.AddDequantizeLinearNode(q_concat_output, 0.05f, 128, output_arg); + } + }; + + auto check_mp_reshape_graph = [&input_shapes, &has_input_float, &has_input_int8, &has_output_int8](InferenceSessionWrapper& session) { + auto op_to_count = CountOpsInGraph(session.GetGraph()); + if (has_input_float || has_input_int8 || has_output_int8) { + EXPECT_EQ(op_to_count["com.microsoft.QLinearConcat"], 0); + } else { + EXPECT_EQ(op_to_count["QuantizeLinear"], static_cast(input_shapes.size())); + EXPECT_EQ(op_to_count["com.microsoft.QLinearConcat"], 1); + EXPECT_EQ(op_to_count["DequantizeLinear"], 1); + } + }; + + TransformerTester(build_test_case, + check_mp_reshape_graph, + TransformerLevel::Level1, + TransformerLevel::Level2, + 12 /*opset_version*/, + 0.01f /*per_sample_tolerance*/, + 0.01f /*relative_per_sample_tolerance*/, + std::make_unique()); + }; + + test_case({{1, 6, 36}, {1, 3, 36}}, 1); + test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2); + test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, true); + test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, false, true); + test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, false, false, true); +} + TEST(QDQTransformerTests, QDQPropagation_QDQCancelOut) { auto test_case = [&](const std::vector& input_shape, size_t maxpool_dim, const std::vector& perms) { auto build_test_case = [&](ModelTestBuilder& builder) { @@ -1566,72 +1703,6 @@ TEST(QDQTransformerTests, QDQPropagation_DQ_Q) { test_case({1, 13, 13, 23}); } -TEST(QDQTransformerTests, Concat_UInt8) { - auto test_case = [&](const std::vector>& input_shapes, - int64_t axis, - bool has_input_float = false, - bool has_input_int8 = false, - bool has_output_int8 = false) { - auto build_test_case = [&](ModelTestBuilder& builder) { - auto input_count = input_shapes.size(); - std::vector input_args; - std::vector q_input_args; - for (size_t i = 0; i < input_count; i++) { - input_args.push_back(builder.MakeInput(input_shapes[i], -1.f, 1.f)); - if (i == 0 && has_input_float) { - q_input_args.push_back(input_args.back()); - } else if (i == 0 && has_input_int8) { - q_input_args.push_back(AddQDQNodePair(builder, input_args.back(), 0.05f, 1)); - } else { - q_input_args.push_back(AddQDQNodePair(builder, input_args.back(), 0.05f, 128)); - } - } - auto* concat_output = builder.MakeIntermediate(); - Node& concat_node = builder.AddNode("Concat", q_input_args, {concat_output}); - concat_node.AddAttribute("axis", axis); - - auto* q_concat_output = builder.MakeIntermediate(); - if (has_output_int8) { - builder.AddQuantizeLinearNode(concat_output, 0.05f, 1, q_concat_output); - - auto* output_arg = builder.MakeOutput(); - builder.AddDequantizeLinearNode(q_concat_output, 0.05f, 1, output_arg); - } else { - builder.AddQuantizeLinearNode(concat_output, 0.05f, 128, q_concat_output); - - auto* output_arg = builder.MakeOutput(); - builder.AddDequantizeLinearNode(q_concat_output, 0.05f, 128, output_arg); - } - }; - - auto check_mp_reshape_graph = [&input_shapes, &has_input_float, &has_input_int8, &has_output_int8](InferenceSessionWrapper& session) { - auto op_to_count = CountOpsInGraph(session.GetGraph()); - if (has_input_float || has_input_int8 || has_output_int8) { - EXPECT_EQ(op_to_count["com.microsoft.QLinearConcat"], 0); - } else { - EXPECT_EQ(op_to_count["QuantizeLinear"], static_cast(input_shapes.size())); - EXPECT_EQ(op_to_count["com.microsoft.QLinearConcat"], 1); - EXPECT_EQ(op_to_count["DequantizeLinear"], 1); - } - }; - - TransformerTester(build_test_case, - check_mp_reshape_graph, - TransformerLevel::Level1, - TransformerLevel::Level2, - 12 /*opset_version*/, - 0.01f /*per_sample_tolerance*/, - 0.01f /*relative_per_sample_tolerance*/, - std::make_unique()); - }; - - test_case({{1, 6, 36}, {1, 3, 36}}, 1); - test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2); - test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, true); - test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, false, true); - test_case({{1, 6, 36}, {1, 6, 8}, {1, 6, 2}}, 2, false, false, true); -} - #endif // DISABLE_CONTRIB_OPS TEST(QDQTransformerTests, QDQ_Selector_Test) { diff --git a/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc b/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc index 3007f07628..5938259b50 100644 --- a/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc +++ b/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc @@ -8,6 +8,7 @@ #include "core/common/common.h" #include "core/framework/op_kernel.h" +#include "core/mlas/inc/mlas.h" #include "core/util/math_cpuonly.h" #include "core/util/qmath.h" @@ -248,6 +249,186 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_No_Zero_Point) { test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); } +#if defined(MLAS_TARGET_ARM_ANY) +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 4}, + {-3, 7, 5, -6, + 4, -5, 8, 7}); + test.AddInput("T2", + {4, 4}, + {5, -3, 7, 8, + -6, -8, -3, 6, + 7, 9, 9, -5, + 8, 7, -6, 7}); + test.AddInput("a_zero_point", {}, {5}); + test.AddInput("b_zero_point", {}, {5}); + test.AddOutput("T3", + {2, 4}, + {-55, 16, 89, -44, + 122, 154, 68, -39}); + + test.Run(); +} + +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 2, 4}, + {-3, 7, 5, -6, + 4, -5, 8, 7, + + 7, -4, 3, 6, + -4, -5, 5, 7}); + + test.AddInput("T2", + {4, 3}, + {5, -3, 7, + 8, -6, -8, + -3, 6, 7, + 9, 9, -5}); + + test.AddInput("a_zero_point", {}, {3}); + test.AddInput("b_zero_point", {}, {4}); + test.AddOutput("T3", + {2, 2, 3}, + {-49, -39, 21, + -46, 103, 78, + + -9, 57, 69, + -33, 153, 45}); + + test.Run(); +} + +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_B_ND_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 4}, + {-3, 7, 5, -6, + 4, -5, 8, 7}); + test.AddInput("T2", + {2, 4, 3}, + {5, -3, 7, + 8, -6, -8, + -3, 6, 7, + 9, 9, -5, + + 5, -3, 7, + 8, -6, -8, + -3, 6, 7, + 9, 9, -5}); + test.AddInput("a_zero_point", {}, {1}); + test.AddInput("b_zero_point", {}, {2}); + test.AddOutput("T3", + {2, 2, 3}, + {-45, -61, -11, + -20, 103, 68, + + -45, -61, -11, + -20, 103, 68}); + + test.Run(); +} + +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_B_ND_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 2, 4}, + {-3, 7, 5, -6, + 4, -5, 8, 7, + + -3, 7, 5, -6, + 4, -5, 8, 7}); + test.AddInput("T2", + {2, 4, 4}, + {5, -3, 7, 8, + -6, -8, -3, 6, + 7, 9, 9, -5, + 8, 7, -6, 7, + + 5, -3, 7, 8, + -6, -8, -3, 6, + 7, 9, 9, -5, + 8, 7, -6, 7}); + test.AddInput("a_zero_point", {}, {5}); + test.AddInput("b_zero_point", {}, {5}); + test.AddOutput("T3", + {2, 2, 4}, + {-55, 16, 89, -44, + 122, 154, 68, -39, + + -55, 16, 89, -44, + 122, 154, 68, -39}); + + test.Run(); +} + +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_Has_Zero_Point_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 2, 4}, + {-3, 7, 5, -6, + 4, -5, 8, 7, + + -3, 7, 5, -6, + 4, -5, 8, 7}); + test.AddInput("T2", + {2, 4, 4}, + {0, -8, 2, 3, + -11, -13, -8, 1, + 2, 4, 4, -10, + 3, 2, -11, 2, + + 0, -8, 2, 3, + -11, -13, -8, 1, + 2, 4, 4, -10, + 3, 2, -11, 2}); + test.AddInput("a_zero_point", {}, {5}); + test.AddOutput("T3", + {2, 2, 4}, + {-55, 16, 89, -44, + 122, 154, 68, -39, + + -55, 16, 89, -44, + 122, 154, 68, -39}); + + test.Run(); +} + +TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_No_Zero_Point_ARM) { + OpTester test("MatMulInteger", 10); + test.AddInput("T1", + {2, 2, 4}, + {-8, 2, 0, -11, + -1, -10, 3, 2, + + -8, 2, 0, -11, + -1, -10, 3, 2}); + test.AddInput("T2", + {2, 4, 4}, + {0, -8, 2, 3, + -11, -13, -8, 1, + 2, 4, 4, -10, + 3, 2, -11, 2, + + 0, -8, 2, 3, + -11, -13, -8, 1, + 2, 4, 4, -10, + 3, 2, -11, 2}); + test.AddOutput("T3", + {2, 2, 4}, + {-55, 16, 89, -44, + 122, 154, 68, -39, + + -55, 16, 89, -44, + 122, 154, 68, -39}); + + test.Run(); +} +#endif + TEST(MatmulIntegerOpTest, MatMulInteger_WithZero_ZeroPoint) { OpTester test("MatMulInteger", 10); test.AddInput("T1", {4, 3}, {11, 7, 3, 10, 6, 2, 9, 5, 1, 8, 4, 0}); diff --git a/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json index 97070b948c..b464f50ac1 100644 --- a/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json +++ b/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json @@ -1,4 +1,12 @@ [ + [ + "MatMulInteger ai.onnx CPUExecutionProvider", + 10315437332566125928 + ], + [ + "MatMulIntegerToFloat com.microsoft CPUExecutionProvider", + 1363870470731747600 + ], [ "QLinearConv ai.onnx CPUExecutionProvider", 1301685544574905024 diff --git a/onnxruntime/test/testdata/matmul_integer_to_float.py b/onnxruntime/test/testdata/matmul_integer_to_float.py index be028e907d..13b38bb11d 100644 --- a/onnxruntime/test/testdata/matmul_integer_to_float.py +++ b/onnxruntime/test/testdata/matmul_integer_to_float.py @@ -3,7 +3,7 @@ from onnx import helper from onnx import TensorProto from enum import Enum -def GenerateModel(model_name, sign, has_zp = True, bias = False): +def GenerateModel(model_name, sign_i, sign_w, has_zp = True, bias = False): nodes = [ # subgraph helper.make_node( "MatMulInteger", @@ -19,8 +19,8 @@ def GenerateModel(model_name, sign, has_zp = True, bias = False): ] inputs = [ # inputs - helper.make_tensor_value_info('A', TensorProto.UINT8, ['M', 'K']), - helper.make_tensor_value_info('B', TensorProto.INT8 if sign else TensorProto.UINT8, ['K', 'N']), + helper.make_tensor_value_info('A', TensorProto.INT8 if sign_i else TensorProto.UINT8, ['M', 'K']), + helper.make_tensor_value_info('B', TensorProto.INT8 if sign_w else TensorProto.UINT8, ['K', 'N']), helper.make_tensor_value_info('a_scale', TensorProto.FLOAT, [1]), helper.make_tensor_value_info('b_scale', TensorProto.FLOAT, ['C']), @@ -28,8 +28,8 @@ def GenerateModel(model_name, sign, has_zp = True, bias = False): if has_zp: inputs.extend([ - helper.make_tensor_value_info('a_zero_point', TensorProto.UINT8, [1]), - helper.make_tensor_value_info('b_zero_point', TensorProto.INT8 if sign else TensorProto.UINT8, ['C']), + helper.make_tensor_value_info('a_zero_point', TensorProto.INT8 if sign_i else TensorProto.UINT8, [1]), + helper.make_tensor_value_info('b_zero_point', TensorProto.INT8 if sign_w else TensorProto.UINT8, ['C']), ]) if bias: @@ -49,7 +49,10 @@ def GenerateModel(model_name, sign, has_zp = True, bias = False): onnx.save(model, model_name) if __name__ == "__main__": - GenerateModel('matmul_integer_to_float_int8.onnx', True) - GenerateModel('matmul_integer_to_float_uint8.onnx', False) - GenerateModel('matmul_integer_to_float_int8_bias.onnx', True, False, True) - GenerateModel('matmul_integer_to_float_uint8_bias.onnx', False, False, True) \ No newline at end of file + GenerateModel('matmul_integer_to_float_int8.onnx', False, True) + GenerateModel('matmul_integer_to_float_uint8.onnx', False, False) + GenerateModel('matmul_integer_to_float_int8_bias.onnx', False, True, False, True) + GenerateModel('matmul_integer_to_float_uint8_bias.onnx', False, False, False, True) + + GenerateModel('matmul_integer_to_float_int8_int8.onnx', True, True) + GenerateModel('matmul_integer_to_float_int8_int8_bias.onnx', True, True, False, True) \ No newline at end of file diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_int8.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_int8.onnx index b8a2ad1ade..9f4465a914 100644 --- a/onnxruntime/test/testdata/matmul_integer_to_float_int8.onnx +++ b/onnxruntime/test/testdata/matmul_integer_to_float_int8.onnx @@ -1,4 +1,4 @@ -: +: U A B @@ -44,4 +44,4 @@ mul_bottom"MulDynamicQuantizeMatMul_fusionZ  M -NB \ No newline at end of file +NB \ No newline at end of file diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_int8_bias.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_int8_bias.onnx index 688b061100..01b7e15aa4 100644 --- a/onnxruntime/test/testdata/matmul_integer_to_float_int8_bias.onnx +++ b/onnxruntime/test/testdata/matmul_integer_to_float_int8_bias.onnx @@ -1,4 +1,4 @@ -: +: 9 A Bmatmul_output_int32 MatMulInteger" MatMulInteger @@ -41,4 +41,4 @@ mul_bottom"Mul  M -NB \ No newline at end of file +NB \ No newline at end of file diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_uint8.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_uint8.onnx index 53a79e4b72..a4c6d20d59 100644 --- a/onnxruntime/test/testdata/matmul_integer_to_float_uint8.onnx +++ b/onnxruntime/test/testdata/matmul_integer_to_float_uint8.onnx @@ -1,4 +1,4 @@ -: +: U A B @@ -44,4 +44,4 @@ mul_bottom"MulDynamicQuantizeMatMul_fusionZ  M -NB \ No newline at end of file +NB \ No newline at end of file diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_uint8_bias.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_uint8_bias.onnx index 4ab08b3a65..a5be0c63f4 100644 --- a/onnxruntime/test/testdata/matmul_integer_to_float_uint8_bias.onnx +++ b/onnxruntime/test/testdata/matmul_integer_to_float_uint8_bias.onnx @@ -1,4 +1,4 @@ -: +: 9 A Bmatmul_output_int32 MatMulInteger" MatMulInteger @@ -41,4 +41,4 @@ mul_bottom"Mul  M -NB \ No newline at end of file +NB \ No newline at end of file From 42c176b60c502ab3a26f7289397fa5cad5becba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Dupr=C3=A9?= Date: Thu, 9 Dec 2021 12:45:35 +0100 Subject: [PATCH 013/113] Update default opset to 14 in ORTModule (#9743) * update to torch 1.10 * update torchvision version * update torchtext version * remove deprecated option enable_onnx_checker * add unit test to test gradient of GatherElements * add ORTMODULE_ONNX_OPSET_VERSION in a docker file --- .../core/optimizer/megatron_transformer.cc | 12 +- orttraining/orttraining/python/ort_trainer.py | 6 +- .../orttraining/python/training/_utils.py | 12 +- .../python/training/ortmodule/__init__.py | 2 +- .../python/training/orttrainer_options.py | 6 +- .../orttraining/test/python/_test_commons.py | 11 +- .../orttraining/test/python/_test_helpers.py | 4 +- .../python/onnxruntime_test_postprocess.py | 2 +- .../python/orttraining_ortmodule_tests.py | 12 ++ .../orttraining_test_onnx_ops_ortmodule.py | 160 ++++++++++++++++++ .../python/orttraining_test_ortmodule_api.py | 41 ++++- .../orttraining_test_orttrainer_frontend.py | 145 +++++++++++----- .../test/python/orttraining_test_utils.py | 2 +- .../orttraining-pai-ci-pipeline.yml | 3 + ...y-packaging-pipeline-torch1100-cuda102.yml | 1 + ...y-packaging-pipeline-torch1100-cuda113.yml | 1 + ...py-packaging-pipeline-torch190-cuda102.yml | 1 + ...py-packaging-pipeline-torch190-cuda111.yml | 1 + ...py-packaging-pipeline-torch190-cuda114.yml | 1 + ...g-linux-gpu-ortmodule-test-ci-pipeline.yml | 2 +- .../templates/py-packaging-stage.yml | 40 ++--- .../py-packaging-training-cuda-stage.yml | 10 ++ .../docker/Dockerfile.manylinux2014_rocm4_2 | 2 + .../docker/Dockerfile.manylinux2014_rocm4_3_1 | 4 +- ...Dockerfile.manylinux2014_training_cuda10_2 | 2 + ...Dockerfile.manylinux2014_training_cuda11_1 | 2 + ...Dockerfile.manylinux2014_training_cuda11_3 | 2 + ...Dockerfile.manylinux2014_training_cuda11_4 | 2 + .../docker/scripts/install_python_deps.sh | 2 +- .../requirements_torch1.10.0_cu10.2.txt | 2 +- .../requirements_torch1.10.0_cu11.1.txt | 6 + .../requirements_torch1.10.0_cu11.3.txt | 2 +- .../stage1/requirements_torch_cpu.txt | 2 +- .../docker/scripts/training/requirements.txt | 6 +- .../pai/rocm-ci-pipeline-env.Dockerfile | 1 + 35 files changed, 417 insertions(+), 93 deletions(-) create mode 100644 orttraining/orttraining/test/python/orttraining_test_onnx_ops_ortmodule.py create mode 100644 tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.1.txt diff --git a/orttraining/orttraining/core/optimizer/megatron_transformer.cc b/orttraining/orttraining/core/optimizer/megatron_transformer.cc index 4d9d1b8b7f..b24a283b03 100644 --- a/orttraining/orttraining/core/optimizer/megatron_transformer.cc +++ b/orttraining/orttraining/core/optimizer/megatron_transformer.cc @@ -33,19 +33,19 @@ const std::initializer_list opset_v1_13 = {1 const std::initializer_list opset_v1_11_13 = {1, 11, 13}; const std::initializer_list opset_v2_11_13 = {2, 11, 13}; const std::initializer_list opset_v5_13 = {5, 13}; -const std::initializer_list opset_v1_6_7_13 = {1, 6, 7, 13}; -const std::initializer_list opset_v7_13 = {7, 13}; +const std::initializer_list opset_v1_6_7_13_14 = {1, 6, 7, 13, 14}; +const std::initializer_list opset_v7_13_14 = {7, 13, 14}; const std::initializer_list opset_v9 = {9}; const std::initializer_list opset_v9_13 = {9, 13}; const std::initializer_list opset_v12_13 = {12, 13}; -const OpInfo add_info = OpInfo("Add", opset_v7_13); +const OpInfo add_info = OpInfo("Add", opset_v7_13_14); const OpInfo split_info = OpInfo("Split", opset_v2_11_13, kOnnxDomainAlias, 3); const OpInfo reshape_info = OpInfo("Reshape", opset_v5_13); const OpInfo transpose_info = OpInfo("Transpose", opset_v1_13); const OpInfo matmul_info = OpInfo("MatMul", opset_v9_13); -const OpInfo div_info = OpInfo("Div", opset_v7_13); -const OpInfo mul_info = OpInfo("Mul", opset_v1_6_7_13); -const OpInfo sub_info = OpInfo("Sub", opset_v7_13); +const OpInfo div_info = OpInfo("Div", opset_v7_13_14); +const OpInfo mul_info = OpInfo("Mul", opset_v1_6_7_13_14); +const OpInfo sub_info = OpInfo("Sub", opset_v7_13_14); const OpInfo softmax_info = OpInfo("Softmax", opset_v1_11_13); const OpInfo dropout_info = OpInfo("Dropout", opset_v12_13); const OpInfo where_info = OpInfo("Where", opset_v9); diff --git a/orttraining/orttraining/python/ort_trainer.py b/orttraining/orttraining/python/ort_trainer.py index 5d1046ad34..692abd6dbb 100644 --- a/orttraining/orttraining/python/ort_trainer.py +++ b/orttraining/orttraining/python/ort_trainer.py @@ -18,7 +18,7 @@ import onnxruntime.capi.pt_patch from onnxruntime.tools.symbolic_shape_infer import SymbolicShapeInference -DEFAULT_OPSET_VERSION = 12 +DEFAULT_OPSET_VERSION = 14 class IODescription(): def __init__(self, name, shape, dtype=None, num_classes=None): @@ -344,7 +344,8 @@ def convert_model_loss_fn_to_onnx(model, loss_fn, model_desc, device, inputs, op other_export_options['training'] = True # This option was added after 1.4 release. - if LooseVersion(torch.__version__) > LooseVersion('1.4.0'): + if (LooseVersion(torch.__version__) > LooseVersion('1.4.0') and + LooseVersion(torch.__version__) < LooseVersion('1.10.0')): other_export_options['enable_onnx_checker'] = False # This option was added after 1.6 release. if LooseVersion(torch.__version__) >= LooseVersion('1.6.0'): @@ -363,7 +364,6 @@ def convert_model_loss_fn_to_onnx(model, loss_fn, model_desc, device, inputs, op output_names=output_names, opset_version=opset_version, dynamic_axes=dynamic_axes, - _retain_param_name=True, example_outputs=tuple(sample_outputs), do_constant_folding=False, **other_export_options) diff --git a/orttraining/orttraining/python/training/_utils.py b/orttraining/orttraining/python/training/_utils.py index 447c6ec71e..91ee336b10 100644 --- a/orttraining/orttraining/python/training/_utils.py +++ b/orttraining/orttraining/python/training/_utils.py @@ -189,10 +189,14 @@ def static_vars(**kwargs): def import_module_from_file(file_path, module_name=None): '''Import a Python module from a file into interpreter''' - assert isinstance(file_path, str) and os.path.exists(file_path),\ - "'file_path' must be a full path string with the python file to load" - assert module_name is None or isinstance(module_name, str) and module_name,\ - "'module_name' must be a string with the python module name to load" + if not isinstance(file_path, str) or not os.path.exists(file_path): + raise AssertionError( + "'file_path' must be a full path string with the python file to load. " + "file_path=%r." % (file_path, )) + if module_name is not None and (not isinstance(module_name, str) or not module_name): + raise AssertionError( + "'module_name' must be a string with the python module name to load. " + "module_name=%r." % (module_name, )) if not module_name: module_name = os.path.basename(file_path).split('.')[0] diff --git a/orttraining/orttraining/python/training/ortmodule/__init__.py b/orttraining/orttraining/python/training/ortmodule/__init__.py index 477e085cde..6e88cc63e9 100644 --- a/orttraining/orttraining/python/training/ortmodule/__init__.py +++ b/orttraining/orttraining/python/training/ortmodule/__init__.py @@ -37,7 +37,7 @@ def _defined_from_envvar(name, default_value, warn=True): # NOTE: To *change* values in runtime, import onnxruntime.training.ortmodule and # assign them new values. Importing them directly do not propagate changes. ################################################################################ -ONNX_OPSET_VERSION = 12 +ONNX_OPSET_VERSION = 14 MINIMUM_RUNTIME_PYTORCH_VERSION_STR = '1.8.1' ORTMODULE_TORCH_CPP_DIR = os.path.join(os.path.dirname(__file__), 'torch_cpp_extensions') _FALLBACK_INIT_EXCEPTION = None diff --git a/orttraining/orttraining/python/training/orttrainer_options.py b/orttraining/orttraining/python/training/orttrainer_options.py index 8b4c6a866e..44ad78c12f 100644 --- a/orttraining/orttraining/python/training/orttrainer_options.py +++ b/orttraining/orttraining/python/training/orttrainer_options.py @@ -436,7 +436,7 @@ class ORTTrainerOptions(object): _internal_use.extra_postprocess (callable, default is None) a functor to postprocess the ONNX model and return a new ONNX model. It does not override :py:attr:`._internal_use.enable_internal_postprocess`, but complement it - _internal_use.onnx_opset_version (int, default is 12): + _internal_use.onnx_opset_version (int, default is 14): ONNX opset version used during model exporting. _internal_use.enable_onnx_contrib_ops (bool, default is True) enable PyTorch to export nodes as contrib ops in ONNX. @@ -820,8 +820,8 @@ _ORTTRAINER_OPTIONS_SCHEMA = { 'onnx_opset_version': { 'type': 'integer', 'min': 12, - 'max': 13, - 'default': 12 + 'max': 14, + 'default': 14 }, 'enable_onnx_contrib_ops': { 'type': 'boolean', diff --git a/orttraining/orttraining/test/python/_test_commons.py b/orttraining/orttraining/test/python/_test_commons.py index 605d651f64..d9dd7d34af 100644 --- a/orttraining/orttraining/test/python/_test_commons.py +++ b/orttraining/orttraining/test/python/_test_commons.py @@ -141,7 +141,16 @@ def generate_dummy_optim_state(model, optimizer): def _load_pytorch_transformer_model(device, dynamic_axes=False, legacy_api=False, data_dir=None): # Loads external Pytorch TransformerModel into utils - pytorch_transformer_path = os.path.join('samples', 'python', 'training', 'orttrainer', 'pytorch_transformer') + root = 'samples' + if not os.path.exists(root): + root = os.path.normpath( + os.path.join( + os.path.dirname( + os.path.abspath(__file__)), "..", "..", "..", "..", "samples")) + if not os.path.exists(root): + raise FileNotFoundError( + "Unable to find folder 'samples', tried %r." % root) + pytorch_transformer_path = os.path.join(root, 'python', 'training', 'orttrainer', 'pytorch_transformer') pt_model_path = os.path.join(pytorch_transformer_path, 'pt_model.py') pt_model = _utils.import_module_from_file(pt_model_path) ort_utils_path = os.path.join(pytorch_transformer_path, 'ort_utils.py') diff --git a/orttraining/orttraining/test/python/_test_helpers.py b/orttraining/orttraining/test/python/_test_helpers.py index e9e13b7196..b190a219e6 100644 --- a/orttraining/orttraining/test/python/_test_helpers.py +++ b/orttraining/orttraining/test/python/_test_helpers.py @@ -51,7 +51,9 @@ def assert_model_outputs(output_a, output_b, verbose=False, rtol=1e-7, atol=0): """ assert isinstance(output_a, list) and isinstance(output_b, list),\ "output_a and output_b must be list of numbers" - assert len(output_a) == len(output_b), "output_a and output_b must have the same length" + if len(output_a) != len(output_b): + raise AssertionError( + "output_a and output_b must have the same length (%r != %r)." % (len(output_a), len(output_b))) # for idx in range(len(output_a)): assert_allclose(output_a, output_b, rtol=rtol, atol=atol, err_msg=f"Model output value mismatch") diff --git a/orttraining/orttraining/test/python/onnxruntime_test_postprocess.py b/orttraining/orttraining/test/python/onnxruntime_test_postprocess.py index 5c0321d795..b10bfcd6b0 100644 --- a/orttraining/orttraining/test/python/onnxruntime_test_postprocess.py +++ b/orttraining/orttraining/test/python/onnxruntime_test_postprocess.py @@ -34,7 +34,7 @@ class Test_PostPasses(unittest.TestCase): device, world_rank=0, world_size=1, - _opset_version=12, + _opset_version=14, _enable_internal_postprocess=_enable_internal_postprocess, _extra_postprocess=_extra_postprocess) diff --git a/orttraining/orttraining/test/python/orttraining_ortmodule_tests.py b/orttraining/orttraining/test/python/orttraining_ortmodule_tests.py index 6a2d8a8004..5d3fea91e8 100644 --- a/orttraining/orttraining/test/python/orttraining_ortmodule_tests.py +++ b/orttraining/orttraining/test/python/orttraining_ortmodule_tests.py @@ -38,6 +38,16 @@ def run_ortmodule_api_tests(cwd, log, transformers_cache): run_subprocess(command, cwd=cwd, log=log, env=env).check_returncode() +def run_ortmodule_ops_tests(cwd, log, transformers_cache): + log.debug('Running: ORTModule-OPS tests') + + env = get_env_with_transformers_cache(transformers_cache) + + command = [sys.executable, '-m', 'pytest', '-sv', 'orttraining_test_onnx_ops_ortmodule.py'] + + run_subprocess(command, cwd=cwd, log=log, env=env).check_returncode() + + def run_ortmodule_fallback_tests(cwd, log, transformers_cache): log.debug('Running: ORTModule-API tests') @@ -119,6 +129,8 @@ def main(): run_ortmodule_api_tests(cwd, log, transformers_cache=args.transformers_cache) + run_ortmodule_ops_tests(cwd, log, transformers_cache=args.transformers_cache) + run_ortmodule_poc_net(cwd, log, no_cuda=False, data_dir=args.mnist) run_ortmodule_poc_net(cwd, log, no_cuda=True, data_dir=args.mnist) diff --git a/orttraining/orttraining/test/python/orttraining_test_onnx_ops_ortmodule.py b/orttraining/orttraining/test/python/orttraining_test_onnx_ops_ortmodule.py new file mode 100644 index 0000000000..12c2bbe155 --- /dev/null +++ b/orttraining/orttraining/test/python/orttraining_test_onnx_ops_ortmodule.py @@ -0,0 +1,160 @@ +""" +@brief test log(time=3s) +""" +import unittest +import copy +import numpy as np +import torch +from onnxruntime.training.ortmodule import ORTModule + + +class TestOnnxOpsOrtModule(unittest.TestCase): + + def assert_values_are_close(self, tensor, other, rtol=1e-05, atol=1e-06): + are_close = torch.allclose(tensor, other, rtol=rtol, atol=atol) + if not are_close: + abs_diff = torch.abs(tensor - other) + abs_other = torch.abs(other) + max_atol = torch.max((abs_diff - rtol * abs_other)) + max_rtol = torch.max((abs_diff - atol) / abs_other) + raise AssertionError( + "The maximum atol is %r, maximum rtol is %r." % ( + max_atol, max_rtol)) + + def assert_gradients_match_and_reset_gradient( + self, ort_model, pt_model, none_pt_params=None, + reset_gradient=True, rtol=1e-05, atol=1e-06): + if none_pt_params is None: + none_pt_params = [] + ort_named_params = list(ort_model.named_parameters()) + pt_named_params = list(pt_model.named_parameters()) + self.assertEqual(len(ort_named_params), len(pt_named_params)) + + for ort_named_param, pt_named_param in zip(ort_named_params, pt_named_params): + ort_name, ort_param = ort_named_param + pt_name, pt_param = pt_named_param + + self.assertIn(pt_name, ort_name) + if pt_name in none_pt_params: + self.assertNotEmpty(pt_param.grad) + if ort_param is not None: + self.assertFalse(torch.is_nonzero( + torch.count_nonzero(ort_param.grad))) + else: + self.assert_values_are_close( + ort_param.grad, pt_param.grad, rtol=rtol, atol=atol) + + if reset_gradient: + ort_param.grad = None + pt_param.grad = None + + def gradient_correctness(self, name, device, debug=False): + pt_model_cls, op_grad_type, kwargs = self.get_torch_model_name(name, device) + if kwargs is None: + kwargs = {} + N = 32 + pt_model = pt_model_cls().to(device) + D_in = pt_model.fc1.in_features + ort_model = ORTModule(copy.deepcopy(pt_model)) + + def run_step(model, x): + prediction = model(x) + loss = prediction.sum() + loss.backward() + return prediction + + for _ in range(10): + x = torch.randn(N, D_in, device=device) + pt_prediction = run_step(pt_model, x) + ort_prediction = run_step(ort_model, x) + + self.assert_values_are_close( + ort_prediction, pt_prediction, **kwargs) + self.assert_gradients_match_and_reset_gradient( + ort_model, pt_model, **kwargs) + + onnx_graph_inf = ort_model._torch_module._execution_manager._training_manager._onnx_models.exported_model + onnx_graph_train = ort_model._torch_module._execution_manager._training_manager._onnx_models.optimized_model + if debug: + with open("debug_%s_ortmodule_infer.onnx" % name, "wb") as f: + f.write(onnx_graph_inf.SerializeToString()) + with open("debug_%s_ortmodule_train.onnx" % name, "wb") as f: + f.write(onnx_graph_train.SerializeToString()) + self.assertIn('op_type: "%s"' % name, str(onnx_graph_inf)) + for onnx_model in [onnx_graph_inf, onnx_graph_train]: + for oimp in onnx_model.opset_import: + if oimp.domain == '': + self.assertEqual(oimp.version, 14) + if op_grad_type is not None: + if isinstance(op_grad_type, tuple): + text = str(onnx_graph_train) + if all(map(lambda op: ('op_type: "%s"' % op) not in text, op_grad_type)): + raise AssertionError( + "Operator %s not found in %s." % (" or ".join(op_grad_type), text)) + else: + self.assertIn('op_type: "%s"' % + op_grad_type, str(onnx_graph_train)) + + def get_torch_model_name(self, name, device): + + def from_numpy(v, device=None, requires_grad=False): + v = torch.from_numpy(v) + if device is not None: + v = v.to(device) + v.requires_grad_(requires_grad) + return v + + if name == 'Softmax': + + class TestSoftmax(torch.nn.Module): + def __init__(self, input_size=128, hidden_size=500, num_classes=100): + torch.nn.Module.__init__(self) + self.fc1 = torch.nn.Linear(input_size, hidden_size) + self.thfct = torch.nn.Softmax() + self.fc2 = torch.nn.Linear(hidden_size, num_classes) + + def forward(self, input1): + out = self.fc1(input1) + out = self.thfct(out) + out = self.fc2(out) + return out + + return TestSoftmax, ('SoftmaxGrad', 'SoftmaxGrad_13'), None + + if name == 'GatherElements': + + class TestGatherElement(torch.nn.Module): + def __init__(self, input_size=32, hidden_size=500, num_classes=100): + torch.nn.Module.__init__(self) + self.fc1 = torch.nn.Linear(input_size, hidden_size) + rev_idx = np.array(list(np.arange(hidden_size)[::-1]), + dtype=np.int64) + idx = np.empty( + (input_size, hidden_size), dtype=np.int64) + for i in range(idx.shape[0]): + idx[i, :] = rev_idx + self.indices = from_numpy(idx, device=device) + self.fc2 = torch.nn.Linear(hidden_size, num_classes) + + def forward(self, input1): + out = self.fc1(input1) + out = torch.gather(out, 1, self.indices) + out = self.fc2(out) + return out + + return TestGatherElement, 'GatherElementsGrad', dict(rtol=1e-04, atol=1e-05) + + raise AssertionError("Unexpected name=%r." % name) + + def test_onnx_ops(self): + for name in ['GatherElements', 'Softmax']: + for device_name in ['cuda:0', 'cpu']: + if device_name == 'cuda:0' and not torch.cuda.is_available(): + continue + with self.subTest(name=name, device=device_name): + device = torch.device(device_name) + self.gradient_correctness(name, device) + + +if __name__ == "__main__": + unittest.main() diff --git a/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py b/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py index 7bb0e675b6..595540a78a 100644 --- a/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py +++ b/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py @@ -28,6 +28,7 @@ from onnxruntime.training.ortmodule import (ORTModule, LogLevel, _fallback, _graph_execution_manager) +import onnxruntime.training.ortmodule as ortmodule_module from onnxruntime.training.optim import FusedAdam from transformers import AdamW @@ -37,6 +38,10 @@ import _test_helpers # Import autocasting libs from torch.cuda import amp + +DEFAULT_OPSET = 14 + + # PyTorch model definitions for tests class NeuralNetSinglePositionalArgument(torch.nn.Module): @@ -4501,7 +4506,7 @@ def test_sigmoid_grad_opset13(): old_opst_cst = ortmodule.ONNX_OPSET_VERSION old_opset = os.getenv("ORTMODULE_ONNX_OPSET_VERSION", None) os.environ["ORTMODULE_ONNX_OPSET_VERSION"] = '13' - assert ortmodule.ONNX_OPSET_VERSION == 12 + assert ortmodule.ONNX_OPSET_VERSION == 14 ort_model = ORTModule(copy.deepcopy(pt_model)) @@ -4530,7 +4535,7 @@ def test_sigmoid_grad_opset13(): assert ortmodule.ONNX_OPSET_VERSION == 13 ortmodule.ONNX_OPSET_VERSION = old_opst_cst -@pytest.mark.parametrize("opset_version", [12, 13]) +@pytest.mark.parametrize("opset_version", [12, 13, 14]) def test_opset_version_change(opset_version): device = 'cuda' @@ -4651,3 +4656,35 @@ def test_softmax(M, N): _test_helpers.assert_values_are_close(pt_prediction, ort_prediction) _test_helpers.assert_values_are_close(pt_loss, ort_loss) _test_helpers.assert_values_are_close(pt_x.grad, ort_x.grad) + + +def test_check_opset_is_default_opset_after_training(): + M, N = 24, 6 + + class NeuralNetSoftmax(torch.nn.Module): + def __init__(self): + super(NeuralNetSoftmax, self).__init__() + self.m = torch.nn.Softmax(dim=1) + + def forward(self, x): + return self.m(x) + + def run_step(model, x): + prediction = model(x) + loss = prediction.sum() + loss.backward() + return prediction, loss + + device = 'cuda' + pt_model = NeuralNetSoftmax().to(device) + ort_model = ORTModule(copy.deepcopy(pt_model)) + + pt_x = torch.rand((M, N), requires_grad=True, device=device) + ort_x = copy.deepcopy(pt_x) + + pt_prediction, pt_loss = run_step(pt_model, pt_x) + ort_prediction, ort_loss = run_step(ort_model, ort_x) + _test_helpers.assert_values_are_close(pt_prediction, ort_prediction) + _test_helpers.assert_values_are_close(pt_loss, ort_loss) + _test_helpers.assert_values_are_close(pt_x.grad, ort_x.grad) + assert ortmodule_module.ONNX_OPSET_VERSION == DEFAULT_OPSET diff --git a/orttraining/orttraining/test/python/orttraining_test_orttrainer_frontend.py b/orttraining/orttraining/test/python/orttraining_test_orttrainer_frontend.py index 40b3b7ba11..c0e0c9f158 100644 --- a/orttraining/orttraining/test/python/orttraining_test_orttrainer_frontend.py +++ b/orttraining/orttraining/test/python/orttraining_test_orttrainer_frontend.py @@ -1,6 +1,7 @@ from functools import partial import inspect import math +from distutils.version import StrictVersion from numpy.testing import assert_allclose import onnx import os @@ -25,6 +26,15 @@ from onnxruntime.training import PropagateCastOpsStrategy # Testing starts here ######################################################### ############################################################################### +pytorch_110 = StrictVersion('.'.join(torch.__version__.split('.')[:2])) >= StrictVersion('1.10.0') + + +def get_model_opset(model_onnx): + for op in model_onnx.opset_import: + if op.domain == '': + return op.version + return None + @pytest.mark.parametrize("test_input", [ ({}), @@ -104,7 +114,7 @@ def testORTTrainerOptionsDefaultValues(test_input): '_internal_use': { 'enable_internal_postprocess': True, 'extra_postprocess': None, - 'onnx_opset_version' : 12, + 'onnx_opset_version' : 14, 'enable_onnx_contrib_ops': True, }, 'provider_options':{}, @@ -621,6 +631,8 @@ def testInstantiateORTTrainer(step_fn, lr_scheduler, expected_lr_values, device) assert input_type == _utils.dtype_onnx_to_torch( trainer._onnx_model.graph.input[i].type.tensor_type.elem_type) + opset = get_model_opset(trainer._onnx_model) + # Check name, shape and dtype of the ORT graph outputs for i in range(len(trainer.model_desc.outputs)): output_name = trainer.model_desc.outputs[i][0] @@ -629,7 +641,8 @@ def testInstantiateORTTrainer(step_fn, lr_scheduler, expected_lr_values, device) assert trainer._onnx_model.graph.output[i].name == output_name for dim_idx, dim in enumerate(trainer._onnx_model.graph.output[i].type.tensor_type.shape.dim): - assert output_dim[dim_idx] == dim.dim_value + if opset != 14: + assert output_dim[dim_idx] == dim.dim_value assert output_type == _utils.dtype_onnx_to_torch( trainer._onnx_model.graph.output[i].type.tensor_type.elem_type) @@ -741,7 +754,8 @@ def testORTTrainerMixedPrecisionLossScaler(seed, device, expected_loss, fetches) def _recompute_data(): device_capability_major = torch.cuda.get_device_capability()[0] if device_capability_major == 7: # V100 for Dev machine - expected_loss = [10.5598 , 10.4591, 10.3477, 10.2726, 10.1945] + expected_loss = {12: [10.5598, 10.4591, 10.3477, 10.2726, 10.1945], + 14: [10.54088, 10.498755, 10.386827, 10.338747, 10.262459]} return [ (False, False, False, 0, expected_loss), # no recompute (True, False, False, 0, expected_loss), # attn_dropout recompute @@ -750,7 +764,8 @@ def _recompute_data(): (False, False, True, 1, expected_loss), # transformer_layer recompute with 1 layer ] elif device_capability_major == 5: # M60 for CI machines - expected_loss = [10.5445, 10.4389, 10.3480, 10.2627, 10.2113] + expected_loss = {12: [10.5445, 10.4389, 10.3480, 10.2627, 10.2113], + 14: [10.5445, 10.4389, 10.3480, 10.2627, 10.2113]} return [ (False, False, False, 0, expected_loss), # no recompute (True, False, False, 0, expected_loss), # attn_dropout recompute @@ -763,7 +778,7 @@ def testORTTrainerRecompute(attn_dropout, gelu, transformer_layer, number_layers seed = 321 device = 'cuda' rtol = 1e-3 - total_steps = len(expected_loss) + total_steps = len(expected_loss[12]) torch.manual_seed(seed) set_seed(seed) @@ -788,8 +803,9 @@ def testORTTrainerRecompute(attn_dropout, gelu, transformer_layer, number_layers actual_loss.append(loss.cpu()) # Compare loss to ground truth computed from current ORTTrainer API - _test_helpers.assert_model_outputs(expected_loss, actual_loss, True, rtol=rtol) assert trainer._onnx_model is not None + opset = get_model_opset(trainer._onnx_model) + _test_helpers.assert_model_outputs(expected_loss[opset], actual_loss, True, rtol=rtol) @pytest.mark.parametrize("seed,device,gradient_accumulation_steps,total_steps,expected_loss", [ @@ -872,7 +888,7 @@ def testORTTrainerInternalUseContribOps(enable_onnx_contrib_ops): # Training loop data, targets = batcher_fn(train_data, 0) - if not enable_onnx_contrib_ops: + if not enable_onnx_contrib_ops and not pytorch_110: with pytest.raises(Exception) as e_info: _, _ = trainer.train_step(data, targets) else: @@ -1499,25 +1515,49 @@ def _adam_max_norm_clip_data(): device_capability_major = torch.cuda.get_device_capability()[0] if device_capability_major == 7: # V100 for Dev machine return [ - (0, 'cuda', 1.0, 1, 12, [10.592951, 10.067989, 9.619152, 9.245731, 8.881137,\ - 8.578644, 8.280573, 8.063023, 7.797933, 7.486215, 7.233806, 7.011791]), - (0, 'cuda', 0.1, 1, 12, [10.592951, 10.068722, 9.620503, 9.247791, 8.883972,\ - 8.582286, 8.285027, 8.068308, 7.803638, 7.492318, 7.240352, 7.018665]), - (42, 'cuda', 1.0, 1, 12, [10.647908, 10.144501, 9.672352, 9.306980, 8.956026,\ - 8.602655, 8.351079, 8.088144, 7.867220, 7.564082, 7.289846, 7.073726]), - (42, 'cuda', 0.1, 1, 12, [10.647908, 10.145191, 9.673690, 9.309031, 8.959020,\ - 8.606632, 8.355836, 8.093478, 7.873327, 7.570731, 7.296772, 7.0809422]), + (0, 'cuda', 1.0, 1, 12, { + 12: [10.592951, 10.067989, 9.619152, 9.245731, 8.881137, + 8.578644, 8.280573, 8.063023, 7.797933, 7.486215, 7.233806, 7.011791], + 14: [10.584141, 10.068119, 9.581743, 9.191472, 8.880169, 8.5352, + 8.311425, 8.061202, 7.773032, 7.523009, 7.258711, 7.02805]}), + (0, 'cuda', 0.1, 1, 12, { + 12: [10.592951, 10.068722, 9.620503, 9.247791, 8.883972, + 8.582286, 8.285027, 8.068308, 7.803638, 7.492318, 7.240352, 7.018665], + 14: [10.584141, 10.068845, 9.583107, 9.193537, 8.882966, 8.538839, + 8.315872, 8.066408, 7.778978, 7.529708, 7.265849, 7.035439]}), + (42, 'cuda', 1.0, 1, 12, { + 12: [10.647908, 10.144501, 9.672352, 9.306980, 8.956026, + 8.602655, 8.351079, 8.088144, 7.867220, 7.564082, 7.289846, 7.073726], + 14: [10.697515, 10.229034, 9.765422, 9.428294, 9.080612, 8.715208, + 8.459574, 8.169073, 7.940211, 7.654147, 7.390446, 7.166227]}), + (42, 'cuda', 0.1, 1, 12, { + 12: [10.647908, 10.145191, 9.673690, 9.309031, 8.959020, + 8.606632, 8.355836, 8.093478, 7.873327, 7.570731, 7.296772, 7.0809422]), + 14: [10.697515, 10.229034, 9.765422, 9.428294, 9.080612, 8.715208, + 8.459574, 8.169073, 7.940211, 7.654147, 7.390446, 7.166227])} ] elif device_capability_major == 5: # M60 for CI machines (Python Packaging Pipeline) return [ - (0, 'cuda', 1.0, 1, 12, [10.618382, 10.08292 , 9.603334, 9.258133, 8.917768, 8.591574, - 8.318401, 8.042292, 7.783608, 7.50226 , 7.236041, 7.035602]), - (0, 'cuda', 0.1, 1, 12, [10.618382, 10.083632, 9.604639, 9.260109, 8.920504, 8.595082, - 8.322799, 8.047493, 7.78929 , 7.508382, 7.242587, 7.042367]), - (42, 'cuda', 1.0, 1, 12, [10.68639 , 10.102986, 9.647681, 9.293091, 8.958928, 8.625297, - 8.351107, 8.079577, 7.840723, 7.543044, 7.284141, 7.072688]), - (42, 'cuda', 0.1, 1, 12, [10.68639 , 10.103672, 9.649025, 9.295167, 8.961777, 8.629059, - 8.355571, 8.084871, 7.846589, 7.549438, 7.290722, 7.079446]), + (0, 'cuda', 1.0, 1, 12, { + 12: [10.618382, 10.08292 , 9.603334, 9.258133, 8.917768, 8.591574, + 8.318401, 8.042292, 7.783608, 7.50226 , 7.236041, 7.035602], + 14: [10.618382, 10.08292 , 9.603334, 9.258133, 8.917768, 8.591574, + 8.318401, 8.042292, 7.783608, 7.50226 , 7.236041, 7.035602]}), + (0, 'cuda', 0.1, 1, 12, { + 12: [10.618382, 10.083632, 9.604639, 9.260109, 8.920504, 8.595082, + 8.322799, 8.047493, 7.78929 , 7.508382, 7.242587, 7.042367], + 14: [10.618382, 10.083632, 9.604639, 9.260109, 8.920504, 8.595082, + 8.322799, 8.047493, 7.78929 , 7.508382, 7.242587, 7.042367]}), + (42, 'cuda', 1.0, 1, 12, { + 12: [10.68639 , 10.102986, 9.647681, 9.293091, 8.958928, 8.625297, + 8.351107, 8.079577, 7.840723, 7.543044, 7.284141, 7.072688], + 14: [10.68639 , 10.102986, 9.647681, 9.293091, 8.958928, 8.625297, + 8.351107, 8.079577, 7.840723, 7.543044, 7.284141, 7.072688]}), + (42, 'cuda', 0.1, 1, 12, { + 12: [10.68639 , 10.103672, 9.649025, 9.295167, 8.961777, 8.629059, + 8.355571, 8.084871, 7.846589, 7.549438, 7.290722, 7.079446], + 14: [10.697515, 10.22967, 9.766556, 9.430037, 9.083106, 8.718601, + 8.463726, 8.17396, 7.945755, 7.660188, 7.396963, 7.172944]}), ] @pytest.mark.parametrize("seed,device,max_norm_clip,gradient_accumulation_steps,total_steps,expected_loss", _adam_max_norm_clip_data()) def testORTTrainerAdamMaxNormClip(seed, device, max_norm_clip, gradient_accumulation_steps, total_steps, expected_loss): @@ -1541,32 +1581,54 @@ def testORTTrainerAdamMaxNormClip(seed, device, max_norm_clip, gradient_accumula actual_loss.append(loss.cpu().item()) # Compare legacy vs experimental APIs - _test_helpers.assert_model_outputs(expected_loss, actual_loss, rtol=rtol) + assert trainer._onnx_model is not None + opset = get_model_opset(trainer._onnx_model) + _test_helpers.assert_model_outputs(expected_loss[opset], actual_loss, rtol=rtol) def _lamb_max_norm_clip_data(): device_capability_major = torch.cuda.get_device_capability()[0] if device_capability_major == 7: # V100 for Dev machine return [ - (0, 'cuda', 1.0, 1, 12, [10.592951, 10.487728, 10.422251, 10.350913, 10.244248, 10.213003,\ - 10.129222, 10.095112, 10.035983, 9.974586, 9.909771, 9.874278]), - (0, 'cuda', 0.1, 1, 12, [10.592951, 10.452503, 10.349832, 10.245314, 10.106587, 10.046009,\ - 9.934781, 9.875164, 9.792067, 9.704592, 9.617104, 9.563070]), - (42, 'cuda', 1.0, 1, 12, [10.647908, 10.566276, 10.476154, 10.406275, 10.311079, 10.240053,\ - 10.196469, 10.113955, 10.117376, 10.013077, 9.930301, 9.893368]), - (42, 'cuda', 0.1, 1, 12, [10.647908, 10.531957, 10.405246, 10.302971, 10.176583, 10.075583,\ - 10.005772, 9.897825, 9.875748, 9.748932, 9.642885, 9.586762]), + (0, 'cuda', 1.0, 1, 12, { + 12: [10.592951, 10.487728, 10.422251, 10.350913, 10.244248, 10.213003, + 10.129222, 10.095112, 10.035983, 9.974586, 9.909771, 9.874278], + 14: [10.584141, 10.497192, 10.389251, 10.286045, 10.231354, 10.17018, + 10.066779, 10.048138, 9.958029, 9.8908, 9.82965, 9.755484]}), + (0, 'cuda', 0.1, 1, 12, { + 12: [10.592951, 10.452503, 10.349832, 10.245314, 10.106587, 10.046009, + 9.934781, 9.875164, 9.792067, 9.704592, 9.617104, 9.563070], + 14: [10.584141, 10.461154, 10.315399, 10.178979, 10.092329, 9.999928, + 9.869949, 9.824564, 9.707565, 9.61643, 9.532847, 9.439593]}), + (42, 'cuda', 1.0, 1, 12, { + 12: [10.647908, 10.566276, 10.476154, 10.406275, 10.311079, 10.240053, + 10.196469, 10.113955, 10.117376, 10.013077, 9.930301, 9.893368], + 14: [10.697515, 10.631279, 10.528757, 10.496689, 10.411219, 10.322109, + 10.297314, 10.215549, 10.149698, 10.087336, 10.010884, 9.934544]}), + (42, 'cuda', 0.1, 1, 12, { + 12: [10.647908, 10.531957, 10.405246, 10.302971, 10.176583, 10.075583, + 10.005772, 9.897825, 9.875748, 9.748932, 9.642885, 9.586762], + 14: [10.697515, 10.596729, 10.457815, 10.393475, 10.277581, 10.158909, + 10.108126, 10.000326, 9.912526, 9.826057, 9.727899, 9.633768]}) ] elif device_capability_major == 5: # M60 for CI machines (Python Packaging Pipeline) return [ - (0, 'cuda', 1.0, 1, 12, [10.618382, 10.50222 , 10.403347, 10.35298 , 10.288447, 10.237399, - 10.184225, 10.089048, 10.008952, 9.972644, 9.897674, 9.84524 ]), - (0, 'cuda', 0.1, 1, 12, [10.618382, 10.466732, 10.330871, 10.24715 , 10.150972, 10.069127, - 9.98974 , 9.870169, 9.763693, 9.704323, 9.605957, 9.533117]), - (42, 'cuda', 1.0, 1, 12, [10.68639 , 10.511692, 10.447308, 10.405255, 10.334866, 10.261473, - 10.169422, 10.107138, 10.069889, 9.97798 , 9.928105, 9.896435]), - (42, 'cuda', 0.1, 1, 12, [10.68639 , 10.477489, 10.376671, 10.301725, 10.200718, 10.098477, - 9.97995 , 9.890104, 9.828899, 9.713555, 9.639567, 9.589856]), + (0, 'cuda', 1.0, 1, 12, { + 12: [10.618382, 10.50222, 10.403347, 10.35298, 10.288447, 10.237399, + 10.184225, 10.089048, 10.008952, 9.972644, 9.897674, 9.84524], + 14: [0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4]}), + (0, 'cuda', 0.1, 1, 12, { + 12: [10.618382, 10.466732, 10.330871, 10.24715 , 10.150972, 10.069127, + 9.98974 , 9.870169, 9.763693, 9.704323, 9.605957, 9.533117], + 14: [1, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4]}), + (42, 'cuda', 1.0, 1, 12, { + 12: [10.68639 , 10.511692, 10.447308, 10.405255, 10.334866, 10.261473, + 10.169422, 10.107138, 10.069889, 9.97798, 9.928105, 9.896435], + 14: [2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4]}), + (42, 'cuda', 0.1, 1, 12, { + 12: [10.68639 , 10.477489, 10.376671, 10.301725, 10.200718, 10.098477, + 9.97995 , 9.890104, 9.828899, 9.713555, 9.639567, 9.589856], + 14: [3, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4]}), ] @pytest.mark.parametrize("seed,device,max_norm_clip, gradient_accumulation_steps,total_steps,expected_loss", _lamb_max_norm_clip_data()) def testORTTrainerLambMaxNormClip(seed, device, max_norm_clip, gradient_accumulation_steps, total_steps, expected_loss): @@ -1590,4 +1652,5 @@ def testORTTrainerLambMaxNormClip(seed, device, max_norm_clip, gradient_accumula actual_loss.append(loss.cpu().item()) # Compare legacy vs experimental APIs - _test_helpers.assert_model_outputs(expected_loss, actual_loss, rtol=rtol) + opset = get_model_opset(trainer._onnx_model) + _test_helpers.assert_model_outputs(expected_loss[opset], actual_loss, rtol=rtol) diff --git a/orttraining/orttraining/test/python/orttraining_test_utils.py b/orttraining/orttraining/test/python/orttraining_test_utils.py index 69248f9fc4..763e16cc47 100644 --- a/orttraining/orttraining/test/python/orttraining_test_utils.py +++ b/orttraining/orttraining/test/python/orttraining_test_utils.py @@ -123,7 +123,7 @@ def run_test(model, model_desc, device, args, gradient_accumulation_steps, fp16, allreduce_post_accumulation=allreduce_post_accumulation, get_lr_this_step=get_lr_this_step if use_internal_get_lr_this_step else None, loss_scaler=loss_scaler if use_internal_loss_scaler else None, - _opset_version=12, + _opset_version=14, _use_deterministic_compute=True) print ("running with old frontend API") diff --git a/tools/ci_build/github/azure-pipelines/orttraining-pai-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/orttraining-pai-ci-pipeline.yml index 907103cc91..d92e371852 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-pai-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-pai-ci-pipeline.yml @@ -65,6 +65,7 @@ jobs: - script: |- cd ./build/RelWithDebInfo export PYTHONPATH=$PWD + export ORTMODULE_ONNX_OPSET_VERSION=12 python \ /stage/huggingface-transformers/examples/pytorch/language-modeling/run_mlm.py \ --model_name_or_path bert-large-uncased \ @@ -89,6 +90,7 @@ jobs: - script: |- cd ./build/RelWithDebInfo export PYTHONPATH=$PWD + export ORTMODULE_ONNX_OPSET_VERSION=12 python \ /stage/huggingface-transformers/examples/pytorch/language-modeling/run_clm.py \ --model_name_or_path gpt2 \ @@ -169,6 +171,7 @@ jobs: - script: |- cd ./build/RelWithDebInfo export PYTHONPATH=$PWD + export ORTMODULE_ONNX_OPSET_VERSION=12 python \ /stage/huggingface-transformers/examples/pytorch/language-modeling/run_mlm.py \ --model_name_or_path distilbert-base-uncased \ diff --git a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda102.yml b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda102.yml index de73fab127..85297e6aba 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda102.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda102.yml @@ -5,6 +5,7 @@ stages: parameters: build_py_parameters: --enable_training --update --build torch_version: '1.10.0' + opset_version: '14' cuda_version: '10.2' gcc_version: 8 cmake_cuda_architectures: 37;50;52;60;61;70;75;80;86 diff --git a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda113.yml b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda113.yml index 6d2575b5b6..88add70b95 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda113.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch1100-cuda113.yml @@ -5,6 +5,7 @@ stages: parameters: build_py_parameters: --enable_training --update --build torch_version: '1.10.0' + opset_version: '14' cuda_version: '11.3' gcc_version: 10 cmake_cuda_architectures: 37;50;52;60;61;70;75;80;86 diff --git a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda102.yml b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda102.yml index 0dc33ef8af..bfaefeb45e 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda102.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda102.yml @@ -5,6 +5,7 @@ stages: parameters: build_py_parameters: --enable_training --update --build torch_version: '1.9.0' + opset_version: '12' cuda_version: '10.2' gcc_version: 8 cmake_cuda_architectures: 35;37;50;52;60;61;70 diff --git a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda111.yml b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda111.yml index ec237be99f..25dbc3cbaa 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda111.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda111.yml @@ -5,6 +5,7 @@ stages: parameters: build_py_parameters: --enable_training --update --build torch_version: '1.9.0' + opset_version: '12' cuda_version: '11.1' gcc_version: 9 cmake_cuda_architectures: 37;50;52;60;61;70;75;80 diff --git a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda114.yml b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda114.yml index f3c354b556..9cbc94a61c 100644 --- a/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda114.yml +++ b/tools/ci_build/github/azure-pipelines/orttraining-py-packaging-pipeline-torch190-cuda114.yml @@ -5,6 +5,7 @@ stages: parameters: build_py_parameters: --enable_training --update --build torch_version: '1.9.0' + opset_version: '12' cuda_version: '11.4' gcc_version: 10 cmake_cuda_architectures: 37;50;52;60;61;70;75;80;86 diff --git a/tools/ci_build/github/azure-pipelines/templates/orttraining-linux-gpu-ortmodule-test-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/templates/orttraining-linux-gpu-ortmodule-test-ci-pipeline.yml index 759ab5f58c..1aa2cd6a09 100644 --- a/tools/ci_build/github/azure-pipelines/templates/orttraining-linux-gpu-ortmodule-test-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/templates/orttraining-linux-gpu-ortmodule-test-ci-pipeline.yml @@ -33,7 +33,7 @@ steps: --volume /bert_data:/bert_data \ --volume /hf_models_cache:/hf_models_cache \ ${{ parameters.DockerImageTag }} \ - bash -c "python3 -m pip uninstall -y -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/requirements.txt && python3 -m pip install -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.9.0_cu11.1.txt && python3 -m pip install -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage2/requirements.txt && rm -rf /build/onnxruntime/ && python3 -m pip install /build/dist/onnxruntime*.whl && python3 -m onnxruntime.training.ortmodule.torch_cpp_extensions.install && /build/launch_test.py --cmd_line_with_args 'python orttraining_ortmodule_tests.py --mnist /mnist --bert_data /bert_data/hf_data/glue_data/CoLA/original/raw --transformers_cache /hf_models_cache/huggingface/transformers' --cwd /build" \ + bash -c "python3 -m pip uninstall -y -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/requirements.txt && python3 -m pip install -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.1.txt && python3 -m pip install -r /onnxruntime_src/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage2/requirements.txt && rm -rf /build/onnxruntime/ && python3 -m pip install /build/dist/onnxruntime*.whl && python3 -m onnxruntime.training.ortmodule.torch_cpp_extensions.install && /build/launch_test.py --cmd_line_with_args 'python orttraining_ortmodule_tests.py --mnist /mnist --bert_data /bert_data/hf_data/glue_data/CoLA/original/raw --transformers_cache /hf_models_cache/huggingface/transformers' --cwd /build" \ displayName: 'Run orttraining_ortmodule_tests.py' condition: succeededOrFailed() timeoutInMinutes: 60 diff --git a/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml b/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml index 8f3fd62dfd..fc599a42b0 100644 --- a/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml +++ b/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml @@ -301,27 +301,27 @@ stages: Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_2 Context: tools/ci_build/github/linux/docker DockerBuildArgs: >- - --build-arg TORCH_VERSION=1.9.0 + --build-arg TORCH_VERSION=1.10.0 --build-arg INSTALL_DEPS_EXTRA_ARGS=-tmur --build-arg BUILD_UID=$(id -u) --network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-10/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-10/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64:/usr/local/lib - Repository: onnxruntimetrainingrocmbuild-torch1.9.0-rocm4.2 + Repository: onnxruntimetrainingrocmbuild-torch1.10.0-rocm4.2 - template: get-docker-image-steps.yml parameters: Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_3_1 Context: tools/ci_build/github/linux/docker DockerBuildArgs: >- - --build-arg TORCH_VERSION=1.9.0 + --build-arg TORCH_VERSION=1.10.0 --build-arg INSTALL_DEPS_EXTRA_ARGS=-tmur --build-arg BUILD_UID=$(id -u) --network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-10/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-10/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64:/usr/local/lib - Repository: onnxruntimetrainingrocmbuild-torch1.9.0-rocm4.3.1 + Repository: onnxruntimetrainingrocmbuild-torch1.10.0-rocm4.3.1 - job: ROCM_training_wheels timeoutInMinutes: 180 @@ -333,37 +333,37 @@ stages: - ROCm_build_environment strategy: matrix: - Python36 Torch190 Rocm42: + Python36 Torch1100 Rocm42: PythonVersion: '3.6' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.2' - Python37 Torch190 Rocm42: + Python37 Torch1100 Rocm42: PythonVersion: '3.7' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.2' - Python38 Torch190 Rocm42: + Python38 Torch1100 Rocm42: PythonVersion: '3.8' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.2' - Python39 Torch190 Rocm42: + Python39 Torch1100 Rocm42: PythonVersion: '3.9' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.2' - Python36 Torch190 Rocm431: + Python36 Torch1100 Rocm431: PythonVersion: '3.6' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.3.1' - Python37 Torch190 Rocm431: + Python37 Torch1100 Rocm431: PythonVersion: '3.7' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.3.1' - Python38 Torch190 Rocm431: + Python38 Torch1100 Rocm431: PythonVersion: '3.8' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.3.1' - Python39 Torch190 Rocm431: + Python39 Torch1100 Rocm431: PythonVersion: '3.9' - TorchVersion: '1.9.0' + TorchVersion: '1.10.0' RocmVersion: '4.3.1' steps: diff --git a/tools/ci_build/github/azure-pipelines/templates/py-packaging-training-cuda-stage.yml b/tools/ci_build/github/azure-pipelines/templates/py-packaging-training-cuda-stage.yml index a24d91d8d6..55b7b802ba 100644 --- a/tools/ci_build/github/azure-pipelines/templates/py-packaging-training-cuda-stage.yml +++ b/tools/ci_build/github/azure-pipelines/templates/py-packaging-training-cuda-stage.yml @@ -10,6 +10,11 @@ parameters: torch_version. type: string +- name: opset_version + displayName: > + opset_version. + type: string + - name: cuda_version displayName: > cuda_version. @@ -55,6 +60,7 @@ stages: Python36: PythonVersion: '3.6' TorchVersion: ${{ parameters.torch_version }} + OpsetVersion: ${{ parameters.opset_version }} CudaVersion: ${{ parameters.cuda_version }} DockerFile: ${{ parameters.docker_file }} GccVersion: ${{ parameters.gcc_version }} @@ -62,6 +68,7 @@ stages: Python37: PythonVersion: '3.7' TorchVersion: ${{ parameters.torch_version }} + OpsetVersion: ${{ parameters.opset_version }} CudaVersion: ${{ parameters.cuda_version }} DockerFile: ${{ parameters.docker_file }} GccVersion: ${{ parameters.gcc_version }} @@ -69,6 +76,7 @@ stages: Python38: PythonVersion: '3.8' TorchVersion: ${{ parameters.torch_version }} + OpsetVersion: ${{ parameters.opset_version }} CudaVersion: ${{ parameters.cuda_version }} DockerFile: ${{ parameters.docker_file }} GccVersion: ${{ parameters.gcc_version }} @@ -76,6 +84,7 @@ stages: Python39: PythonVersion: '3.9' TorchVersion: ${{ parameters.torch_version }} + OpsetVersion: ${{ parameters.opset_version }} CudaVersion: ${{ parameters.cuda_version }} DockerFile: ${{ parameters.docker_file }} GccVersion: ${{ parameters.gcc_version }} @@ -94,6 +103,7 @@ stages: Context: tools/ci_build/github/linux/docker DockerBuildArgs: >- --build-arg TORCH_VERSION=$(TorchVersion) + --build-arg OPSET_VERSION=$(OpsetVersion) --build-arg PYTHON_VERSION=$(PythonVersion) --build-arg INSTALL_DEPS_EXTRA_ARGS=-tu --build-arg BUILD_UID=$(id -u) diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_2 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_2 index f8aa03df15..2886bd349e 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_2 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_2 @@ -188,6 +188,7 @@ CMD ["/bin/bash"] ARG PYTHON_VERSION=3.6 ARG TORCH_VERSION=1.9.0 +ARG OPSET_VERSION=12 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -213,3 +214,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_3_1 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_3_1 index 4c641c6473..10f30e5ddd 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_3_1 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_rocm4_3_1 @@ -187,7 +187,8 @@ CMD ["/bin/bash"] #Build manylinux2014 docker image end ARG PYTHON_VERSION=3.6 -ARG TORCH_VERSION=1.9.0 +ARG TORCH_VERSION=1.10.0 +ARG OPSET_VERSION=14 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -213,3 +214,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda10_2 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda10_2 index 659bf36df4..15aa8dde5e 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda10_2 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda10_2 @@ -184,6 +184,7 @@ CMD ["/bin/bash"] ARG PYTHON_VERSION=3.6 ARG TORCH_VERSION=1.9.0 +ARG OPSET_VERSION=12 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -201,3 +202,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_1 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_1 index 1d9ddf2d0a..4236a066af 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_1 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_1 @@ -183,6 +183,7 @@ CMD ["/bin/bash"] #Build manylinux2014 docker image end ARG PYTHON_VERSION=3.6 ARG TORCH_VERSION=1.9.0 +ARG OPSET_VERSION=12 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -200,3 +201,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_3 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_3 index 1ba6696f7c..17d7ebc216 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_3 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_3 @@ -183,6 +183,7 @@ CMD ["/bin/bash"] #Build manylinux2014 docker image end ARG PYTHON_VERSION=3.6 ARG TORCH_VERSION=1.10.0 +ARG OPSET_VERSION=14 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -200,3 +201,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_4 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_4 index 9bb44c3421..1a7eb16bf8 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_4 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_training_cuda11_4 @@ -183,6 +183,7 @@ CMD ["/bin/bash"] #Build manylinux2014 docker image end ARG PYTHON_VERSION=3.6 ARG TORCH_VERSION=1.9.0 +ARG OPSET_VERSION=12 ARG INSTALL_DEPS_EXTRA_ARGS #Add our own dependencies @@ -200,3 +201,4 @@ RUN adduser --uid $BUILD_UID $BUILD_USER WORKDIR /home/$BUILD_USER USER $BUILD_USER ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH +ENV ORTMODULE_ONNX_OPSET_VERSION=$OPSET_VERSION diff --git a/tools/ci_build/github/linux/docker/scripts/install_python_deps.sh b/tools/ci_build/github/linux/docker/scripts/install_python_deps.sh index 282efc402f..d4f8aeae3b 100755 --- a/tools/ci_build/github/linux/docker/scripts/install_python_deps.sh +++ b/tools/ci_build/github/linux/docker/scripts/install_python_deps.sh @@ -6,7 +6,7 @@ INSTALL_DEPS_DISTRIBUTED_SETUP=false ORTMODULE_BUILD=false TARGET_ROCM=false CU_VER="11.1" -TORCH_VERSION='1.9.0' +TORCH_VERSION='1.10.0' USE_CONDA=false while getopts p:h:d:v:tmurc parameter_Option diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu10.2.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu10.2.txt index 589234fa09..944e6029de 100644 --- a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu10.2.txt +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu10.2.txt @@ -2,5 +2,5 @@ -f https://download.pytorch.org/whl/torch_stable.html torch==1.10.0 torchvision==0.11.0 -torchtext==0.10.0 +torchtext==0.11.0 setuptools>=41.4.0 diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.1.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.1.txt new file mode 100644 index 0000000000..7a51d5b270 --- /dev/null +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.1.txt @@ -0,0 +1,6 @@ +--pre +-f https://download.pytorch.org/whl/cu111/torch_stable.html +torch==1.10.0+cu111 +torchvision==0.11.0+cu111 +torchtext==0.11.0 +setuptools>=41.4.0 diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.3.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.3.txt index 2e1ff22b31..6651bcf5fa 100644 --- a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.3.txt +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch1.10.0_cu11.3.txt @@ -2,5 +2,5 @@ -f https://download.pytorch.org/whl/cu113/torch_stable.html torch==1.10.0+cu113 torchvision==0.11.0+cu113 -torchtext==0.10.0+cu113 +torchtext==0.11.0 setuptools>=41.4.0 diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_cpu.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_cpu.txt index bee52b123d..462b954c42 100644 --- a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_cpu.txt +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_cpu.txt @@ -1,2 +1,2 @@ -torch==1.9.0 +torch==1.10.0 setuptools>=41.4.0 diff --git a/tools/ci_build/github/linux/docker/scripts/training/requirements.txt b/tools/ci_build/github/linux/docker/scripts/training/requirements.txt index ae28b6fa71..2350ce48d1 100644 --- a/tools/ci_build/github/linux/docker/scripts/training/requirements.txt +++ b/tools/ci_build/github/linux/docker/scripts/training/requirements.txt @@ -4,9 +4,9 @@ sklearn numpy==1.19.5 transformers==v2.10.0 -torch==1.8.1+cu102 -torchvision==0.9.1+cu102 -torchtext==0.9.1 +torch==1.10.0+cu113 +torchvision==0.11.1+cu113 +torchtext==0.11.0 tensorboard>=2.2.0,<2.5.0 h5py setuptools>=41.4.0 diff --git a/tools/ci_build/github/pai/rocm-ci-pipeline-env.Dockerfile b/tools/ci_build/github/pai/rocm-ci-pipeline-env.Dockerfile index 2c9d9c6f05..4564ae808c 100644 --- a/tools/ci_build/github/pai/rocm-ci-pipeline-env.Dockerfile +++ b/tools/ci_build/github/pai/rocm-ci-pipeline-env.Dockerfile @@ -32,3 +32,4 @@ RUN pip install \ sentencepiece RUN pip install torch-ort --no-dependencies +ENV ORTMODULE_ONNX_OPSET_VERSION=12 From a7abd541c79748d6fc6ba596ddb21ccdcb3c1ce1 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 9 Dec 2021 10:00:44 -0800 Subject: [PATCH 014/113] Correct message type (#9973) --- cmake/onnxruntime_common.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/onnxruntime_common.cmake b/cmake/onnxruntime_common.cmake index c2a0254940..4065e4e4ee 100644 --- a/cmake/onnxruntime_common.cmake +++ b/cmake/onnxruntime_common.cmake @@ -93,7 +93,7 @@ endif() if (onnxruntime_USE_MIMALLOC) if(NOT WIN32) - message(FATAL "Currently do not support MIMALLOC in GPU builds") + message(FATAL_ERROR "Currently do not support MIMALLOC in GPU builds") endif() if(onnxruntime_USE_CUDA OR onnxruntime_USE_OPENVINO) message(WARNING "Currently do not support MIMALLOC in GPU builds") From 41fd745996d2b7f949d67b985fad8f57a3b7ff07 Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Thu, 9 Dec 2021 10:01:35 -0800 Subject: [PATCH 015/113] Fix build error when using '--build_minimal extended' and '--build_wheel' build.py options. (#9979) --- onnxruntime/python/onnxruntime_pybind_state.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc index 387d996c98..05bed14739 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.cc +++ b/onnxruntime/python/onnxruntime_pybind_state.cc @@ -1502,9 +1502,7 @@ void CreateInferencePybindStateModule(py::module& m) { addSparseTensorMethods(m); addIoBindingMethods(m); -#if !defined(__APPLE__) && \ - (!defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS)) - Ort::SessionOptions tmp_options; +#if !defined(__APPLE__) && !defined(ORT_MINIMAL_BUILD) if (!InitProvidersSharedLibrary()) { const logging::Logger& default_logger = logging::LoggingManager::DefaultLogger(); LOGS(default_logger, WARNING) << "Init provider bridge failed."; From 2fdcaffbb726398be80e8f21f37636c1a0458e54 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Thu, 9 Dec 2021 13:25:15 -0800 Subject: [PATCH 016/113] add missing test files (#9989) --- .../matmul_integer_to_float_int8_int8.onnx | 47 +++++++++++++++++++ ...atmul_integer_to_float_int8_int8_bias.onnx | 44 +++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 onnxruntime/test/testdata/matmul_integer_to_float_int8_int8.onnx create mode 100644 onnxruntime/test/testdata/matmul_integer_to_float_int8_int8_bias.onnx diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8.onnx new file mode 100644 index 0000000000..9d38828e25 --- /dev/null +++ b/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8.onnx @@ -0,0 +1,47 @@ +: +U +A +B + a_zero_point + b_zero_pointmatmul_output_int32 MatMulInteger" MatMulInteger +. +a_scale +b_scale +multiplier mul_right"Mul +A +matmul_output_int32matmul_output_floatcast"Cast* +to +5 +matmul_output_float + +multiplierY +mul_bottom"MulDynamicQuantizeMatMul_fusionZ +A + + +M +KZ +B + + +K +NZ +a_scale + + +Z +b_scale +  +CZ + a_zero_point + + +Z + b_zero_point +  +Cb +Y + + +M +NB \ No newline at end of file diff --git a/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8_bias.onnx b/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8_bias.onnx new file mode 100644 index 0000000000..4d9a55af50 --- /dev/null +++ b/onnxruntime/test/testdata/matmul_integer_to_float_int8_int8_bias.onnx @@ -0,0 +1,44 @@ +: +9 +A +Bmatmul_output_int32 MatMulInteger" MatMulInteger +. +a_scale +b_scale +multiplier mul_right"Mul +A +matmul_output_int32matmul_output_floatcast"Cast* +to +E +matmul_output_float + +multipliermul_bottom_output +mul_bottom"Mul +& +mul_bottom_output +biasYadd"AddDynamicQuantizeMatMul_fusionZ +A + + +M +KZ +B + + +K +NZ +a_scale + + +Z +b_scale +  +CZ +bias +  +Nb +Y + + +M +NB \ No newline at end of file From c7e8365e1fff0ebdd029b81477422dbc2afa67e2 Mon Sep 17 00:00:00 2001 From: Sunghoon <35605090+hanbitmyths@users.noreply.github.com> Date: Thu, 9 Dec 2021 13:45:56 -0800 Subject: [PATCH 017/113] Resolve security issue reported by dependabot (#9983) --- js/react_native/package.json | 16 +- js/react_native/yarn.lock | 1634 ++++++++++++++++++---------------- 2 files changed, 862 insertions(+), 788 deletions(-) diff --git a/js/react_native/package.json b/js/react_native/package.json index eb642c9520..a11fb88e0f 100644 --- a/js/react_native/package.json +++ b/js/react_native/package.json @@ -49,17 +49,17 @@ "registry": "https://registry.npmjs.org/" }, "devDependencies": { - "@release-it/conventional-changelog": "^2.0.0", + "@release-it/conventional-changelog": "^3.3.0", "@types/fs-extra": "^9.0.11", - "@types/jest": "^26.0.0", - "@types/react": "^16.9.19", - "@types/react-native": "0.62.13", - "jest": "^26.0.1", + "@types/jest": "^27.0.3", + "@types/react": "^17.0.37", + "@types/react-native": "0.66.8", + "jest": "^27.4.3", "pod-install": "^0.1.0", "prettier": "^2.0.5", - "react": "16.13.1", - "react-native": "0.64.1", - "react-native-builder-bob": "^0.17.1", + "react": "17.0.2", + "react-native": "0.66.3", + "react-native-builder-bob": "^0.18.2", "release-it": "^14.2.2", "typescript": "^4.1.3" }, diff --git a/js/react_native/yarn.lock b/js/react_native/yarn.lock index 9d4e55f47e..c1683a8239 100644 --- a/js/react_native/yarn.lock +++ b/js/react_native/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== @@ -14,7 +14,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== -"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": +"@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.14.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== @@ -35,7 +35,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.16.0", "@babel/generator@^7.5.0": +"@babel/generator@^7.14.0", "@babel/generator@^7.16.0", "@babel/generator@^7.7.2": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== @@ -251,7 +251,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3": +"@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3", "@babel/parser@^7.7.2": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== @@ -541,7 +541,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.16.0": +"@babel/plugin-syntax-typescript@^7.16.0", "@babel/plugin-syntax-typescript@^7.7.2": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb" integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ== @@ -555,7 +555,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-async-to-generator@^7.16.0": +"@babel/plugin-transform-async-to-generator@^7.0.0", "@babel/plugin-transform-async-to-generator@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604" integrity sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw== @@ -1027,7 +1027,7 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3", "@babel/traverse@^7.7.2": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== @@ -1101,100 +1101,101 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" - integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== +"@jest/console@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.4.2.tgz#7a95612d38c007ddb528ee446fe5e5e785e685ce" + integrity sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.6.2" - jest-util "^26.6.2" + jest-message-util "^27.4.2" + jest-util "^27.4.2" slash "^3.0.0" -"@jest/core@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" - integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== +"@jest/core@^27.4.3": + version "27.4.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.4.3.tgz#9b9b34f4e6429a633085f476402aa2e3ce707877" + integrity sha512-V9ms3zSxUHxh1E/ZLAiXF7SLejsdFnjWTFizWotMOWvjho0lW5kSjZymhQSodNW0T0ZMQRiha7f8+NcFVm3hJQ== dependencies: - "@jest/console" "^26.6.2" - "@jest/reporters" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.4.2" + "@jest/reporters" "^27.4.2" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" + emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^26.6.2" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-resolve-dependencies "^26.6.3" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - jest-watcher "^26.6.2" - micromatch "^4.0.2" - p-each-series "^2.1.0" + jest-changed-files "^27.4.2" + jest-config "^27.4.3" + jest-haste-map "^27.4.2" + jest-message-util "^27.4.2" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.2" + jest-resolve-dependencies "^27.4.2" + jest-runner "^27.4.3" + jest-runtime "^27.4.2" + jest-snapshot "^27.4.2" + jest-util "^27.4.2" + jest-validate "^27.4.2" + jest-watcher "^27.4.2" + micromatch "^4.0.4" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/create-cache-key-function@^26.5.0": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-26.6.2.tgz#04cf439207a4fd12418d8aee551cddc86f9ac5f5" - integrity sha512-LgEuqU1f/7WEIPYqwLPIvvHuc1sB6gMVbT6zWhin3txYUNYK/kGQrC1F2WR4gR34YlI9bBtViTm5z98RqVZAaw== +"@jest/create-cache-key-function@^27.0.1": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.4.2.tgz#09b585f9dbafec0f56cfb0e4d4edfe2bec0e0768" + integrity sha512-aSSCAJwUNX4R1hJQoyimsND5l+2EsFgzlepS8NuOJJHjXij/UdxYFngac44tmv9IYdI+kglAyORg0plt4/aFMQ== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" -"@jest/environment@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" - integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== +"@jest/environment@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.2.tgz#03efabce528dbb09bffd3ec7e39bb0f3f7475cc2" + integrity sha512-uSljKxh/rGlHlmhyeG4ZoVK9hOec+EPBkwTHkHKQ2EqDu5K+MaG9uJZ8o1CbRsSdZqSuhXvJCYhBWsORPPg6qw== dependencies: - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^26.6.2" + jest-mock "^27.4.2" -"@jest/fake-timers@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" - integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== +"@jest/fake-timers@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.4.2.tgz#d217f86c3ba2027bf29e0b731fd0cb761a72d093" + integrity sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg== dependencies: - "@jest/types" "^26.6.2" - "@sinonjs/fake-timers" "^6.0.1" + "@jest/types" "^27.4.2" + "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-message-util "^27.4.2" + jest-mock "^27.4.2" + jest-util "^27.4.2" -"@jest/globals@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" - integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== +"@jest/globals@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.2.tgz#56a402c5ebf22eba1d34e900772147f5126ea2d8" + integrity sha512-KkfaHEttlGpXYAQTZHgrESiEPx2q/DKAFLGLFda1uGVrqc17snd3YVPhOxlXOHIzVPs+lQ/SDB2EIvxyGzb3Ew== dependencies: - "@jest/environment" "^26.6.2" - "@jest/types" "^26.6.2" - expect "^26.6.2" + "@jest/environment" "^27.4.2" + "@jest/types" "^27.4.2" + expect "^27.4.2" -"@jest/reporters@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" - integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== +"@jest/reporters@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.4.2.tgz#d3860c5d3f668fa1326ab2bf5989f774e5c03f04" + integrity sha512-sp4aqmdBJtjKetEakzDPcZggPcVIF6w9QLkYBbaWDV6e/SIsHnF1S4KtIH91eEc2fp7ep6V/e1xvdfEoho1d2w== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.4.2" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" + "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -1205,64 +1206,61 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^26.6.2" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" + jest-haste-map "^27.4.2" + jest-resolve "^27.4.2" + jest-util "^27.4.2" + jest-worker "^27.4.2" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^7.0.0" - optionalDependencies: - node-notifier "^8.0.0" + v8-to-istanbul "^8.1.0" -"@jest/source-map@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" - integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== +"@jest/source-map@^27.4.0": + version "27.4.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" + integrity sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" - integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== +"@jest/test-result@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.4.2.tgz#05fd4a5466ec502f3eae0b39dff2b93ea4d5d9ec" + integrity sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA== dependencies: - "@jest/console" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.4.2" + "@jest/types" "^27.4.2" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" - integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== +"@jest/test-sequencer@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.2.tgz#94bb7e5412d59ae2a8a4b8f9925bb16b6dc82b4c" + integrity sha512-HmHp5mlh9f9GyNej5yCS1JZIFfUGnP9+jEOH5zoq5EmsuZeYD+dGULqyvGDPtuzzbyAFJ6R4+z4SS0VvnFwwGQ== dependencies: - "@jest/test-result" "^26.6.2" + "@jest/test-result" "^27.4.2" graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" + jest-haste-map "^27.4.2" + jest-runtime "^27.4.2" -"@jest/transform@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" - integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== +"@jest/transform@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.2.tgz#459885e96de2e21fc68b8b371e90aa653966dd0d" + integrity sha512-RTKcPZllfcmLfnlxBya7aypofhdz05+E6QITe55Ex0rxyerkgjmmpMlvVn11V0cP719Ps6WcDYCnDzxnnJUwKg== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-regex-util "^26.0.0" - jest-util "^26.6.2" - micromatch "^4.0.2" + jest-haste-map "^27.4.2" + jest-regex-util "^27.4.0" + jest-util "^27.4.2" + micromatch "^4.0.4" pirates "^4.0.1" slash "^3.0.0" source-map "^0.6.1" @@ -1279,6 +1277,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" + integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1401,31 +1410,31 @@ dependencies: "@octokit/openapi-types" "^11.2.0" -"@react-native-community/cli-debugger-ui@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-5.0.1.tgz#6b1f3367b8e5211e899983065ea2e72c1901d75f" - integrity sha512-5gGKaaXYOVE423BUqxIfvfAVSj5Cg1cU/TpGbeg/iqpy2CfqyWqJB3tTuVUbOOiOvR5wbU8tti6pIi1pchJ+oA== +"@react-native-community/cli-debugger-ui@^6.0.0-rc.0": + version "6.0.0-rc.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-6.0.0-rc.0.tgz#774378626e4b70f5e1e2e54910472dcbaffa1536" + integrity sha512-achYcPPoWa9D02C5tn6TBzjeY443wQTyx37urptc75JpZ7gR5YHsDyIEEWa3DDYp1va9zx/iGg+uZ/hWw07GAw== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-hermes@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-5.0.1.tgz#039d064bf2dcd5043beb7dcd6cdf5f5cdd51e7fc" - integrity sha512-nD+ZOFvu5MfjLB18eDJ01MNiFrzj8SDtENjGpf0ZRFndOWASDAmU54/UlU/wj8OzTToK1+S1KY7j2P2M1gleww== +"@react-native-community/cli-hermes@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz#92b2f07d08626a60f6893c3e3d57c1538c8fb5a7" + integrity sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA== dependencies: - "@react-native-community/cli-platform-android" "^5.0.1" - "@react-native-community/cli-tools" "^5.0.1" - chalk "^3.0.0" + "@react-native-community/cli-platform-android" "^6.3.0" + "@react-native-community/cli-tools" "^6.2.0" + chalk "^4.1.2" hermes-profile-transformer "^0.0.6" ip "^1.1.5" -"@react-native-community/cli-platform-android@^5.0.1", "@react-native-community/cli-platform-android@^5.0.1-alpha.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-5.0.1.tgz#7f761e1818e5a099877ec59a1b739553fd6a6905" - integrity sha512-qv9GJX6BJ+Y4qvV34vgxKwwN1cnveXUdP6y2YmTW7XoAYs5YUzKqHajpY58EyucAL2y++6+573t5y4U/9IIoww== +"@react-native-community/cli-platform-android@^6.0.0", "@react-native-community/cli-platform-android@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz#ab7d156bd69a392493323eeaba839a874c0e201f" + integrity sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ== dependencies: - "@react-native-community/cli-tools" "^5.0.1" - chalk "^3.0.0" + "@react-native-community/cli-tools" "^6.2.0" + chalk "^4.1.2" execa "^1.0.0" fs-extra "^8.1.0" glob "^7.1.3" @@ -1435,26 +1444,43 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^5.0.1-alpha.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-5.0.2.tgz#62485534053c0dad28a67de188248de177f4b0fb" - integrity sha512-IAJ2B3j2BTsQUJZ4R6cVvnTbPq0Vza7+dOgP81ISz2BKRtQ0VqNFv+VOALH2jLaDzf4t7NFlskzIXFqWqy2BLg== +"@react-native-community/cli-platform-ios@^6.0.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz#ceaa23995511a8e400b506632ac7e6a66a17ec2a" + integrity sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg== dependencies: - "@react-native-community/cli-tools" "^5.0.1" - chalk "^3.0.0" + "@react-native-community/cli-tools" "^6.2.0" + chalk "^4.1.2" glob "^7.1.3" js-yaml "^3.13.1" lodash "^4.17.15" - plist "^3.0.1" + ora "^3.4.0" + plist "^3.0.2" xcode "^2.0.0" -"@react-native-community/cli-server-api@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-5.0.1.tgz#3cf92dac766fab766afedf77df3fe4d5f51e4d2b" - integrity sha512-OOxL+y9AOZayQzmSW+h5T54wQe+QBc/f67Y9QlWzzJhkKJdYx+S4VOooHoD5PFJzGbYaxhu2YF17p517pcEIIA== +"@react-native-community/cli-plugin-metro@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.2.0.tgz#143f459f1b6d595011e787ecfbe87621195de6ae" + integrity sha512-JfmzuFNzOr+dFTUQJo1rV0t87XAqgHRTMYXNleQVt8otOVCk1FSCgKlgqMdvQc/FCx2ZjoMWEEV/g0LrPI8Etw== dependencies: - "@react-native-community/cli-debugger-ui" "^5.0.1" - "@react-native-community/cli-tools" "^5.0.1" + "@react-native-community/cli-server-api" "^6.2.0" + "@react-native-community/cli-tools" "^6.2.0" + chalk "^4.1.2" + metro "^0.66.1" + metro-config "^0.66.1" + metro-core "^0.66.1" + metro-react-native-babel-transformer "^0.66.1" + metro-resolver "^0.66.1" + metro-runtime "^0.66.1" + readline "^1.3.0" + +"@react-native-community/cli-server-api@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-6.2.0.tgz#8dc399ef0e14e07c9942515b507292fb850f41f2" + integrity sha512-OnbnYclhoDpjge33QO5Slhfn0DsmLzzAgyrSCnb24HhSqwq7ObjMHaLpoEhpajzLG71wq5oKh0APEQjiL4Mknw== + dependencies: + "@react-native-community/cli-debugger-ui" "^6.0.0-rc.0" + "@react-native-community/cli-tools" "^6.2.0" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.0" @@ -1463,37 +1489,40 @@ serve-static "^1.13.1" ws "^1.1.0" -"@react-native-community/cli-tools@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-5.0.1.tgz#9ee564dbe20448becd6bce9fbea1b59aa5797919" - integrity sha512-XOX5w98oSE8+KnkMZZPMRT7I5TaP8fLbDl0tCu40S7Epz+Zz924n80fmdu6nUDIfPT1nV6yH1hmHmWAWTDOR+Q== +"@react-native-community/cli-tools@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz#8f4adc2d83ab96e5654348533c8fa602742c4fce" + integrity sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA== dependencies: - chalk "^3.0.0" + appdirsjs "^1.2.4" + chalk "^4.1.2" lodash "^4.17.15" mime "^2.4.1" node-fetch "^2.6.0" open "^6.2.0" + semver "^6.3.0" shell-quote "1.6.1" -"@react-native-community/cli-types@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-5.0.1.tgz#8c5db4011988b0836d27a5efe230cb34890915dc" - integrity sha512-BesXnuFFlU/d1F3+sHhvKt8fUxbQlAbZ3hhMEImp9A6sopl8TEtryUGJ1dbazGjRXcADutxvjwT/i3LJVTIQug== +"@react-native-community/cli-types@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-6.0.0.tgz#90269fbdc7229d5e3b8f2f3e029a94083551040d" + integrity sha512-K493Fk2DMJC0ZM8s8gnfseKxGasIhuDaCUDeLZcoCSFlrjKEuEs1BKKEJiev0CARhKEXKOyyp/uqYM9nWhisNw== dependencies: ora "^3.4.0" -"@react-native-community/cli@^5.0.1-alpha.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-5.0.1.tgz#1f7a66d813d5daf102e593f3c550650fa0cc8314" - integrity sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw== +"@react-native-community/cli@^6.0.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-6.3.0.tgz#27e3fdd544fcbb7035c368f81847172709c17a4f" + integrity sha512-rMdm/S8i5VIDQBJAU6YfNz15uwdguht0wVUOrJpEW8DCTKDfATanTlc5a1bsi0vitl9lS896VrgBiuW/VFOOXA== dependencies: - "@react-native-community/cli-debugger-ui" "^5.0.1" - "@react-native-community/cli-hermes" "^5.0.1" - "@react-native-community/cli-server-api" "^5.0.1" - "@react-native-community/cli-tools" "^5.0.1" - "@react-native-community/cli-types" "^5.0.1" + "@react-native-community/cli-debugger-ui" "^6.0.0-rc.0" + "@react-native-community/cli-hermes" "^6.3.0" + "@react-native-community/cli-plugin-metro" "^6.2.0" + "@react-native-community/cli-server-api" "^6.2.0" + "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-types" "^6.0.0" appdirsjs "^1.2.4" - chalk "^3.0.0" + chalk "^4.1.2" command-exists "^1.2.8" commander "^2.19.0" cosmiconfig "^5.1.0" @@ -1507,14 +1536,7 @@ joi "^17.2.1" leven "^3.1.0" lodash "^4.17.15" - metro "^0.64.0" - metro-config "^0.64.0" - metro-core "^0.64.0" - metro-react-native-babel-transformer "^0.64.0" - metro-resolver "^0.64.0" - metro-runtime "^0.64.0" minimist "^1.2.0" - mkdirp "^0.5.1" node-stream-zip "^1.9.1" ora "^3.4.0" pretty-format "^26.6.2" @@ -1535,25 +1557,25 @@ resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-1.0.0.tgz#c52a99d4fe01049102d47dc45d40cbde4f720ab6" integrity sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg== -"@react-native/polyfills@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-1.0.0.tgz#05bb0031533598f9458cf65a502b8df0eecae780" - integrity sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w== +"@react-native/polyfills@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" + integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ== -"@release-it/conventional-changelog@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@release-it/conventional-changelog/-/conventional-changelog-2.0.1.tgz#bdd52ad3ecc0d6e39d637592d6ea2bd6d28e5ecb" - integrity sha512-q67D3Jod935kZt6wThsDeOmhY+RWYPMY7nYyl0YxiXK8vVZzD+9z957fXGz+8Uk3iugmgDaucht7VxTaZlu6nA== +"@release-it/conventional-changelog@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@release-it/conventional-changelog/-/conventional-changelog-3.3.0.tgz#0f79e4b736412040d37c2b84bf433e393268c08e" + integrity sha512-pchCHf+wNpn15oj2hau4gisFKQat/01JuTzAwlGsQE83ZUBknU4dRlPA3xf5F5f3K70VVTQ3lx4/lgQvR+zxww== dependencies: concat-stream "^2.0.0" conventional-changelog "^3.1.24" conventional-recommended-bump "^6.1.0" prepend-file "^2.0.0" -"@sideway/address@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1" - integrity sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA== +"@sideway/address@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.3.tgz#d93cce5d45c5daec92ad76db492cc2ee3c64ab27" + integrity sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ== dependencies: "@hapi/hoek" "^9.0.0" @@ -1584,10 +1606,10 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== dependencies: "@sinonjs/commons" "^1.7.0" @@ -1610,10 +1632,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" - integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.17" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64" + integrity sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1691,13 +1713,13 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.0": - version "26.0.24" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" - integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== +"@types/jest@^27.0.3": + version "27.0.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.3.tgz#0cf9dfe9009e467f70a342f0f94ead19842a783a" + integrity sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg== dependencies: - jest-diff "^26.0.0" - pretty-format "^26.0.0" + jest-diff "^27.0.0" + pretty-format "^27.0.0" "@types/keyv@*": version "3.1.3" @@ -1712,9 +1734,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "16.11.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.10.tgz#2e3ad0a680d96367103d3e670d41c2fed3da61ae" - integrity sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA== + version "16.11.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10" + integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1726,7 +1748,7 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/prettier@^2.0.0": +"@types/prettier@^2.1.5": version "2.4.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.2.tgz#4c62fae93eb479660c3bd93f9d24d561597a8281" integrity sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA== @@ -1736,14 +1758,14 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== -"@types/react-native@0.62.13": - version "0.62.13" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.62.13.tgz#c688c5ae03e426f927f7e1fa1a59cd067f35d1c2" - integrity sha512-hs4/tSABhcJx+J8pZhVoXHrOQD89WFmbs8QiDLNSA9zNrD46pityAuBWuwk1aMjPk9I3vC5ewkJroVRHgRIfdg== +"@types/react-native@0.66.8": + version "0.66.8" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.66.8.tgz#0f9d42202452e9951e4f45277c254de12d1e11b9" + integrity sha512-xiW7MfTPzd6xsJB8VEtheF9RH1Vyr1FlbM5jguMa+3ZtnFlE38H4TZSCFAaA3YGIZDnAOlG7qT13RUWyFpW2uw== dependencies: "@types/react" "*" -"@types/react@*": +"@types/react@*", "@types/react@^17.0.37": version "17.0.37" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.37.tgz#6884d0aa402605935c397ae689deed115caad959" integrity sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg== @@ -1752,15 +1774,6 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@^16.9.19": - version "16.14.21" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.21.tgz#35199b21a278355ec7a3c40003bd6a334bd4ae4a" - integrity sha512-rY4DzPKK/4aohyWiDRHS2fotN5rhBSK6/rz1X37KzNna9HJyqtaGAbq9fVttrEPWF5ywpfIP1ITL8Xi2QZn6Eg== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" @@ -1790,6 +1803,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -1918,6 +1938,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2030,11 +2055,6 @@ async-retry@1.3.3: dependencies: retry "0.13.1" -async@0.9.x: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= - async@^2.4.0: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -2062,16 +2082,16 @@ babel-core@^7.0.0-bridge.0: resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== -babel-jest@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" - integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== +babel-jest@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.2.tgz#6edf80971045cfd44f3f10b6eda6007d95f62742" + integrity sha512-MADrjb3KBO2eyZCAc6QaJg6RT5u+6oEdDyHO5HEalnpwQ6LrhTsQF2Kj1Wnz2t6UPXIXPk18dSXXOT0wF5yTxA== dependencies: - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/babel__core" "^7.1.7" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" + "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^26.6.2" + babel-preset-jest "^27.4.0" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -2094,10 +2114,10 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" - integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== +babel-plugin-jest-hoist@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" + integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -2151,7 +2171,7 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-fbjs@^3.3.0: +babel-preset-fbjs@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== @@ -2184,12 +2204,12 @@ babel-preset-fbjs@^3.3.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" - integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== +babel-preset-jest@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" + integrity sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg== dependencies: - babel-plugin-jest-hoist "^26.6.2" + babel-plugin-jest-hoist "^27.4.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -2337,11 +2357,6 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2445,9 +2460,9 @@ camelcase@^6.0.0, camelcase@^6.2.0: integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== caniuse-lite@^1.0.30001280: - version "1.0.30001283" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz#8573685bdae4d733ef18f78d44ba0ca5fe9e896b" - integrity sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg== + version "1.0.30001285" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz#fe1e52229187e11d6670590790d669b9e03315b7" + integrity sha512-KAOkuUtcQ901MtmvxfKD+ODHH9YVDYnBt+TGYSz2KIfnq22CiArbUxXPN9067gNbgMlnNYRSwho8OPXZPALB9Q== capture-exit@^2.0.0: version "2.0.0" @@ -2456,7 +2471,7 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2473,14 +2488,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -2501,10 +2508,10 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== -cjs-module-lexer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" - integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== class-utils@^0.3.5: version "0.3.6" @@ -2909,9 +2916,9 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.18.0, core-js-compat@^3.19.1: - version "3.19.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.2.tgz#18066a3404a302433cb0aa8be82dd3d75c76e5c4" - integrity sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ== + version "3.19.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.3.tgz#de75e5821c5ce924a0a1e7b7d5c2cb973ff388aa" + integrity sha512-59tYzuWgEEVU9r+SRgceIGXSSUn47JknoiXW6Oq7RW8QHjXWz3/vp8pa7dbtuVu40sewz3OP3JmQEcDdztrLhA== dependencies: browserslist "^4.18.1" semver "7.0.0" @@ -3194,10 +3201,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== +diff-sequences@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" + integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== dir-glob@^3.0.1: version "3.0.1" @@ -3230,22 +3237,15 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^3.1.5: - version "3.1.6" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" - integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== - dependencies: - jake "^10.6.1" - electron-to-chromium@^1.3.896: - version "1.4.5" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz#912e8fd1645edee2f0f212558f40916eb538b1f9" - integrity sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw== + version "1.4.14" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.14.tgz#b0aa41fbfbf2eff8c2c6f7a871c03075250f8956" + integrity sha512-RsGkAN9JEAYMObS72kzUsPPcPGMqX1rBqGuXi9aa4TBKLzICoLf+DAAtd0fVFzrniJqYzpby47gthCUoObfs0Q== -emittery@^0.7.1: - version "0.7.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" - integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== emoji-regex@^8.0.0: version "8.0.0" @@ -3358,7 +3358,7 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== -execa@5.1.1: +execa@5.1.1, execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -3386,7 +3386,7 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^4.0.0, execa@^4.0.2, execa@^4.0.3: +execa@^4.0.2, execa@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== @@ -3419,17 +3419,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" - integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== +expect@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.2.tgz#4429b0f7e307771d176de9bdf23229b101db6ef6" + integrity sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg== dependencies: - "@jest/types" "^26.6.2" - ansi-styles "^4.0.0" - jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" + "@jest/types" "^27.4.2" + ansi-styles "^5.0.0" + jest-get-type "^27.4.0" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-regex-util "^27.4.0" extend-shallow@^2.0.1: version "2.0.1" @@ -3511,13 +3511,6 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -filelist@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b" - integrity sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ== - dependencies: - minimatch "^3.0.4" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -3590,9 +3583,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flow-parser@0.*: - version "0.165.1" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.165.1.tgz#e420c560d0c9bd0e546b9f1b79afed37174298c5" - integrity sha512-vz/5MZIePDCZO9FfnRaH398cc+XSwtgoUzR6pC5zbekpk5ttCaXOnxypho+hb0NzUyQNFV+6vpU8joRZ1llrCw== + version "0.166.1" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.166.1.tgz#6869ab40bd71e1129053f53435864b08616d57e9" + integrity sha512-7iJ1cPcOYL/eOPGpGPaxwW8MytKGeXSnfvJA0uIvymXI4MnjjhZLWz1qPIqj2hfYJ7p/yXssbv7k2H3C90cyDw== flow-parser@^0.121.0: version "0.121.0" @@ -3667,7 +3660,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2: +fsevents@^2.1.2, fsevents@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -3735,13 +3728,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -gh-got@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-8.1.0.tgz#2378d07ac293f524549c75f8dc6f3604a885ab01" - integrity sha512-Jy7+73XqsAVeAtM5zA0dd+A7mmzkQVIzFuw3xRjFbPsQVqS+aeci8v8H1heOCAPlBYWED5ZYPhlYqZVXdD3Fmg== - dependencies: - got "^9.5.0" - git-raw-commits@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" @@ -3791,13 +3777,6 @@ gitconfiglocal@^1.0.0: dependencies: ini "^1.3.2" -github-username@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/github-username/-/github-username-5.0.1.tgz#f4e8c2cd7a3247bd75ae2841f5f69347f5b4c1f0" - integrity sha512-HxFIz5tIQDoiob2ienSKLHoCSFFC6F79IcnM5E5KNAxkxMjvpuUSE7K4fU2n51fwo0idT0ZsMFZIUy4SIPXoVA== - dependencies: - gh-got "^8.1.0" - glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -3858,7 +3837,7 @@ got@11.8.3: p-cancelable "^2.0.0" responselike "^2.0.0" -got@^9.5.0, got@^9.6.0: +got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== @@ -3880,11 +3859,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - handlebars@^4.7.6: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -3960,10 +3934,15 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hermes-engine@~0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.7.2.tgz#303cd99d23f68e708b223aec2d49d5872985388b" - integrity sha512-E2DkRaO97gwL98LPhgfkMqhHiNsrAjIfEk3wWYn2Y31xdkdWn0572H7RnVcGujMJVqZNJvtknxlpsUb8Wzc3KA== +hermes-engine@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.9.0.tgz#84d9cfe84e8f6b1b2020d6e71b350cec84ed982f" + integrity sha512-r7U+Y4P2Qg/igFVZN+DpT7JFfXUn1MM4dFne8aW+cCrF6RRymof+VqrUHs1kl07j8h8V2CNesU19RKgWbr3qPw== + +hermes-parser@0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.4.7.tgz#410f5129d57183784d205a0538e6fbdcf614c9ea" + integrity sha512-jc+zCtXbtwTiXoMAoXOHepxAaGVFIp89wwE9qcdwnMd/uGVEtPoY8FaFSsx0ThPvyKirdR2EsIIDVrpbSXz1Ag== hermes-profile-transformer@^0.0.6: version "0.0.6" @@ -4457,7 +4436,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.1, is-wsl@^2.2.0: +is-wsl@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -4536,134 +4515,157 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384" - integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.1.tgz#7085857f17d2441053c6ce5c3b8fdf6882289397" + integrity sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jake@^10.6.1: - version "10.8.2" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" - integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== +jest-changed-files@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" + integrity sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A== dependencies: - async "0.9.x" - chalk "^2.4.2" - filelist "^1.0.1" - minimatch "^3.0.4" + "@jest/types" "^27.4.2" + execa "^5.0.0" + throat "^6.0.1" -jest-changed-files@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" - integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== +jest-circus@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.2.tgz#466f482207ca9f323b78416c28f4d1fa7588159a" + integrity sha512-2ePUSru1BGMyzxsMvRfu+tNb+PW60rUyMLJBfw1Nrh5zC8RoTPfF+zbE0JToU31a6ZVe4nnrNKWYRzlghAbL0A== dependencies: - "@jest/types" "^26.6.2" - execa "^4.0.0" - throat "^5.0.0" + "@jest/environment" "^27.4.2" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.4.2" + is-generator-fn "^2.0.0" + jest-each "^27.4.2" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-runtime "^27.4.2" + jest-snapshot "^27.4.2" + jest-util "^27.4.2" + pretty-format "^27.4.2" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" -jest-cli@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" - integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== +jest-cli@^27.4.3: + version "27.4.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.4.3.tgz#89acba683b9f91c7a5e342e2ea13aa5414836a0d" + integrity sha512-zZSJBXNC/i8UnJPwcKWsqnhGgIF3uoTYP7th32Zej7KNQJdxzOMj+wCfy2Ox3kU7nXErJ36DtYyXDhfiqaiDRw== dependencies: - "@jest/core" "^26.6.3" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/core" "^27.4.3" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" - is-ci "^2.0.0" - jest-config "^26.6.3" - jest-util "^26.6.2" - jest-validate "^26.6.2" + jest-config "^27.4.3" + jest-util "^27.4.2" + jest-validate "^27.4.2" prompts "^2.0.1" - yargs "^15.4.1" + yargs "^16.2.0" -jest-config@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" - integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== +jest-config@^27.4.3: + version "27.4.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.4.3.tgz#7820e08f7526fa3f725423e2f0fa7888ee0ef9c9" + integrity sha512-DQ10HTSqYtC2pO7s9j2jw+li4xUnm2wLYWH2o7K1ftB8NyvToHsXoLlXxtsGh3AW9gUQR6KY/4B7G+T/NswJBw== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.6.3" - "@jest/types" "^26.6.2" - babel-jest "^26.6.3" + "@jest/test-sequencer" "^27.4.2" + "@jest/types" "^27.4.2" + babel-jest "^27.4.2" chalk "^4.0.0" + ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-environment-jsdom "^26.6.2" - jest-environment-node "^26.6.2" - jest-get-type "^26.3.0" - jest-jasmine2 "^26.6.3" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - micromatch "^4.0.2" - pretty-format "^26.6.2" + jest-circus "^27.4.2" + jest-environment-jsdom "^27.4.3" + jest-environment-node "^27.4.2" + jest-get-type "^27.4.0" + jest-jasmine2 "^27.4.2" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.2" + jest-runner "^27.4.3" + jest-util "^27.4.2" + jest-validate "^27.4.2" + micromatch "^4.0.4" + pretty-format "^27.4.2" + slash "^3.0.0" -jest-diff@^26.0.0, jest-diff@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== +jest-diff@^27.0.0, jest-diff@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" + integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== dependencies: chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + diff-sequences "^27.4.0" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-docblock@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" - integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== +jest-docblock@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" + integrity sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg== dependencies: detect-newline "^3.0.0" -jest-each@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" - integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== +jest-each@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.4.2.tgz#19364c82a692d0d26557642098d1f4619c9ee7d3" + integrity sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" chalk "^4.0.0" - jest-get-type "^26.3.0" - jest-util "^26.6.2" - pretty-format "^26.6.2" + jest-get-type "^27.4.0" + jest-util "^27.4.2" + pretty-format "^27.4.2" -jest-environment-jsdom@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" - integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== +jest-environment-jsdom@^27.4.3: + version "27.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.3.tgz#74198285f6284888ca9c7486c4e5e67add75aa53" + integrity sha512-x1AUVz3G14LpEJs7KIFUaTINT2n0unOUmvdAby3s/sldUpJJetOJifHo1O/EUQC5fNBowggwJbVulko18y6OWw== dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^27.4.2" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" - jsdom "^16.4.0" + jest-mock "^27.4.2" + jest-util "^27.4.2" + jsdom "^16.6.0" -jest-environment-node@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" - integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== +jest-environment-node@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.2.tgz#bf5586a0924a8d21c13838121ac0941638c7d15e" + integrity sha512-nzTZ5nJ+FabuZPH2YVci7SZIHpvtNRHPt8+vipLkCnAgXGjVzHm7XJWdnNqXbAkExIgiKeVEkVMNZOZE/LeiIg== dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^27.4.2" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-mock "^27.4.2" + jest-util "^27.4.2" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^26.5.2, jest-haste-map@^26.6.2: +jest-get-type@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" + integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== + +jest-haste-map@^26.5.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== @@ -4684,69 +4686,89 @@ jest-haste-map@^26.5.2, jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" - integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== +jest-haste-map@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.2.tgz#7fc7d5e568cca704284f4850885b74a0b8b87587" + integrity sha512-foiyAEePORUN2eeJnOtcM1y8qW0ShEd9kTjWVL4sVaMcuCJM6gtHegvYPBRT0mpI/bs4ueThM90+Eoj2ncoNsA== + dependencies: + "@jest/types" "^27.4.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^27.4.0" + jest-serializer "^27.4.0" + jest-util "^27.4.2" + jest-worker "^27.4.2" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.2.tgz#c956c88b9c05ca22afdc779deebc2890cb891797" + integrity sha512-VO/fyAJSH9u0THjbteFiL8qc93ufU+yW+bdieDc8tzTCWwlWzO53UHS5nFK1qmE8izb5Smkn+XHlVt6/l06MKQ== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^27.4.2" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^26.6.2" + expect "^27.4.2" is-generator-fn "^2.0.0" - jest-each "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - pretty-format "^26.6.2" - throat "^5.0.0" + jest-each "^27.4.2" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-runtime "^27.4.2" + jest-snapshot "^27.4.2" + jest-util "^27.4.2" + pretty-format "^27.4.2" + throat "^6.0.1" -jest-leak-detector@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" - integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== +jest-leak-detector@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz#7fc3120893a7a911c553f3f2bdff9faa4454abbb" + integrity sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw== dependencies: - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-matcher-utils@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" - integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== +jest-matcher-utils@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" + integrity sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ== dependencies: chalk "^4.0.0" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + jest-diff "^27.4.2" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-message-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" - integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== +jest-message-util@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.2.tgz#07f3f1bf207d69cf798ce830cc57f1a849f99388" + integrity sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w== dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.2" + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.4.2" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" - micromatch "^4.0.2" - pretty-format "^26.6.2" + micromatch "^4.0.4" + pretty-format "^27.4.2" slash "^3.0.0" - stack-utils "^2.0.2" + stack-utils "^2.0.3" -jest-mock@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" - integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== +jest-mock@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.4.2.tgz#184ff197a25491bfe4570c286daa5d62eb760b88" + integrity sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -4759,87 +4781,95 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" - integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== - dependencies: - "@jest/types" "^26.6.2" - jest-regex-util "^26.0.0" - jest-snapshot "^26.6.2" +jest-regex-util@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" + integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== -jest-resolve@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" - integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== +jest-resolve-dependencies@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.2.tgz#2f4f363cca26f75a22aefd496f9c7ae65b3de37f" + integrity sha512-hb++cTpqvOWfU49MCP/JQkxmnrhKoAVqXWFjgYXswRSVGk8Q6bDTSvhbCeYXDtXaymY0y7WrrSIlKogClcKJuw== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" + jest-regex-util "^27.4.0" + jest-snapshot "^27.4.2" + +jest-resolve@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.2.tgz#d3e4cbee7acb4a4f8c8bfc270767bec34d2aefaf" + integrity sha512-d/zqPjxCzMqHlOdRTg8cTpO9jY+1/T74KazT8Ws/LwmwxV5sRMWOkiLjmzUCDj/5IqA5XHNK4Hkmlq9Kdpb9Sg== + dependencies: + "@jest/types" "^27.4.2" chalk "^4.0.0" graceful-fs "^4.2.4" + jest-haste-map "^27.4.2" jest-pnp-resolver "^1.2.2" - jest-util "^26.6.2" - read-pkg-up "^7.0.1" - resolve "^1.18.1" + jest-util "^27.4.2" + jest-validate "^27.4.2" + resolve "^1.20.0" + resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" - integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== +jest-runner@^27.4.3: + version "27.4.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.3.tgz#9f05d4733829787778e8a143ade913834d0828dc" + integrity sha512-JgR6Om/j22Fd6ZUUIGTWNcCtuZVYbNrecb4k89W4UyFJoRtHpo2zMKWkmFFFJoqwWGrfrcPLnVBIgkJiTV3cyA== dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.4.2" + "@jest/environment" "^27.4.2" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" - emittery "^0.7.1" + emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-docblock "^26.0.0" - jest-haste-map "^26.6.2" - jest-leak-detector "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" - jest-runtime "^26.6.3" - jest-util "^26.6.2" - jest-worker "^26.6.2" + jest-docblock "^27.4.0" + jest-environment-jsdom "^27.4.3" + jest-environment-node "^27.4.2" + jest-haste-map "^27.4.2" + jest-leak-detector "^27.4.2" + jest-message-util "^27.4.2" + jest-resolve "^27.4.2" + jest-runtime "^27.4.2" + jest-util "^27.4.2" + jest-worker "^27.4.2" source-map-support "^0.5.6" - throat "^5.0.0" + throat "^6.0.1" -jest-runtime@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" - integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== +jest-runtime@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.2.tgz#d72da8a0e97366c16ad515a2c437191a72600d38" + integrity sha512-eqPgcBaUNaw6j8T5M+dnfAEh6MIrh2YmtskCr9sl50QYpD22Sg+QqHw3J3nmaLzVMbBtOMHFFxLF0Qx8MsZVFQ== dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/globals" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/yargs" "^15.0.0" + "@jest/console" "^27.4.2" + "@jest/environment" "^27.4.2" + "@jest/globals" "^27.4.2" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" + "@types/yargs" "^16.0.0" chalk "^4.0.0" - cjs-module-lexer "^0.6.0" + cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" + execa "^5.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" + jest-haste-map "^27.4.2" + jest-message-util "^27.4.2" + jest-mock "^27.4.2" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.2" + jest-snapshot "^27.4.2" + jest-util "^27.4.2" + jest-validate "^27.4.2" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^15.4.1" + yargs "^16.2.0" jest-serializer@^26.6.2: version "26.6.2" @@ -4849,26 +4879,42 @@ jest-serializer@^26.6.2: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" - integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== +jest-serializer@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" + integrity sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ== dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.0.0" - chalk "^4.0.0" - expect "^26.6.2" + "@types/node" "*" graceful-fs "^4.2.4" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - jest-haste-map "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" + +jest-snapshot@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.2.tgz#bd1ea04a8fab402e5ab18b788809fa597ddff532" + integrity sha512-DI7lJlNIu6WSQ+esqhnJzEzU70+dV+cNjoF1c+j5FagWEd3KtOyZvVliAH0RWNQ6KSnAAnKSU0qxJ8UXOOhuUQ== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/parser" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.4.2" + "@jest/types" "^27.4.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.4.2" + graceful-fs "^4.2.4" + jest-diff "^27.4.2" + jest-get-type "^27.4.0" + jest-haste-map "^27.4.2" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-resolve "^27.4.2" + jest-util "^27.4.2" natural-compare "^1.4.0" - pretty-format "^26.6.2" + pretty-format "^27.4.2" semver "^7.3.2" jest-util@^26.6.2: @@ -4883,7 +4929,19 @@ jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" -jest-validate@^26.5.2, jest-validate@^26.6.2: +jest-util@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" + integrity sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA== + dependencies: + "@jest/types" "^27.4.2" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.4" + picomatch "^2.2.3" + +jest-validate@^26.5.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== @@ -4895,17 +4953,29 @@ jest-validate@^26.5.2, jest-validate@^26.6.2: leven "^3.1.0" pretty-format "^26.6.2" -jest-watcher@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" - integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== +jest-validate@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.4.2.tgz#eecfcc1b1c9429aa007da08a2bae4e32a81bbbc3" + integrity sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A== dependencies: - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/types" "^27.4.2" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.4.0" + leven "^3.1.0" + pretty-format "^27.4.2" + +jest-watcher@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.4.2.tgz#c9037edfd80354c9fe90de4b6f8b6e2b8e736744" + integrity sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg== + dependencies: + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.6.2" + jest-util "^27.4.2" string-length "^4.0.1" jest-worker@^26.0.0, jest-worker@^26.6.2: @@ -4917,14 +4987,23 @@ jest-worker@^26.0.0, jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^26.0.1: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" - integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== +jest-worker@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.2.tgz#0fb123d50955af1a450267787f340a1bf7e12bc4" + integrity sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag== dependencies: - "@jest/core" "^26.6.3" + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.4.3: + version "27.4.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.3.tgz#cf7d1876a84c70efece2e01e4f9dfc2e464d9cbb" + integrity sha512-jwsfVABBzuN3Atm+6h6vIEpTs9+VApODLt4dk2qv1WMOpb1weI1IIZfuwpMiWZ62qvWj78MvdvMHIYdUfqrFaA== + dependencies: + "@jest/core" "^27.4.3" import-local "^3.0.2" - jest-cli "^26.6.3" + jest-cli "^27.4.3" jetifier@^1.6.2, jetifier@^1.6.6: version "1.6.8" @@ -4932,13 +5011,13 @@ jetifier@^1.6.2, jetifier@^1.6.6: integrity sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw== joi@^17.2.1: - version "17.4.2" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.2.tgz#02f4eb5cf88e515e614830239379dcbbe28ce7f7" - integrity sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw== + version "17.5.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.5.0.tgz#7e66d0004b5045d971cf416a55fb61d33ac6e011" + integrity sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw== dependencies: "@hapi/hoek" "^9.0.0" "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.0" + "@sideway/address" "^4.1.3" "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" @@ -4955,10 +5034,10 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsc-android@^245459.0.0: - version "245459.0.0" - resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" - integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== +jsc-android@^250230.2.1: + version "250230.2.1" + resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250230.2.1.tgz#3790313a970586a03ab0ad47defbc84df54f1b83" + integrity sha512-KmxeBlRjwoqCnBBKGsihFtvsBHyUFlBxJPK4FzeYcIuBfdjv6jFys44JITAgSTbQD+vIdwMEfyZklsuQX0yI1Q== jscodeshift@^0.11.0: version "0.11.0" @@ -4985,7 +5064,7 @@ jscodeshift@^0.11.0: temp "^0.8.1" write-file-atomic "^2.3.0" -jsdom@^16.4.0: +jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== @@ -5345,92 +5424,93 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -metro-babel-register@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.64.0.tgz#1a2d23f68da8b8ee42e78dca37ad21a5f4d3647d" - integrity sha512-Kf6YvE3kIRumGnjK0Q9LqGDIdnsX9eFGtNBmBuCVDuB9wGGA/5CgX8We8W7Y44dz1RGTcHJRhfw5iGg+pwC3aQ== +metro-babel-register@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.66.2.tgz#c6bbe36c7a77590687ccd74b425dc020d17d05af" + integrity sha512-3F+vsVubUPJYKfVMeol8/7pd8CC287Rw92QYzJD8LEmI980xcgwMUEVBZ0UIAUwlLgiJG/f4Mwhuji2EeBXrPg== dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/core" "^7.14.0" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" "@babel/plugin-transform-flow-strip-types" "^7.0.0" "@babel/plugin-transform-modules-commonjs" "^7.0.0" "@babel/register" "^7.0.0" escape-string-regexp "^1.0.5" -metro-babel-transformer@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.64.0.tgz#a21f8a989a5ea60c1109456e21bd4d9374194ea0" - integrity sha512-itZaxKTgmKGEZWxNzbSZBc22NngrMZzoUNuU92aHSTGkYi2WH4XlvzEHsstmIKHMsRVKl75cA+mNmgk4gBFJKw== +metro-babel-transformer@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.66.2.tgz#fce0a3e314d28a5e7141c135665e1cc9b8e7ce86" + integrity sha512-aJ/7fc/Xkofw8Fqa51OTDhBzBz26mmpIWrXAZcPdQ8MSTt883EWncxeCEjasc79NJ89BRi7sOkkaWZo2sXlKvw== dependencies: - "@babel/core" "^7.0.0" - metro-source-map "0.64.0" + "@babel/core" "^7.14.0" + hermes-parser "0.4.7" + metro-source-map "0.66.2" nullthrows "^1.1.1" -metro-cache-key@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.64.0.tgz#98d0a94332453c4c52b74f72c07cc62a5c264c4f" - integrity sha512-O9B65G8L/fopck45ZhdRosyVZdMtUQuX5mBWEC1NRj02iWBIUPLmYMjrunqIe8vHipCMp3DtTCm/65IlBmO8jg== +metro-cache-key@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.66.2.tgz#d6463d2a53e887a38419d523962cc24ea0e780b4" + integrity sha512-WtkNmRt41qOpHh1MkNA4nLiQ/m7iGL90ysSKD+fcLqlUnOBKJptPQm0ZUv8Kfqk18ddWX2KmsSbq+Sf3I6XohQ== -metro-cache@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.64.0.tgz#a769503e12521d9e9d95ce5840ffb2efdb4e8703" - integrity sha512-QvGfxe/1QQYM9XOlR8W1xqE9eHDw/AgJIgYGn/TxZxBu9Zga+Rgs1omeSZju45D8w5VWgMr83ma5kACgzvOecg== +metro-cache@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.66.2.tgz#e0af4e0a319898f7d42a980f7ee5da153fcfd019" + integrity sha512-5QCYJtJOHoBSbL3H4/Fpl36oA697C3oYHqsce+Hk/dh2qtODUGpS3gOBhvP1B8iB+H8jJMyR75lZq129LJEsIQ== dependencies: - metro-core "0.64.0" + metro-core "0.66.2" mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@0.64.0, metro-config@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.64.0.tgz#b634fa05cffd06b1e50e4339c200f90a42924afb" - integrity sha512-QhM4asnX5KhlRWaugwVGNNXhX0Z85u5nK0UQ/A90bBb4xWyXqUe20e788VtdA75rkQiiI6wXTCIHWT0afbnjwQ== +metro-config@0.66.2, metro-config@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.66.2.tgz#e365acdb66ad0cda0182b9c9910760a97ee4293b" + integrity sha512-0C+PrKKIBNNzLZUKN/8ZDJS2U5FLMOTXDWbvBHIdqb6YXz8WplXR2+xlSlaSCCi5b+GR7cWFWUNeKA4GQS1/AQ== dependencies: cosmiconfig "^5.0.5" jest-validate "^26.5.2" - metro "0.64.0" - metro-cache "0.64.0" - metro-core "0.64.0" - metro-runtime "0.64.0" + metro "0.66.2" + metro-cache "0.66.2" + metro-core "0.66.2" + metro-runtime "0.66.2" -metro-core@0.64.0, metro-core@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.64.0.tgz#7616b27acfe7baa476f6cd6bd9e70ae64fa62541" - integrity sha512-v8ZQ5j72EaUwamQ8pLfHlOHTyp7SbdazvHPzFGDpHnwIQqIT0Bw3Syg8R4regTlVG3ngpeSEAi005UITljmMcQ== +metro-core@0.66.2, metro-core@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.66.2.tgz#ead776a17b3e5a307e6dc22259db30bf5c7e8490" + integrity sha512-JieLZkef/516yxXYvQxWnf3OWw5rcgWRy76K8JV/wr/i8LGVGulPAXlIi445/QZzXVydzRVASKAEVqyxM5F4mA== dependencies: jest-haste-map "^26.5.2" lodash.throttle "^4.1.1" - metro-resolver "0.64.0" + metro-resolver "0.66.2" -metro-hermes-compiler@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.64.0.tgz#e6043d7aa924e5b2be99bd3f602e693685d15386" - integrity sha512-CLAjVDWGAoGhbi2ZyPHnH5YDdfrDIx6+tzFWfHGIMTZkYBXsYta9IfYXBV8lFb6BIbrXLjlXZAOoosknetMPOA== +metro-hermes-compiler@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.66.2.tgz#30290748f83805faa601aa487632444915795823" + integrity sha512-nCVL1g9uR6vrw5+X1wjwZruRyMkndnzGRMqjqoljf+nGEqBTD607CR7elXw4fMWn/EM+1y0Vdq5altUu9LdgCA== -metro-inspector-proxy@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.64.0.tgz#9a481b3f49773d5418e028178efec68f861bec88" - integrity sha512-KywbH3GNSz9Iqw4UH3smgaV2dBHHYMISeN7ORntDL/G+xfgPc6vt13d+zFb907YpUcXj5N0vdoiAHI5V/0y8IA== +metro-inspector-proxy@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.66.2.tgz#a83c76bd2f2fd7b9240be92acf9a8b1d1404547a" + integrity sha512-gnLc9121eznwP0iiA9tCBW8qZjwIsCgwHWMF1g1Qaki9le9tzeJv3dK4/lFNGxyfSaLO7vahQEhsEYsiRnTROg== dependencies: connect "^3.6.5" debug "^2.2.0" ws "^1.1.5" yargs "^15.3.1" -metro-minify-uglify@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.64.0.tgz#da6ab4dda030e3211f5924e7f41ed308d466068f" - integrity sha512-DRwRstqXR5qfte9Nuwoov5dRXxL7fJeVlO5fGyOajWeO3+AgPjvjXh/UcLJqftkMWTPGUFuzAD5/7JC5v5FLWw== +metro-minify-uglify@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.66.2.tgz#6061dbee4f61e6d5bb3c100e4379ff6f2e16e42b" + integrity sha512-7TUK+L5CmB5x1PVnFbgmjzHW4CUadq9H5jgp0HfFoWT1skXAyEsx0DHkKDXwnot0khnNhBOEfl62ctQOnE110Q== dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.64.0.tgz#76861408681dfda3c1d962eb31a8994918c976f8" - integrity sha512-HcZ0RWQRuJfpPiaHyFQJzcym+/dDIVUPwUAXWoub/C4GkGu+mPjp8vqK6g0FxokCnnI2TK0gZTza2IDfiNNscQ== +metro-react-native-babel-preset@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.66.2.tgz#fddebcf413ad4ea617d4f47f7c1da401052de734" + integrity sha512-H/nLBAz0MgfDloSe1FjyH4EnbokHFdncyERvLPXDACY3ROVRCeUyFNo70ywRGXW2NMbrV4H7KUyU4zkfWhC2HQ== dependencies: - "@babel/core" "^7.0.0" + "@babel/core" "^7.14.0" "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" @@ -5443,6 +5523,7 @@ metro-react-native-babel-preset@0.64.0: "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" "@babel/plugin-syntax-optional-chaining" "^7.0.0" "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" "@babel/plugin-transform-block-scoping" "^7.0.0" "@babel/plugin-transform-classes" "^7.0.0" "@babel/plugin-transform-computed-properties" "^7.0.0" @@ -5470,97 +5551,98 @@ metro-react-native-babel-preset@0.64.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.64.0, metro-react-native-babel-transformer@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.64.0.tgz#eafef756972f20efdc51bd5361d55f8598355623" - integrity sha512-K1sHO3ODBFCr7uEiCQ4RvVr+cQg0EHQF8ChVPnecGh/WDD8udrTq9ECwB0dRfMjAvlsHtRUlJm6ZSI8UPgum2w== +metro-react-native-babel-transformer@0.66.2, metro-react-native-babel-transformer@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.66.2.tgz#768f341e7c3d3d1c38189799c9884b90d1c32eb7" + integrity sha512-z1ab7ihIT0pJrwgi9q2IH+LcW/xUWMQ0hH+Mrk7wbKQB0RnJdXFoxphrfoVHBHMUu+TBPetUcEkKawkK1e7Cng== dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.3.0" - metro-babel-transformer "0.64.0" - metro-react-native-babel-preset "0.64.0" - metro-source-map "0.64.0" + "@babel/core" "^7.14.0" + babel-preset-fbjs "^3.4.0" + hermes-parser "0.4.7" + metro-babel-transformer "0.66.2" + metro-react-native-babel-preset "0.66.2" + metro-source-map "0.66.2" nullthrows "^1.1.1" -metro-resolver@0.64.0, metro-resolver@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.64.0.tgz#21126b44f31346ac2ce0b06b77ef65e8c9e2294a" - integrity sha512-cJ26Id8Zf+HmS/1vFwu71K3u7ep/+HeXXAJIeVDYf+niE7AWB9FijyMtAlQgbD8elWqv1leJCnQ/xHRFBfGKYA== +metro-resolver@0.66.2, metro-resolver@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.66.2.tgz#f743ddbe7a12dd137d1f7a555732cafcaea421f8" + integrity sha512-pXQAJR/xauRf4kWFj2/hN5a77B4jLl0Fom5I3PHp6Arw/KxSBp0cnguXpGLwNQ6zQC0nxKCoYGL9gQpzMnN7Hw== dependencies: absolute-path "^0.0.0" -metro-runtime@0.64.0, metro-runtime@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.64.0.tgz#cdaa1121d91041bf6345f2a69eb7c2fb289eff7b" - integrity sha512-m7XbWOaIOeFX7YcxUhmnOi6Pg8EaeL89xyZ+quZyZVF1aNoTr4w8FfbKxvijpjsytKHIZtd+43m2Wt5JrqyQmQ== +metro-runtime@0.66.2, metro-runtime@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.66.2.tgz#3409ee957b949b6c7b72ef6ed2b9af9a4f4a910e" + integrity sha512-vFhKBk2ot9FS4b+2v0OTa/guCF/QDAOJubY0CNg7PzCS5+w4y3IvZIcPX4SSS1t8pYEZBLvtdtTDarlDl81xmg== -metro-source-map@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.64.0.tgz#4310e17c3d4539c6369688022494ad66fa4d39a1" - integrity sha512-OCG2rtcp5cLEGYvAbfkl6mEc0J2FPRP4/UCEly+juBk7hawS9bCBMBfhJm/HIsvY1frk6nT2Vsl1O8YBbwyx2g== +metro-source-map@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.66.2.tgz#b5304a282a5d55fa67b599265e9cf3217175cdd7" + integrity sha512-038tFmB7vSh73VQcDWIbr5O1m+WXWyYafDaOy+1A/2K308YP0oj33gbEgDnZsLZDwcJ+xt1x6KUEBIzlX4YGeQ== dependencies: - "@babel/traverse" "^7.0.0" + "@babel/traverse" "^7.14.0" "@babel/types" "^7.0.0" invariant "^2.2.4" - metro-symbolicate "0.64.0" + metro-symbolicate "0.66.2" nullthrows "^1.1.1" - ob1 "0.64.0" + ob1 "0.66.2" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.64.0.tgz#405c21438ab553c29f6841da52ca76ee87bb06ac" - integrity sha512-qIi+YRrDWnLVmydj6gwidYLPaBsakZRibGWSspuXgHAxOI3UuLwlo4dpQ73Et0gyHjI7ZvRMRY8JPiOntf9AQQ== +metro-symbolicate@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.66.2.tgz#addd095ce5f77e73ca21ddb5dfb396ff5d4fa041" + integrity sha512-u+DeQHyAFXVD7mVP+GST/894WHJ3i/U8oEJFnT7U3P52ZuLgX8n4tMNxhqZU12RcLR6etF8143aP0Ktx1gFLEQ== dependencies: invariant "^2.2.4" - metro-source-map "0.64.0" + metro-source-map "0.66.2" nullthrows "^1.1.1" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro-transform-plugins@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.64.0.tgz#41d3dce0f2966bbd79fea1ecff61bcc8a00e4665" - integrity sha512-iTIRBD/wBI98plfxj8jAoNUUXfXLNlyvcjPtshhpGvdwu9pzQilGfnDnOaaK+vbITcOk9w5oQectXyJwAqTr1A== +metro-transform-plugins@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.66.2.tgz#39dd044a23b1343e4f2d2ec34d08128cdf255ed4" + integrity sha512-KTvqplh0ut7oDKovvDG6yzXM02R6X+9b2oVG+qYq8Zd3aCGTi51ASx4ThCNkAHyEvCuJdYg9fxXTL+j+wvhB5w== dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.5.0" + "@babel/core" "^7.14.0" + "@babel/generator" "^7.14.0" "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" + "@babel/traverse" "^7.14.0" nullthrows "^1.1.1" -metro-transform-worker@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.64.0.tgz#f94429b2c42b13cb1c93be4c2e25e97f2d27ca60" - integrity sha512-wegRtK8GyLF6IPZRBJp+zsORgA4iX0h1DRpknyAMDCtSbJ4VU2xV/AojteOgAsDvY3ucAGsvfuZLNDJHUdUNHQ== +metro-transform-worker@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.66.2.tgz#0a8455992132c479721accd52c9bd47deb77769e" + integrity sha512-dO4PtYOMGB7Vzte8aIzX39xytODhmbJrBYPu+zYzlDjyefJZT7BkZ0LkPIThtyJi96xWcGqi9JBSo0CeRupAHw== dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/parser" "^7.0.0" + "@babel/core" "^7.14.0" + "@babel/generator" "^7.14.0" + "@babel/parser" "^7.14.0" "@babel/types" "^7.0.0" - babel-preset-fbjs "^3.3.0" - metro "0.64.0" - metro-babel-transformer "0.64.0" - metro-cache "0.64.0" - metro-cache-key "0.64.0" - metro-hermes-compiler "0.64.0" - metro-source-map "0.64.0" - metro-transform-plugins "0.64.0" + babel-preset-fbjs "^3.4.0" + metro "0.66.2" + metro-babel-transformer "0.66.2" + metro-cache "0.66.2" + metro-cache-key "0.66.2" + metro-hermes-compiler "0.66.2" + metro-source-map "0.66.2" + metro-transform-plugins "0.66.2" nullthrows "^1.1.1" -metro@0.64.0, metro@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.64.0.tgz#0091a856cfbcc94dd576da563eee466e96186195" - integrity sha512-G2OC08Rzfs0kqnSEuKo2yZxR+/eNUpA93Ru45c60uN0Dw3HPrDi+ZBipgFftC6iLE0l+6hu8roFFIofotWxybw== +metro@0.66.2, metro@^0.66.1: + version "0.66.2" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.66.2.tgz#f21759bf00995470e7577b5b88a5277963f24492" + integrity sha512-uNsISfcQ3iKKSHoN5Q+LAh0l3jeeg7ZcNZ/4BAHGsk02erA0OP+l2m+b5qYVoPptHz9Oc3KyG5oGJoTu41pWjg== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/core" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/parser" "^7.0.0" + "@babel/core" "^7.14.0" + "@babel/generator" "^7.14.0" + "@babel/parser" "^7.14.0" "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" + "@babel/traverse" "^7.14.0" "@babel/types" "^7.0.0" absolute-path "^0.0.0" accepts "^1.3.7" @@ -5573,27 +5655,28 @@ metro@0.64.0, metro@^0.64.0: error-stack-parser "^2.0.6" fs-extra "^1.0.0" graceful-fs "^4.1.3" + hermes-parser "0.4.7" image-size "^0.6.0" invariant "^2.2.4" jest-haste-map "^26.5.2" jest-worker "^26.0.0" lodash.throttle "^4.1.1" - metro-babel-register "0.64.0" - metro-babel-transformer "0.64.0" - metro-cache "0.64.0" - metro-cache-key "0.64.0" - metro-config "0.64.0" - metro-core "0.64.0" - metro-hermes-compiler "0.64.0" - metro-inspector-proxy "0.64.0" - metro-minify-uglify "0.64.0" - metro-react-native-babel-preset "0.64.0" - metro-resolver "0.64.0" - metro-runtime "0.64.0" - metro-source-map "0.64.0" - metro-symbolicate "0.64.0" - metro-transform-plugins "0.64.0" - metro-transform-worker "0.64.0" + metro-babel-register "0.66.2" + metro-babel-transformer "0.66.2" + metro-cache "0.66.2" + metro-cache-key "0.66.2" + metro-config "0.66.2" + metro-core "0.66.2" + metro-hermes-compiler "0.66.2" + metro-inspector-proxy "0.66.2" + metro-minify-uglify "0.66.2" + metro-react-native-babel-preset "0.66.2" + metro-resolver "0.66.2" + metro-runtime "0.66.2" + metro-source-map "0.66.2" + metro-symbolicate "0.66.2" + metro-transform-plugins "0.66.2" + metro-transform-worker "0.66.2" mime-types "^2.1.27" mkdirp "^0.5.1" node-fetch "^2.2.0" @@ -5810,23 +5893,6 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" - integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== - dependencies: - growly "^1.3.0" - is-wsl "^2.2.0" - semver "^7.3.2" - shellwords "^0.1.1" - uuid "^8.3.0" - which "^2.0.2" - node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" @@ -5903,10 +5969,10 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -ob1@0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.64.0.tgz#f254a55a53ca395c4f9090e28a85483eac5eba19" - integrity sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ== +ob1@0.66.2: + version "0.66.2" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.66.2.tgz#8caf548202cf2688944bae47db405a08bca17a61" + integrity sha512-RFewnL/RjE0qQBOuM+2bbY96zmJPIge/aDtsiDbLSb+MOiK8CReAhBHDgL+zrA3F1hQk00lMWpUwYcep750plA== object-assign@^4.1.1: version "4.1.1" @@ -5923,9 +5989,9 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + version "1.11.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" + integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -6074,11 +6140,6 @@ p-cancelable@^2.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== -p-each-series@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" - integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -6274,11 +6335,9 @@ pify@^4.0.1: integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pirates@^4.0.0, pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" + version "4.0.4" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" + integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== pkg-dir@^3.0.0: version "3.0.0" @@ -6294,7 +6353,7 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -plist@^3.0.1, plist@^3.0.4: +plist@^3.0.2, plist@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.4.tgz#a62df837e3aed2bb3b735899d510c4f186019cbe" integrity sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg== @@ -6331,11 +6390,11 @@ prepend-http@^2.0.0: integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= prettier@^2.0.5: - version "2.5.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.0.tgz#a6370e2d4594e093270419d9cc47f7670488f893" - integrity sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg== + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== -pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: +pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== @@ -6345,6 +6404,16 @@ pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^27.0.0, pretty-format@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" + integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== + dependencies: + "@jest/types" "^27.4.2" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -6365,7 +6434,7 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -6410,9 +6479,9 @@ q@^1.5.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qs@^6.9.4: - version "6.10.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" - integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + version "6.10.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.2.tgz#c1431bea37fc5b24c5bdbafa20f16bdf2a4b9ffe" + integrity sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw== dependencies: side-channel "^1.0.4" @@ -6456,7 +6525,7 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-devtools-core@^4.6.0: +react-devtools-core@^4.13.0: version "4.21.0" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.21.0.tgz#a54c9a0fd7261491e616d6c87d1869e011d8521d" integrity sha512-clGWwJHV5MHwTwYyKc+7FZHwzdbzrD2/AoZSkicUcr6YLc3Za9a9FaLhccWDHfjQ+ron9yzNhDT6Tv+FiPkD3g== @@ -6474,10 +6543,10 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-native-builder-bob@^0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/react-native-builder-bob/-/react-native-builder-bob-0.17.1.tgz#4bb12f721acf9417d62065232d42e0201b673315" - integrity sha512-vO3PYa/vgIqUFOfXZWNEsqQfjJMiNJAfJ0Sq4ovZa4zb/bnMKF4vDbARo3uhA8eg/wA0h4W6BlceY/Kjo74+6g== +react-native-builder-bob@^0.18.2: + version "0.18.2" + resolved "https://registry.yarnpkg.com/react-native-builder-bob/-/react-native-builder-bob-0.18.2.tgz#e3a96abe3ead84b167c1c1ea97747ef8ffc2a9f4" + integrity sha512-HA7ryoG99tkWh92s7Qb/619qAAfa3TMAKP4Q5l/smqZQwnJ77z5ESiPgRZl8gQMiCnrmmPVb/c5yUscKOL9GdQ== dependencies: "@babel/core" "^7.12.10" "@babel/plugin-proposal-class-properties" "^7.12.1" @@ -6491,61 +6560,57 @@ react-native-builder-bob@^0.17.1: cross-spawn "^7.0.3" dedent "^0.7.0" del "^6.0.0" - ejs "^3.1.5" fs-extra "^9.0.1" - github-username "^5.0.1" glob "^7.1.6" is-git-dirty "^2.0.1" json5 "^2.1.3" prompts "^2.4.0" - validate-npm-package-name "^3.0.0" which "^2.0.2" yargs "^16.2.0" optionalDependencies: jetifier "^1.6.6" -react-native-codegen@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.6.tgz#b3173faa879cf71bfade8d030f9c4698388f6909" - integrity sha512-cMvrUelD81wiPitEPiwE/TCNscIVauXxmt4NTGcy18HrUd0WRWXfYzAQGXm0eI87u3NMudNhqFj2NISJenxQHg== +react-native-codegen@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.7.tgz#86651c5c5fec67a8077ef7f4e36f7ed459043e14" + integrity sha512-dwNgR8zJ3ALr480QnAmpTiqvFo+rDtq6V5oCggKhYFlRjzOmVSFn3YD41u8ltvKS5G2nQ8gCs2vReFFnRGLYng== dependencies: flow-parser "^0.121.0" jscodeshift "^0.11.0" nullthrows "^1.1.1" -react-native@0.64.1: - version "0.64.1" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.64.1.tgz#cd38f5b47b085549686f34eb0c9dcd466f307635" - integrity sha512-jvSj+hNAfwvhaSmxd5KHJ5HidtG0pDXzoH6DaqNpU74g3CmAiA8vuk58B5yx/DYuffGq6PeMniAcwuh3Xp4biQ== +react-native@0.66.3: + version "0.66.3" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.66.3.tgz#25c7c4c7d81867326b3eb7a36f0fe6a61fa4104e" + integrity sha512-B/dQpuvta9YvF5MihDWefoGlTvxzUHK5X5RjdrXHAu/ihTehJXxEA+m6z/tufp1ZUMDjU+tMZK6gnehzCuYfzw== dependencies: - "@jest/create-cache-key-function" "^26.5.0" - "@react-native-community/cli" "^5.0.1-alpha.0" - "@react-native-community/cli-platform-android" "^5.0.1-alpha.0" - "@react-native-community/cli-platform-ios" "^5.0.1-alpha.0" + "@jest/create-cache-key-function" "^27.0.1" + "@react-native-community/cli" "^6.0.0" + "@react-native-community/cli-platform-android" "^6.0.0" + "@react-native-community/cli-platform-ios" "^6.0.0" "@react-native/assets" "1.0.0" "@react-native/normalize-color" "1.0.0" - "@react-native/polyfills" "1.0.0" + "@react-native/polyfills" "2.0.0" abort-controller "^3.0.0" anser "^1.4.9" base64-js "^1.1.2" event-target-shim "^5.0.1" - hermes-engine "~0.7.0" + hermes-engine "~0.9.0" invariant "^2.2.4" - jsc-android "^245459.0.0" - metro-babel-register "0.64.0" - metro-react-native-babel-transformer "0.64.0" - metro-runtime "0.64.0" - metro-source-map "0.64.0" + jsc-android "^250230.2.1" + metro-babel-register "0.66.2" + metro-react-native-babel-transformer "0.66.2" + metro-runtime "0.66.2" + metro-source-map "0.66.2" nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.0.3" prop-types "^15.7.2" - react-devtools-core "^4.6.0" - react-native-codegen "^0.0.6" + react-devtools-core "^4.13.0" + react-native-codegen "^0.0.7" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "^0.20.1" - shelljs "^0.8.4" + scheduler "^0.20.2" stacktrace-parser "^0.1.3" use-subscription "^1.0.0" whatwg-fetch "^3.0.0" @@ -6556,14 +6621,13 @@ react-refresh@^0.4.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA== -react@16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" - integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== +react@17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" read-pkg-up@^3.0.0: version "3.0.0" @@ -6623,6 +6687,11 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readline@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" + integrity sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw= + recast@^0.20.3: version "0.20.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" @@ -6810,7 +6879,12 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.18.1: +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -6962,7 +7036,7 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -scheduler@^0.20.1: +scheduler@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== @@ -7099,7 +7173,7 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== -shelljs@0.8.4, shelljs@^0.8.4: +shelljs@0.8.4: version "0.8.4" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== @@ -7108,11 +7182,6 @@ shelljs@0.8.4, shelljs@^0.8.4: interpret "^1.0.0" rechoir "^0.6.2" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -7281,7 +7350,7 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -stack-utils@^2.0.2: +stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== @@ -7419,6 +7488,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" @@ -7490,6 +7566,11 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + through2@^2.0.0, through2@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -7678,9 +7759,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.14.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" - integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g== + version "3.14.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.4.tgz#68756f17d1b90b9d289341736cb9a567d6882f90" + integrity sha512-AbiSR44J0GoCeV81+oxcy/jDOElO2Bx3d0MfQCUShq7JRXaM4KtQopZsq2vFv8bCq2yMaGrw1FgygUd03RyRDA== ultron@1.0.x: version "1.0.2" @@ -7819,7 +7900,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@8.3.2, uuid@^8.3.0: +uuid@8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -7829,10 +7910,10 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v8-to-istanbul@^7.0.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" - integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== +v8-to-istanbul@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" + integrity sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -7846,13 +7927,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -8118,7 +8192,7 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^15.1.0, yargs@^15.3.1, yargs@^15.4.1: +yargs@^15.1.0, yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== From b9909f985e6794ba091c490b683c852611eeb2a1 Mon Sep 17 00:00:00 2001 From: Yulong Wang <7679871+fs-eire@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:17:42 -0800 Subject: [PATCH 018/113] [js/web] rename build-def.ts to build-def.d.ts (#9954) --- js/web/.gitignore | 2 ++ js/web/lib/{build-def.ts => build-def.d.ts} | 0 2 files changed, 2 insertions(+) rename js/web/lib/{build-def.ts => build-def.d.ts} (100%) diff --git a/js/web/.gitignore b/js/web/.gitignore index e6da0a8e2d..b1a07a75aa 100644 --- a/js/web/.gitignore +++ b/js/web/.gitignore @@ -6,6 +6,8 @@ dist/ tsconfig.tsbuildinfo +!lib/build-def.d.ts + lib/**/*.js lib/**/*.js.map test/**/*.js diff --git a/js/web/lib/build-def.ts b/js/web/lib/build-def.d.ts similarity index 100% rename from js/web/lib/build-def.ts rename to js/web/lib/build-def.d.ts From e0960d7d79ad25d7f50036ea81342265affd1e04 Mon Sep 17 00:00:00 2001 From: Ryan Hill <38674843+RyanUnderhill@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:44:58 -0800 Subject: [PATCH 019/113] Change assert on a null value to an ort_enforce (#9982) --- .../orttraining/test/graph/optimizer_graph_builder_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orttraining/orttraining/test/graph/optimizer_graph_builder_test.cc b/orttraining/orttraining/test/graph/optimizer_graph_builder_test.cc index 13b186729d..751d056f7e 100644 --- a/orttraining/orttraining/test/graph/optimizer_graph_builder_test.cc +++ b/orttraining/orttraining/test/graph/optimizer_graph_builder_test.cc @@ -199,7 +199,7 @@ static void TestOptimizerGraphBuilderWithInitialStates(OptimizerGraphConfig conf const ONNX_NAMESPACE::TensorProto* tensor{}; for (auto& weight_item : opt_initializer_names_map) { for (auto& opt_item : weight_item.second) { - ASSERT_TRUE(graph.GetInitializedTensor(opt_item.second, tensor)); + ORT_ENFORCE(graph.GetInitializedTensor(opt_item.second, tensor)); ASSERT_TRUE(tensor->data_type() == ONNX_NAMESPACE::TensorProto::FLOAT || tensor->data_type() == ONNX_NAMESPACE::TensorProto::INT64); if (tensor->data_type() == ONNX_NAMESPACE::TensorProto::FLOAT) { VerifyTensorValue(tensor, values[0]); From 4669048b478172914fa9611df5b5d042bc208f45 Mon Sep 17 00:00:00 2001 From: Chi Lo <54722500+chilo-ms@users.noreply.github.com> Date: Thu, 9 Dec 2021 15:33:52 -0800 Subject: [PATCH 020/113] Handle compiler warnings for TRT EP (#9956) * fix error C4996 * remove wd4996 and fix error C4966 * fix typo * remove wd4996 for onnx-tensorrt * remove more /wd for onnx-tensorrt * gix bug for strncpy_s of (Buffer is too small && 0) * fix code to remove warning 4244 * fix code to remove warning 4267 * remove /wd4267 /wd4244 * fix bug * change int to size_t * using size_t instead of int * use float instead of double * Use size_t instead of int * use size_t instead of int * use size_t instead of int. Also fix typo --- cmake/onnxruntime_providers.cmake | 6 +- .../tensorrt/tensorrt_execution_provider.cc | 127 +++++++++--------- .../tensorrt/tensorrt_execution_provider.h | 22 +-- .../tensorrt/tensorrt_provider_factory.cc | 12 ++ 4 files changed, 93 insertions(+), 74 deletions(-) diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index cfa128f6b9..d8f1e08a55 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -499,13 +499,13 @@ if (onnxruntime_USE_TENSORRT) if (WIN32) add_definitions(-D_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING=1) set(OLD_CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996 /wd4244 /wd4267 /wd4099 /wd4551 /wd4505 /wd4515 /wd4706 /wd4456 /wd4324 /wd4701 /wd4804 /wd4702 /wd4458 /wd4703") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4099 /wd4551 /wd4505 /wd4515 /wd4706 /wd4456 /wd4324 /wd4701 /wd4804 /wd4702 /wd4458 /wd4703") if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4805") endif() set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -include algorithm") set(PROTOBUF_LIBRARY libprotobuf) - set(DISABLED_WARNINGS_FOR_TRT /wd4267 /wd4244 /wd4996 /wd4456) + set(DISABLED_WARNINGS_FOR_TRT /wd4456) endif() if ( CMAKE_COMPILER_IS_GNUCC ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers") @@ -550,7 +550,7 @@ if (onnxruntime_USE_TENSORRT) target_compile_definitions(onnxruntime_providers_tensorrt PRIVATE ONNXIFI_BUILD_LIBRARY=1) target_compile_options(onnxruntime_providers_tensorrt PRIVATE ${DISABLED_WARNINGS_FOR_TRT}) if (WIN32) - target_compile_options(onnxruntime_providers_tensorrt INTERFACE /wd4267 /wd4244 /wd4996 /wd4456) + target_compile_options(onnxruntime_providers_tensorrt INTERFACE /wd4456) endif() # Needed for the provider interface, as it includes training headers when training is enabled diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc index ed7f654ef5..8617b8e2b6 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc @@ -61,7 +61,7 @@ float ConvertSinglePrecisionIEEE754ToFloat(unsigned long input) { for (int i = 0; i < 23; ++i) { m += ((input >> (23 - i - 1)) & 0x01) * pow(2.0, p--); } - return (s ? -1 : 1) * pow(2.0, e) * (m + 1.0); + return static_cast((s ? -1 : 1) * pow(2.0, e) * (m + 1.0)); } /* @@ -72,7 +72,7 @@ float ConvertSinglePrecisionIEEE754ToFloat(unsigned long input) { * key: tensor_a, value: dim_0 min_shape max_shape dim_2 min_shape max_shape * key: tensor_b, value: dim_1 min_shape max_shape */ -void SerializeProfile(const std::string& file_name, std::unordered_map>>& shape_ranges) { +void SerializeProfile(const std::string& file_name, std::unordered_map>>& shape_ranges) { // Serialize profile flexbuffers::Builder builder; auto profile_start = builder.StartMap(); @@ -97,7 +97,7 @@ void SerializeProfile(const std::string& file_name, std::unordered_map>> DeserializeProfile(std::ifstream& infile) { +std::unordered_map>> DeserializeProfile(std::ifstream& infile) { // Load flexbuffer infile.seekg(0, std::ios::end); size_t length = infile.tellg(); @@ -107,13 +107,13 @@ std::unordered_map>> shape_ranges; + std::unordered_map>> shape_ranges; auto tensors_range_entries = flexbuffers::GetRoot((const uint8_t*)data.get(), length).AsMap(); auto keys = tensors_range_entries.Keys(); auto values = tensors_range_entries.Values(); for (size_t i = 0, end = keys.size(); i < end; ++i) { auto dim_range_vectors = values[i].AsTypedVector(); - std::unordered_map> inner_map; + std::unordered_map> inner_map; for (size_t j = 0, end = dim_range_vectors.size() / 3; j < end; ++j) { size_t idx = 3 * j; inner_map[dim_range_vectors[idx].AsInt64()] = std::make_pair(dim_range_vectors[idx + 1].AsInt64(), dim_range_vectors[idx + 2].AsInt64()); @@ -124,7 +124,7 @@ std::unordered_map* adjacency_map, bool visited[], bool* st, std::vector& cycles) { +bool FindCycleHelper(size_t i, const std::list* adjacency_map, bool visited[], bool* st, std::vector& cycles) { if (!visited[i]) { visited[i] = true; st[i] = true; @@ -184,7 +184,7 @@ bool ReadDynamicRange(const std::string file_name, const bool is_trt_calibration std::getline(in_line, str, delim); unsigned long scale_int = std::strtoul(str.c_str(), nullptr, 16); float scale_float = ConvertSinglePrecisionIEEE754ToFloat(scale_int); - float dynamic_range = scale_float * 127.0; + float dynamic_range = scale_float * 127.0f; dynamic_range_map[tensor_name] = dynamic_range; } } else { @@ -202,7 +202,8 @@ bool ReadDynamicRange(const std::string file_name, const bool is_trt_calibration auto flat_table = flatbuffers::GetRoot((const uint8_t*)data.get()); auto flat_dict = flat_table->dict(); for (size_t i = 0, end = flat_dict->size(); i < end; ++i) { - dynamic_range_map[flat_dict->Get(i)->key()->str()] = std::stof(flat_dict->Get(i)->value()->str()); + flatbuffers::uoffset_t idx = static_cast(i); + dynamic_range_map[flat_dict->Get(idx)->key()->str()] = std::stof(flat_dict->Get(idx)->value()->str()); } } return true; @@ -255,7 +256,7 @@ bool SetDynamicRange(nvinfer1::INetworkDefinition& network, std::unordered_mapgetOutput(j)->setDynamicRange(-max_weight, max_weight)) { + if (!trt_layer->getOutput(j)->setDynamicRange(static_cast(-max_weight), static_cast(max_weight))) { return false; } } @@ -959,8 +960,8 @@ SubGraphCollection_t TensorrtExecutionProvider::GetSupportedList(SubGraphCollect SubGraphCollection_t next_nodes_list; const std::vector& subgraph_node_index = graph_viewer->GetNodesInTopologicalOrder(); next_nodes_list = GetSupportedList(parser_nodes_list, iterations, max_iterations, *graph_viewer, early_termination); - for (int i = 0, end = next_nodes_list.size(); i < end; ++i) { - for (int j = 0, end = next_nodes_list[i].first.size(); j < end; ++j) { + for (size_t i = 0, end = next_nodes_list.size(); i < end; ++i) { + for (size_t j = 0, end = next_nodes_list[i].first.size(); j < end; ++j) { next_nodes_list[i].first[j] = group.first[subgraph_node_index[next_nodes_list[i].first[j]]]; } nodes_list_output.push_back(next_nodes_list[i]); @@ -977,11 +978,11 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& bool trt_cycle = true; while (trt_cycle) { trt_cycle = false; - std::unordered_map node_to_index_map; - std::unordered_map index_to_node_map; + std::unordered_map node_to_index_map; + std::unordered_map index_to_node_map; std::unordered_map> input_to_nodes_map, node_to_outputs_map; - std::unordered_set non_trt_node_index(node_index.begin(), node_index.end()); - int id = 0; + std::unordered_set non_trt_node_index(node_index.begin(), node_index.end()); + size_t id = 0; for (const auto& group : supported_nodes_vector) { if (!group.first.empty()) { // Construct subgraph from node list @@ -1030,15 +1031,15 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& } // Create adjacency list - int graph_size = node_to_index_map.size(); - std::list* adjacency_map = new std::list[graph_size]; + size_t graph_size = node_to_index_map.size(); + std::list* adjacency_map = new std::list[graph_size]; for (const auto& node : node_to_outputs_map) { for (auto iter = node.second.begin(); iter != node.second.end(); ++iter) { const auto& loc = input_to_nodes_map.find(*iter); if (loc != input_to_nodes_map.end()) { - int parent_node_index = node_to_index_map.find(node.first)->second; + size_t parent_node_index = node_to_index_map.find(node.first)->second; for (auto child_node : loc->second) { - int child_node_index = node_to_index_map.find(child_node)->second; + size_t child_node_index = node_to_index_map.find(child_node)->second; adjacency_map[parent_node_index].push_back(child_node_index); } } @@ -1048,14 +1049,14 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& // Check cycle in the graph bool* visited = new bool[graph_size]; bool* st = new bool[graph_size]; - for (int i = 0; i < graph_size; ++i) { + for (size_t i = 0; i < graph_size; ++i) { visited[i] = false; st[i] = false; } - std::vector cycles; + std::vector cycles; bool has_cycle = false; - for (int i = 0; i < graph_size; ++i) { + for (size_t i = 0; i < graph_size; ++i) { if (FindCycleHelper(i, adjacency_map, visited, st, cycles)) { has_cycle = true; break; @@ -1064,7 +1065,7 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& // Remove TensorRT subgraph from the supported node list if it's part of the cycle if (has_cycle) { - for (int i = 0; i < static_cast(cycles.size()); ++i) { + for (size_t i = 0; i < cycles.size(); ++i) { auto loc = index_to_node_map.find(cycles[i]); if (loc != index_to_node_map.end() && loc->second.find("TRTKernel") != std::string::npos) { supported_nodes_vector.erase(supported_nodes_vector.begin() + cycles[i]); @@ -1086,7 +1087,7 @@ TensorrtExecutionProvider::GetCapability(const GraphViewer& graph, // Get ModelPath const auto& path_string = graph.ModelPath().ToPathString(); #ifdef _WIN32 - wcstombs(model_path_, path_string.c_str(), sizeof(model_path_)); + wcstombs_s(nullptr, model_path_, sizeof(model_path_), path_string.c_str(), sizeof(model_path_)); #else strcpy(model_path_, path_string.c_str()); #endif @@ -1104,7 +1105,7 @@ TensorrtExecutionProvider::GetCapability(const GraphViewer& graph, // Remove subgraphs if its size is less than the predefined minimal size for (auto it = supported_nodes_vector.begin(); it != supported_nodes_vector.end(); ++it) { - const int subgraph_size = it->first.size(); + const size_t subgraph_size = it->first.size(); if (subgraph_size < min_subgraph_size_) { supported_nodes_vector.erase(it--); } @@ -1120,17 +1121,17 @@ TensorrtExecutionProvider::GetCapability(const GraphViewer& graph, if (!group.first.empty()) { std::unique_ptr sub_graph = GetSubGraph(group, graph); result.push_back(ComputeCapability::Create(std::move(sub_graph))); - number_of_trt_nodes += group.first.size(); + number_of_trt_nodes += static_cast(group.first.size()); } } - const int number_of_subgraphs = supported_nodes_vector.size(); + const size_t number_of_subgraphs = supported_nodes_vector.size(); if (number_of_trt_nodes == 0) { - LOGS_DEFAULT(WARNING) << "[TensorRT EP] No graph will run on TensorRT exeuction provider"; + LOGS_DEFAULT(WARNING) << "[TensorRT EP] No graph will run on TensorRT execution provider"; } else if (number_of_trt_nodes == number_of_ort_nodes) { - LOGS_DEFAULT(INFO) << "[TensorRT EP] Whole graph will run on TensorRT exeuction provider"; + LOGS_DEFAULT(INFO) << "[TensorRT EP] Whole graph will run on TensorRT execution provider"; } else { - LOGS_DEFAULT(INFO) << "[TensorRT EP] Graph is partitioned and number of subgraphs running on TensorRT exeuction provider is " << number_of_subgraphs; + LOGS_DEFAULT(INFO) << "[TensorRT EP] Graph is partitioned and number of subgraphs running on TensorRT execution provider is " << number_of_subgraphs; } return result; @@ -1147,18 +1148,18 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse std::vector& node_compute_funcs) { for (const auto* fused_node : fused_nodes) { // Build map from input name to its index in input definitions - std::unordered_map input_map; + std::unordered_map input_map; const auto& input_defs = fused_node->InputDefs(); input_map.reserve(input_defs.size()); - for (int i = 0, end = input_defs.size(); i < end; ++i) { + for (size_t i = 0, end = input_defs.size(); i < end; ++i) { input_map[input_defs[i]->Name()] = i; } // Build map from output name to its index in output definitions - std::unordered_map output_map; + std::unordered_map output_map; const auto& output_defs = fused_node->OutputDefs(); output_map.reserve(output_defs.size()); - for (int i = 0, end = output_defs.size(); i < end; ++i) { + for (size_t i = 0, end = output_defs.size(); i < end; ++i) { output_map[output_defs[i]->Name()] = i; } @@ -1193,10 +1194,10 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse int num_inputs = trt_network->getNbInputs(); int num_outputs = trt_network->getNbOutputs(); - std::unordered_map input_indexes(num_inputs); - std::unordered_map>> input_shape_ranges; - std::unordered_map output_indexes(num_outputs); - std::unordered_map output_types(num_outputs); + std::unordered_map input_indexes(num_inputs); + std::unordered_map>> input_shape_ranges; + std::unordered_map output_indexes(num_outputs); + std::unordered_map output_types(num_outputs); // Initialize shape range for dynamic shape tensors bool has_dynamic_shape = false; @@ -1423,17 +1424,17 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse Ort::CustomOpApi ort{*api}; TensorrtFuncState* trt_state = reinterpret_cast(state); std::lock_guard lock(*(trt_state->tensorrt_mu_ptr)); - const std::unordered_map& input_indexes = (trt_state->input_info)[0]; - const std::unordered_map& output_indexes = (trt_state->output_info)[0]; - const std::unordered_map& output_types = (trt_state->output_info)[1]; + const std::unordered_map& input_indexes = (trt_state->input_info)[0]; + const std::unordered_map& output_indexes = (trt_state->output_info)[0]; + const std::unordered_map& output_types = (trt_state->output_info)[1]; auto& shape_ranges = trt_state->input_shape_ranges; auto trt_builder = trt_state->builder->get(); auto trt_engine = trt_state->engine->get(); auto trt_context = trt_state->context->get(); auto trt_profile = &(trt_state->trt_profile); auto alloc = trt_state->scratch_allocator; - int num_inputs = input_indexes.size(); - int num_outputs = output_indexes.size(); + int num_inputs = static_cast(input_indexes.size()); + int num_outputs = static_cast(output_indexes.size()); bool engine_update = false; std::unordered_set input_names; std::unordered_map> tensor_shape_values; @@ -1513,7 +1514,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse // Check and update shape ranges for dynamic shape inputs input_names.insert(input_name); if (shape_ranges.find(input_name) != shape_ranges.end()) { - int input_index = 0; + size_t input_index = 0; const auto& iter = input_indexes.find(input_name); if (iter != input_indexes.end()) { input_index = iter->second; @@ -1528,7 +1529,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse if (input->isShapeTensor()) { // Get shape values for shape tensor input const auto& tensor_type = ort.GetTensorElementType(tensor_info); - int shape_size = nb_dims == 0 ? 1 : tensor_shapes[0]; + int shape_size = nb_dims == 0 ? 1 : static_cast(tensor_shapes[0]); tensor_shape_values[input_name].resize(shape_size); switch (tensor_type) { case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32: { @@ -1559,13 +1560,13 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse // Update shape ranges std::vector shapes_min(shape_size), shapes_opt(shape_size), shapes_max(shape_size); - int shape_range_size = shape_range.size(); + int shape_range_size = static_cast(shape_range.size()); if (shape_size == shape_range_size) { // If shape size matches, check/update shape range for (int j = 0; j < shape_size; ++j) { - shapes_min[j] = shape_range[j].first; - shapes_opt[j] = shape_range[j].second; - shapes_max[j] = shape_range[j].second; + shapes_min[j] = static_cast(shape_range[j].first); + shapes_opt[j] = static_cast(shape_range[j].second); + shapes_max[j] = static_cast(shape_range[j].second); const auto& tensor_shape_value = tensor_shape_values[input_name][j]; // Update shape range lower bound @@ -1606,21 +1607,21 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse for (int j = 0, end = nb_dims; j < end; ++j) { const auto& tensor_shape = tensor_shapes[j]; if (shape_range.find(j) != shape_range.end()) { - dims_min.d[j] = shape_range[j].first; - dims_opt.d[j] = shape_range[j].second; - dims_max.d[j] = shape_range[j].second; + dims_min.d[j] = static_cast(shape_range[j].first); + dims_opt.d[j] = static_cast(shape_range[j].second); + dims_max.d[j] = static_cast(shape_range[j].second); // Update minimum dimension if (tensor_shape < shape_range[j].first) { shape_range[j].first = tensor_shape; - dims_min.d[j] = tensor_shape; + dims_min.d[j] = static_cast(tensor_shape); engine_update = true; } // Update maximum dimension if (tensor_shape > shape_range[j].second) { shape_range[j].second = tensor_shape; - dims_max.d[j] = tensor_shape; - dims_opt.d[j] = tensor_shape; + dims_max.d[j] = static_cast(tensor_shape); + dims_opt.d[j] = static_cast(tensor_shape); engine_update = true; } } @@ -1725,14 +1726,14 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse // Set input shapes and assign input buffers std::vector> scratch_buffers; - for (int i = 0, end = input_binding_names.size(); i < end; ++i) { + for (size_t i = 0, end = input_binding_names.size(); i < end; ++i) { const std::string& input_name = input_binding_names[i]; int binding_index = trt_engine->getBindingIndex(input_name.c_str()); if (binding_index == -1) { continue; } - int input_index = 0; + size_t input_index = 0; const auto& iter = input_indexes.find(input_name); if (iter != input_indexes.end()) { input_index = iter->second; @@ -1749,7 +1750,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse trt_context->setInputShapeBinding(binding_index, &tensor_shape_values[input_name][0]); } else { for (int j = 0, end = nb_dims; j < end; ++j) { - dimensions.d[j] = tensor_shapes[j]; + dimensions.d[j] = static_cast(tensor_shapes[j]); } trt_context->setBindingDimensions(binding_index, dimensions); } @@ -1862,7 +1863,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse // Set output shapes and assign output buffers std::vector output_dim_sizes(num_outputs, 1); std::vector output_tensor(num_outputs, nullptr); - for (int i = 0, end = output_binding_names.size(); i < end; ++i) { + for (size_t i = 0, end = output_binding_names.size(); i < end; ++i) { // Set dynamic shapes const std::string& output_name = output_binding_names[i]; int binding_index = trt_engine->getBindingIndex(output_name.c_str()); @@ -1870,7 +1871,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse continue; } - int output_index = 0; + size_t output_index = 0; const auto& index_iter = output_indexes.find(output_name); if (index_iter != output_indexes.end()) { output_index = index_iter->second; @@ -1883,7 +1884,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse } output_tensor[i] = ort.KernelContext_GetOutput(context, output_index, output_shapes.data(), output_shapes.size()); - int output_type = 0; + size_t output_type = 0; const auto& type_iter = output_types.find(output_name); if (type_iter != output_types.end()) { output_type = type_iter->second; @@ -1998,10 +1999,10 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector& fuse } // Cast INT64 input to INT32 because TensorRT doesn't fully support INT64 - for (int i = 0, end = output_binding_names.size(); i < end; ++i) { + for (size_t i = 0, end = output_binding_names.size(); i < end; ++i) { const std::string& output_name = output_binding_names[i]; size_t binding_index = trt_engine->getBindingIndex(output_name.c_str()); - int output_type = 0; + size_t output_type = 0; const auto& iter = output_types.find(output_name); if (iter != output_types.end()) { output_type = iter->second; diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h index a1e3e14f19..ee759228ae 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h @@ -39,10 +39,16 @@ class TensorrtLogger : public nvinfer1::ILogger { void log(Severity severity, const char* msg) noexcept override { if (severity <= verbosity_) { time_t rawtime = std::time(0); + struct tm stm; +#ifdef _MSC_VER + gmtime_s(&stm, &rawtime); +#else + gmtime_r(&rawtime, &stm); +#endif char buf[256]; strftime(&buf[0], 256, "%Y-%m-%d %H:%M:%S", - std::gmtime(&rawtime)); + &stm); const char* sevstr = (severity == Severity::kINTERNAL_ERROR ? " BUG" : severity == Severity::kERROR ? " ERROR" : severity == Severity::kWARNING ? "WARNING" : severity == Severity::kINFO ? " INFO" @@ -81,9 +87,9 @@ struct TensorrtFuncState { tensorrt_ptr::unique_pointer* context = nullptr; tensorrt_ptr::unique_pointer* builder = nullptr; tensorrt_ptr::unique_pointer* network = nullptr; - std::vector> input_info; - std::vector> output_info; - std::unordered_map>> input_shape_ranges; + std::vector> input_info; + std::vector> output_info; + std::unordered_map>> input_shape_ranges; OrtMutex* tensorrt_mu_ptr = nullptr; bool fp16_enable; bool int8_enable; @@ -140,7 +146,7 @@ class TensorrtExecutionProvider : public IExecutionProvider { bool external_stream_ = false; cudaStream_t stream_ = nullptr; int max_partition_iterations_ = 1000; - int min_subgraph_size_ = 1; + size_t min_subgraph_size_ = 1; size_t max_workspace_size_ = 1 << 30; // 1GB bool fp16_enable_ = false; bool int8_enable_ = false; @@ -167,9 +173,9 @@ class TensorrtExecutionProvider : public IExecutionProvider { std::unordered_map> contexts_; std::unordered_map> builders_; std::unordered_map> networks_; - std::unordered_map>> input_info_; - std::unordered_map>> output_info_; - std::unordered_map>>> input_shape_ranges_; + std::unordered_map>> input_info_; + std::unordered_map>> output_info_; + std::unordered_map>>> input_shape_ranges_; /**Get IndexedSubGraph based on node list of the subgraph*/ std::unique_ptr GetSubGraph(SubGraph_t graph_nodes_index, diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.cc b/onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.cc index 8e1c4084a0..d65c91d88f 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.cc @@ -88,7 +88,11 @@ struct Tensorrt_Provider : Provider { trt_options.trt_int8_calibration_table_name = nullptr; } else { dest = new char[str_size + 1]; +#ifdef _MSC_VER + strncpy_s(dest, str_size + 1, internal_options.int8_calibration_table_name.c_str(), str_size); +#else strncpy(dest, internal_options.int8_calibration_table_name.c_str(), str_size); +#endif dest[str_size] = '\0'; trt_options.trt_int8_calibration_table_name = (const char*)dest; } @@ -104,7 +108,11 @@ struct Tensorrt_Provider : Provider { trt_options.trt_engine_cache_path = nullptr; } else { dest = new char[str_size + 1]; +#ifdef _MSC_VER + strncpy_s(dest, str_size + 1, internal_options.engine_cache_path.c_str(), str_size); +#else strncpy(dest, internal_options.engine_cache_path.c_str(), str_size); +#endif dest[str_size] = '\0'; trt_options.trt_engine_cache_path = (const char*)dest; } @@ -116,7 +124,11 @@ struct Tensorrt_Provider : Provider { trt_options.trt_engine_decryption_lib_path = nullptr; } else { dest = new char[str_size + 1]; +#ifdef _MSC_VER + strncpy_s(dest, str_size + 1, internal_options.engine_decryption_lib_path.c_str(), str_size); +#else strncpy(dest, internal_options.engine_decryption_lib_path.c_str(), str_size); +#endif dest[str_size] = '\0'; trt_options.trt_engine_decryption_lib_path = (const char*)dest; } From 343a76945be1323e14c5251eb5302037c7d77eca Mon Sep 17 00:00:00 2001 From: Ryan Hill <38674843+RyanUnderhill@users.noreply.github.com> Date: Thu, 9 Dec 2021 17:42:34 -0800 Subject: [PATCH 021/113] Fix some documentation errors plus ones generating doxygen warnings (#9993) --- .../core/session/onnxruntime_c_api.h | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 12d3c54268..9384ad8700 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -3066,12 +3066,14 @@ struct OrtApi { /// @{ /** \brief Used for custom operators, gets the GPU compute stream to use to launch the custom a GPU kernel * \see ::OrtCustomOp - * \param[context] OrtKernelContext instance - * \param[out] Returns pointer to a GPU compute stream that can be used to launch the custom GPU kernel. + * \param[in] context OrtKernelContext instance + * \param[out] out Returns pointer to a GPU compute stream that can be used to launch the custom GPU kernel. * If retrieving the GPU compute stream is not relevant (GPU not enabled in the build, kernel partitioned to * some other EP), then a nullptr is returned as the output param. * Do not free or mutate the returned pointer as it refers to internal data owned by the underlying session. * Only use it for custom kernel launching. + * + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(KernelContext_GetGPUComputeStream, _In_ const OrtKernelContext* context, _Outptr_ void** out); @@ -3079,7 +3081,7 @@ struct OrtApi { /// \name GetTensorMemoryInfo /// @{ /** \brief Returns a pointer to the ::OrtMemoryInfo of a Tensor - * \param[in] ort_value ::OrtValue containing tensor. + * \param[in] value ::OrtValue containing tensor. * \param[out] mem_info ::OrtMemoryInfo of the tensor. Do NOT free the returned pointer. It is valid for the lifetime of the ::OrtValue * * \snippet{doc} snippets.dox OrtStatus Return Value @@ -3107,28 +3109,28 @@ struct OrtApi { /// @{ /** \brief Set custom thread creation function * - * \param[in] session options - * \param[in] custom thread creation function + * \param[in] options Session options + * \param[in] ort_custom_create_thread_fn Custom thread creation function * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SessionOptionsSetCustomCreateThreadFn, _Inout_ OrtSessionOptions* options, _In_ OrtCustomCreateThreadFn ort_custom_create_thread_fn); /** \brief Set creation options for custom thread * - * \param[in] session options - * \param[in] custom thread creation options (can be nullptr) + * \param[in] options Session options + * \param[in] ort_custom_thread_creation_options Custom thread creation options (can be nullptr) * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SessionOptionsSetCustomThreadCreationOptions, _Inout_ OrtSessionOptions* options, _In_ void* ort_custom_thread_creation_options); /** \brief Set custom thread join function * - * \param[in] session options - * \param[in] custom join thread function, must not be nullptr when ort_custom_create_thread_fn is set + * \param[in] options Session options + * \param[in] ort_custom_join_thread_fn Custom join thread function, must not be nullptr when ort_custom_create_thread_fn is set * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SessionOptionsSetCustomJoinThreadFn, _Inout_ OrtSessionOptions* options, _In_ OrtCustomJoinThreadFn ort_custom_join_thread_fn); /// @} @@ -3138,27 +3140,27 @@ struct OrtApi { /** \brief Set custom thread creation function for global thread pools * * \param[inout] tp_options - * \param[in] custom thread creation function + * \param[in] ort_custom_create_thread_fn Custom thread creation function * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SetGlobalCustomCreateThreadFn, _Inout_ OrtThreadingOptions* tp_options, _In_ OrtCustomCreateThreadFn ort_custom_create_thread_fn); /** \brief Set custom thread creation options for global thread pools * * \param[inout] tp_options - * \param[in] custom thread creation options (can be nullptr) + * \param[in] ort_custom_thread_creation_options Custom thread creation options (can be nullptr) * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SetGlobalCustomThreadCreationOptions, _Inout_ OrtThreadingOptions* tp_options, _In_ void* ort_custom_thread_creation_options); /** \brief Set custom thread join function for global thread pools * * \param[inout] tp_options - * \param[in] custom thread join function, must not be nullptr when global ort_custom_create_thread_fn is set + * \param[in] ort_custom_join_thread_fn Custom thread join function, must not be nullptr when global ort_custom_create_thread_fn is set * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SetGlobalCustomJoinThreadFn, _Inout_ OrtThreadingOptions* tp_options, _In_ OrtCustomJoinThreadFn ort_custom_join_thread_fn); /// @} @@ -3169,7 +3171,7 @@ struct OrtApi { * * \param[inout] binding_ptr * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SynchronizeBoundInputs, _Inout_ OrtIoBinding* binding_ptr); @@ -3179,7 +3181,7 @@ struct OrtApi { * * \param[inout] binding_ptr * - * * \snippet{doc} snippets.dox OrtStatus Return Value + * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SynchronizeBoundOutputs, _Inout_ OrtIoBinding* binding_ptr); }; From 3c79f3055f4b9d3a67c7ee814f8ebc9cba1bda12 Mon Sep 17 00:00:00 2001 From: Yi-Hong Lyu Date: Fri, 10 Dec 2021 17:30:26 +0800 Subject: [PATCH 022/113] Weaken x86.get_pc_thunk for NDK <= r22 (#9994) Otherwise there is multiple definition of '__x86.get_pc_thunk.bx' --- onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S b/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S index b3c4f6ac8b..fd81ddb7e3 100644 --- a/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S +++ b/onnxruntime/core/mlas/lib/x86/x86.get_pc_thunk.S @@ -14,9 +14,6 @@ Abstract: --*/ - -#include "asmmacro.h" - .intel_syntax noprefix /*++ @@ -28,7 +25,9 @@ Routine Description: --*/ - FUNCTION_ENTRY __x86.get_pc_thunk.bx - + .p2align 4 + .weak __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx,@function +__x86.get_pc_thunk.bx: mov ebx, [esp] ret From ffdafb2012d6a651c8f440ac486f9d0d5a939901 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Fri, 10 Dec 2021 11:33:19 -0800 Subject: [PATCH 023/113] add fallback of s8s8 support on x64 (#9995) * add fallback of s8s8 support on x64 --- docs/OperatorKernels.md | 10 +- .../contrib_ops/cpu/cpu_contrib_kernels.cc | 4 - .../quantization/dynamic_quantize_matmul.cc | 2 - onnxruntime/core/mlas/lib/mlasi.h | 2 +- onnxruntime/core/mlas/lib/qgemm.h | 9 +- .../core/mlas/lib/qgemm_kernel_default.cpp | 58 +++-- .../providers/cpu/cpu_execution_provider.cc | 8 - .../core/providers/cpu/math/matmul_integer.cc | 2 - .../cpu/math/quantize_linear_matmul.cc | 2 - .../core/providers/cpu/nn/qlinearconv.cc | 4 - .../matmul_integer_to_float_test.cc | 2 - onnxruntime/test/mlas/unittest/test_qgemm.cpp | 16 -- .../providers/cpu/math/matmul_integer_test.cc | 232 +++--------------- .../cpu/math/quantize_linear_matmul_test.cc | 8 - .../providers/cpu/nn/qlinearconv_op_test.cc | 2 - .../test/providers/kernel_def_hash_test.cc | 4 - .../kernel_def_hashes/arm_ops.cpu.json | 22 -- .../kernel_def_hashes/contrib.cpu.json | 8 + .../testdata/kernel_def_hashes/onnx.cpu.json | 12 + 19 files changed, 95 insertions(+), 312 deletions(-) delete mode 100644 onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md index a7ea71314f..052367130e 100644 --- a/docs/OperatorKernels.md +++ b/docs/OperatorKernels.md @@ -165,7 +165,7 @@ Do not modify directly.* |MatMul|*in* A:**T**
*in* B:**T**
*out* Y:**T**|13+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)| |||[9, 12]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)| |||[1, 8]|**T** = tensor(double), tensor(float)| -|MatMulInteger|*in* A:**T1**
*in* B:**T2**
*in* a_zero_point:**T1**
*in* b_zero_point:**T2**
*out* Y:**T3**|10+|**T1** = tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(int32)| +|MatMulInteger|*in* A:**T1**
*in* B:**T2**
*in* a_zero_point:**T1**
*in* b_zero_point:**T2**
*out* Y:**T3**|10+|**T1** = tensor(int8), tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(int32)| |Max|*in* data_0:**T**
*out* max:**T**|13+|**T** = tensor(double), tensor(float), tensor(float16), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)| |||12|**T** = tensor(double), tensor(float), tensor(float16), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)| |||[8, 11]|**T** = tensor(double), tensor(float)| @@ -213,8 +213,8 @@ Do not modify directly.* |||[13, 14]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T1** = tensor(double), tensor(float), tensor(int32), tensor(int64)| |||12|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T1** = tensor(double), tensor(float), tensor(int32), tensor(int64)| |||[7, 11]|**T** = tensor(double), tensor(float)| -|QLinearConv|*in* x:**T1**
*in* x_scale:**tensor(float)**
*in* x_zero_point:**T1**
*in* w:**T2**
*in* w_scale:**tensor(float)**
*in* w_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*in* B:**T4**
*out* y:**T3**|10+|**T1** = tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(uint8)
**T4** = tensor(int32)| -|QLinearMatMul|*in* a:**T1**
*in* a_scale:**tensor(float)**
*in* a_zero_point:**T1**
*in* b:**T2**
*in* b_scale:**tensor(float)**
*in* b_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*out* y:**T3**|10+|**T1** = tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(uint8)| +|QLinearConv|*in* x:**T1**
*in* x_scale:**tensor(float)**
*in* x_zero_point:**T1**
*in* w:**T2**
*in* w_scale:**tensor(float)**
*in* w_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*in* B:**T4**
*out* y:**T3**|10+|**T1** = tensor(int8), tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(int8), tensor(uint8)
**T4** = tensor(int32)| +|QLinearMatMul|*in* a:**T1**
*in* a_scale:**tensor(float)**
*in* a_zero_point:**T1**
*in* b:**T2**
*in* b_scale:**tensor(float)**
*in* b_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*out* y:**T3**|10+|**T1** = tensor(int8), tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(int8), tensor(uint8)| |QuantizeLinear|*in* x:**T1**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T2**
*out* y:**T2**|13+|**T1** = tensor(float)
**T2** = tensor(int8), tensor(uint8)| |||[10, 12]|**T1** = tensor(float)
**T2** = tensor(int8), tensor(uint8)| |RNN|*in* X:**T**
*in* W:**T**
*in* R:**T**
*in* B:**T**
*in* sequence_lens:**T1**
*in* initial_h:**T**
*out* Y:**T**
*out* Y_h:**T**|14+|**T** = tensor(float)
**T1** = tensor(int32)| @@ -396,7 +396,7 @@ Do not modify directly.* |GridSample|*in* X:**T1**
*in* Grid:**T1**
*out* Y:**T2**|1+|**T** = tensor(float)| |Inverse|*in* X:**T**
*out* Y:**T**|1+|**T** = tensor(double), tensor(float), tensor(float16)| |MatMulInteger16|*in* A:**T1**
*in* B:**T2**
*out* Y:**T3**|1+|**T1** = tensor(int16)
**T2** = tensor(int16)
**T3** = tensor(int32)| -|MatMulIntegerToFloat|*in* A:**T1**
*in* B:**T2**
*in* a_scale:**T3**
*in* b_scale:**T3**
*in* a_zero_point:**T1**
*in* b_zero_point:**T2**
*in* bias:**T3**
*out* Y:**T3**|1+|**T1** = tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(float)| +|MatMulIntegerToFloat|*in* A:**T1**
*in* B:**T2**
*in* a_scale:**T3**
*in* b_scale:**T3**
*in* a_zero_point:**T1**
*in* b_zero_point:**T2**
*in* bias:**T3**
*out* Y:**T3**|1+|**T1** = tensor(int8), tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(float)| |MaxpoolWithMask|*in* X:**T**
*in* M:**tensor(int32)**
*out* Y:**T**|1+|**X** = tensor(float)| |MurmurHash3|*in* X:**T1**
*out* Y:**T2**|1+|**T1** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(string), tensor(uint32), tensor(uint64)
**T2** = tensor(int32), tensor(uint32)| |NGramRepeatBlock|*in* input_ids:**Tid**
*in* scores:**T**
*out* scores_out:**T**|1+|**T** = tensor(float)
**Tid** = tensor(int64)| @@ -406,7 +406,7 @@ Do not modify directly.* |QEmbedLayerNormalization|*in* input_ids:**T1**
*in* segment_ids:**T1**
*in* word_embedding_quant:**T2**
*in* position_embedding_quant:**T2**
*in* segment_embedding:**T2**
*in* gamma_quant:**T2**
*in* beta_quant:**T2**
*in* mask:**T1**
*in* word_embedding_scale:**T**
*in* position_embedding_scale:**T**
*in* segment_embedding_scale:**T**
*in* gamma_scale:**T**
*in* beta_scale:**T**
*in* word_embedding_zero_point:**T2**
*in* position_embedding_zero_point:**T2**
*in* segment_embedding_zero_point:**T2**
*in* gamma_zero_point:**T2**
*in* beta_zero_point:**T2**
*out* layernorm_out:**T**
*out* mask_index_out:**T1**|1+|**T** = tensor(float)| |QGemm|*in* A:**TA**
*in* a_scale:**T**
*in* a_zero_point:**TA**
*in* B:**TB**
*in* b_scale:**T**
*in* b_zero_point:**TB**
*in* C:**TC**
*in* y_scale:**T**
*in* y_zero_point:**TYZ**
*out* Y:**TY**|1+|**T** = tensor(float)
**TA** = tensor(uint8)
**TB** = tensor(int8), tensor(uint8)
**TC** = tensor(int32)
**TY** = tensor(float), tensor(uint8)
**TYZ** = tensor(uint8)| |QLinearAdd|*in* A:**T**
*in* A_scale:**tensor(float)**
*in* A_zero_point:**T**
*in* B:**T**
*in* B_scale:**tensor(float)**
*in* B_zero_point:**T**
*in* C_scale:**tensor(float)**
*in* C_zero_point:**T**
*out* C:**T**|1+|**T** = tensor(int8), tensor(uint8)| -|QLinearConv|*in* x:**T1**
*in* x_scale:**tensor(float)**
*in* x_zero_point:**T1**
*in* w:**T2**
*in* w_scale:**tensor(float)**
*in* w_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*in* B:**T4**
*out* y:**T3**|1+|**T1** = tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(uint8)
**T4** = tensor(int32)| +|QLinearConv|*in* x:**T1**
*in* x_scale:**tensor(float)**
*in* x_zero_point:**T1**
*in* w:**T2**
*in* w_scale:**tensor(float)**
*in* w_zero_point:**T2**
*in* y_scale:**tensor(float)**
*in* y_zero_point:**T3**
*in* B:**T4**
*out* y:**T3**|1+|**T1** = tensor(int8), tensor(uint8)
**T2** = tensor(int8), tensor(uint8)
**T3** = tensor(int8), tensor(uint8)
**T4** = tensor(int32)| |QLinearLeakyRelu|*in* X:**T**
*in* X_scale:**tensor(float)**
*in* X_zero_point:**T**
*in* Y_scale:**tensor(float)**
*in* Y_zero_point:**T**
*out* Y:**T**|1+|**T** = tensor(int8), tensor(uint8)| |QLinearMul|*in* A:**T**
*in* A_scale:**tensor(float)**
*in* A_zero_point:**T**
*in* B:**T**
*in* B_scale:**tensor(float)**
*in* B_zero_point:**T**
*in* C_scale:**tensor(float)**
*in* C_zero_point:**T**
*out* C:**T**|1+|**T** = tensor(int8), tensor(uint8)| |QLinearSigmoid|*in* X:**T**
*in* X_scale:**tensor(float)**
*in* X_zero_point:**T**
*in* Y_scale:**tensor(float)**
*in* Y_zero_point:**T**
*out* Y:**T**|1+|**T** = tensor(int8), tensor(uint8)| diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc index d65e23c7ac..77669f74ea 100644 --- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc @@ -82,10 +82,8 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, DynamicQuantizeLSTM); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, MatMulIntegerToFloat); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, QLinearConv); -#if defined(MLAS_TARGET_ARM_ANY) class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t, MatMulIntegerToFloat); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t_int8_t, QLinearConv); -#endif class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, int8_t, NhwcMaxPool); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, uint8_t, NhwcMaxPool); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, QEmbedLayerNormalization); @@ -175,10 +173,8 @@ Status RegisterQuantizationKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, -#if defined(MLAS_TARGET_ARM_ANY) BuildKernelCreateInfo, BuildKernelCreateInfo, -#endif BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, diff --git a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc index 7168cb8663..a9d817b5e8 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc @@ -320,7 +320,6 @@ ONNX_OPERATOR_TYPED_KERNEL_EX( .TypeConstraint("T3", DataTypeImpl::GetTensorType()), MatMulIntegerToFloat); -#if defined(MLAS_TARGET_ARM_ANY) ONNX_OPERATOR_TYPED_KERNEL_EX( MatMulIntegerToFloat, kMSDomain, @@ -332,7 +331,6 @@ ONNX_OPERATOR_TYPED_KERNEL_EX( .TypeConstraint("T2", DataTypeImpl::GetTensorType()) .TypeConstraint("T3", DataTypeImpl::GetTensorType()), MatMulIntegerToFloat); -#endif } // namespace contrib } // namespace onnxruntime diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h index 6ea1fe9a0d..a41dacf448 100644 --- a/onnxruntime/core/mlas/lib/mlasi.h +++ b/onnxruntime/core/mlas/lib/mlasi.h @@ -667,7 +667,7 @@ extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmS8S8DispatchNeon; extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmU8X8DispatchUdot; extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmS8S8DispatchSdot; extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmU8X8DispatchWasmSimd; -extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmU8X8DispatchDefault; +extern const MLAS_GEMM_QUANT_DISPATCH MlasGemmQuantDispatchDefault; // // Symmetric quantized integer convolution dispatch structure. diff --git a/onnxruntime/core/mlas/lib/qgemm.h b/onnxruntime/core/mlas/lib/qgemm.h index 31dadffb08..13781bcff7 100644 --- a/onnxruntime/core/mlas/lib/qgemm.h +++ b/onnxruntime/core/mlas/lib/qgemm.h @@ -703,8 +703,9 @@ MlasGemmQuantGetDispatch( { const MLAS_GEMM_QUANT_DISPATCH* GemmQuantDispatch = nullptr; - MLAS_UNREFERENCED_PARAMETER(AIsSigned); - MLAS_UNREFERENCED_PARAMETER(BIsSigned); + if (!AIsSigned || BIsSigned) { + GemmQuantDispatch = &MlasGemmQuantDispatchDefault; + } #if defined(MLAS_TARGET_AMD64_IX86) if (!AIsSigned) { @@ -733,10 +734,6 @@ MlasGemmQuantGetDispatch( if (!AIsSigned) { GemmQuantDispatch = &MlasGemmU8X8DispatchWasmSimd; } -#else - if (!AIsSigned) { - GemmQuantDispatch = &MlasGemmU8X8DispatchDefault; - } #endif if (nullptr == GemmQuantDispatch) { diff --git a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp index 49ea0e445f..c394ac8661 100644 --- a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp +++ b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp @@ -17,7 +17,7 @@ Abstract: #include "mlasi.h" #include "qgemm.h" -struct MLAS_GEMM_U8X8_KERNEL_DEFAULT +struct MLAS_GEMM_QUANT_KERNEL_DEFAULT { typedef uint8_t PackedAType; typedef uint8_t PackedBType; @@ -29,20 +29,35 @@ struct MLAS_GEMM_U8X8_KERNEL_DEFAULT static constexpr MLAS_GEMM_QUANT_STRIDES PackedStrides{ 16, 128, 128 }; }; -constexpr size_t MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK; -constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_U8X8_KERNEL_DEFAULT::Strides; -constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedStrides; +constexpr size_t MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK; +constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::Strides; +constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedStrides; template<> MLAS_FORCEINLINE int32_t -MlasGemmQuantFixupZeroPointB( +MlasGemmQuantFixupZeroPointA( + int32_t ZeroPointA, + bool AIsSigned + ) +{ + if (AIsSigned) { + ZeroPointA = (uint8_t)(ZeroPointA ^ 0x80); + } + + return ZeroPointA; +} + +template<> +MLAS_FORCEINLINE +int32_t +MlasGemmQuantFixupZeroPointB( int32_t ZeroPointB, bool BIsSigned ) { if (BIsSigned) { - ZeroPointB = MLAS_GEMM_U8X8_KERNEL_DEFAULT::OffsetBType(ZeroPointB ^ 0x80); + ZeroPointB = MLAS_GEMM_QUANT_KERNEL_DEFAULT::OffsetBType(ZeroPointB ^ 0x80); } return ZeroPointB; @@ -50,8 +65,8 @@ MlasGemmQuantFixupZeroPointB( template<> void -MlasGemmQuantCopyPackA( - MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedAType* D, +MlasGemmQuantCopyPackA( + MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedAType* D, const uint8_t* A, size_t lda, size_t CountM, @@ -60,9 +75,10 @@ MlasGemmQuantCopyPackA( bool AIsSigned ) { - MLAS_UNREFERENCED_PARAMETER(AIsSigned); - const size_t AlignedCountK = - (CountK + MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK - 1) & ~(MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK - 1); + const size_t AlignedCountK = (CountK + MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK - 1) & + ~(MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK - 1); + + const uint8_t BitFlipValue = (AIsSigned ? 0x80 : 0); // // Process a single row of matrix A in a loop. @@ -74,7 +90,7 @@ MlasGemmQuantCopyPackA( for (size_t k = 0; k < CountK; k++) { - uint8_t a0 = A[k]; + uint8_t a0 = A[k] ^ BitFlipValue; D[k] = a0; RowSum += a0; @@ -93,8 +109,8 @@ MlasGemmQuantCopyPackA( template<> void -MlasGemmQuantCopyPackB( - MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedBType* D, +MlasGemmQuantCopyPackB( + MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedBType* D, const uint8_t* B, size_t ldb, size_t CountN, @@ -104,7 +120,7 @@ MlasGemmQuantCopyPackB( ) { const size_t AlignedCountK = - (CountK + MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK - 1) & ~(MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK - 1); + (CountK + MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK - 1) & ~(MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK - 1); const uint8_t BitFlipValue = (BIsSigned ? 0x80 : 0); // @@ -143,9 +159,9 @@ MlasGemmQuantCopyPackB( template<> size_t -MlasGemmQuantKernel( - const MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedAType* A, - const MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedBType* B, +MlasGemmQuantKernel( + const MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedAType* A, + const MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedBType* B, int32_t* C, size_t PackedCountK, size_t CountM, @@ -198,10 +214,10 @@ MlasGemmQuantKernel( return 1; } -const MLAS_GEMM_QUANT_DISPATCH MlasGemmU8X8DispatchDefault = { - MlasGemmQuantOperation, +const MLAS_GEMM_QUANT_DISPATCH MlasGemmQuantDispatchDefault = { + MlasGemmQuantOperation, nullptr, nullptr, - MLAS_GEMM_U8X8_KERNEL_DEFAULT::PackedK, + MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedK, 0, }; diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index 44a34f06f1..c2fad48e06 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -317,15 +317,11 @@ class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOn class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 12, int8_t, QuantizeLinear); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, QLinearMatMul); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, uint8_t, MatMulInteger); -#if defined(MLAS_TARGET_ARM_ANY) class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int8_t_int8_t, QLinearMatMul); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int8_t, MatMulInteger); -#endif class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, ConvInteger); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, QLinearConv); -#if defined(MLAS_TARGET_ARM_ANY) class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int8_t_int8_t, QLinearConv); -#endif class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, Slice); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 11, Dropout); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, NonMaxSuppression); @@ -1221,16 +1217,12 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, -#if defined(MLAS_TARGET_ARM_ANY) BuildKernelCreateInfo, BuildKernelCreateInfo, -#endif BuildKernelCreateInfo, BuildKernelCreateInfo, -#if defined(MLAS_TARGET_ARM_ANY) BuildKernelCreateInfo, -#endif BuildKernelCreateInfo, BuildKernelCreateInfo()), MatMulInteger); -#if defined(MLAS_TARGET_ARM_ANY) ONNX_OPERATOR_TYPED_KERNEL_EX( MatMulInteger, kOnnxDomain, @@ -52,7 +51,6 @@ ONNX_OPERATOR_TYPED_KERNEL_EX( .TypeConstraint("T2", DataTypeImpl::GetTensorType()) .TypeConstraint("T3", DataTypeImpl::GetTensorType()), MatMulInteger); -#endif Status MatMulInteger::Compute(OpKernelContext* ctx) const { const auto* a = ctx->Input(IN_A); diff --git a/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc b/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc index 6ebcf951ee..548a6ac75c 100644 --- a/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc +++ b/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc @@ -36,9 +36,7 @@ ONNX_OPERATOR_KERNEL_EX( .TypeConstraint("T3", DataTypeImpl::GetTensorType()), \ QLinearMatMul); -#if defined(MLAS_TARGET_ARM_ANY) REGISTER_QLINEARMATMUL_TYPED_KERNEL(int8_t, int8_t); -#endif Status QLinearMatMul::Compute(OpKernelContext* ctx) const { const auto* a = ctx->Input(IN_A); diff --git a/onnxruntime/core/providers/cpu/nn/qlinearconv.cc b/onnxruntime/core/providers/cpu/nn/qlinearconv.cc index fc698b7290..27b23781b3 100644 --- a/onnxruntime/core/providers/cpu/nn/qlinearconv.cc +++ b/onnxruntime/core/providers/cpu/nn/qlinearconv.cc @@ -239,9 +239,7 @@ ONNX_CPU_OPERATOR_KERNEL( .TypeConstraint("T4", DataTypeImpl::GetTensorType()), \ QLinearConv); -#if defined(MLAS_TARGET_ARM_ANY) REGISTER_QLINEARCONV_TYPED_KERNEL(kOnnxDomain, 10, int8_t, int8_t); -#endif #ifndef DISABLE_CONTRIB_OPS @@ -261,9 +259,7 @@ ONNX_OPERATOR_KERNEL_EX( .TypeConstraint("T4", DataTypeImpl::GetTensorType()), QLinearConv); -#if defined(MLAS_TARGET_ARM_ANY) REGISTER_QLINEARCONV_TYPED_KERNEL(kMSDomain, 1, int8_t, int8_t); -#endif } // namespace contrib diff --git a/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc b/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc index 19e3d8d765..a470515a5a 100644 --- a/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc +++ b/onnxruntime/test/contrib_ops/matmul_integer_to_float_test.cc @@ -144,7 +144,6 @@ TEST(MatMulIntegerToFloat, NoZeroPoint_HasBias_test_U8X8) { RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_uint8_bias.onnx"); } -#if defined(MLAS_TARGET_ARM_ANY) TEST(MatMulIntegerToFloat, HasZeroPoint_NoBias_test_S8S8) { RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_int8.onnx"); } @@ -152,7 +151,6 @@ TEST(MatMulIntegerToFloat, HasZeroPoint_NoBias_test_S8S8) { TEST(MatMulIntegerToFloat, NoZeroPoint_HasBias_test_S8S8) { RunMatMulIntegerToFloatTest("testdata/matmul_integer_to_float_int8_int8_bias.onnx"); } -#endif TEST(MatMulIntegerToFloat, MatMulInteger_Nuphar) { auto test_case = [&](const std::vector& input_shape, diff --git a/onnxruntime/test/mlas/unittest/test_qgemm.cpp b/onnxruntime/test/mlas/unittest/test_qgemm.cpp index fc4e28bd81..1eddde0513 100644 --- a/onnxruntime/test/mlas/unittest/test_qgemm.cpp +++ b/onnxruntime/test/mlas/unittest/test_qgemm.cpp @@ -6,12 +6,10 @@ template <> MlasQgemmTest* MlasTestFixtur template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); -#if defined(MLAS_TARGET_ARM_ANY) template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); -#endif template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); @@ -23,12 +21,10 @@ template <> MlasQgemmTest* MlasTestFixture< template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); -#if defined(MLAS_TARGET_ARM_ANY) template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); -#endif template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); template <> MlasQgemmTest* MlasTestFixture>::mlas_tester(nullptr); @@ -42,20 +38,16 @@ static size_t QGemmRegistLongExecute() { count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); -#if defined(MLAS_TARGET_ARM_ANY) count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); -#endif if (GetMlasThreadPool() != nullptr) { count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); -#if defined(MLAS_TARGET_ARM_ANY) count += MlasLongExecuteTests>::RegisterLongExecute(); count += MlasLongExecuteTests>::RegisterLongExecute(); -#endif } return count; @@ -68,10 +60,8 @@ static size_t QGemmRegistShortExecute() { count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); - #if defined(MLAS_TARGET_ARM_ANY) count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); - #endif if (MlasGemmPackBSize(128, 128, false /*AIsSigned*/, false /*BIsSigned*/) > 0) { // QGEMM U8U8=float packed tests count += QgemmShortExecuteTest::RegisterShortExecuteTests(); @@ -84,24 +74,20 @@ static size_t QGemmRegistShortExecute() { // QGEMM U8S8=int32_t packed tests count += QgemmShortExecuteTest::RegisterShortExecuteTests(); } - #if defined(MLAS_TARGET_ARM_ANY) if (MlasGemmPackBSize(128, 128, true /*AIsSigned*/, true /*BIsSigned*/) > 0) { // QGEMM U8S8=float packed tests count += QgemmShortExecuteTest::RegisterShortExecuteTests(); // QGEMM U8S8=int32_t packed tests count += QgemmShortExecuteTest::RegisterShortExecuteTests(); } - #endif if (GetMlasThreadPool() != nullptr) { count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); - #if defined(MLAS_TARGET_ARM_ANY) count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); - #endif if (MlasGemmPackBSize(128, 128, false /*AIsSigned*/, false /*BIsSigned*/) > 0) { count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); @@ -110,12 +96,10 @@ static size_t QGemmRegistShortExecute() { count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); } - #if defined(MLAS_TARGET_ARM_ANY) if (MlasGemmPackBSize(128, 128, true /*AIsSigned*/, true /*BIsSigned*/) > 0) { count += QgemmShortExecuteTest::RegisterShortExecuteTests(); count += QgemmShortExecuteTest::RegisterShortExecuteTests(); } - #endif } return count; diff --git a/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc b/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc index 5938259b50..7e41fe020a 100644 --- a/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc +++ b/onnxruntime/test/providers/cpu/math/matmul_integer_test.cc @@ -48,7 +48,10 @@ TEST(MatmulIntegerOpTest, MatMulInteger) { } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -68,13 +71,14 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t) { {-55, 16, 89, -44, 122, 154, 68, -39}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); + test.Run(); } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -102,13 +106,14 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND) { -9, 57, 69, -33, 153, 45}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); + test.Run(); } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_B_ND) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -136,13 +141,14 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_B_ND) { -45, -61, -11, -20, 103, 68}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); + test.Run(); } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_B_ND) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -173,13 +179,14 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_B_ND) { -55, 16, 89, -44, 122, 154, 68, -39}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); + test.Run(); } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_Has_Zero_Point) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -209,13 +216,14 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_Has_Zero_Point) { -55, 16, 89, -44, 122, 154, 68, -39}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); + test.Run(); } TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_No_Zero_Point) { - if (!DefaultCudaExecutionProvider() || !HasCudaEnvironment(530 /*min_cuda_architecture*/)) return; + if (DefaultCudaExecutionProvider() && + !HasCudaEnvironment(530 /*min_cuda_architecture*/)) { + return; + } OpTester test("MatMulInteger", 10); test.AddInput("T1", @@ -244,191 +252,9 @@ TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_No_Zero_Point) { -55, 16, 89, -44, 122, 154, 68, -39}); - std::vector> execution_providers; - execution_providers.push_back(DefaultCudaExecutionProvider()); - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers); -} - -#if defined(MLAS_TARGET_ARM_ANY) -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 4}, - {-3, 7, 5, -6, - 4, -5, 8, 7}); - test.AddInput("T2", - {4, 4}, - {5, -3, 7, 8, - -6, -8, -3, 6, - 7, 9, 9, -5, - 8, 7, -6, 7}); - test.AddInput("a_zero_point", {}, {5}); - test.AddInput("b_zero_point", {}, {5}); - test.AddOutput("T3", - {2, 4}, - {-55, 16, 89, -44, - 122, 154, 68, -39}); - test.Run(); } -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 2, 4}, - {-3, 7, 5, -6, - 4, -5, 8, 7, - - 7, -4, 3, 6, - -4, -5, 5, 7}); - - test.AddInput("T2", - {4, 3}, - {5, -3, 7, - 8, -6, -8, - -3, 6, 7, - 9, 9, -5}); - - test.AddInput("a_zero_point", {}, {3}); - test.AddInput("b_zero_point", {}, {4}); - test.AddOutput("T3", - {2, 2, 3}, - {-49, -39, 21, - -46, 103, 78, - - -9, 57, 69, - -33, 153, 45}); - - test.Run(); -} - -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_B_ND_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 4}, - {-3, 7, 5, -6, - 4, -5, 8, 7}); - test.AddInput("T2", - {2, 4, 3}, - {5, -3, 7, - 8, -6, -8, - -3, 6, 7, - 9, 9, -5, - - 5, -3, 7, - 8, -6, -8, - -3, 6, 7, - 9, 9, -5}); - test.AddInput("a_zero_point", {}, {1}); - test.AddInput("b_zero_point", {}, {2}); - test.AddOutput("T3", - {2, 2, 3}, - {-45, -61, -11, - -20, 103, 68, - - -45, -61, -11, - -20, 103, 68}); - - test.Run(); -} - -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_ND_B_ND_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 2, 4}, - {-3, 7, 5, -6, - 4, -5, 8, 7, - - -3, 7, 5, -6, - 4, -5, 8, 7}); - test.AddInput("T2", - {2, 4, 4}, - {5, -3, 7, 8, - -6, -8, -3, 6, - 7, 9, 9, -5, - 8, 7, -6, 7, - - 5, -3, 7, 8, - -6, -8, -3, 6, - 7, 9, 9, -5, - 8, 7, -6, 7}); - test.AddInput("a_zero_point", {}, {5}); - test.AddInput("b_zero_point", {}, {5}); - test.AddOutput("T3", - {2, 2, 4}, - {-55, 16, 89, -44, - 122, 154, 68, -39, - - -55, 16, 89, -44, - 122, 154, 68, -39}); - - test.Run(); -} - -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_A_Has_Zero_Point_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 2, 4}, - {-3, 7, 5, -6, - 4, -5, 8, 7, - - -3, 7, 5, -6, - 4, -5, 8, 7}); - test.AddInput("T2", - {2, 4, 4}, - {0, -8, 2, 3, - -11, -13, -8, 1, - 2, 4, 4, -10, - 3, 2, -11, 2, - - 0, -8, 2, 3, - -11, -13, -8, 1, - 2, 4, 4, -10, - 3, 2, -11, 2}); - test.AddInput("a_zero_point", {}, {5}); - test.AddOutput("T3", - {2, 2, 4}, - {-55, 16, 89, -44, - 122, 154, 68, -39, - - -55, 16, 89, -44, - 122, 154, 68, -39}); - - test.Run(); -} - -TEST(MatmulIntegerOpTest, MatMulInteger_int8_t_No_Zero_Point_ARM) { - OpTester test("MatMulInteger", 10); - test.AddInput("T1", - {2, 2, 4}, - {-8, 2, 0, -11, - -1, -10, 3, 2, - - -8, 2, 0, -11, - -1, -10, 3, 2}); - test.AddInput("T2", - {2, 4, 4}, - {0, -8, 2, 3, - -11, -13, -8, 1, - 2, 4, 4, -10, - 3, 2, -11, 2, - - 0, -8, 2, 3, - -11, -13, -8, 1, - 2, 4, 4, -10, - 3, 2, -11, 2}); - test.AddOutput("T3", - {2, 2, 4}, - {-55, 16, 89, -44, - 122, 154, 68, -39, - - -55, 16, 89, -44, - 122, 154, 68, -39}); - - test.Run(); -} -#endif - TEST(MatmulIntegerOpTest, MatMulInteger_WithZero_ZeroPoint) { OpTester test("MatMulInteger", 10); test.AddInput("T1", {4, 3}, {11, 7, 3, 10, 6, 2, 9, 5, 1, 8, 4, 0}); diff --git a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc index bf79a1a3f1..090feb09ae 100644 --- a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc +++ b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc @@ -86,7 +86,6 @@ TEST(QuantizeLinearMatmulOpTest, QLinearMatMul3D_U8S8) { test.Run(); } -#if defined(MLAS_TARGET_ARM_ANY) TEST(QuantizeLinearMatmulOpTest, QLinearMatMul3D_S8S8) { OpTester test("QLinearMatMul", 10); test.AddInput("T1", {2, 2, 4}, @@ -124,7 +123,6 @@ TEST(QuantizeLinearMatmulOpTest, QLinearMatMul3D_S8S8) { test.Run(); } -#endif TEST(QuantizeLinearMatmulOpTest, QLinearMatMul2D_U8U8) { auto run_test = [](bool only_t1_not_initializer) { @@ -196,7 +194,6 @@ TEST(QuantizeLinearMatmulOpTest, QLinearMatMul2D_U8S8) { run_test(true); } -#if defined(MLAS_TARGET_ARM_ANY) TEST(QuantizeLinearMatmulOpTest, QLinearMatMul2D_S8S8) { auto run_test = [](bool only_t1_not_initializer) { OpTester test("QLinearMatMul", 10); @@ -231,7 +228,6 @@ TEST(QuantizeLinearMatmulOpTest, QLinearMatMul2D_S8S8) { // NNAPI will require all inputs except T1 to be initializers run_test(true); } -#endif static void QLinearMatMul2DTest(bool only_t1_not_initializer) { // Test non-empty inputs @@ -302,7 +298,6 @@ TEST(QuantizeLinearMatmulOpTest, PerColumn_2D) { test.Run(); } -#if defined(MLAS_TARGET_ARM_ANY) TEST(QuantizeLinearMatmulOpTest, PerColumn_2D_S8S8) { OpTester test("QLinearMatMul", 10); test.AddInput("a", @@ -332,7 +327,6 @@ TEST(QuantizeLinearMatmulOpTest, PerColumn_2D_S8S8) { test.Run(); } -#endif TEST(QuantizeLinearMatmulOpTest, PerColumn_ND) { OpTester test("QLinearMatMul", 10); @@ -377,7 +371,6 @@ TEST(QuantizeLinearMatmulOpTest, PerColumn_ND) { test.Run(); } -#if defined(MLAS_TARGET_ARM_ANY) TEST(QuantizeLinearMatmulOpTest, PerColumn_ND_S8S8) { OpTester test("QLinearMatMul", 10); test.AddInput("a", @@ -420,7 +413,6 @@ TEST(QuantizeLinearMatmulOpTest, PerColumn_ND_S8S8) { test.Run(); } -#endif /** * @brief Extend QLinearMatMul for verifying prepacking behavior diff --git a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc index 37f432eaf4..f42b4969b5 100644 --- a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc @@ -1007,7 +1007,6 @@ TEST(QLinearConvTest, Conv2D_U8S8_Requantize_Bias_PerChannel) { } } -#if defined(MLAS_TARGET_ARM_ANY) TEST(QLinearConvTest, Conv1D_S8S8) { QLinearConvOpTester test; test.GenerateRandomInput({3, 24, 15}, .05f, 4); @@ -1394,7 +1393,6 @@ TEST(QLinearConvTest, Conv2D_S8S8_Requantize_Bias_PerChannel) { test.Run(); } } -#endif #ifndef ENABLE_TRAINING // Prepacking is enabled only on non-training builds TEST(QLinearConvTest, SharedPrepackedWeights) { diff --git a/onnxruntime/test/providers/kernel_def_hash_test.cc b/onnxruntime/test/providers/kernel_def_hash_test.cc index a917235578..6f869218b7 100644 --- a/onnxruntime/test/providers/kernel_def_hash_test.cc +++ b/onnxruntime/test/providers/kernel_def_hash_test.cc @@ -177,10 +177,6 @@ TEST(KernelDefHashTest, ExpectedCpuKernelDefHashes) { #if !defined(DISABLE_OPTIONAL_TYPE) AppendKernelDefHashesFromFile(ORT_TSTR("testdata/kernel_def_hashes/onnx.optional_type_ops.cpu.json"), result); #endif // !DISABLE_OPTIONAL_TYPE - -#if defined(MLAS_TARGET_ARM_ANY) - AppendKernelDefHashesFromFile(ORT_TSTR("testdata/kernel_def_hashes/arm_ops.cpu.json"), result); -#endif // MLAS_TARGET_ARM_ANY // TODO also handle kernels enabled by these symbols: BUILD_MS_EXPERIMENTAL_OPS std::sort(result.begin(), result.end()); return result; diff --git a/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json deleted file mode 100644 index b464f50ac1..0000000000 --- a/onnxruntime/test/testdata/kernel_def_hashes/arm_ops.cpu.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - [ - "MatMulInteger ai.onnx CPUExecutionProvider", - 10315437332566125928 - ], - [ - "MatMulIntegerToFloat com.microsoft CPUExecutionProvider", - 1363870470731747600 - ], - [ - "QLinearConv ai.onnx CPUExecutionProvider", - 1301685544574905024 - ], - [ - "QLinearConv com.microsoft CPUExecutionProvider", - 10904143578341560456 - ], - [ - "QLinearMatMul ai.onnx CPUExecutionProvider", - 7936962119982759552 - ] -] \ No newline at end of file diff --git a/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json index dfacf05f30..410625083c 100644 --- a/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json +++ b/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json @@ -147,6 +147,10 @@ "MatMulInteger16 com.microsoft CPUExecutionProvider", 5265636774129358144 ], + [ + "MatMulIntegerToFloat com.microsoft CPUExecutionProvider", + 1363870470731747600 + ], [ "MatMulIntegerToFloat com.microsoft CPUExecutionProvider", 7172777464471435800 @@ -187,6 +191,10 @@ "QLinearAveragePool com.microsoft CPUExecutionProvider", 9152647959212466896 ], + [ + "QLinearConv com.microsoft CPUExecutionProvider", + 10904143578341560456 + ], [ "QLinearConv com.microsoft CPUExecutionProvider", 16835965565578160400 diff --git a/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json index cab47016d7..9de2bbd54c 100644 --- a/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json +++ b/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json @@ -1155,6 +1155,10 @@ "MatMul ai.onnx CPUExecutionProvider", 16997422825780227992 ], + [ + "MatMulInteger ai.onnx CPUExecutionProvider", + 10315437332566125928 + ], [ "MatMulInteger ai.onnx CPUExecutionProvider", 8304157459354278720 @@ -1515,6 +1519,10 @@ "PRelu ai.onnx CPUExecutionProvider", 18013428254891374496 ], + [ + "QLinearConv ai.onnx CPUExecutionProvider", + 1301685544574905024 + ], [ "QLinearConv ai.onnx CPUExecutionProvider", 6630340551594954312 @@ -1523,6 +1531,10 @@ "QLinearMatMul ai.onnx CPUExecutionProvider", 17071666635484846840 ], + [ + "QLinearMatMul ai.onnx CPUExecutionProvider", + 7936962119982759552 + ], [ "QuantizeLinear ai.onnx CPUExecutionProvider", 1532667988771795616 From 7a70d22150b383b342a849143549d10e69aeab54 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Fri, 10 Dec 2021 20:26:59 +0000 Subject: [PATCH 024/113] Change some const to constexpr in unit tests code(#10002) --- onnxruntime/test/common/denormal_test.cc | 4 +- .../test/common/logging/logging_test.cc | 17 +-- onnxruntime/test/common/logging/sinks_test.cc | 5 +- .../contrib_ops/attention_lstm_op_test.cc | 34 +++--- .../test/contrib_ops/bias_dropout_op_test.cc | 2 +- .../test/contrib_ops/tokenizer_test.cc | 2 +- .../test/framework/allocation_planner_test.cc | 2 +- onnxruntime/test/framework/allocator_test.cc | 4 +- onnxruntime/test/framework/bfc_arena_test.cc | 4 +- onnxruntime/test/framework/data_types_test.cc | 2 +- onnxruntime/test/framework/endian_test.cc | 2 +- .../test/framework/inference_session_test.cc | 8 +- .../framework/insert_cast_transformer_test.cc | 2 +- onnxruntime/test/framework/math_test.cc | 26 ++--- .../framework/mem_pattern_planner_test.cc | 2 +- .../test/framework/tensorutils_test.cc | 2 +- .../test/framework/test_tensor_loader.cc | 2 +- onnxruntime/test/ir/op_test.cc | 18 ++-- onnxruntime/test/mlas/unittest/test_pool2d.h | 4 +- onnxruntime/test/mlas/unittest/test_pool3d.h | 6 +- onnxruntime/test/mlas/unittest/test_qgemm.h | 6 +- onnxruntime/test/mlas/unittest/test_util.h | 4 +- onnxruntime/test/onnx/heap_buffer.cc | 3 - onnxruntime/test/onnx/heap_buffer.h | 13 +-- onnxruntime/test/onnx/testcase_request.cc | 1 + .../test/optimizer/nchwc_optimizer_test.cc | 7 +- .../test/optimizer/nhwc_transformer_test.cc | 4 +- onnxruntime/test/optimizer/optimizer_test.cc | 4 +- onnxruntime/test/platform/threadpool_test.cc | 2 +- .../platform/windows/logging/etw_sink_test.cc | 4 +- .../providers/cpu/controlflow/loop_test.cc | 8 +- .../providers/cpu/controlflow/scan_test.cc | 54 +++++----- .../test/providers/cpu/math/topk_op_test.cc | 12 +-- .../cpu/ml/array_feature_extractor_test.cc | 4 +- .../test/providers/cpu/ml/imputer_test.cc | 2 +- .../cpu/ml/tree_ensembler_classifier_test.cc | 10 +- .../providers/cpu/nn/max_roi_pool_op_test.cc | 8 +- .../providers/cpu/nn/qlinearconv_op_test.cc | 4 +- .../providers/cpu/nn/tfidfvectorizer_test.cc | 2 +- .../cpu/object_detection/roialign_test.cc | 64 +++++------ .../providers/cpu/rnn/deep_cpu_gru_op_test.cc | 102 +++++++++--------- .../cpu/rnn/deep_cpu_lstm_op_test.cc | 44 ++++---- .../cpu/tensor/gather_elements_op_test.cc | 2 +- .../test/providers/cpu/tensor/isinf_test.cc | 12 +-- .../providers/cpu/tensor/resize_op_test.cc | 84 +++++++-------- .../cpu/tensor/space_depth_ops_test.cc | 36 +++---- .../providers/cpu/tensor/upsample_op_test.cc | 26 ++--- .../internal_testing_partitioning_tests.cc | 2 +- .../test/quantization/quantization_test.cc | 16 +-- onnxruntime/test/shared_lib/test_inference.cc | 16 +-- .../test/shared_lib/test_nontensor_types.cc | 16 +-- .../my_allocator.cc | 4 +- .../my_allocator.h | 2 +- onnxruntime/test/util/include/file_util.h | 4 +- onnxruntime/test/util/scoped_env_vars.cc | 26 +++-- onnxruntime/test/util/test_allocator.cc | 4 +- onnxruntime/test/util/test_utils.cc | 2 +- 57 files changed, 389 insertions(+), 373 deletions(-) diff --git a/onnxruntime/test/common/denormal_test.cc b/onnxruntime/test/common/denormal_test.cc index af9f5c1a68..40730eb15c 100644 --- a/onnxruntime/test/common/denormal_test.cc +++ b/onnxruntime/test/common/denormal_test.cc @@ -16,8 +16,8 @@ namespace test { TEST(DenormalTest, DenormalAsZeroTest) { auto test_denormal = [&](bool set_denormal_as_zero) { - const float denormal_float = 1e-38f; - const double denormal_double = 1e-308; + constexpr float denormal_float = 1e-38f; + constexpr double denormal_double = 1e-308; volatile float input_float = denormal_float; volatile double input_double = denormal_double; diff --git a/onnxruntime/test/common/logging/logging_test.cc b/onnxruntime/test/common/logging/logging_test.cc index c88eff79b2..48d1d4f68e 100644 --- a/onnxruntime/test/common/logging/logging_test.cc +++ b/onnxruntime/test/common/logging/logging_test.cc @@ -10,7 +10,10 @@ #include "core/common/logging/sinks/clog_sink.h" #include "test/common/logging/helpers.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif // if we pull in the whole 'testing' namespace we get warnings from date.h as both use '_' in places. // to avoid that we explicitly pull in the pieces we are using using testing::Eq; @@ -88,7 +91,7 @@ TEST_F(LoggingTestsFixture, TestWhereMacro) { TEST_F(LoggingTestsFixture, TestDefaultFiltering) { const std::string logid{"TestDefaultFiltering"}; const Severity min_log_level = Severity::kWARNING; - const bool filter_user_data = true; + constexpr bool filter_user_data = true; MockSink* sink_ptr = new MockSink(); @@ -117,8 +120,8 @@ TEST_F(LoggingTestsFixture, TestDefaultFiltering) { /// TEST_F(LoggingTestsFixture, TestLoggerFiltering) { const std::string logid{"TestLoggerFiltering"}; - const bool default_filter_user_data = true; - const int default_max_vlog_level = -1; + constexpr bool default_filter_user_data = true; + constexpr int default_max_vlog_level = -1; MockSink* sink_ptr = new MockSink(); @@ -166,7 +169,7 @@ TEST_F(LoggingTestsFixture, TestLoggingManagerCtor) { TEST_F(LoggingTestsFixture, TestConditionalMacros) { const std::string logger_id{"TestConditionalMacros"}; const Severity min_log_level = Severity::kVERBOSE; - const bool filter_user_data = false; + constexpr bool filter_user_data = false; MockSink* sink_ptr = new MockSink(); @@ -211,7 +214,7 @@ TEST_F(LoggingTestsFixture, TestVLog) { .Times(0); #endif - const bool filter_user_data = false; + constexpr bool filter_user_data = false; LoggingManager manager{std::unique_ptr(sink_ptr), Severity::kVERBOSE, filter_user_data, InstanceType::Temporal}; int max_vlog_level = 2; @@ -246,7 +249,7 @@ class CTestSink : public OStreamSink { TEST_F(LoggingTestsFixture, TestTruncation) { const std::string logger_id{"TestTruncation"}; const Severity min_log_level = Severity::kVERBOSE; - const bool filter_user_data = false; + constexpr bool filter_user_data = false; std::ostringstream out; auto* sink_ptr = new CTestSink{out}; diff --git a/onnxruntime/test/common/logging/sinks_test.cc b/onnxruntime/test/common/logging/sinks_test.cc index a748e004f2..07f477d632 100644 --- a/onnxruntime/test/common/logging/sinks_test.cc +++ b/onnxruntime/test/common/logging/sinks_test.cc @@ -121,7 +121,10 @@ TEST(LoggingTests, TestFileSink) { CheckStringInFile(filename, message); DeleteFile(filename); } - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif /// /// Tests that a composite_sink works correctly. /// diff --git a/onnxruntime/test/contrib_ops/attention_lstm_op_test.cc b/onnxruntime/test/contrib_ops/attention_lstm_op_test.cc index 8dc85363d5..6a9ac1b01f 100644 --- a/onnxruntime/test/contrib_ops/attention_lstm_op_test.cc +++ b/onnxruntime/test/contrib_ops/attention_lstm_op_test.cc @@ -250,15 +250,15 @@ static std::vector ConvertIcfoToIofc(const std::vector& icfo, int cell_hid } //Settings for this group of test data -static const int batch_size = 1; -static const int memory_max_step = 3; -static const int memory_depth = 3; -static const int input_max_step = 3; -static const int input_only_depth = 3; -static const int am_attn_size = 2; -static const int cell_hidden_size = 3; -static const int aw_attn_size = 2; -static const int input_size = input_only_depth + aw_attn_size; +static constexpr int batch_size = 1; +static constexpr int memory_max_step = 3; +static constexpr int memory_depth = 3; +static constexpr int input_max_step = 3; +static constexpr int input_only_depth = 3; +static constexpr int am_attn_size = 2; +static constexpr int cell_hidden_size = 3; +static constexpr int aw_attn_size = 2; +static constexpr int input_size = input_only_depth + aw_attn_size; // [batch_size=1, memory_max_step=3, memory_depth=3] static std::vector s_M_data{0.1f, -0.25f, 1.0f, 1.0f, -1.0f, -1.5f, 1.0f, 0.25f, -0.125f}; @@ -324,7 +324,7 @@ TEST(AttnLSTMTest, ForwardLstmWithBahdanauAMZeroAttention) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); // Fake zero for attention input weight now std::fill(W_T_data.begin() + 3 * 12, W_T_data.begin() + W_data_size, 0.0f); @@ -364,7 +364,7 @@ TEST(AttnLSTMTest, ForwardLstmWithBahdanauAM) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); std::vector R_T_data(&(WR_T_data[0]) + W_data_size, &(WR_T_data[0]) + WR_T_data.size()); @@ -401,7 +401,7 @@ TEST(AttnLSTMTest, ForwardLstmWithBahdanauAMShortenSeqLength) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); std::vector R_T_data(&(WR_T_data[0]) + W_data_size, &(WR_T_data[0]) + WR_T_data.size()); @@ -440,7 +440,7 @@ TEST(AttnLSTMTest, ReverseLstmWithBahdanauAMShortenSeqLength) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); std::vector R_T_data(&(WR_T_data[0]) + W_data_size, &(WR_T_data[0]) + WR_T_data.size()); @@ -479,7 +479,7 @@ TEST(AttnLSTMTest, BidirectionLstmWithBahdanauAMShortenSeqLength) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); std::vector R_T_data(&(WR_T_data[0]) + W_data_size, &(WR_T_data[0]) + WR_T_data.size()); @@ -529,8 +529,8 @@ TEST(AttnLSTMTest, BidirectionLstmWithBahdanauAMShortenSeqLength) { } TEST(AttnLSTMTest, BidirectionLstmWithBahdanauAM2BatchShortenSeqLen) { - const int batch2Size = 2; - const int inputMaxStep4 = 4; + constexpr int batch2Size = 2; + constexpr int inputMaxStep4 = 4; static const std::vector s_X_T_2batch{0.25f, -1.5f, 1.0f, 0.25f, -0.5f, -1.5f, 0.1f, 1.5f, 0.25f, 0.0f, 0.0f, 0.0f, 0.1f, -0.125f, 0.25f, -0.5f, 0.25f, 0.1f, 1.0f, 0.5f, -1.5f, 0.0f, 0.0f, 0.0f}; @@ -540,7 +540,7 @@ TEST(AttnLSTMTest, BidirectionLstmWithBahdanauAM2BatchShortenSeqLen) { std::vector WR_T_data = ConvertIcfoToIofc(s_WR_T_data_ICFO, cell_hidden_size); - const size_t W_data_size = 5 * 12; + constexpr size_t W_data_size = 5 * 12; std::vector W_T_data(&(WR_T_data[0]), &(WR_T_data[0]) + W_data_size); std::vector R_T_data(&(WR_T_data[0]) + W_data_size, &(WR_T_data[0]) + WR_T_data.size()); diff --git a/onnxruntime/test/contrib_ops/bias_dropout_op_test.cc b/onnxruntime/test/contrib_ops/bias_dropout_op_test.cc index eaa583a633..68cf3fe231 100644 --- a/onnxruntime/test/contrib_ops/bias_dropout_op_test.cc +++ b/onnxruntime/test/contrib_ops/bias_dropout_op_test.cc @@ -33,7 +33,7 @@ void RunBiasDropoutTest(const bool use_mask, const std::vector& input_s TrainingMode training_mode = TrainingTrue, bool use_float16_ratio = false, bool has_residual = true, bool has_same_shape_bias = false) { OpTester t{"BiasDropout", 1, kMSDomain}; - const int64_t seed = 42; + constexpr int64_t seed = 42; t.AddAttribute("seed", seed); const auto input_size = std::accumulate( diff --git a/onnxruntime/test/contrib_ops/tokenizer_test.cc b/onnxruntime/test/contrib_ops/tokenizer_test.cc index cdd382a952..4daf9dac88 100644 --- a/onnxruntime/test/contrib_ops/tokenizer_test.cc +++ b/onnxruntime/test/contrib_ops/tokenizer_test.cc @@ -13,7 +13,7 @@ const std::string end_mark{0x3}; const std::string padval(u8"0xdeadbeaf"); constexpr const char* domain = onnxruntime::kMSDomain; -const int opset_ver = 1; +constexpr int opset_ver = 1; } // namespace tokenizer_test diff --git a/onnxruntime/test/framework/allocation_planner_test.cc b/onnxruntime/test/framework/allocation_planner_test.cc index b5605d50b2..379ef1d4e4 100644 --- a/onnxruntime/test/framework/allocation_planner_test.cc +++ b/onnxruntime/test/framework/allocation_planner_test.cc @@ -271,7 +271,7 @@ class PlannerTest : public ::testing::Test { // CreatePlan is called inside FinalizeSessionState and usually the initializers are removed following that. // Leave initializers so we can duplicate the call to CreatePlan from here to validate. - const bool remove_initializers = false; + constexpr bool remove_initializers = false; status = state_->FinalizeSessionState(ORT_TSTR(""), kernel_registry_manager, {}, nullptr, remove_initializers); EXPECT_TRUE(status.IsOK()) << status.ErrorMessage(); diff --git a/onnxruntime/test/framework/allocator_test.cc b/onnxruntime/test/framework/allocator_test.cc index c2bd393c55..23809ef49c 100644 --- a/onnxruntime/test/framework/allocator_test.cc +++ b/onnxruntime/test/framework/allocator_test.cc @@ -32,7 +32,9 @@ TEST(AllocatorTest, CPUAllocatorTest) { cpu_arena->Free(bytes); //todo: test the used / max api. } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif // helper class to validate values in Alloc and Free calls made via IAllocator::MakeUniquePtr class TestAllocator : public IAllocator { public: diff --git a/onnxruntime/test/framework/bfc_arena_test.cc b/onnxruntime/test/framework/bfc_arena_test.cc index 873032fa37..13247cc58a 100644 --- a/onnxruntime/test/framework/bfc_arena_test.cc +++ b/onnxruntime/test/framework/bfc_arena_test.cc @@ -221,7 +221,7 @@ TEST(BFCArenaTest, AllocationsAndDeallocationsWithGrowth) { // 64 megs. std::srand(static_cast(std::time(nullptr))); - const int32_t max_mem = 1 << 27; + constexpr int32_t max_mem = 1 << 27; std::vector initial_ptrs; for (int s = 1; s < 10; s++) { @@ -242,7 +242,7 @@ TEST(BFCArenaTest, AllocationsAndDeallocationsWithGrowth) { } } - const int32_t max_mem_2 = 1 << 26; + constexpr int32_t max_mem_2 = 1 << 26; // Allocate a lot of raw pointers between 100 bytes and 64 megs. for (int s = 1; s < 10; s++) { size_t size = std::min( diff --git a/onnxruntime/test/framework/data_types_test.cc b/onnxruntime/test/framework/data_types_test.cc index 222271c6e3..15362cbabf 100644 --- a/onnxruntime/test/framework/data_types_test.cc +++ b/onnxruntime/test/framework/data_types_test.cc @@ -419,7 +419,7 @@ TEST_F(DataTypeTest, VectorMapInt64ToFloatTest) { TEST_F(DataTypeTest, BFloat16Test) { // Test data type { - const float sample = 1.0f; + constexpr float sample = 1.0f; BFloat16 flt16(sample); auto int_rep = flt16.val; BFloat16 flt_from_int(int_rep); diff --git a/onnxruntime/test/framework/endian_test.cc b/onnxruntime/test/framework/endian_test.cc index cd7bbba086..7b8f56bd97 100644 --- a/onnxruntime/test/framework/endian_test.cc +++ b/onnxruntime/test/framework/endian_test.cc @@ -13,7 +13,7 @@ namespace utils { namespace test { TEST(EndianTest, EndiannessDetection) { - const uint16_t test_value = 0x1234; + constexpr uint16_t test_value = 0x1234; const unsigned char* test_value_first_byte = reinterpret_cast(&test_value); if constexpr (endian::native == endian::little) { EXPECT_EQ(*test_value_first_byte, 0x34); diff --git a/onnxruntime/test/framework/inference_session_test.cc b/onnxruntime/test/framework/inference_session_test.cc index f8f1745042..4f1e831020 100644 --- a/onnxruntime/test/framework/inference_session_test.cc +++ b/onnxruntime/test/framework/inference_session_test.cc @@ -2706,7 +2706,7 @@ TEST(InferenceSessionTests, InitializerSharing_EnsureSessionsUseUserAddedInitial void RunModelWithDenormalAsZero(InferenceSession& session_object, const RunOptions& run_options, bool set_denormal_as_zero) { - const float denormal_float = 1e-38f; + constexpr float denormal_float = 1e-38f; // prepare input X std::vector dims_mul{3, 2}; @@ -2741,9 +2741,9 @@ void RunModelWithDenormalAsZero(InferenceSession& session_object, void VerifyThreadPoolWithDenormalAsZero(onnxruntime::concurrency::ThreadPool* tp, bool set_denormal_as_zero) { - const int num_tasks = 4; - const float denormal_float = 1e-38f; - const double denormal_double = 1e-308; + constexpr int num_tasks = 4; + constexpr float denormal_float = 1e-38f; + constexpr double denormal_double = 1e-308; std::array input_float; input_float.fill(denormal_float); diff --git a/onnxruntime/test/framework/insert_cast_transformer_test.cc b/onnxruntime/test/framework/insert_cast_transformer_test.cc index a161857b04..3f8d37d3ed 100644 --- a/onnxruntime/test/framework/insert_cast_transformer_test.cc +++ b/onnxruntime/test/framework/insert_cast_transformer_test.cc @@ -228,7 +228,7 @@ TEST(TransformerTest, Fp16NodeWithSubgraph) { const Graph& subgraph = *node_with_subgraph_iter->GetSubgraphs().front(); - const bool recurse_into_subgraphs = false; + constexpr bool recurse_into_subgraphs = false; std::map orig_graph_ops = CountOpsInGraph(graph, recurse_into_subgraphs); std::map orig_subgraph_ops = CountOpsInGraph(subgraph, recurse_into_subgraphs); diff --git a/onnxruntime/test/framework/math_test.cc b/onnxruntime/test/framework/math_test.cc index 7f071339ac..3a0965c872 100644 --- a/onnxruntime/test/framework/math_test.cc +++ b/onnxruntime/test/framework/math_test.cc @@ -28,7 +28,7 @@ namespace onnxruntime { //parameter is thread pool size class MathGemmTest : public testing::TestWithParam { protected: - static OrtThreadPoolParams CreateThreadPoolOptions(int size) { + constexpr static OrtThreadPoolParams CreateThreadPoolOptions(int size) { OrtThreadPoolParams option; option.thread_pool_size = size; return option; @@ -51,9 +51,9 @@ TEST_P(MathGemmTest, GemmNoTransNoTrans) { EXPECT_EQ(W[i], 1); } - const float kOne = 1.0; - const float kPointFive = 0.5; - const float kZero = 0.0; + constexpr float kOne = 1.0; + constexpr float kPointFive = 0.5; + constexpr float kZero = 0.0; math::Gemm(CblasNoTrans, CblasNoTrans, 5, 6, 10, kOne, VECTOR_HEAD(X), VECTOR_HEAD(W), kZero, VECTOR_HEAD(Y), tp.get()); @@ -96,9 +96,9 @@ TEST_P(MathGemmTest, GemmNoTransTrans) { EXPECT_EQ(W[i], 1); } - const float kOne = 1.0; - const float kPointFive = 0.5; - const float kZero = 0.0; + constexpr float kOne = 1.0; + constexpr float kPointFive = 0.5; + constexpr float kZero = 0.0; math::Gemm(CblasNoTrans, CblasTrans, 5, 6, 10, kOne, VECTOR_HEAD(X), VECTOR_HEAD(W), kZero, VECTOR_HEAD(Y), tp.get()); @@ -141,9 +141,9 @@ TEST(MathTest, GemvNoTrans) { EXPECT_EQ(X[i], 1); } - const float kOne = 1.0; - const float kPointFive = 0.5; - const float kZero = 0.0; + constexpr float kOne = 1.0; + constexpr float kPointFive = 0.5; + constexpr float kZero = 0.0; math::Gemv(CblasNoTrans, 5, 10, kOne, VECTOR_HEAD(A), VECTOR_HEAD(X), kZero, VECTOR_HEAD(Y), &provider); for (size_t i = 0; i < Y.size(); ++i) { @@ -179,9 +179,9 @@ TEST(MathTest, GemvTrans) { EXPECT_EQ(X[i], 1); } - const float kOne = 1.0; - const float kPointFive = 0.5; - const float kZero = 0.0; + constexpr float kOne = 1.0; + constexpr float kPointFive = 0.5; + constexpr float kZero = 0.0; math::Gemv(CblasTrans, 6, 10, kOne, VECTOR_HEAD(A), VECTOR_HEAD(X), kZero, VECTOR_HEAD(Y), &provider); for (size_t i = 0; i < Y.size(); ++i) { diff --git a/onnxruntime/test/framework/mem_pattern_planner_test.cc b/onnxruntime/test/framework/mem_pattern_planner_test.cc index 42e9018e0c..e70d83e7a3 100644 --- a/onnxruntime/test/framework/mem_pattern_planner_test.cc +++ b/onnxruntime/test/framework/mem_pattern_planner_test.cc @@ -7,7 +7,7 @@ namespace onnxruntime { namespace test { TEST(MemPatternPlannerTest, TraceAllocaitonTest) { - const bool using_counters = false; // we're not tracking start/end for use/re-use of each allocation via counters + constexpr bool using_counters = false; // we're not tracking start/end for use/re-use of each allocation via counters MemPatternPlanner planner{using_counters}; planner.TraceAllocation(0, 1024); planner.TraceAllocation(1, 256); diff --git a/onnxruntime/test/framework/tensorutils_test.cc b/onnxruntime/test/framework/tensorutils_test.cc index e42ce9b17b..0a56ba0bfa 100644 --- a/onnxruntime/test/framework/tensorutils_test.cc +++ b/onnxruntime/test/framework/tensorutils_test.cc @@ -25,7 +25,7 @@ void TestUnpackFloatTensor(TensorProto_DataType type, const Path& model_path) { TensorProto float_tensor_proto; float_tensor_proto.set_data_type(type); T f[4] = {1.1f, 2.2f, 3.3f, 4.4f}; - const size_t len = sizeof(T) * 4; + constexpr size_t len = sizeof(T) * 4; char rawdata[len]; for (int i = 0; i < 4; ++i) { memcpy(rawdata + i * sizeof(T), &(f[i]), sizeof(T)); diff --git a/onnxruntime/test/framework/test_tensor_loader.cc b/onnxruntime/test/framework/test_tensor_loader.cc index 940e3735d3..dc2db7e907 100644 --- a/onnxruntime/test/framework/test_tensor_loader.cc +++ b/onnxruntime/test/framework/test_tensor_loader.cc @@ -138,7 +138,7 @@ TEST(CApiTensorTest, load_huge_tensor_with_external_data) { for (int i = 0; i != 1025; ++i) { ASSERT_EQ(len, fwrite(data.data(), 1, len, fp)); } - const size_t total_ele_count = 524288 * 1025; + constexpr size_t total_ele_count = 524288 * 1025; ASSERT_EQ(0, fclose(fp)); // construct a tensor proto onnx::TensorProto p; diff --git a/onnxruntime/test/ir/op_test.cc b/onnxruntime/test/ir/op_test.cc index c39f0c66b6..c7283d6faf 100644 --- a/onnxruntime/test/ir/op_test.cc +++ b/onnxruntime/test/ir/op_test.cc @@ -63,27 +63,23 @@ TEST(FeatureVectorizerTest, TraditionalMlOpTest) { map_value_type->set_elem_type(TensorProto::FLOAT); map_value_type->mutable_shape(); - NodeArg* input_arg1 = new NodeArg("node_1_in_1", &map_int64_float); + std::unique_ptr input_arg1 = std::make_unique("node_1_in_1", &map_int64_float); inputs.clear(); - inputs.push_back(input_arg1); - NodeArg* output_arg1 = new NodeArg("node_1_out_1", &tensor_float); + inputs.push_back(input_arg1.get()); + std::unique_ptr output_arg1 = std::make_unique("node_1_out_1", &tensor_float); outputs.clear(); - outputs.push_back(output_arg1); + outputs.push_back(output_arg1.get()); graph.AddNode("node_1", "CastMap", "node 1", inputs, outputs, nullptr, kMLDomain); inputs.clear(); - inputs.push_back(output_arg1); + inputs.push_back(output_arg1.get()); - NodeArg* output_arg4 = new NodeArg("node_4_out_1", &tensor_float); + std::unique_ptr output_arg4 = std::make_unique("node_4_out_1", &tensor_float); outputs.clear(); - outputs.push_back(output_arg4); + outputs.push_back(output_arg4.get()); graph.AddNode("node_4", "FeatureVectorizer", "node 4", inputs, outputs, nullptr, kMLDomain); auto status = graph.Resolve(); EXPECT_TRUE(status.IsOK()) << status.ErrorMessage(); - - delete input_arg1; - delete output_arg1; - delete output_arg4; } #endif diff --git a/onnxruntime/test/mlas/unittest/test_pool2d.h b/onnxruntime/test/mlas/unittest/test_pool2d.h index 39f3734026..ebb1f256ae 100644 --- a/onnxruntime/test/mlas/unittest/test_pool2d.h +++ b/onnxruntime/test/mlas/unittest/test_pool2d.h @@ -31,8 +31,8 @@ class MlasPool2DTest : public MlasTestBase { size_t PaddingRightWidth, size_t StrideHeight, size_t StrideWidth) { - const size_t DilationHeight = 1; - const size_t DilationWidth = 1; + constexpr size_t DilationHeight = 1; + constexpr size_t DilationWidth = 1; int64_t OutputHeight64 = ((int64_t(InputHeight) + int64_t(PaddingLeftHeight) + int64_t(PaddingRightHeight)) - diff --git a/onnxruntime/test/mlas/unittest/test_pool3d.h b/onnxruntime/test/mlas/unittest/test_pool3d.h index 9ac8d14e9b..4ad69c682b 100644 --- a/onnxruntime/test/mlas/unittest/test_pool3d.h +++ b/onnxruntime/test/mlas/unittest/test_pool3d.h @@ -38,9 +38,9 @@ class MlasPool3DTest : public MlasTestBase { size_t StrideDepth, size_t StrideHeight, size_t StrideWidth) { - const size_t DilationDepth = 1; - const size_t DilationHeight = 1; - const size_t DilationWidth = 1; + constexpr size_t DilationDepth = 1; + constexpr size_t DilationHeight = 1; + constexpr size_t DilationWidth = 1; int64_t OutputDepth64 = ((int64_t(InputDepth) + int64_t(PaddingLeftDepth) + int64_t(PaddingRightDepth)) - diff --git a/onnxruntime/test/mlas/unittest/test_qgemm.h b/onnxruntime/test/mlas/unittest/test_qgemm.h index 2ec61ec4dd..d9ddb8f6c2 100644 --- a/onnxruntime/test/mlas/unittest/test_qgemm.h +++ b/onnxruntime/test/mlas/unittest/test_qgemm.h @@ -413,19 +413,19 @@ class MlasQgemmTest : public MlasQgemmTes float* CReference = BufferCReference.GetBuffer(N * M * BatchSize); const float* Bias = BufferBias.GetBuffer(N); - const float AScale = 0.5f; + constexpr float AScale = 0.5f; float* AFloat = BufferAFloat.GetBuffer(K * M * BatchSize); for (size_t b = 0; b < BatchSize; b++) { DequantizeLinear((AType*)(A + K * M * b), AFloat + K * M * b, K * M, AScale, (AType)offa); } - const float BScale = 0.25f; + constexpr float BScale = 0.25f; float* BFloat = BufferBFloat.GetBuffer(N * K * BatchSize); for (size_t b = 0; b < BatchSize; b++) { DequantizeLinear((BType*)(B + N * K * b), BFloat + N * K * b, N * K, BScale, BType(offb)); } - const float CScale = AScale * BScale; + constexpr float CScale = AScale * BScale; Test(M, N, K, BatchSize, A, AFloat, K, offa, B, BFloat, N, offb, C, CReference, N, CScale, nullptr); Test(M, N, K, BatchSize, A, AFloat, K, offa, B, BFloat, N, offb, C, CReference, N, CScale, Bias); diff --git a/onnxruntime/test/mlas/unittest/test_util.h b/onnxruntime/test/mlas/unittest/test_util.h index 468a53ea00..c14f1f57ce 100644 --- a/onnxruntime/test/mlas/unittest/test_util.h +++ b/onnxruntime/test/mlas/unittest/test_util.h @@ -110,8 +110,8 @@ class MatrixGuardBuffer { std::fill_n(buffer, Elements, T(0)); } else { - const int MinimumFillValue = -23; - const int MaximumFillValue = 23; + constexpr int MinimumFillValue = -23; + constexpr int MaximumFillValue = 23; int FillValue = MinimumFillValue; T* FillAddress = buffer; diff --git a/onnxruntime/test/onnx/heap_buffer.cc b/onnxruntime/test/onnx/heap_buffer.cc index 10ddfa244b..8bd58b8b82 100644 --- a/onnxruntime/test/onnx/heap_buffer.cc +++ b/onnxruntime/test/onnx/heap_buffer.cc @@ -15,9 +15,6 @@ HeapBuffer::~HeapBuffer() { for (auto d : deleters_) { d.Run(); } - for (void* p : buffers_) { - delete[] reinterpret_cast(p); - } } } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/onnx/heap_buffer.h b/onnxruntime/test/onnx/heap_buffer.h index 37ca6aa615..8e513793c4 100644 --- a/onnxruntime/test/onnx/heap_buffer.h +++ b/onnxruntime/test/onnx/heap_buffer.h @@ -3,12 +3,12 @@ #pragma once -#include "callback.h" +#include #include #include #include - +#include "callback.h" namespace onnxruntime { namespace test { /** @@ -22,9 +22,10 @@ class HeapBuffer { */ ~HeapBuffer(); void* AllocMemory(size_t size) { - void* p = new (std::nothrow) uint8_t[size]; - buffers_.push_back(p); - return p; + auto p = std::make_unique(size); + void* ret = p.get(); + buffers_.emplace_back(std::move(p)); + return ret; } void AddDeleter(const OrtCallback& d); @@ -33,7 +34,7 @@ class HeapBuffer { private: std::vector deleters_; - std::vector buffers_; + std::vector > buffers_; }; } // namespace test diff --git a/onnxruntime/test/onnx/testcase_request.cc b/onnxruntime/test/onnx/testcase_request.cc index 35469c0e81..ccb64e7131 100644 --- a/onnxruntime/test/onnx/testcase_request.cc +++ b/onnxruntime/test/onnx/testcase_request.cc @@ -204,6 +204,7 @@ void TestCaseRequestContext::CalculateAndLogStats() const { break; case EXECUTE_RESULT::MODEL_TYPE_MISMATCH: LOGF_DEFAULT(ERROR, "%s: type in model file mismatch. Dataset:%s\n", test_case_name.c_str(), s.c_str()); + break; default: //nothing to do break; diff --git a/onnxruntime/test/optimizer/nchwc_optimizer_test.cc b/onnxruntime/test/optimizer/nchwc_optimizer_test.cc index 132771b437..a753e794e5 100644 --- a/onnxruntime/test/optimizer/nchwc_optimizer_test.cc +++ b/onnxruntime/test/optimizer/nchwc_optimizer_test.cc @@ -1234,8 +1234,11 @@ TEST(NchwcOptimizerTests, UpsampleNearest) { std::vector sizes_shape(4); sizes_shape[0] = 3; sizes_shape[1] = 42; - sizes_shape[2] = static_cast(scale_h * 27); - sizes_shape[3] = static_cast(scale_w * 15); + constexpr int64_t shape2 = 27; + constexpr int64_t shape3 = 15; + //The result is 64-bit. Use double for calculation to get better precision. + sizes_shape[2] = static_cast(static_cast(scale_h) * shape2); + sizes_shape[3] = static_cast(static_cast(scale_w) * shape3); input_args.push_back(helper.Make1DInitializer({})); input_args.push_back(helper.Make1DInitializer(sizes_shape)); } else { diff --git a/onnxruntime/test/optimizer/nhwc_transformer_test.cc b/onnxruntime/test/optimizer/nhwc_transformer_test.cc index 305c6979a8..cbb4de74bf 100644 --- a/onnxruntime/test/optimizer/nhwc_transformer_test.cc +++ b/onnxruntime/test/optimizer/nhwc_transformer_test.cc @@ -270,7 +270,7 @@ TEST(NhwcTransformerTests, ConvSplit) { auto* qladd_output_arg = builder.MakeIntermediate(); auto* output_arg = builder.MakeOutput(); - const int64_t conv1_output_channels = 32; + constexpr int64_t conv1_output_channels = 32; auto* conv1_weight_arg = NhwcMakeInitializer(builder, {conv1_output_channels, 23, 3, 3}); Node& conv_node = builder.AddQLinearConvNode(input_arg, .01f, 135, @@ -315,7 +315,7 @@ TEST(NhwcTransformerTests, ConvSplitQLinearConcat) { auto* qlconcat_output_arg = builder.MakeIntermediate(); auto* output_arg = builder.MakeOutput(); - const int64_t conv1_output_channels = 32; + constexpr int64_t conv1_output_channels = 32; auto* conv1_weight_arg = NhwcMakeInitializer(builder, {conv1_output_channels, 23, 3, 3}); Node& conv_node = builder.AddQLinearConvNode(input_arg, .01f, 135, conv1_weight_arg, .02f, 126, diff --git a/onnxruntime/test/optimizer/optimizer_test.cc b/onnxruntime/test/optimizer/optimizer_test.cc index 3d04d44de4..b4297f7e90 100644 --- a/onnxruntime/test/optimizer/optimizer_test.cc +++ b/onnxruntime/test/optimizer/optimizer_test.cc @@ -30,8 +30,8 @@ TEST(OptimizerTest, Basic) { Model model("OptimizerBasic", false, ModelMetaData(), PathString(), IOnnxRuntimeOpSchemaRegistryList(), {{kOnnxDomain, 12}}, {}, DefaultLoggingManager().DefaultLogger()); auto& graph = model.MainGraph(); - const int tensor_dim = 10; - const int input_num = 2; + constexpr int tensor_dim = 10; + constexpr int input_num = 2; TensorProto initializer_tensor[input_num]; std::vector> inputs(input_num); std::vector> outputs(1); diff --git a/onnxruntime/test/platform/threadpool_test.cc b/onnxruntime/test/platform/threadpool_test.cc index 6ba9493c67..e4a06446d2 100644 --- a/onnxruntime/test/platform/threadpool_test.cc +++ b/onnxruntime/test/platform/threadpool_test.cc @@ -171,7 +171,7 @@ void TestPoolCreation(const std::string&, int iter) { // Test multi-loop parallel sections, with a series of fixed-size loops void TestMultiLoopSections(const std::string& name, int num_threads, int num_loops) { for (int rep = 0; rep < 5; rep++) { - const int num_tasks = 1024; + constexpr int num_tasks = 1024; auto test_data = CreateTestData(num_tasks); CreateThreadPoolAndTest(name, num_threads, [&](ThreadPool* tp) { ThreadPool::ParallelSection ps(tp); diff --git a/onnxruntime/test/platform/windows/logging/etw_sink_test.cc b/onnxruntime/test/platform/windows/logging/etw_sink_test.cc index c71bab2119..7436ac5bd1 100644 --- a/onnxruntime/test/platform/windows/logging/etw_sink_test.cc +++ b/onnxruntime/test/platform/windows/logging/etw_sink_test.cc @@ -10,7 +10,9 @@ #include "core/common/logging/sinks/composite_sink.h" #include "test/common/logging/helpers.h" - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif namespace onnxruntime { namespace test { diff --git a/onnxruntime/test/providers/cpu/controlflow/loop_test.cc b/onnxruntime/test/providers/cpu/controlflow/loop_test.cc index 7df10bdfe6..32f1a120e2 100644 --- a/onnxruntime/test/providers/cpu/controlflow/loop_test.cc +++ b/onnxruntime/test/providers/cpu/controlflow/loop_test.cc @@ -34,8 +34,8 @@ struct RunOptions { static const ONNX_NAMESPACE::GraphProto CreateSubgraph(const RunOptions& options); -static const float kOuterNodeAddValue = 3.f; -static const float kSumMax = 8.f; +static constexpr float kOuterNodeAddValue = 3.f; +static constexpr float kSumMax = 8.f; class LoopOpTester : public OpTester { public: @@ -371,7 +371,7 @@ void RunTest(int64_t max_iterations, // this should take 3 iterations as we add 3 each time. void ExitDueToCond(const RunOptions& options) { int64_t max_iterations = 5; - const int64_t expected_num_iterations = 3; + constexpr int64_t expected_num_iterations = 3; float loop_var_0_final = kOuterNodeAddValue * expected_num_iterations; @@ -438,7 +438,7 @@ TEST(Loop, LoopSubgraphRankMismatch) { TEST(Loop, ExitDueToMaxIterations) { int64_t max_iterations = 2; - const int64_t expected_num_iterations = 2; + constexpr int64_t expected_num_iterations = 2; float loop_var_0_final = kOuterNodeAddValue * expected_num_iterations; diff --git a/onnxruntime/test/providers/cpu/controlflow/scan_test.cc b/onnxruntime/test/providers/cpu/controlflow/scan_test.cc index ca9dfe279e..ccc60266a4 100644 --- a/onnxruntime/test/providers/cpu/controlflow/scan_test.cc +++ b/onnxruntime/test/providers/cpu/controlflow/scan_test.cc @@ -30,7 +30,7 @@ struct RunOptions { static common::Status CreateSubgraph(Graph& graph, RunOptions& options, const std::string& failure_message = ""); -static const float kOuterNodeAddValue = 42.f; +static constexpr float kOuterNodeAddValue = 42.f; class ScanOpTester : public OpTester { public: @@ -420,9 +420,9 @@ static void RunTest_v9(const std::string test_name, int64_t sequence_len, int64_ } static void ShortSequenceOneInBatchOneLoopStateVar(const RunOptions& options, const std::string& expected_error = "") { - const int64_t batch_size = 1; - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 1; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; @@ -581,9 +581,9 @@ TEST(Scan9, DISABLED_BadShape) { } TEST(Scan8, ShortSequenceTwoInBatchOneLoopStateVar) { - const int64_t batch_size = 2; - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f, 10.f}; // start at 0 for first item in batch, and 10 for second @@ -615,9 +615,9 @@ TEST(Scan8, ShortSequenceTwoInBatchOneLoopStateVar) { } TEST(Scan8, MixedSequenceLens) { - const int64_t batch_size = 3; - const int64_t max_sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 3; + constexpr int64_t max_sequence_len = 2; + constexpr int64_t input_size = 2; std::vector sequence_lens{1, 2, 2}; @@ -662,9 +662,9 @@ TEST(Scan8, MixedSequenceLens) { } TEST(Scan8, MixedSequenceLensReverse) { - const int64_t batch_size = 2; - const int64_t max_sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 2; + constexpr int64_t max_sequence_len = 2; + constexpr int64_t input_size = 2; std::vector sequence_lens{1, 2}; std::vector directions{1, 1}; // reverse both inputs @@ -706,9 +706,9 @@ TEST(Scan8, MixedSequenceLensReverse) { } TEST(Scan8, ShortSequenceTwoInBatchOneLoopStateVarReverseFirstInput) { - const int64_t batch_size = 2; - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f, 10.f}; // start at 0 for first item in batch, and 10 for second @@ -744,8 +744,8 @@ TEST(Scan8, ShortSequenceTwoInBatchOneLoopStateVarReverseFirstInput) { } TEST(Scan9, ReversedInput) { - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; @@ -773,8 +773,8 @@ TEST(Scan9, ReversedInput) { } TEST(Scan9, ReversedOutput) { - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; @@ -802,8 +802,8 @@ TEST(Scan9, ReversedOutput) { } TEST(Scan9, TransposeInput) { - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; @@ -833,8 +833,8 @@ TEST(Scan9, TransposeInput) { } TEST(Scan9, TransposeOutput) { - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; @@ -904,9 +904,9 @@ TEST(Scan9, TransposeOutputDim2) { } static void InvalidInput(bool is_v8) { - const int64_t batch_size = 1; - const int64_t sequence_len = 2; - const int64_t input_size = 2; + constexpr int64_t batch_size = 1; + constexpr int64_t sequence_len = 2; + constexpr int64_t input_size = 2; std::vector iteration_count_in{0.f}; diff --git a/onnxruntime/test/providers/cpu/math/topk_op_test.cc b/onnxruntime/test/providers/cpu/math/topk_op_test.cc index f1f6b34ca5..5b3f9e9219 100644 --- a/onnxruntime/test/providers/cpu/math/topk_op_test.cc +++ b/onnxruntime/test/providers/cpu/math/topk_op_test.cc @@ -824,9 +824,9 @@ static void TestThreaded(int64_t k, int64_t n, int64_t batch_size) { // and sufficient items to process given this calculation: // int64_t threads_needed = static_cast(std::floor(input_shape.Size() * k / (128 * 1024))); TEST(TopKOperator, PriorityQueueThreaded) { - const int64_t k = 200; - const int64_t n = 2; - const int64_t batch_size = 1000; + constexpr int64_t k = 200; + constexpr int64_t n = 2; + constexpr int64_t batch_size = 1000; TestThreaded(k, n, batch_size); TestThreaded(k, n, batch_size); } @@ -835,9 +835,9 @@ TEST(TopKOperator, PriorityQueueThreaded) { // and sufficient items to process given this calculation: // int64_t threads_needed = static_cast(std::floor(input_shape.Size() * k / (128 * 1024))); TEST(TopKOperator, SelectTopKThreaded) { - const int64_t k = 400; - const int64_t n = 2; - const int64_t batch_size = 500; + constexpr int64_t k = 400; + constexpr int64_t n = 2; + constexpr int64_t batch_size = 500; TestThreaded(k, n, batch_size); TestThreaded(k, n, batch_size); } diff --git a/onnxruntime/test/providers/cpu/ml/array_feature_extractor_test.cc b/onnxruntime/test/providers/cpu/ml/array_feature_extractor_test.cc index 1cd29abe9e..4d77f9675c 100644 --- a/onnxruntime/test/providers/cpu/ml/array_feature_extractor_test.cc +++ b/onnxruntime/test/providers/cpu/ml/array_feature_extractor_test.cc @@ -16,11 +16,11 @@ class ArrayFeatureExtractorTest : public ::testing::Test { }; TEST_F(ArrayFeatureExtractorTest, Basic) { - const int N = 3; + constexpr int N = 3; const std::vector X = {0.8f, -1.5f, 2.0f, 3.8f, -4.0f, 5.0f, 6.8f, -7.5f, 8.0f, 9.8f, -9.0f, 4.0f, 4.8f, -4.5f, 4.0f, 4.8f, -4.0f, 4.0f}; - const int kCols = 6; + constexpr int kCols = 6; const vector x_dims = {N, kCols}; test_.AddInput("X", x_dims, X); diff --git a/onnxruntime/test/providers/cpu/ml/imputer_test.cc b/onnxruntime/test/providers/cpu/ml/imputer_test.cc index 964efce562..0e0f45b5c1 100644 --- a/onnxruntime/test/providers/cpu/ml/imputer_test.cc +++ b/onnxruntime/test/providers/cpu/ml/imputer_test.cc @@ -9,7 +9,7 @@ namespace test { TEST(MLOpTest, ImputerOpFloat) { OpTester test("Imputer", 1, onnxruntime::kMLDomain); - const int N = 5; + constexpr int N = 5; std::vector impute = {10.0f}; float replace = 1.f; test.AddAttribute("imputed_value_floats", impute); diff --git a/onnxruntime/test/providers/cpu/ml/tree_ensembler_classifier_test.cc b/onnxruntime/test/providers/cpu/ml/tree_ensembler_classifier_test.cc index f0ec922919..78b086d276 100644 --- a/onnxruntime/test/providers/cpu/ml/tree_ensembler_classifier_test.cc +++ b/onnxruntime/test/providers/cpu/ml/tree_ensembler_classifier_test.cc @@ -34,7 +34,7 @@ TEST(MLOpTest, TreeEnsembleClassifier) { std::vector log_probs = {}; //define the context of the operator call - const int N = 8; + constexpr int N = 8; test.AddAttribute("nodes_truenodeids", lefts); test.AddAttribute("nodes_falsenodeids", rights); test.AddAttribute("nodes_treeids", treeids); @@ -79,7 +79,7 @@ TEST(MLOpTest, TreeEnsembleClassifier_N1) { std::vector log_probs = {}; //define the context of the operator call - const int N = 1; + constexpr int N = 1; test.AddAttribute("nodes_truenodeids", lefts); test.AddAttribute("nodes_falsenodeids", rights); test.AddAttribute("nodes_treeids", treeids); @@ -126,7 +126,7 @@ TEST(MLOpTest, TreeEnsembleClassifierLabels) { std::vector scores{-5, 5, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 3, -3}; //define the context of the operator call - const int N = 8; + constexpr int N = 8; test.AddAttribute("nodes_truenodeids", lefts); test.AddAttribute("nodes_falsenodeids", rights); test.AddAttribute("nodes_treeids", treeids); @@ -175,7 +175,7 @@ TEST(MLOpTest, TreeEnsembleClassifierBinary) { std::vector scores{5, -1, -1, -1, -1, 1, -1, -3}; //define the context of the operator call - const int N = 8; + constexpr int N = 8; test.AddAttribute("nodes_truenodeids", lefts); test.AddAttribute("nodes_falsenodeids", rights); test.AddAttribute("nodes_treeids", treeids); @@ -232,7 +232,7 @@ TEST(MLOpTest, TreeEnsembleClassifierBinaryProbabilities) { 0.5f, 0.04742586f}; //define the context of the operator call - const int N = 8; + constexpr int N = 8; test.AddAttribute("nodes_truenodeids", lefts); test.AddAttribute("nodes_falsenodeids", rights); test.AddAttribute("nodes_treeids", treeids); diff --git a/onnxruntime/test/providers/cpu/nn/max_roi_pool_op_test.cc b/onnxruntime/test/providers/cpu/nn/max_roi_pool_op_test.cc index fa407eb425..af555061ab 100644 --- a/onnxruntime/test/providers/cpu/nn/max_roi_pool_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/max_roi_pool_op_test.cc @@ -11,12 +11,12 @@ namespace test { TEST(RoIPoolTest, MaxRoiPool) { OpTester test("MaxRoiPool"); - const int64_t pooled_height = 1, pooled_width = 1; + constexpr int64_t pooled_height = 1, pooled_width = 1; test.AddAttribute("pooled_shape", std::vector{pooled_height, pooled_width}); - const int H = 6, W = 6; - const int image_size = H * W; - const int input_channels = 3; + constexpr int H = 6, W = 6; + constexpr int image_size = H * W; + constexpr int input_channels = 3; std::vector input; for (int i = 0; i < input_channels * image_size; i++) input.push_back(1.0f * i / 10); diff --git a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc index f42b4969b5..f718f80993 100644 --- a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc @@ -25,8 +25,8 @@ struct QuantizedTensor { min = std::min(min, 0.f); max = std::max(max, 0.f); - float qmin = std::numeric_limits::min(); - float qmax = std::numeric_limits::max(); + constexpr float qmin = std::numeric_limits::min(); + constexpr float qmax = std::numeric_limits::max(); // compute scale and zero point scale_ = (max - min) / (qmax - qmin); diff --git a/onnxruntime/test/providers/cpu/nn/tfidfvectorizer_test.cc b/onnxruntime/test/providers/cpu/nn/tfidfvectorizer_test.cc index 2cce80aa61..1f626c3704 100644 --- a/onnxruntime/test/providers/cpu/nn/tfidfvectorizer_test.cc +++ b/onnxruntime/test/providers/cpu/nn/tfidfvectorizer_test.cc @@ -11,7 +11,7 @@ namespace onnxruntime { namespace test { namespace tfidfvectorizer_test { -const int opset_ver = 9; +constexpr int opset_ver = 9; void InitTestAttr(OpTester& test, const std::string& mode, int64_t min_gram_length, int64_t max_gram_length, int64_t max_skip_count, diff --git a/onnxruntime/test/providers/cpu/object_detection/roialign_test.cc b/onnxruntime/test/providers/cpu/object_detection/roialign_test.cc index 491711a1c0..3218f7be26 100644 --- a/onnxruntime/test/providers/cpu/object_detection/roialign_test.cc +++ b/onnxruntime/test/providers/cpu/object_detection/roialign_test.cc @@ -14,10 +14,10 @@ TEST(RoiAlignTest, AvgModePositive) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; std::vector rois{0.,7.,5.,7.,5.,0.,-15.,-15.,-15.,-15.,0.,-10.,21.,-10.,21.,0.,13.,8.,13.,8.,0.,-14.,19.,-14.,19.}; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., @@ -56,10 +56,10 @@ TEST(RoiAlignTest, OnnxTest) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f); - const int N = 1; - const int C = 1; - const int H = 10; - const int W = 10; + constexpr int N = 1; + constexpr int C = 1; + constexpr int H = 10; + constexpr int W = 10; test.AddInput("X", {N, C, H, W}, { 0.2764f, 0.7150f, 0.1958f, 0.3416f, 0.4638f, 0.0259f, 0.2963f, 0.6518f, 0.4856f, 0.7250f, @@ -105,10 +105,10 @@ TEST(RoiAlignTest, MaxModePositive) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; std::vector rois{0.,7.,5.,7.,5.,0.,-15.,-15.,-15.,-15.,0.,-10.,21.,-10.,21.,0.,13.,8.,13.,8.,0.,-14.,19.,-14.,19.}; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., @@ -143,10 +143,10 @@ TEST(RoiAlignTest, AvgModeNegativeInvalidMode) { test.AddAttribute("sampling_ratio", -2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; std::vector rois{0.,7.,5.,7.,5.,0.,-15.,-15.,-15.,-15.,0.,-10.,21.,-10.,21.,0.,13.,8.,13.,8.,0.,-14.,19.,-14.,19.}; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., @@ -185,10 +185,10 @@ TEST(RoiAlignTest, AvgModeNegativeSamplingRatio) { test.AddAttribute("sampling_ratio", -2); // <-- failure condition test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., 25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46., @@ -226,10 +226,10 @@ TEST(RoiAlignTest, AvgModeNegativeInvalidNumRoiDims) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; std::vector rois{0.,7.,5.,7.,5.,0.,-15.,-15.,-15.,-15.,0.,-10.,21.,-10.,21.,0.,13.,8.,13.,8.,0.,-14.,19.,-14.,19.}; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., @@ -268,10 +268,10 @@ TEST(RoiAlignTest, AvgModeNegativeInvalidSecondRoiDims) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., 25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46., @@ -309,10 +309,10 @@ TEST(RoiAlignTest, MismatchNumRois) { test.AddAttribute("sampling_ratio", 2); test.AddAttribute("spatial_scale", 1.0f / 16.0f); - const int N = 1; - const int C = 3; - const int H = 5; - const int W = 5; + constexpr int N = 1; + constexpr int C = 3; + constexpr int H = 5; + constexpr int W = 5; std::vector rois{0.,7.,5.,7.,5.,0.,-15.,-15.,-15.,-15.,0.,-10.,21.,-10.,21.,0.,13.,8.,13.,8.,0.,-14.,19.,-14.,19.}; test.AddInput("X", {N, C, H, W}, {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24., diff --git a/onnxruntime/test/providers/cpu/rnn/deep_cpu_gru_op_test.cc b/onnxruntime/test/providers/cpu/rnn/deep_cpu_gru_op_test.cc index 1a23a62f08..e13c7bbeb2 100644 --- a/onnxruntime/test/providers/cpu/rnn/deep_cpu_gru_op_test.cc +++ b/onnxruntime/test/providers/cpu/rnn/deep_cpu_gru_op_test.cc @@ -310,7 +310,7 @@ TEST(GRUTest, ForwardDefaultActivationsSimpleWeightsWithBiasBatchParallelLinearB 0.19538902f, -0.19016478f, -0.05644283f, 0.30856851f, -0.15190377f, 0.05999807f}; - const bool linear_before_reset = true; + constexpr bool linear_before_reset = true; DefaultActivationsSimpleWeightsWithBias("forward", Y_data, linear_before_reset); } @@ -322,7 +322,7 @@ TEST(GRUTest, ReverseDefaultActivationsSimpleWeightsWithBiasBatchParallelLinearB 0.12252139f, -0.12032216f, -0.05064924f, 0.21249877f, -0.08884402f, 0.04751285f}; - const bool linear_before_reset = true; + constexpr bool linear_before_reset = true; DefaultActivationsSimpleWeightsWithBias("reverse", Y_data, linear_before_reset); } @@ -332,8 +332,8 @@ TEST(GRUTest, ForwardDefaultActivationsSimpleWeightsWithBiasLinearBeforeReset) { 0.15024948f, -0.11097029f, -0.02121867f, 0.19538902f, -0.19016478f, -0.05644283f}; - const bool linear_before_reset = true; - const bool one_row = true; + constexpr bool linear_before_reset = true; + constexpr bool one_row = true; DefaultActivationsSimpleWeightsWithBias("forward", Y_data, linear_before_reset, one_row); } @@ -343,8 +343,8 @@ TEST(GRUTest, ReverseDefaultActivationsSimpleWeightsWithBiasLinearBeforeReset) { 0.20910699f, -0.18880953f, -0.04005555f, 0.12252139f, -0.12032216f, -0.05064924f}; - const bool linear_before_reset = true; - const bool one_row = true; + constexpr bool linear_before_reset = true; + constexpr bool one_row = true; DefaultActivationsSimpleWeightsWithBias("reverse", Y_data, linear_before_reset, one_row); } @@ -543,8 +543,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpForwardBasic) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch = 1; - const int seq_length = 2; + constexpr int batch = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -561,8 +561,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpBackwardBasic) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.185934f, -0.269585f, -0.455351f, -0.276391f}; std::vector sequence_length = {2}; @@ -580,8 +580,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpBidirectionalBasic) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -603,8 +603,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpForwardActivation) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -622,8 +622,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpForwardInitialHiddenState) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -641,8 +641,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpForwardBatch) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 2; - const int seq_length = 2; + constexpr int batch_size = 2; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.455351f, -0.276391f, @@ -668,8 +668,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpForwardBatchLinearBeforeReset) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 2; - const int seq_length = 2; + constexpr int batch_size = 2; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.455351f, -0.276391f, @@ -695,8 +695,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpGrowBatchSequenceLength) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -707,8 +707,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpGrowBatchSequenceLength) { ctx.RunTest(X, batch_size, seq_length, sequence_length, &initial_h, expected_Y, expected_Y_h); - const int batch2 = 2; - const int seq_length2 = 2; + constexpr int batch2 = 2; + constexpr int seq_length2 = 2; std::vector X2 = {-0.455351f, -0.276391f, -0.455351f, -0.276391f, @@ -735,8 +735,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpGrowBatchSequenceLengthLinearBeforeReset) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -747,8 +747,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpGrowBatchSequenceLengthLinearBeforeReset) { ctx.RunTest(X, batch_size, seq_length, sequence_length, &initial_h, expected_Y, expected_Y_h, true); - const int batch2 = 2; - const int seq_length2 = 2; + constexpr int batch2 = 2; + constexpr int seq_length2 = 2; std::vector X2 = {-0.455351f, -0.276391f, -0.455351f, -0.276391f, @@ -775,8 +775,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthWithBidirectionalLinearBeforeRe DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector sequence_length = {2}; @@ -796,8 +796,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthWithBidirectionalLinearBeforeRe DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 1; - const int seq_length = 2; + constexpr int batch_size = 1; + constexpr int seq_length = 2; std::vector X = {0.855351f, 0.676391f, 0.585934f, 0.669585f}; std::vector sequence_length = {2}; @@ -816,8 +816,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthWithBidirectionalLinearBeforeRe DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 2; - const int seq_length = 2; + constexpr int batch_size = 2; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, 0.855351f, 0.676391f, -0.185934f, -0.269585f, @@ -844,8 +844,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpShorterSeqInMiddle) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 3; - const int seq_length = 2; + constexpr int batch_size = 3; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, 0.855351f, 0.676391f, -0.185934f, -0.269585f, @@ -877,8 +877,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpZeroSeqInMiddle) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 4; - const int seq_length = 2; + constexpr int batch_size = 4; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, 0.855351f, 0.676391f, -0.185934f, -0.269585f, @@ -910,8 +910,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthWithPartialZero) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch_size = 2; - const int seq_length = 2; + constexpr int batch_size = 2; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, 0.455351f, 0.276391f, -0.185934f, -0.269585f, @@ -938,8 +938,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthShorterThanInputSequenceLength) DeepCpuGruOpTestContext ctx(direction, activations); - const int batch = 1; - const int seq_length = 2; + constexpr int batch = 1; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -967,8 +967,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthAllZeros) { DeepCpuGruOpTestContext ctx(direction, activations); - const int batch = 2; - const int seq_length = 2; + constexpr int batch = 2; + constexpr int seq_length = 2; std::vector X = {-0.455351f, -0.276391f, -0.455351f, -0.276391f, @@ -995,8 +995,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSingleBatchMultipleHiddenThreads) { DeepCpuGruOpTestContext ctx(direction, activations, true, {}, {}, /*large_hidden*/ true); - const int batch_size = 1; - const int seq_length = 1; + constexpr int batch_size = 1; + constexpr int seq_length = 1; std::vector X = {0.1f, -0.2f}; std::vector sequence_length = {1}; std::vector initial_h(32); @@ -1025,8 +1025,8 @@ TEST(GRUTest, ONNXRuntime_TestGRUPositiveActivationClipping) { DeepCpuGruOpTestContext ctx(direction, activations, true, {}, {}, /*large_hidden*/ true); - const int batch_size = 2; - const int seq_length = 1; + constexpr int batch_size = 2; + constexpr int seq_length = 1; std::vector X = {1000.0f, 2000.0f, -1e+20f, -1e+10f}; std::vector sequence_length = {1, 1}; std::vector initial_h(64); @@ -1054,9 +1054,9 @@ TEST(GRUTest, ONNXRuntime_TestGRUPositiveActivationAlphaBeta) { const std::vector alpha = {0.5f, 2.0f}; const std::vector beta = {2.0f}; - const int input_size = 2; // 4; - const int batch_size = 1; - const int seq_length = 1; + constexpr int input_size = 2; // 4; + constexpr int batch_size = 1; + constexpr int seq_length = 1; std::vector X = {1.0f, 2.0f}; // , -3.0f, -4.0f}; std::vector sequence_length = {1}; diff --git a/onnxruntime/test/providers/cpu/rnn/deep_cpu_lstm_op_test.cc b/onnxruntime/test/providers/cpu/rnn/deep_cpu_lstm_op_test.cc index 0de874ad2b..18fbb4ed74 100644 --- a/onnxruntime/test/providers/cpu/rnn/deep_cpu_lstm_op_test.cc +++ b/onnxruntime/test/providers/cpu/rnn/deep_cpu_lstm_op_test.cc @@ -662,7 +662,7 @@ class LstmOpContext2x1x2x2 { TEST(LSTMTest, ONNXRuntime_TestLSTMForwardPeepHole) { ///////////////Attributes//////////////////////// - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; std::vector input = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; std::vector Y_data = {-0.0251062475f, 0.0561261699f, -0.03277518f, 0.05935364f}; @@ -675,7 +675,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardPeepHole) { } TEST(LSTMTest, ONNXRuntime_TestLSTMBidirectionalBasic) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; std::vector X_data = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -693,7 +693,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMBidirectionalBasic) { } TEST(LSTMTest, ONNXRuntime_TestLSTMForwardNoBiasUsePeepholes) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; bool use_bias = false; bool use_peepholes = true; @@ -711,7 +711,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardNoBiasUsePeepholes) { } TEST(LSTMTest, ONNXRuntime_TestLSTMForwardInputForget) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; bool use_bias = true; bool use_peepholes = true; @@ -732,7 +732,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardInputForget) { } TEST(LSTMTest, ONNXRuntime_TestLSTMForwardClip) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; bool use_bias = true; bool use_peepholes = true; @@ -751,7 +751,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardClip) { } TEST(LSTMTest, ONNXRuntime_TestLSTMBackward) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; std::vector X_data = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -765,7 +765,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMBackward) { } TEST(LSTMTest, ONNXRuntime_TestLSTMBackward_gpu) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; std::vector X_data = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -780,7 +780,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMBackward_gpu) { } TEST(LSTMTest, ONNXRuntime_TestLSTMForwardHiddenState) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; bool use_bias = true; bool use_peepholes = false; @@ -799,7 +799,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardHiddenState) { } TEST(LSTMTest, ONNXRuntime_TestLSTMForwardCellState) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; bool use_bias = true; bool use_peepholes = false; @@ -819,7 +819,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMForwardCellState) { } TEST(LSTMTest, ONNXRuntime_TestLSTMActivation) { - const int seq_len = 2, batch_size = 1; + constexpr int seq_len = 2, batch_size = 1; std::vector activations = {"tanh", "sigmoid", "tanh"}; @@ -844,10 +844,10 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMActivation) { // The reallocation doesn't apply any more so this mainly tests larger batches with non-default activations. TEST(LSTMTest, ONNXRuntime_TestLSTMBatchReallocation) { ///////////////Attributes//////////////////////// - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 1; - bool use_bias = true; - bool use_peepholes = false; + constexpr bool use_bias = true; + constexpr bool use_peepholes = false; std::vector activations = {"tanh", "sigmoid", "tanh"}; @@ -903,7 +903,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMBatchReallocation) { // Most of these aren't relevant anymore as we don't re-use buffers given Compute is stateless. // It does test a batch > 1 with bidirectional output and custom activations though. TEST(LSTMTest, ONNXRuntime_TestLSTMOutputWrite) { - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 1; std::vector activations = {"tanh", "sigmoid", "tanh", "tanh", "sigmoid", "tanh"}; @@ -975,7 +975,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMOutputWrite) { } TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthAllZeros) { - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 2; std::vector activations = {"tanh", "sigmoid", "tanh", "tanh", "sigmoid", "tanh"}; @@ -1019,7 +1019,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthAllZeros) { } TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthPartialZeros) { - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 2; std::vector activations = {"tanh", "sigmoid", "tanh", "tanh", "sigmoid", "tanh"}; @@ -1065,8 +1065,8 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthPartialZeros) { } TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLength) { - const int seq_len = 2; - const int batch_size = 1; + constexpr int seq_len = 2; + constexpr int batch_size = 1; std::vector X_data = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -1095,8 +1095,8 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLength) } TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLengthNoP) { - const int seq_len = 2; - const int batch_size = 1; + constexpr int seq_len = 2; + constexpr int batch_size = 1; std::vector X_data = {-0.455351f, -0.276391f, -0.185934f, -0.269585f}; @@ -1126,7 +1126,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLengthN } TEST(LSTMTest, ONNXRuntime_TestLSTMShorterSeqInMiddle) { - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 3; std::vector activations = {"sigmoid", "tanh", "tanh", "sigmoid", "tanh", "tanh"}; @@ -1166,7 +1166,7 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMShorterSeqInMiddle) { } TEST(LSTMTest, ONNXRuntime_TestLSTMZeroSeqInMiddle) { - const int seq_len = 2; + constexpr int seq_len = 2; int batch_size = 4; std::vector activations = {"sigmoid", "tanh", "tanh", "sigmoid", "tanh", "tanh"}; diff --git a/onnxruntime/test/providers/cpu/tensor/gather_elements_op_test.cc b/onnxruntime/test/providers/cpu/tensor/gather_elements_op_test.cc index 3b48d7e9df..783d2eca1a 100644 --- a/onnxruntime/test/providers/cpu/tensor/gather_elements_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/gather_elements_op_test.cc @@ -360,7 +360,7 @@ TEST(GatherElementsOpTest, BigIndices) { OpTester test1("GatherElements", 11); test1.AddAttribute("axis", 0LL); - const int kNumIndices = 10 * 1000; // must be >= kParallelizationThreshold in gather_elements.cc + constexpr int kNumIndices = 10 * 1000; // must be >= kParallelizationThreshold in gather_elements.cc std::vector input(2 * kNumIndices); std::iota(std::begin(input), std::end(input), 0.f); test1.AddInput("data", {2, kNumIndices}, input); diff --git a/onnxruntime/test/providers/cpu/tensor/isinf_test.cc b/onnxruntime/test/providers/cpu/tensor/isinf_test.cc index 6a0542df55..ddb392eb82 100644 --- a/onnxruntime/test/providers/cpu/tensor/isinf_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/isinf_test.cc @@ -9,13 +9,13 @@ namespace onnxruntime { namespace test { -const float FLOAT_INF = std::numeric_limits::infinity(); -const float FLOAT_NINF = -std::numeric_limits::infinity(); -const float FLOAT_NAN = std::numeric_limits::quiet_NaN(); +constexpr float FLOAT_INF = std::numeric_limits::infinity(); +constexpr float FLOAT_NINF = -std::numeric_limits::infinity(); +constexpr float FLOAT_NAN = std::numeric_limits::quiet_NaN(); -const double DOUBLE_INF = std::numeric_limits::infinity(); -const double DOUBLE_NINF = -std::numeric_limits::infinity(); -const double DOUBLE_NAN = std::numeric_limits::quiet_NaN(); +constexpr double DOUBLE_INF = std::numeric_limits::infinity(); +constexpr double DOUBLE_NINF = -std::numeric_limits::infinity(); +constexpr double DOUBLE_NAN = std::numeric_limits::quiet_NaN(); TEST(IsInfTest, test_isinf_float) { // Defaults for detect_negative = 1 diff --git a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc index 949123c092..96556f8e8d 100644 --- a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc @@ -16,7 +16,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_tf_crop_and_resize) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); - const int64_t H = 4, W = 4; + constexpr int64_t H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -46,7 +46,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_tf_crop_and_resize_with_extrapol test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); test.AddAttribute("extrapolation_value", 10.0f); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -72,7 +72,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_4DBilinear) { test.AddAttribute("mode", "linear"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -104,7 +104,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_4DBilinear1) { test.AddAttribute("mode", "linear"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -129,7 +129,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_4DBilinear1_WithSizes) { OpTester test("Resize", 13); std::vector roi{}; std::vector scales{}; - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector sizes{N, C, 1, 2}; test.AddAttribute("mode", "linear"); @@ -162,7 +162,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_4DBilinear_align_corners) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "align_corners"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -195,7 +195,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_2DBilinear_pytorch_half_pixel) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "pytorch_half_pixel"); - const int64_t H = 4, W = 4; + constexpr int64_t H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -224,7 +224,7 @@ TEST(ResizeOpTest, ResizeOpLinearUpSampleTest_4DBilinear_asymmetric) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "asymmetric"); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f, @@ -261,7 +261,7 @@ TEST(ResizeOpTest, ResizeOpLinearUpSampleTest_2DBilinear_align_corners) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "align_corners"); - const int64_t H = 2, W = 2; + constexpr int64_t H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f}; @@ -288,7 +288,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_3DTrilinear_pytorch_half_pixel) test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "pytorch_half_pixel"); - const int64_t D = 2, H = 4, W = 4; + constexpr int64_t D = 2, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -320,7 +320,7 @@ TEST(ResizeOpTest, ResizeOpLinearUpSampleTest_5DTrilinear_pytorch_half_pixel) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "pytorch_half_pixel"); - const int64_t N = 1, C = 2, D = 2, H = 1, W = 2; + constexpr int64_t N = 1, C = 2, D = 2, H = 1, W = 2; std::vector X = { 1.0f, 2.0f, 1.0f, 2.0f, 1.0f, 2.0f, 1.0f, 2.0f}; @@ -346,7 +346,7 @@ TEST(ResizeOpTest, ResizeOpLinearScalesNoOpTest) { std::vector scales{1.0f, 1.0f, 1.0f, 1.0f}; test.AddAttribute("mode", "linear"); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f, @@ -378,7 +378,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -400,7 +400,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_Opset12) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -423,7 +423,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_WithSizes) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -448,7 +448,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_tf_half_pixel) { test.AddAttribute("coordinate_transformation_mode", "tf_half_pixel_for_nn"); test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -477,7 +477,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_tf_crop_and_resize_with_extrapo test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); test.AddAttribute("extrapolation_value", 10.0f); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -505,7 +505,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSample5dTest_tf_crop_and_resize_with_extra test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); test.AddAttribute("extrapolation_value", 10.0f); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -532,7 +532,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSampleTest) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f}; test.AddInput("X", {N, C, H, W}, X); @@ -557,7 +557,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSampleTest_WithSizes_CeilMode) { test.AddAttribute("mode", "nearest"); test.AddAttribute("nearest_mode", "ceil"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f}; test.AddInput("X", {N, C, H, W}, X); @@ -586,7 +586,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSample5dTest_WithSizes_CeilMode) { test.AddAttribute("mode", "nearest"); test.AddAttribute("nearest_mode", "ceil"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f}; test.AddInput("X", {1, N, C, H, W}, X); @@ -617,7 +617,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSample_Floor_Align_Corners) { test.AddAttribute("coordinate_transformation_mode", "align_corners"); test.AddAttribute("nearest_mode", "floor"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -655,7 +655,7 @@ TEST(ResizeOpTest, ResizeOpNearest_OneToOneMappingBetweenInputAndOutputDataDims) test.AddAttribute("coordinate_transformation_mode", "tf_half_pixel_for_nn"); test.AddAttribute("nearest_mode", "ceil"); - const int64_t C = 2, D = 3; + constexpr int64_t C = 2, D = 3; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; test.AddInput("X", {C, D}, X); @@ -720,7 +720,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSample_Nearest2xOptimization_Scales) { test.AddAttribute("coordinate_transformation_mode", "asymmetric"); test.AddAttribute("nearest_mode", "floor"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f}; @@ -753,7 +753,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSample_Nearest2xOptimization_Sizes) { test.AddAttribute("coordinate_transformation_mode", "asymmetric"); test.AddAttribute("nearest_mode", "floor"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f}; @@ -783,7 +783,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest) { test.AddAttribute("mode", "cubic"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -812,7 +812,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_exclude_outside) { test.AddAttribute("exclude_outside", static_cast(1)); test.AddAttribute("cubic_coeff_a", -0.5f); - const int64_t H = 4, W = 4; + constexpr int64_t H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -840,7 +840,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_coeff) { test.AddAttribute("mode", "cubic"); test.AddAttribute("cubic_coeff_a", -0.5f); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -867,7 +867,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_with_roi) { test.AddAttribute("mode", "cubic"); test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -894,7 +894,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_asymmetric) { test.AddAttribute("mode", "cubic"); test.AddAttribute("coordinate_transformation_mode", "asymmetric"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -921,7 +921,7 @@ TEST(ResizeOpTest, ResizeOpCubicUpSampleTest) { test.AddAttribute("mode", "cubic"); test.AddAttribute("coordinate_transformation_mode", "asymmetric"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -953,7 +953,7 @@ TEST(ResizeOpTest, ResizeOpCubicUpSampleTest_MultiChannel) { test.AddAttribute("mode", "cubic"); - const int64_t N = 1, C = 2, H = 4, W = 4; + constexpr int64_t N = 1, C = 2, H = 4, W = 4; std::vector X = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, @@ -1002,7 +1002,7 @@ TEST(ResizeOpTest, ResizeOpCubicUpSampleTest_tf_half_pixel_for_nn) { test.AddAttribute("mode", "cubic"); test.AddAttribute("coordinate_transformation_mode", "tf_half_pixel_for_nn"); - const int64_t N = 1, C = 1, H = 4, W = 4; + constexpr int64_t N = 1, C = 1, H = 4, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, @@ -1032,7 +1032,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_4DBilinear_Ver10) { test.AddAttribute("mode", "linear"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -1052,7 +1052,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_2DBilinear_Ver10) { test.AddAttribute("mode", "linear"); - const int64_t H = 2, W = 4; + constexpr int64_t H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -1071,7 +1071,7 @@ TEST(ResizeOpTest, ResizeOpLinearUpSampleTest_4DBilinear_Ver10) { std::vector scales{1.0f, 1.0f, 2.0f, 4.0f}; test.AddAttribute("mode", "linear"); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f, @@ -1101,7 +1101,7 @@ TEST(ResizeOpTest, ResizeOpLinearUpSampleTest_2DBilinear_Ver10) { std::vector scales{2.0f, 4.0f}; test.AddAttribute("mode", "linear"); - const int64_t H = 2, W = 2; + constexpr int64_t H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f}; @@ -1123,7 +1123,7 @@ TEST(ResizeOpTest, ResizeOpLinearScalesNoOpTest_Ver10) { std::vector scales{1.0f, 1.0f, 1.0f, 1.0f}; test.AddAttribute("mode", "linear"); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 4.0f, 8.0f, @@ -1149,7 +1149,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_Ver10) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 4; + constexpr int64_t N = 1, C = 1, H = 2, W = 4; std::vector X = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; @@ -1169,7 +1169,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSampleTest_Ver10) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f}; test.AddInput("X", {N, C, H, W}, X); @@ -1190,7 +1190,7 @@ TEST(UpsampleOpTest, ResizeOpNearestNoScaleTest_Ver10) { test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 1, H = 2, W = 2; + constexpr int64_t N = 1, C = 1, H = 2, W = 2; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f}; test.AddInput("X", {N, C, H, W}, X); @@ -1208,7 +1208,7 @@ TEST(ResizeOpTest, ResizeOp_MissingRoiAndMissingScalesOptionalInputs) { test.AddAttribute("mode", "linear"); test.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); - const int64_t H = 4, W = 4; + constexpr int64_t H = 4, W = 4; std::vector X = { 1.0f, 1.0f, 1.0f, 1.0f, diff --git a/onnxruntime/test/providers/cpu/tensor/space_depth_ops_test.cc b/onnxruntime/test/providers/cpu/tensor/space_depth_ops_test.cc index 69c0ce6c47..2631f460f2 100644 --- a/onnxruntime/test/providers/cpu/tensor/space_depth_ops_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/space_depth_ops_test.cc @@ -10,9 +10,9 @@ namespace test { TEST(TensorOpTest, SpaceToDepthTest_1) { OpTester test("SpaceToDepth"); - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 1, C = 2, H = 2, W = 4; + constexpr int64_t N = 1, C = 2, H = 2, W = 4; const std::vector X = {0.0f, 0.1f, 0.2f, 0.3f, 1.0f, 1.1f, 1.2f, 1.3f, @@ -40,9 +40,9 @@ TEST(TensorOpTest, SpaceToDepthTest_1) { TEST(TensorOpTest, SpaceToDepthTest_1_double) { OpTester test("SpaceToDepth"); - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 1, C = 2, H = 2, W = 4; + constexpr int64_t N = 1, C = 2, H = 2, W = 4; const std::vector X = {0.0, 0.1, 0.2, 0.3, 1.0, 1.1, 1.2, 1.3, @@ -70,9 +70,9 @@ TEST(TensorOpTest, SpaceToDepthTest_1_double) { } TEST(TensorOpTest, SpaceToDepthTest_2) { OpTester test("SpaceToDepth"); - const int64_t blocksize = 3; + constexpr int64_t blocksize = 3; test.AddAttribute("blocksize", blocksize); - const int64_t N = 2, C = 3, H = 3, W = 6; + constexpr int64_t N = 2, C = 3, H = 3, W = 6; const std::vector X = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., @@ -104,10 +104,10 @@ TEST(TensorOpTest, SpaceToDepthTest_2) { TEST(TensorOpTest, DepthToSpaceTest_1) { OpTester test("DepthToSpace", 7); // create an opset 7 model - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 1, C = 8, H = 1, W = 2; + constexpr int64_t N = 1, C = 8, H = 1, W = 2; const std::vector X = { 0.0f, 0.2f, 2.0f, 2.2f, @@ -135,10 +135,10 @@ TEST(TensorOpTest, DepthToSpaceTest_1) { TEST(TensorOpTest, DepthToSpaceTest_1_double) { OpTester test("DepthToSpace", 7); // create an opset 7 model - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 1, C = 8, H = 1, W = 2; + constexpr int64_t N = 1, C = 8, H = 1, W = 2; const std::vector X = { 0.0, 0.2, 2.0, 2.2, @@ -165,10 +165,10 @@ TEST(TensorOpTest, DepthToSpaceTest_1_double) { } TEST(TensorOpTest, DepthToSpaceTest_2) { OpTester test("DepthToSpace", 7); // create an opset 7 model - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 2, C = 12, H = 3, W = 2; + constexpr int64_t N = 2, C = 12, H = 3, W = 2; const std::vector X = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., @@ -208,10 +208,10 @@ TEST(TensorOpTest, DepthToSpaceTest_2) { TEST(TensorOpTest, DepthToSpaceTest_3) { OpTester test("DepthToSpace", 11); // create an opset 11 model with missing default attribute - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); - const int64_t N = 2, C = 12, H = 3, W = 2; + constexpr int64_t N = 2, C = 12, H = 3, W = 2; const std::vector X = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., @@ -251,11 +251,11 @@ TEST(TensorOpTest, DepthToSpaceTest_3) { TEST(TensorOpTest, DepthToSpaceTest_4) { OpTester test("DepthToSpace", 11); // create an opset 11 model with attribute present = "DCR" mode - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); test.AddAttribute("mode", "DCR"); - const int64_t N = 2, C = 12, H = 3, W = 2; + constexpr int64_t N = 2, C = 12, H = 3, W = 2; const std::vector X = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., @@ -295,11 +295,11 @@ TEST(TensorOpTest, DepthToSpaceTest_4) { TEST(TensorOpTest, DepthToSpaceTest_5) { OpTester test("DepthToSpace", 11); // create an opset 11 model with attribute present = "CRD" mode - const int64_t blocksize = 2; + constexpr int64_t blocksize = 2; test.AddAttribute("blocksize", blocksize); test.AddAttribute("mode", "CRD"); - const int64_t N = 1, C = 4, H = 2, W = 3; + constexpr int64_t N = 1, C = 4, H = 2, W = 3; const std::vector X = {0., 1., 2., 3., 4., 5., 9., 10., 11., diff --git a/onnxruntime/test/providers/cpu/tensor/upsample_op_test.cc b/onnxruntime/test/providers/cpu/tensor/upsample_op_test.cc index 4ae11b07e1..9174b0fc15 100644 --- a/onnxruntime/test/providers/cpu/tensor/upsample_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/upsample_op_test.cc @@ -18,7 +18,7 @@ TEST(UpsampleOpTest, UpsampleOpNearestTest) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -49,7 +49,7 @@ TEST(UpsampleOpTest, UpsampleOpNearestTest_int32) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1, 3, 3, 5, @@ -80,7 +80,7 @@ TEST(UpsampleOpTest, UpsampleOpNearestTest_uint8) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1, 3, 3, 5, @@ -111,7 +111,7 @@ TEST(UpsampleOpTest, UpsampleOpNearest2XTest) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -142,7 +142,7 @@ TEST(UpsampleOpTest, UpsampleOpNearest222XTest) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -183,7 +183,7 @@ TEST(UpsampleOpTest, UpsampleOpNearest15XTest) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -214,7 +214,7 @@ TEST(UpsampleOpTest, UpsampleOpNearestTest_NoScale) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -240,7 +240,7 @@ TEST(UpsampleOpTest, UpsampleOpNearest2XTest_int32) { test.AddAttribute("mode", "nearest"); test.AddAttribute("scales", scales); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1, 3, 3, 5, @@ -271,7 +271,7 @@ TEST(UpsampleOpTest, UpsampleOp4DBilinearTest) { test.AddAttribute("mode", "linear"); test.AddAttribute("scales", scales); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -302,7 +302,7 @@ TEST(UpsampleOpTest, UpsampleOp2DBilinearTest) { test.AddAttribute("mode", "linear"); test.AddAttribute("scales", scales); - const int64_t H = 2, W = 2; + constexpr int64_t H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f}; @@ -325,7 +325,7 @@ TEST(UpsampleOpTest, UpsampleOp4DBilinearTest_ScalesNoOp) { test.AddAttribute("mode", "linear"); test.AddAttribute("scales", scales); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1.0f, 3.0f, 3.0f, 5.0f, @@ -351,7 +351,7 @@ TEST(UpsampleOpTest, UpsampleOp4DBilinearTest_int32) { test.AddAttribute("mode", "linear"); test.AddAttribute("scales", scales); - const int64_t N = 2, C = 1, H = 2, W = 2; + constexpr int64_t N = 2, C = 1, H = 2, W = 2; std::vector X = {1, 3, 3, 5, @@ -403,7 +403,7 @@ TEST(UpsampleOpTest, UpsampleOpNearest2XTest_opset9) { std::vector scales{1.0f, 1.0f, 2.0f, 2.0f}; test.AddAttribute("mode", "nearest"); - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = {1, 3, 3, 5, diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc index 953c1bfa64..d59ec0f4bd 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc @@ -319,7 +319,7 @@ TEST(InternalTestingEP, DISABLED_TestNnapiPartitioningMlPerfModels) { } std::cout << std::endl; - const bool debug_output = false; + constexpr bool debug_output = false; PartitionStats stats{}, stop_at_nms_stats{}, slice_stats{}; // arbitrary examples of running different combinations to test what partitioning results diff --git a/onnxruntime/test/quantization/quantization_test.cc b/onnxruntime/test/quantization/quantization_test.cc index 73e4b4e902..c75ea89d6b 100644 --- a/onnxruntime/test/quantization/quantization_test.cc +++ b/onnxruntime/test/quantization/quantization_test.cc @@ -141,7 +141,7 @@ TEST(Quantization, CreateQuantizationParamsFromTensors) { // TEST(Quantization, QuantizeFloat_Int8) { - const float x = 2.34f; + constexpr float x = 2.34f; quantization::Params params(/*scale=*/0.0872204f, /*zero_point=*/0); EXPECT_EQ(quantization::Quantize(x, params), 27); } @@ -155,8 +155,8 @@ TEST(Quantization, QuantizeFloatValues_Int8) { TEST(Quantization, QuantizeLinear_Int8) { std::vector values = {-3.412f, -12.42f, 1.032f, 2.32f, 9.8212f}; - const float expected_scale = 0.0872204f; - const int8_t expected_zero_point = 15; + constexpr float expected_scale = 0.0872204f; + constexpr int8_t expected_zero_point = 15; std::vector expected_values = {-24, -127, 27, 41, 127}; TestQuantizeLinearVectorAndValues(values, @@ -166,7 +166,7 @@ TEST(Quantization, QuantizeLinear_Int8) { } TEST(Quantization, Dequantize_Int8) { - const int8_t x_i8 = 12; + constexpr int8_t x_i8 = 12; quantization::Params params(/*scale=*/0.0124f, /*zero_point=*/-1); EXPECT_NEAR(quantization::Dequantize(x_i8, params), 0.1612f, kEpsilon); } @@ -185,7 +185,7 @@ TEST(Quantization, DequantizeValues_Int8) { // TEST(Quantization, QuantizeFloat_UInt8) { - const float x = 1.25f; + constexpr float x = 1.25f; quantization::Params params(/*scale=*/0.0117647f, /*zero_point=*/85); EXPECT_EQ(quantization::Quantize(x, params), 191); } @@ -200,8 +200,8 @@ TEST(Quantization, QuantizeFloatValues_UInt8) { TEST(Quantization, QuantizeLinear_UInt8) { std::vector values = {-3.412f, -12.42f, 1.032f, 2.32f, 9.8212f}; - const float expected_scale = 0.0872203931f; - const uint8_t expected_zero_point = 142; + constexpr float expected_scale = 0.0872203931f; + constexpr uint8_t expected_zero_point = 142; std::vector expected_values = {103, 0, 154, 169, 255}; TestQuantizeLinearVectorAndValues(values, @@ -211,7 +211,7 @@ TEST(Quantization, QuantizeLinear_UInt8) { } TEST(Quantization, Dequantize_UInt8) { - const uint8_t x_u8 = 200; + constexpr uint8_t x_u8 = 200; quantization::Params params(/*scale=*/0.0124f, /*zero_point=*/127); EXPECT_NEAR(quantization::Dequantize(x_u8, params), 0.9052f, kEpsilon); } diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 4fb80b311c..f5167e1089 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -1633,9 +1633,9 @@ TEST(CApiTest, TestSharingOfInitializerAndItsPrepackedVersion) { Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); // These values are different from the actual initializer values in the model float data[] = {2.0f, 1.0f}; - const int data_len = sizeof(data) / sizeof(data[0]); + constexpr int data_len = sizeof(data) / sizeof(data[0]); const int64_t shape[] = {2, 1}; - const size_t shape_len = sizeof(shape) / sizeof(shape[0]); + constexpr size_t shape_len = sizeof(shape) / sizeof(shape[0]); Ort::Value val = Ort::Value::CreateTensor(mem_info, data, data_len, shape, shape_len); session_options.AddInitializer("W", val); @@ -1676,9 +1676,9 @@ TEST(CApiTest, TestIncorrectInputTypeToModel_Tensors) { Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); double data[] = {2., 1., 4., 3., 6., 5.}; - const int data_len = sizeof(data) / sizeof(data[0]); + constexpr int data_len = sizeof(data) / sizeof(data[0]); const int64_t shape[] = {3, 2}; - const size_t shape_len = sizeof(shape) / sizeof(shape[0]); + constexpr size_t shape_len = sizeof(shape) / sizeof(shape[0]); Ort::Value val = Ort::Value::CreateTensor(mem_info, data, data_len, shape, shape_len); std::vector input_names{"X"}; @@ -1703,9 +1703,9 @@ TEST(CApiTest, TestIncorrectInputTypeToModel_SequenceTensors) { Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); double data[] = {2., 1., 4., 3., 6., 5.}; - const int data_len = sizeof(data) / sizeof(data[0]); + constexpr int data_len = sizeof(data) / sizeof(data[0]); const int64_t shape[] = {2, 3}; - const size_t shape_len = sizeof(shape) / sizeof(shape[0]); + constexpr size_t shape_len = sizeof(shape) / sizeof(shape[0]); Ort::Value val = Ort::Value::CreateTensor(mem_info, data, data_len, shape, shape_len); std::vector seq; @@ -1870,7 +1870,7 @@ void JoinThreadCustomized(OrtCustomThreadHandle handle) { } TEST(CApiTest, TestPerSessionCustomThreadPoolHooks) { - const int32_t thread_count = 3; + constexpr int32_t thread_count = 3; Ort::SessionOptions session_options; // test both intra and inter op thread pool session_options.SetExecutionMode(ExecutionMode::ORT_PARALLEL); @@ -1892,7 +1892,7 @@ TEST(CApiTest, TestPerSessionCustomThreadPoolHooks) { TEST(CApiTest, crop_and_resize) { std::vector input_value_0; input_value_0.resize(2 * 36 * 36 * 3); - for (int i = 0; i < 36 * 36 * 3; ++i) { + for (ptrdiff_t i = 0; i < 36 * 36 * 3; ++i) { input_value_0[i] = 1.f; input_value_0[i + 36 * 36 * 3] = 2.f; } diff --git a/onnxruntime/test/shared_lib/test_nontensor_types.cc b/onnxruntime/test/shared_lib/test_nontensor_types.cc index cf3e9a320c..bd81a83077 100644 --- a/onnxruntime/test/shared_lib/test_nontensor_types.cc +++ b/onnxruntime/test/shared_lib/test_nontensor_types.cc @@ -36,8 +36,8 @@ TEST(CApiTest, CreateGetVectorOfMapsInt64Float) { // support zipmap output type auto default_allocator = std::make_unique(); Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault); - const size_t N = 3; - const int NUM_KV_PAIRS = 4; + constexpr size_t N = 3; + constexpr int NUM_KV_PAIRS = 4; std::vector in; std::vector keys{3, 1, 2, 0}; std::vector dims = {4}; @@ -100,8 +100,8 @@ TEST(CApiTest, CreateGetVectorOfMapsStringFloat) { // support zipmap output typ auto default_allocator = std::make_unique(); Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault); - const size_t N = 3; - const int64_t NUM_KV_PAIRS = 4; + constexpr size_t N = 3; + constexpr int64_t NUM_KV_PAIRS = 4; std::vector in; const char* keys_arr[NUM_KV_PAIRS] = {"abc", "def", "ghi", "jkl"}; std::vector keys{keys_arr, keys_arr + NUM_KV_PAIRS}; @@ -166,7 +166,7 @@ TEST(CApiTest, TypeInfoMap) { auto default_allocator = std::make_unique(); Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault); - const int64_t NUM_KV_PAIRS = 4; + constexpr int64_t NUM_KV_PAIRS = 4; std::vector keys{0, 1, 2, 3}; std::vector dims = {NUM_KV_PAIRS}; std::vector values{3.0f, 1.0f, 2.f, 0.f}; @@ -220,7 +220,7 @@ TEST(CApiTest, CreateGetSeqTensors) { std::vector in; std::vector vals{3, 1, 2, 0}; std::vector dims{1, 4}; - const int N = 2; + constexpr int N = 2; for (int i = 0; i < N; ++i) { // create tensor Ort::Value tensor = Ort::Value::CreateTensor(info, vals.data(), vals.size() * sizeof(int64_t), @@ -246,7 +246,7 @@ TEST(CApiTest, CreateGetSeqStringTensors) { std::vector in; const char* string_input_data[] = {"abs", "def"}; - const int N = 2; + constexpr int N = 2; for (int i = 0; i < N; ++i) { // create tensor std::vector shape{2}; @@ -287,7 +287,7 @@ TEST(CApiTest, TypeInfoSequence) { std::vector in; std::vector vals{3, 1, 2, 0}; std::vector dims{1, 4}; - const int N = 2; + constexpr int N = 2; for (int i = 0; i < N; ++i) { // create tensor Ort::Value tensor = Ort::Value::CreateTensor(info, vals.data(), vals.size() * sizeof(int64_t), diff --git a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc index eceb62266c..ac053eca95 100644 --- a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc +++ b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc @@ -9,7 +9,9 @@ MyEPAllocator::MyEPAllocator(OrtDevice::DeviceId device_id) : IAllocator(OrtMemoryInfo(MyEP, OrtAllocatorType::OrtArenaAllocator, OrtDevice(MyEPDevice, OrtDevice::MemType::DEFAULT, device_id))) { } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif void* MyEPAllocator::Alloc(size_t size) { void* device_address = new (std::nothrow) uint8_t[size]; return device_address; diff --git a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.h b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.h index 72610e6cce..a2eb4d97b3 100644 --- a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.h +++ b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.h @@ -7,7 +7,7 @@ namespace onnxruntime { constexpr const char* MyEP = "MyEP"; -static const OrtDevice::DeviceType MyEPDevice = 11; +static constexpr OrtDevice::DeviceType MyEPDevice = 11; } // namespace onnxruntime namespace onnxruntime { diff --git a/onnxruntime/test/util/include/file_util.h b/onnxruntime/test/util/include/file_util.h index fed1585bfe..4ea2e47b0f 100644 --- a/onnxruntime/test/util/include/file_util.h +++ b/onnxruntime/test/util/include/file_util.h @@ -16,8 +16,8 @@ class ScopedFileDeleter { public: ScopedFileDeleter() = default; ScopedFileDeleter(const PathString& path) : path_{path} {} - ScopedFileDeleter(ScopedFileDeleter&& other) { *this = std::move(other); } - ScopedFileDeleter& operator=(ScopedFileDeleter&& other) { + ScopedFileDeleter(ScopedFileDeleter&& other) noexcept { *this = std::move(other); } + ScopedFileDeleter& operator=(ScopedFileDeleter&& other) noexcept { CleanUp(); path_ = std::move(other.path_); other.path_.clear(); diff --git a/onnxruntime/test/util/scoped_env_vars.cc b/onnxruntime/test/util/scoped_env_vars.cc index 0dd22a8373..b202ed7842 100644 --- a/onnxruntime/test/util/scoped_env_vars.cc +++ b/onnxruntime/test/util/scoped_env_vars.cc @@ -43,20 +43,24 @@ Status SetEnvironmentVar(const std::string& name, const optional& v Status GetEnvironmentVar(const std::string& name, optional& value) { constexpr DWORD kBufferSize = 32767; - char buffer[kBufferSize]; + std::string buffer(kBufferSize, '\0'); - const auto char_count = GetEnvironmentVariableA(name.c_str(), buffer, kBufferSize); - if (char_count > 0) { - value = std::string{buffer, buffer + char_count}; - return Status::OK(); + const DWORD char_count = GetEnvironmentVariableA(name.c_str(), buffer.data(), kBufferSize); + if (0 == char_count) { + DWORD dwErr = GetLastError(); + if (ERROR_ENVVAR_NOT_FOUND == dwErr) { + value = optional{}; + return Status::OK(); + } + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "GetEnvironmentVariableA() failed: ", dwErr); } - - if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - value = optional{}; - return Status::OK(); + if (kBufferSize < char_count) { + //Shouldn't reach here, 32767 is the max size. + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "GetEnvironmentVariableA() failed: not enough memory"); } - - return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "GetEnvironmentVariableA() failed: ", GetLastError()); + buffer.resize(char_count); + value = buffer; + return Status::OK(); } #endif diff --git a/onnxruntime/test/util/test_allocator.cc b/onnxruntime/test/util/test_allocator.cc index 4418dcf613..1383894372 100644 --- a/onnxruntime/test/util/test_allocator.cc +++ b/onnxruntime/test/util/test_allocator.cc @@ -15,7 +15,9 @@ MockedOrtAllocator::MockedOrtAllocator() { MockedOrtAllocator::~MockedOrtAllocator() { Ort::GetApi().ReleaseMemoryInfo(cpu_memory_info); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26400) +#endif void* MockedOrtAllocator::Alloc(size_t size) { constexpr size_t extra_len = sizeof(size_t); memory_inuse.fetch_add(size += extra_len); diff --git a/onnxruntime/test/util/test_utils.cc b/onnxruntime/test/util/test_utils.cc index a413adb733..1ccfb359fc 100644 --- a/onnxruntime/test/util/test_utils.cc +++ b/onnxruntime/test/util/test_utils.cc @@ -36,7 +36,7 @@ static void VerifyOutputs(const std::vector& output_names, << " mismatch for " << output_names[i]; break; case ONNX_NAMESPACE::TensorProto_DataType_FLOAT: { - const float abs_err = float(1e-5); + constexpr float abs_err = 1e-5f; EXPECT_THAT(ltensor.DataAsSpan(), ::testing::Pointwise(::testing::FloatNear(abs_err), rtensor.DataAsSpan())); From b000ec91cc3141a43ba7a136a8ce1b2bc82e6341 Mon Sep 17 00:00:00 2001 From: Zhang Lei Date: Fri, 10 Dec 2021 16:40:01 -0800 Subject: [PATCH 025/113] Add quantization tool and its unittest with s8s8 support (#10007) * Add quantization tool with s8s8 support * Add unittest for existing s8s8 support operators * Comment ready unittest for upcomming s8s8 operator (ConvInteger, and Resize) * Minor change on quantization tools * Use different s8 min value upon weight or activation. * use same qmin for reduce ranged s8. --- .../tools/quantization/operators/concat.py | 3 +- .../python/tools/quantization/quant_utils.py | 13 ++- .../test/python/quantization/op_test_utils.py | 26 ++++- .../python/quantization/test_conv_dynamic.py | 45 ++++++--- .../python/quantization/test_op_concat.py | 47 ++++++--- .../python/quantization/test_op_gavgpool.py | 48 +++++---- .../test/python/quantization/test_op_gemm.py | 98 ++++++++++++------- .../python/quantization/test_op_maxpool.py | 53 ++++++---- .../test/python/quantization/test_op_pad.py | 76 +++++++++++--- .../python/quantization/test_op_pooling.py | 46 ++++++--- .../python/quantization/test_op_reshape.py | 30 ++++-- .../python/quantization/test_op_resize.py | 33 +++++-- .../quantization/test_op_squeeze_unsqueeze.py | 43 +++++--- .../python/quantization/test_op_transpose.py | 31 ++++-- .../test/python/quantization/test_qdq.py | 2 +- 15 files changed, 418 insertions(+), 176 deletions(-) diff --git a/onnxruntime/python/tools/quantization/operators/concat.py b/onnxruntime/python/tools/quantization/operators/concat.py index ada842c7b6..76c05828e5 100644 --- a/onnxruntime/python/tools/quantization/operators/concat.py +++ b/onnxruntime/python/tools/quantization/operators/concat.py @@ -12,7 +12,8 @@ class QLinearConcat(QuantOperatorBase): data_found, output_scale_name, output_zp_name, _, _ = \ self.quantizer._get_quantization_params(node.output[0]) - (q_input_names, zero_point_names, scale_names, nodes) = self.quantizer.quantize_inputs(node, [*range(0, len(node.input))]) + (q_input_names, zero_point_names, scale_names, nodes) = \ + self.quantizer.quantize_inputs(node, [*range(0, len(node.input))], initializer_use_weight_qType=False) if not data_found or q_input_names is None: return super().quantize() diff --git a/onnxruntime/python/tools/quantization/quant_utils.py b/onnxruntime/python/tools/quantization/quant_utils.py index e57160275f..73dd7fdbf7 100644 --- a/onnxruntime/python/tools/quantization/quant_utils.py +++ b/onnxruntime/python/tools/quantization/quant_utils.py @@ -176,7 +176,7 @@ def quantize_data(data, qType, symmetric, reduce_range=False): if len(data): rmin = min(data) rmax = max(data) - qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range) + qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, for_weight=True) zero_point, scale = compute_scale_zp(rmin, rmax, qmin, qmax, symmetric) @@ -184,7 +184,7 @@ def quantize_data(data, qType, symmetric, reduce_range=False): return rmin, rmax, zero_point, scale, quantized_data -def get_qmin_qmax_for_qType(qType, reduce_range=False): +def get_qmin_qmax_for_qType(qType, reduce_range=False, for_weight=False): ''' Return qmin and qmax, the minimum and maximum value representable by the given qType :parameter qType: onnx.onnx_pb.TensorProto.UINT8 or onnx.onnx_pb.TensorProto.UINT8 @@ -193,18 +193,21 @@ def get_qmin_qmax_for_qType(qType, reduce_range=False): if qType == onnx_proto.TensorProto.UINT8: (qmin, qmax) = (0,127) if reduce_range else (0,255) elif qType == onnx_proto.TensorProto.INT8: - (qmin, qmax) = (-64,64) if reduce_range else (-127,127) + if for_weight: + (qmin, qmax) = (-64,64) if reduce_range else (-127,127) + else: + (qmin, qmax) = (-64,64) if reduce_range else (-128,127) else: raise ValueError("Unexpected data type {} requested. Only INT8 and UINT8 are supported.".format(qType)) return qmin, qmax -def get_qrange_for_qType(qType, reduce_range=False): +def get_qrange_for_qType(qType, reduce_range=False, for_weight=False): ''' Helper function to get the quantization range for a type. parameter qType: quantization type. return: quantization range. ''' - qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range) + qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, for_weight=for_weight) return qmax - qmin class QuantizedInitializer: diff --git a/onnxruntime/test/python/quantization/op_test_utils.py b/onnxruntime/test/python/quantization/op_test_utils.py index a5aaae027c..a3f0192289 100644 --- a/onnxruntime/test/python/quantization/op_test_utils.py +++ b/onnxruntime/test/python/quantization/op_test_utils.py @@ -34,7 +34,6 @@ def InputFeedsNegOneZeroOne(n, name2shape): dr = TestDataFeeds(input_data_list) return dr - def check_op_type_order(testcase, model_to_check, ops): if isinstance(model_to_check, string_types): model = onnx.load(model_to_check) @@ -78,3 +77,28 @@ def check_op_nodes(testcase, model_path, node_checker): model = onnx.load(Path(model_path)) for node in model.graph.node: testcase.assertTrue(node_checker(node)) + +def check_qtype_by_node_type(testcase, model_to_check, check_list): + if isinstance(model_to_check, string_types): + model = onnx.load(model_to_check) + elif isinstance(model_to_check, onnx.ModelProto): + model = model_to_check + model = onnx.shape_inference.infer_shapes(model) + value_infos = {vi.name: vi for vi in model.graph.value_info} + value_infos.update({ot.name: ot for ot in model.graph.output}) + value_infos.update({it.name: it for it in model.graph.input}) + initializers = {init.name : init for init in model.graph.initializer} + + for node in model.graph.node: + if node.op_type in check_list: + input_output_check_list = check_list[node.op_type] + for check_item in input_output_check_list: + tensor_name = node.input[check_item[1]] if check_item[0] == 'i' else node.output[check_item[1]] + testcase.assertTrue((tensor_name in value_infos) or (tensor_name in initializers)) + if tensor_name in value_infos: + vi = value_infos[tensor_name] + testcase.assertTrue(vi.type.HasField('tensor_type')) + testcase.assertTrue(vi.type.tensor_type.elem_type == check_item[2]) + else: #if (tensor_name in initializers): + init = initializers[tensor_name] + testcase.assertTrue(init.data_type == check_item[2]) diff --git a/onnxruntime/test/python/quantization/test_conv_dynamic.py b/onnxruntime/test/python/quantization/test_conv_dynamic.py index a95ac9b50f..6a54081979 100644 --- a/onnxruntime/test/python/quantization/test_conv_dynamic.py +++ b/onnxruntime/test/python/quantization/test_conv_dynamic.py @@ -11,17 +11,18 @@ import onnx import onnxruntime import numpy as np from onnx import helper, TensorProto, numpy_helper -from onnxruntime.quantization import quantize_dynamic -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_type_order +from onnxruntime.quantization import quantize_dynamic, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_type_order, check_qtype_by_node_type def generate_input_initializer(tensor_shape, tensor_dtype, input_name): - ''' - Helper function to generate initializers for test inputs - ''' - tensor = np.random.normal(0, 0.3, tensor_shape).astype(tensor_dtype) - init = numpy_helper.from_array(tensor, input_name) - return init + ''' + Helper function to generate initializers for test inputs + ''' + tensor = np.random.normal(0, 0.3, tensor_shape).astype(tensor_dtype) + init = numpy_helper.from_array(tensor, input_name) + return init + class TestONNXModel(unittest.TestCase): def construct_model(self, model_path): @@ -52,19 +53,31 @@ class TestONNXModel(unittest.TestCase): model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) onnx.save(model, model_path) - def dynamic_quant_conv(self, model_fp32_path, model_int8_path): - quantize_dynamic(model_fp32_path, model_int8_path) - quant_nodes = {'ConvInteger' : 2} + def dynamic_quant_conv_test(self, activation_type, weight_type, extra_options={}): + np.random.seed(1) + model_fp32_path = 'conv_bias.fp32.onnx' + self.construct_model(model_fp32_path) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_int8_path = 'conv_bias.quant.{}{}.onnx'.format(activation_type_str, weight_type_str) + + quantize_dynamic(model_fp32_path, model_int8_path, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + quant_nodes = {'ConvInteger': 2} check_op_type_count(self, model_int8_path, **quant_nodes) + qnode_io_qtypes = {'ConvInteger': [['i', 2, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_int8_path, qnode_io_qtypes) check_model_correctness(self, model_fp32_path, model_int8_path, {'input': np.random.rand(4, 2, 8, 8).astype(np.float32)}) def test_quant_conv(self): - np.random.seed(1) - model_fp32_path = 'conv_bias.fp32.onnx' - model_int8_path = 'conv_bias.quant.onnx' - self.construct_model(model_fp32_path) + self.dynamic_quant_conv_test(QuantType.QUInt8, QuantType.QUInt8, extra_options={}) + + # TODO: uncomment following after ConvInteger s8 supportted + # def test_quant_conv_s8s8(self): + # self.dynamic_quant_conv_test(QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) - self.dynamic_quant_conv(model_fp32_path, model_int8_path) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_concat.py b/onnxruntime/test/python/quantization/test_op_concat.py index f7952d4c50..01291df157 100644 --- a/onnxruntime/test/python/quantization/test_op_concat.py +++ b/onnxruntime/test/python/quantization/test_op_concat.py @@ -7,8 +7,8 @@ import unittest import numpy as np from onnx import helper, TensorProto, numpy_helper, save -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import InputFeedsNegOneZeroOne, check_model_correctness, check_op_type_count +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import InputFeedsNegOneZeroOne, check_model_correctness, check_op_type_count, check_qtype_by_node_type class TestONNXModel(unittest.TestCase): @@ -47,7 +47,7 @@ class TestONNXModel(unittest.TestCase): conv3_node = helper.make_node('Conv', ['input', 'conv3_weight'], ['conv3_output'], name='conv3_node') concat_node = helper.make_node('Concat', ['conv1_output', 'conv2_output', 'conv3_output'], [ - 'concat_output'], name='concat_node', axis=1) + 'concat_output'], name='concat_node', axis=1) identity_node = helper.make_node('Identity', ['concat_output'], ['output'], name='identity_node') @@ -57,31 +57,48 @@ class TestONNXModel(unittest.TestCase): model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) save(model, model_path) - def test_quantize_concat(self): + def quantize_concat_test(self, activation_type, weight_type, extra_options={}): np.random.seed(1) - model_fp32_path = 'concat_fp32.onnx' - model_uint8_path = 'concat_uint8.onnx' - model_uint8_qdq_path = 'concat_uint8_qdq.onnx' - self.construct_model(model_fp32_path) + data_reader = InputFeedsNegOneZeroOne(1, {'input': [1, 3, 15, 15]}) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_q8_path = 'concat_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_q8_qdq_path = 'concat_{}{}_qdq.onnx'.format(activation_type_str, weight_type_str) # Verify QOperator mode - data_reader = InputFeedsNegOneZeroOne(1, {'input': [1, 3, 15, 15]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) + data_reader.rewind() + quantize_static(model_fp32_path, model_q8_path, data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) qnode_counts = {'QLinearConv': 3, 'QuantizeLinear': 1, 'DequantizeLinear': 1, 'QLinearConcat': 1} - check_op_type_count(self, model_uint8_path, **qnode_counts) + check_op_type_count(self, model_q8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'QLinearConcat': [['i', 1, activation_proto_qtype], [ + 'i', 4, activation_proto_qtype], ['i', 7, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_q8_path, qnode_io_qtypes) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) + check_model_correctness(self, model_fp32_path, model_q8_path, data_reader.get_next()) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_q8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) qdqnode_counts = {'Conv': 3, 'QuantizeLinear': 5, 'DequantizeLinear': 8, 'Concat': 1} - check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + check_op_type_count(self, model_q8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_q8_qdq_path, qnode_io_qtypes) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + check_model_correctness(self, model_fp32_path, model_q8_qdq_path, data_reader.get_next()) + + def test_quantize_concat(self): + self.quantize_concat_test(QuantType.QUInt8, QuantType.QUInt8, extra_options={}) + + def test_quantize_concat_s8s8(self): + self.quantize_concat_test(QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) if __name__ == '__main__': diff --git a/onnxruntime/test/python/quantization/test_op_gavgpool.py b/onnxruntime/test/python/quantization/test_op_gavgpool.py index 7e89758c99..abf739aa33 100644 --- a/onnxruntime/test/python/quantization/test_op_gavgpool.py +++ b/onnxruntime/test/python/quantization/test_op_gavgpool.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, quantize_dynamic -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count +from onnxruntime.quantization import quantize_static, quantize_dynamic, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_qtype_by_node_type class TestOpGlobalAveragePool(unittest.TestCase): @@ -44,10 +44,10 @@ class TestOpGlobalAveragePool(unittest.TestCase): output_name = 'output' initializers = [] - #make 1st GlobalAveragePool node + # make 1st GlobalAveragePool node gavgpool_node_1 = onnx.helper.make_node('GlobalAveragePool', [input_name], [expand_input]) - #make Expand node + # make Expand node expand_shape_name = 'expand_shape' initializers.append(onnx.numpy_helper.from_array(np.array(input_shape, dtype=np.int64), name=expand_shape_name)) expand_node = onnx.helper.make_node('Expand', [expand_input, expand_shape_name], [conv_input]) @@ -59,7 +59,7 @@ class TestOpGlobalAveragePool(unittest.TestCase): initializers.append(onnx.numpy_helper.from_array(conv_weight_data, name=weight_name)) conv_node = onnx.helper.make_node('Conv', [conv_input, weight_name], [gavgpool_input_2nd], name=conv_name) - #make 1st GlobalAveragePool node + # make 1st GlobalAveragePool node gavgpool_node_2 = onnx.helper.make_node('GlobalAveragePool', [gavgpool_input_2nd], [output_name]) # make graph @@ -69,30 +69,42 @@ class TestOpGlobalAveragePool(unittest.TestCase): graph = helper.make_graph([gavgpool_node_1, expand_node, conv_node, gavgpool_node_2], graph_name, [input_tensor], [output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def test_quantize_reshape(self): + def quantize_gavgpool_test(self, activation_type, weight_type, extra_options={}): np.random.seed(1) model_fp32_path = 'gavg_pool_fp32.onnx' - model_int8_path = 'gavg_pool_fp32.quant.onnx' data_reader = self.input_feeds(1, {'input': [1, 8, 33, 33]}) self.construct_model_gavgpool(model_fp32_path, [1, 8, 33, 33], [16, 8, 3, 3], [1, 16, 1, 1]) - quantize_static(model_fp32_path, - model_int8_path, - data_reader) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_q8_path = 'gavg_pool_{}{}.onnx'.format(activation_type_str, weight_type_str) + data_reader.rewind() - quant_nodes = {'QLinearConv' : 1, - 'GlobalAveragePool' : 1, - 'QLinearGlobalAveragePool' : 1, - 'QuantizeLinear' : 1, - 'DequantizeLinear' : 1} - check_op_type_count(self, model_int8_path, **quant_nodes) - check_model_correctness(self, model_fp32_path, model_int8_path, data_reader.get_next()) + quantize_static(model_fp32_path, model_q8_path, data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + + quant_nodes = {'QLinearConv': 1, 'GlobalAveragePool': 1, 'QLinearGlobalAveragePool': 1, + 'QuantizeLinear': 1, 'DequantizeLinear': 1} + check_op_type_count(self, model_q8_path, **quant_nodes) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'QLinearGlobalAveragePool': [['i', 2, activation_proto_qtype], ['i', 4, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_q8_path, qnode_io_qtypes) + data_reader.rewind() + check_model_correctness(self, model_fp32_path, model_q8_path, data_reader.get_next()) + + def test_quantize_gavgpool(self): + self.quantize_gavgpool_test(QuantType.QUInt8, QuantType.QUInt8, extra_options={}) + + def test_quantize_gavgpool_s8s8(self): + self.quantize_gavgpool_test(QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) if __name__ == '__main__': diff --git a/onnxruntime/test/python/quantization/test_op_gemm.py b/onnxruntime/test/python/quantization/test_op_gemm.py index e41ee633e2..cf61402fa5 100644 --- a/onnxruntime/test/python/quantization/test_op_gemm.py +++ b/onnxruntime/test/python/quantization/test_op_gemm.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, quantize_dynamic, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count +from onnxruntime.quantization import quantize_static, quantize_dynamic, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_qtype_by_node_type class TestOpGEMM(unittest.TestCase): @@ -46,12 +46,12 @@ class TestOpGEMM(unittest.TestCase): bias_data = np.random.normal(0, 0.1, bias_shape).astype(np.float32) initializers.append(onnx.numpy_helper.from_array(bias_data, name=bias_name)) - return onnx.helper.make_node('Gemm', [input_name, weight_name, bias_name], [output_name], alpha=1.0, beta=1.0, transB = 1) + return onnx.helper.make_node('Gemm', [input_name, weight_name, bias_name], [output_name], alpha=1.0, beta=1.0, transB=1) # make gemm1 node gemm1_output_name = "gemm1_output" gemm1_node = make_gemm(input_name, [100, 10], 'linear1.weight', [100], 'linear1.bias', gemm1_output_name) - #make Clip + # make Clip clip_min_name = 'clip_min' clip_max_name = 'clip_max' clip_output_name = 'clip_output' @@ -71,7 +71,7 @@ class TestOpGEMM(unittest.TestCase): graph = helper.make_graph([gemm1_node, clip_node, gemm2_node], graph_name, [input_tensor], [output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) @@ -121,55 +121,82 @@ class TestOpGEMM(unittest.TestCase): onnx.save(model, output_model_path) - def static_quant_test(self, model_fp32_path, model_int8_path): - data_reader = self.input_feeds(1, {'input': [5, 10]}) - quantize_static(model_fp32_path, - model_int8_path, - data_reader) + def static_quant_test(self, model_fp32_path, data_reader, activation_type, weight_type, extra_options={}): + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_int8_path = 'gemm_fp32.quant_{}{}.onnx'.format(activation_type_str, weight_type_str) + data_reader.rewind() - quant_nodes = {'QLinearMatMul' : 2, - 'QLinearAdd' : 2, - 'QuantizeLinear' : 1, - 'DequantizeLinear' : 1} + quantize_static(model_fp32_path, model_int8_path, data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + quant_nodes = {'QLinearMatMul': 2, 'QLinearAdd': 2, 'QuantizeLinear': 1, 'DequantizeLinear': 1} check_op_type_count(self, model_int8_path, **quant_nodes) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear': [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_int8_path, qnode_io_qtypes) + data_reader.rewind() check_model_correctness(self, model_fp32_path, model_int8_path, data_reader.get_next()) - def static_quant_test_qdq(self, model_fp32_path, model_int8_path): - data_reader = self.input_feeds(1, {'input': [5, 10]}) - quantize_static(model_fp32_path, - model_int8_path, - data_reader, - quant_format=QuantFormat.QDQ) + def static_quant_test_qdq(self, model_fp32_path, data_reader, activation_type, weight_type, extra_options={}): + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_int8_path = 'gemm_fp32.quant_dqd_{}{}.onnx'.format(activation_type_str, weight_type_str) + data_reader.rewind() - quant_nodes = {'MatMul' : 2, - 'Add' : 2, - 'QuantizeLinear' : 5, - 'DequantizeLinear' : 9} + quantize_static(model_fp32_path, model_int8_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + quant_nodes = {'MatMul': 2, 'Add': 2, 'QuantizeLinear': 5, 'DequantizeLinear': 9} check_op_type_count(self, model_int8_path, **quant_nodes) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_int8_path, qnode_io_qtypes) + data_reader.rewind() check_model_correctness(self, model_fp32_path, model_int8_path, data_reader.get_next()) + def dynamic_quant_test(self, model_fp32_path, data_reader, activation_type, weight_type, extra_options={}): + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_int8_path = 'gemm_fp32.quant_dynamic_{}{}.onnx'.format(activation_type_str, weight_type_str) - def dynamic_quant_test(self, model_fp32_path, model_int8_path): - quantize_dynamic(model_fp32_path, model_int8_path) - quant_nodes = {'MatMulInteger' : 2} + quantize_dynamic(model_fp32_path, model_int8_path, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + quant_nodes = {'MatMulInteger': 2} check_op_type_count(self, model_int8_path, **quant_nodes) - check_model_correctness(self, model_fp32_path, model_int8_path, {'input': np.random.rand(5,10).astype(np.float32)}) + qnode_io_qtypes = {'MatMulInteger': [['i', 2, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_int8_path, qnode_io_qtypes) + data_reader.rewind() + check_model_correctness(self, model_fp32_path, model_int8_path, {'input': np.random.rand(5, 10).astype(np.float32)}) def dynamic_attention_quant_test(self, model_fp32_path, model_int8_path, per_channel, reduce_range): quantize_dynamic(model_fp32_path, model_int8_path, per_channel=per_channel, reduce_range=reduce_range) - quant_nodes = {'QAttention' : 1, 'MatMulInteger' : 1} + quant_nodes = {'QAttention': 1, 'MatMulInteger': 1} check_op_type_count(self, model_int8_path, **quant_nodes) - check_model_correctness(self, model_fp32_path, model_int8_path, {'input': np.random.rand(1,5,10).astype(np.float32)}) + check_model_correctness(self, model_fp32_path, model_int8_path, {'input': np.random.rand(1, 5, 10).astype(np.float32)}) - def test_quantize_reshape(self): + def test_quantize_gemm(self): np.random.seed(1) model_fp32_path = 'gemm_fp32.onnx' - model_int8_path = 'gemm_fp32.quant.onnx' self.construct_model_gemm(model_fp32_path) + data_reader = self.input_feeds(1, {'input': [5, 10]}) - self.static_quant_test(model_fp32_path, model_int8_path) - self.static_quant_test_qdq(model_fp32_path, model_int8_path) - self.dynamic_quant_test(model_fp32_path, model_int8_path) + self.static_quant_test(model_fp32_path, data_reader, activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8) + self.static_quant_test_qdq(model_fp32_path, data_reader, activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8) + self.dynamic_quant_test(model_fp32_path, data_reader, activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8) + + def test_quantize_gemm_s8s8(self): + np.random.seed(1) + model_fp32_path = 'gemm_fp32.onnx' + self.construct_model_gemm(model_fp32_path) + data_reader = self.input_feeds(1, {'input': [5, 10]}) + + self.static_quant_test(model_fp32_path, data_reader, activation_type=QuantType.QInt8, weight_type=QuantType.QInt8, + extra_options={'ActivationSymmetric': True}) + self.static_quant_test_qdq(model_fp32_path, data_reader, activation_type=QuantType.QInt8, weight_type=QuantType.QInt8, + extra_options={'ActivationSymmetric': True}) + self.dynamic_quant_test(model_fp32_path, data_reader, activation_type=QuantType.QInt8, weight_type=QuantType.QInt8, + extra_options={'ActivationSymmetric': True}) def test_quantize_attention(self): np.random.seed(1) @@ -182,5 +209,6 @@ class TestOpGEMM(unittest.TestCase): self.dynamic_attention_quant_test(model_fp32_path, model_int8_path, False, True) self.dynamic_attention_quant_test(model_fp32_path, model_int8_path, False, False) + if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_maxpool.py b/onnxruntime/test/python/quantization/test_op_maxpool.py index 9a891f10b9..f474c9a547 100644 --- a/onnxruntime/test/python/quantization/test_op_maxpool.py +++ b/onnxruntime/test/python/quantization/test_op_maxpool.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes, check_qtype_by_node_type class TestOpMaxPool(unittest.TestCase): @@ -54,40 +54,55 @@ class TestOpMaxPool(unittest.TestCase): graph = helper.make_graph([conv_node, identity_node, maxpool_node], 'TestOpQuantizerMaxPool_test_model', [input_tensor], [identity_out, output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 14)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def test_quantize_maxpool(self): + def quantize_maxpool_test(self, activation_type, weight_type, extra_options={}): np.random.seed(1) - model_fp32_path = 'maxpool_fp32.onnx' - model_uint8_path = 'maxpool_uint8.onnx' - model_uint8_qdq_path = 'maxpool_uint8_qdq.onnx' - self.construct_model_conv_maxpool(model_fp32_path, [1, 2, 26, 42], [3, 2, 3, 3], [1, 3, 24, 40], {'kernel_shape': [3, 3]}, [1, 3, 22, 38]) + data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_q8_path = 'maxpool_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_q8_qdq_path = 'maxpool_dqd_{}{}.onnx'.format(activation_type_str, weight_type_str) # Verify QOperator mode - data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) - - # make sure maxpool become xint8 operator, its input name could tell that - check_op_nodes(self, model_uint8_path, lambda node: (node.name != "maxpool_node" or node.input[0] != 'conv_output')) - qnode_counts = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 2, 'MaxPool': 1} - check_op_type_count(self, model_uint8_path, **qnode_counts) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) + quantize_static(model_fp32_path, model_q8_path, data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) + # make sure maxpool become xint8 operator, its input name could tell that + check_op_nodes(self, model_q8_path, lambda node: (node.name != "maxpool_node" or node.input[0] != 'conv_output')) + qnode_counts = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 2, 'MaxPool': 1} + check_op_type_count(self, model_q8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear': [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_q8_path, qnode_io_qtypes) + data_reader.rewind() + check_model_correctness(self, model_fp32_path, model_q8_path, data_reader.get_next()) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_q8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) qdqnode_counts = {'Conv': 1, 'QuantizeLinear': 3, 'DequantizeLinear': 4, 'MaxPool': 1} - check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + check_op_type_count(self, model_q8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear': [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_q8_qdq_path, qnode_io_qtypes) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + check_model_correctness(self, model_fp32_path, model_q8_qdq_path, data_reader.get_next()) + def test_quantize_maxpool(self): + self.quantize_maxpool_test(QuantType.QUInt8, QuantType.QUInt8, extra_options={ }) + + def test_quantize_maxpool_s8s8(self): + self.quantize_maxpool_test(QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_pad.py b/onnxruntime/test/python/quantization/test_op_pad.py index f83d97757e..b34996a9b8 100644 --- a/onnxruntime/test/python/quantization/test_op_pad.py +++ b/onnxruntime/test/python/quantization/test_op_pad.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, quantize_dynamic -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count +from onnxruntime.quantization import quantize_static, quantize_dynamic, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_qtype_by_node_type class TestOpQuatizerPad(unittest.TestCase): @@ -51,7 +51,7 @@ class TestOpQuatizerPad(unittest.TestCase): graph = helper.make_graph([pad_node], 'TestOpQuantizerPad_test_model', [input_tensor], [output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) @@ -91,14 +91,17 @@ class TestOpQuatizerPad(unittest.TestCase): graph = helper.make_graph([conv_node, identity_node, pad_node], 'TestOpQuantizerPad_test_model', [input_tensor], [identity_out, output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def quantize_model(self, model_fp32_path, model_i8_path, data_reader=None): + def quantize_model(self, model_fp32_path, model_i8_path, data_reader=None, + activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8, extra_options={}): if data_reader is not None: - quantize_static(model_fp32_path, model_i8_path, data_reader, reduce_range=True) + quantize_static(model_fp32_path, model_i8_path, data_reader, reduce_range=True, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) else: - quantize_dynamic(model_fp32_path, model_i8_path, reduce_range=True) + quantize_dynamic(model_fp32_path, model_i8_path, reduce_range=True, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) def verify_should_not_trigger(self, quantize_mode='static'): np.random.seed(108) @@ -118,23 +121,39 @@ class TestOpQuatizerPad(unittest.TestCase): def test_dynamic_quantize_no_trigger(self): self.verify_should_not_trigger(quantize_mode='dynamic') - def verify_quantize_with_pad_mode(self, pad_mode, constant_value=None, quantize_mode='static'): + def verify_quantize_with_pad_mode(self, pad_mode, constant_value=None, quantize_mode='static', rtol=0.01, atol=0.05, + activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8, extra_options={}): np.random.seed(108) tag_pad_mode = pad_mode if pad_mode is not None else 'none' tag_constant_value = '' if constant_value is None else '_value' model_fp32_path = 'qop_pad_{}_fp32_{}{}.onnx'.format(quantize_mode, tag_pad_mode, tag_constant_value) - model_i8_path = 'qop_pad_{}_i8_{}{}.onnx'.format(quantize_mode, tag_pad_mode, tag_constant_value) data_reader = self.input_feeds(1, {'input': [1, 8, 33, 33]}) self.construct_model_conv_pad(model_fp32_path, [1, 8, 33, 33], [16, 8, 3, 3], [1, 16, 31, 31], pad_mode, [0, 0, 1, 2, 0, 0, 3, 4], constant_value=constant_value) - self.quantize_model(model_fp32_path, model_i8_path, None if quantize_mode != 'static' else data_reader) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_i8_path = 'qop_pad_{}_i8_{}{}_{}{}.onnx'.format( + quantize_mode, tag_pad_mode, tag_constant_value, activation_type_str, weight_type_str) data_reader.rewind() + self.quantize_model(model_fp32_path, model_i8_path, None if quantize_mode != 'static' else data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) # DequantizeLinear=2 means there are one DequantizeLinear Node aftr both conv and pad, # which means pad node is running in quantized semantic. # In dynamic quantize mode, pad operator in fact not quantized as input is fp32. - kwargs = {'DynamicQuantizeLinear': 1} if quantize_mode != 'static' else {'DequantizeLinear': 2, 'QuantizeLinear': 1} + if quantize_mode != 'static': + kwargs = {'DynamicQuantizeLinear': 1} if activation_type == QuantType.QUInt8 else {'QuantizeLinear': 1} + else: + kwargs = {'DequantizeLinear': 2, 'QuantizeLinear': 1} check_op_type_count(self, model_i8_path, **kwargs) - check_model_correctness(self, model_fp32_path, model_i8_path, data_reader.get_next()) + # check node input/output type if such node exists in the graph + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear': [['i', 2, activation_proto_qtype]]}) + qnode_io_qtypes.update({'ConvInteger': [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_i8_path, qnode_io_qtypes) + data_reader.rewind() + check_model_correctness(self, model_fp32_path, model_i8_path, data_reader.get_next(), rtol=rtol, atol=atol) def test_static_mode_edge(self): self.verify_quantize_with_pad_mode('edge', constant_value=None) @@ -148,6 +167,22 @@ class TestOpQuatizerPad(unittest.TestCase): def test_static_mode_constant_value(self): self.verify_quantize_with_pad_mode('constant', constant_value=3.75) + def test_static_mode_edge_s8s8(self): + self.verify_quantize_with_pad_mode('edge', constant_value=None, rtol=0.1, atol=0.1, activation_type=QuantType.QInt8, + weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + def test_static_mode_reflect_s8s8(self): + self.verify_quantize_with_pad_mode('reflect', constant_value=None, rtol=0.1, atol=0.1, activation_type=QuantType.QInt8, + weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + def test_static_mode_constant_default_s8s8(self): + self.verify_quantize_with_pad_mode('constant', constant_value=None, rtol=0.1, atol=0.1, activation_type=QuantType.QInt8, + weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + def test_static_mode_constant_value_s8s8(self): + self.verify_quantize_with_pad_mode('constant', constant_value=3.75, rtol=0.1, atol=0.1, activation_type=QuantType.QInt8, + weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + def test_dynamic_mode_edge(self): self.verify_quantize_with_pad_mode('edge', constant_value=None, quantize_mode='dynamic') @@ -160,6 +195,23 @@ class TestOpQuatizerPad(unittest.TestCase): def test_dynamic_mode_constant_value(self): self.verify_quantize_with_pad_mode('constant', constant_value=3.75, quantize_mode='dynamic') + # TODO: uncomment following after ConvInteger s8 supported + # def test_dynamic_mode_edge_s8s8(self): + # self.verify_quantize_with_pad_mode('edge', constant_value=None, quantize_mode='dynamic', activation_type=QuantType.QInt8, + # weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + # def test_dynamic_mode_reflect_s8s8(self): + # self.verify_quantize_with_pad_mode('reflect', constant_value=None, quantize_mode='dynamic', activation_type=QuantType.QInt8, + # weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + # def test_dynamic_mode_constant_default_s8s8(self): + # self.verify_quantize_with_pad_mode('constant', constant_value=None, quantize_mode='dynamic', activation_type=QuantType.QInt8, + # weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + # def test_dynamic_mode_constant_value_s8s8(self): + # self.verify_quantize_with_pad_mode('constant', constant_value=3.75, quantize_mode='dynamic', activation_type=QuantType.QInt8, + # weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_pooling.py b/onnxruntime/test/python/quantization/test_op_pooling.py index bb40ff9a8f..ee2bff4e02 100644 --- a/onnxruntime/test/python/quantization/test_op_pooling.py +++ b/onnxruntime/test/python/quantization/test_op_pooling.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes, check_qtype_by_node_type class TestOpAveragePool(unittest.TestCase): @@ -57,34 +57,50 @@ class TestOpAveragePool(unittest.TestCase): model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def test_quantize_avgpool(self): + def quantize_avgpool_test(self, activation_type, weight_type, extra_options = {}): np.random.seed(1) - model_fp32_path = 'avgpool_fp32.onnx' - model_uint8_path = 'avgpool_uint8.onnx' - model_uint8_qdq_path = 'avgpool_uint8_qdq.onnx' - self.construct_model_conv_avgpool(model_fp32_path, [1, 2, 26, 42], [3, 2, 3, 3], [1, 3, 24, 40], {'kernel_shape': [3, 3]}, [1, 3, 22, 38]) + data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) + + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_q8_path = 'avgpool_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_q8_qdq_path = 'avgpool_qdq_{}{}.onnx'.format(activation_type_str, weight_type_str) # Verify QOperator mode - data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) - qnode_counts = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 2, 'QLinearAveragePool': 1} - check_op_type_count(self, model_uint8_path, **qnode_counts) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) + quantize_static(model_fp32_path, model_q8_path, data_reader, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) + qnode_counts = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 2, 'QLinearAveragePool': 1} + check_op_type_count(self, model_q8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'QLinearConv' : [['i', 2, activation_proto_qtype], ['i', 7, activation_proto_qtype], ['o', 0, activation_proto_qtype]]}) + qnode_io_qtypes.update({'QLinearAveragePool' : [['i', 4, activation_proto_qtype]]}) # shape info note workig on custome ops + check_qtype_by_node_type(self, model_q8_path, qnode_io_qtypes) + data_reader.rewind() + check_model_correctness(self, model_fp32_path, model_q8_path, data_reader.get_next()) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_q8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) qdqnode_counts = {'Conv': 1, 'QuantizeLinear': 3, 'DequantizeLinear': 4, 'AveragePool': 1} - check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + check_op_type_count(self, model_q8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_q8_qdq_path, qnode_io_qtypes) data_reader.rewind() - check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + check_model_correctness(self, model_fp32_path, model_q8_qdq_path, data_reader.get_next()) + def test_quantize_avgpool(self): + self.quantize_avgpool_test(QuantType.QUInt8, QuantType.QUInt8) + + def test_quantize_avgpool_s8s8(self): + self.quantize_avgpool_test(QuantType.QInt8, QuantType.QInt8, extra_options = {'ActivationSymmetric' : True}) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_reshape.py b/onnxruntime/test/python/quantization/test_op_reshape.py index a457a21570..0397d1a9c2 100644 --- a/onnxruntime/test/python/quantization/test_op_reshape.py +++ b/onnxruntime/test/python/quantization/test_op_reshape.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes, check_qtype_by_node_type class TestOpReshape(unittest.TestCase): @@ -67,35 +67,51 @@ class TestOpReshape(unittest.TestCase): onnx.save(model, output_model_path) - def test_quantize_reshape(self): + def quantize_reshape_test(self, activation_type, weight_type, extra_options = {}): np.random.seed(1) model_fp32_path = 'reshape_fp32.onnx' - model_uint8_path = 'reshape_uint8.onnx' - model_uint8_qdq_path = 'reshape_uint8_qdq.onnx' self.construct_model_matmul_reshape(model_fp32_path, [3, 7], [7, 3], [1, 9]) + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_uint8_path = 'reshape_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_uint8_qdq_path = 'reshape_{}{}_qdq.onnx'.format(activation_type_str, weight_type_str) + # Verify QOperator mode data_reader = self.input_feeds(1, {'input': [3, 7]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) + quantize_static(model_fp32_path, model_uint8_path, data_reader, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) # make sure transpose become xint8 operator, its input name could tell that check_op_nodes(self, model_uint8_path, lambda node: (node.name != "reshape_node" or node.input[0] != 'matmul_output')) qnode_counts = {'QLinearMatMul': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 1, 'Reshape': 1} check_op_type_count(self, model_uint8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear' : [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_uint8_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) qdqnode_counts = {'MatMul': 1, 'QuantizeLinear': 3, 'DequantizeLinear': 4, 'Reshape': 1} check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_uint8_qdq_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + def test_quantize_reshape(self): + self.quantize_reshape_test(QuantType.QUInt8, QuantType.QUInt8) + + def test_quantize_reshape_s8s8(self): + self.quantize_reshape_test(QuantType.QInt8, QuantType.QInt8, extra_options = {'ActivationSymmetric' : True}) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_resize.py b/onnxruntime/test/python/quantization/test_op_resize.py index 66724c38a1..df9371c2c0 100644 --- a/onnxruntime/test/python/quantization/test_op_resize.py +++ b/onnxruntime/test/python/quantization/test_op_resize.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes, check_qtype_by_node_type class TestOpResize(unittest.TestCase): @@ -81,12 +81,9 @@ class TestOpResize(unittest.TestCase): model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def test_quantize_resize(self): + def quantize_resize_test(self, activation_type, weight_type, extra_options = {}): np.random.seed(1) - model_fp32_path = 'resize_fp32.onnx' - model_uint8_path = 'resize_uint8.onnx' - model_uint8_qdq_path = 'resize_uint8_qdq.onnx' kwargs = {'coordinate_transformation_mode': 'asymmetric', 'mode': 'nearest', 'nearest_mode': 'floor'} self.construct_model_conv_resize(model_fp32_path, @@ -95,25 +92,43 @@ class TestOpResize(unittest.TestCase): kwargs, [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 2.0, 2.0], None) + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_uint8_path = 'resize_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_uint8_qdq_path = 'resize_{}{}_qdq.onnx'.format(activation_type_str, weight_type_str) + # Verify QOperator mode data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) - + quantize_static(model_fp32_path, model_uint8_path, data_reader, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) # make sure resize become xint8 operator, its input name could tell that check_op_nodes(self, model_uint8_path, lambda node: (node.name != "resize_node" or node.input[0] != 'conv_output')) qnode_counts = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 2, 'Resize': 1} check_op_type_count(self, model_uint8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear' : [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_uint8_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) qdqnode_counts = {'Conv': 1, 'QuantizeLinear': 3, 'DequantizeLinear': 4, 'Resize': 1} check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_uint8_qdq_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + def test_quantize_resize(self): + self.quantize_resize_test(QuantType.QUInt8, QuantType.QUInt8) + + # TODO: Uncomment following after resize s8 support is enabled + # def test_quantize_resize_s8s8(self): + # self.quantize_resize_test(QuantType.QInt8, QuantType.QInt8, extra_options = {'ActivationSymmetric' : True}) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_squeeze_unsqueeze.py b/onnxruntime/test/python/quantization/test_op_squeeze_unsqueeze.py index 579dba9c9c..18252ec7a1 100644 --- a/onnxruntime/test/python/quantization/test_op_squeeze_unsqueeze.py +++ b/onnxruntime/test/python/quantization/test_op_squeeze_unsqueeze.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_qtype_by_node_type class TestOpSqueezeUnsqueeze(unittest.TestCase): @@ -26,8 +26,8 @@ class TestOpSqueezeUnsqueeze(unittest.TestCase): return dr def construct_model_conv_squeezes(self, output_model_path, - conv_input_shape, conv_weight_shape, conv_output_shape, - opset = 13): + conv_input_shape, conv_weight_shape, conv_output_shape, + opset=13): # (input) # / | \ # Conv1 conv2 conv3 @@ -55,7 +55,6 @@ class TestOpSqueezeUnsqueeze(unittest.TestCase): conv3_weight_initializer = onnx.numpy_helper.from_array(conv3_weight_arr, name='conv3_weight') conv3_node = onnx.helper.make_node('Conv', ['input', 'conv3_weight'], ['conv3_output'], name='conv3_node') - if (opset >= 13): squeeze_axes_initializer = onnx.numpy_helper.from_array(np.array([0], dtype=np.int64), name='squeeze_axes') squeeze1_node = helper.make_node('Squeeze', ['conv1_output', 'squeeze_axes'], ['squeeze1_output'], name='suqeeze1_node') @@ -66,9 +65,10 @@ class TestOpSqueezeUnsqueeze(unittest.TestCase): add1_node = helper.make_node('Add', ['squeeze1_output', 'squeeze2_output'], ['add1_output'], name='add1_node') if (opset >= 13): - unsqueeze_node = helper.make_node('Unsqueeze', ['add1_output', 'squeeze_axes'], ['unsqueeze_output'], name = 'unsqueeze_node') + unsqueeze_node = helper.make_node('Unsqueeze', ['add1_output', 'squeeze_axes'], [ + 'unsqueeze_output'], name='unsqueeze_node') else: - unsqueeze_node = helper.make_node('Unsqueeze', ['add1_output'], ['unsqueeze_output'], name = 'unsqueeze_node', axes=[0]) + unsqueeze_node = helper.make_node('Unsqueeze', ['add1_output'], ['unsqueeze_output'], name='unsqueeze_node', axes=[0]) output_tensor = helper.make_tensor_value_info('output', TensorProto.FLOAT, conv_output_shape) add2_node = helper.make_node('Add', ['unsqueeze_output', 'conv3_output'], ['output'], name='add2_node') @@ -79,33 +79,43 @@ class TestOpSqueezeUnsqueeze(unittest.TestCase): graph = helper.make_graph([conv1_node, conv2_node, conv3_node, squeeze1_node, squeeze2_node, add1_node, unsqueeze_node, add2_node], 'TestOpSuqeezes_test_model', [input_tensor], [output_tensor], initializer=initializers) model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", opset)]) - model.ir_version = 7 # use stable onnx ir version + model.ir_version = 7 # use stable onnx ir version onnx.save(model, output_model_path) - def run_quantize_squeezes_of_opset(self, opset = 13): + def run_quantize_squeezes_of_opset(self, opset=13, activation_type=QuantType.QUInt8, weight_type=QuantType.QUInt8, extra_options={}): np.random.seed(1) model_fp32_path = 'squeezes_opset{}_fp32.onnx'.format(opset) - model_uint8_path = 'squeezes_opset{}_uint8.onnx'.format(opset) - model_uint8_qdq_path = 'squeezes_opset{}_uint8_qdq.onnx'.format(opset) - self.construct_model_conv_squeezes(model_fp32_path, [1, 2, 26, 42], [3, 2, 3, 3], [1, 3, 24, 40], opset=opset) + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_uint8_path = 'squeezes_opset{}_{}{}.onnx'.format(opset, activation_type_str, weight_type_str) + model_uint8_qdq_path = 'squeezes_opset{}_{}{}_qdq.onnx'.format(opset, activation_type_str, weight_type_str) + # Verify QOperator mode data_reader = self.input_feeds(1, {'input': [1, 2, 26, 42]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) + quantize_static(model_fp32_path, model_uint8_path, data_reader, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) # make sure squeezes become xint8 operator, its input name could tell that qnode_counts = {'QuantizeLinear': 1, 'DequantizeLinear': 1} check_op_type_count(self, model_uint8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear': [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_uint8_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next(), rtol=0.01, atol=0.5) # Verify QDQ mode data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type=activation_type, weight_type=weight_type, extra_options=extra_options) qdqnode_counts = {'Conv': 3, 'QuantizeLinear': 9, 'DequantizeLinear': 12} check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear': [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_uint8_qdq_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next(), rtol=0.01, atol=0.5) @@ -113,5 +123,10 @@ class TestOpSqueezeUnsqueeze(unittest.TestCase): self.run_quantize_squeezes_of_opset(11) self.run_quantize_squeezes_of_opset(13) + def test_quantize_squeeze_unsqueeze_s8s8(self): + self.run_quantize_squeezes_of_opset(11, QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + self.run_quantize_squeezes_of_opset(13, QuantType.QInt8, QuantType.QInt8, extra_options={'ActivationSymmetric': True}) + + if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_op_transpose.py b/onnxruntime/test/python/quantization/test_op_transpose.py index f1dd8a780e..a83ec6022d 100644 --- a/onnxruntime/test/python/quantization/test_op_transpose.py +++ b/onnxruntime/test/python/quantization/test_op_transpose.py @@ -10,8 +10,8 @@ import unittest import onnx import numpy as np from onnx import helper, TensorProto -from onnxruntime.quantization import quantize_static, QuantFormat -from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes +from onnxruntime.quantization import quantize_static, QuantFormat, QuantType +from op_test_utils import TestDataFeeds, check_model_correctness, check_op_type_count, check_op_nodes, check_qtype_by_node_type class TestOpTranspose(unittest.TestCase): @@ -62,32 +62,47 @@ class TestOpTranspose(unittest.TestCase): onnx.save(model, output_model_path) - def test_quantize_transpose(self): + def quantize_transpose_test(self, activation_type, weight_type, extra_options = {}): np.random.seed(1) model_fp32_path = 'transpose_fp32.onnx' - model_uint8_path = 'transpose_uint8.onnx' - model_uint8_qdq_path = 'transpose_uint8_qdq.onnx' - self.construct_model_matmul_transpose(model_fp32_path, [3, 7], [7, 5], [5, 3]) + activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8 + activation_type_str = 'u8' if (activation_type == QuantType.QUInt8) else 's8' + weight_type_str = 'u8' if (weight_type == QuantType.QUInt8) else 's8' + model_uint8_path = 'transpose_{}{}.onnx'.format(activation_type_str, weight_type_str) + model_uint8_qdq_path = 'transpose_{}{}_qdq.onnx'.format(activation_type_str, weight_type_str) + # Verify QOperator model data_reader = self.input_feeds(1, {'input': [3, 7]}) - quantize_static(model_fp32_path, model_uint8_path, data_reader) + quantize_static(model_fp32_path, model_uint8_path, data_reader, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) # make sure transpose become xint8 operator, its input name could tell that check_op_nodes(self, model_uint8_path, lambda node: (node.name != "transpose_node" or node.input[0] != 'matmul_output')) qnode_counts = {'QLinearMatMul': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 1, 'Transpose': 1} check_op_type_count(self, model_uint8_path, **qnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + qnode_io_qtypes.update({'DequantizeLinear' : [['i', 2, activation_proto_qtype]]}) + check_qtype_by_node_type(self, model_uint8_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_path, data_reader.get_next()) # Verify QDQ model data_reader.rewind() - quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ) + quantize_static(model_fp32_path, model_uint8_qdq_path, data_reader, quant_format=QuantFormat.QDQ, + activation_type = activation_type, weight_type = weight_type, extra_options = extra_options) qdqnode_counts = {'MatMul': 1, 'QuantizeLinear': 3, 'DequantizeLinear': 4, 'Transpose': 1} check_op_type_count(self, model_uint8_qdq_path, **qdqnode_counts) + qnode_io_qtypes = {'QuantizeLinear' : [['i', 2, activation_proto_qtype], ['o', 0, activation_proto_qtype]]} + check_qtype_by_node_type(self, model_uint8_qdq_path, qnode_io_qtypes) data_reader.rewind() check_model_correctness(self, model_fp32_path, model_uint8_qdq_path, data_reader.get_next()) + def test_quantize_transpose(self): + self.quantize_transpose_test(QuantType.QUInt8, QuantType.QUInt8) + + def test_quantize_transpose_s8s8(self): + self.quantize_transpose_test(QuantType.QInt8, QuantType.QInt8, extra_options = {'ActivationSymmetric' : True}) if __name__ == '__main__': unittest.main() diff --git a/onnxruntime/test/python/quantization/test_qdq.py b/onnxruntime/test/python/quantization/test_qdq.py index d8d4280e37..2aca1eacdb 100644 --- a/onnxruntime/test/python/quantization/test_qdq.py +++ b/onnxruntime/test/python/quantization/test_qdq.py @@ -104,7 +104,7 @@ class TestQDQExtraOptions(unittest.TestCase): # This QuantizeLinear node should be followed by Add1 if node.name == 'P_QuantizeLinear': qdq_added_to_node_output_flag = True - self.assertTrue(node.input[0] is 'P') + self.assertTrue(node.input[0] == 'P') self.assertTrue(qdq_added_to_node_output_flag) From b4434c76946eaabb5310b1444309c49e401bd9cb Mon Sep 17 00:00:00 2001 From: "Nat Kershaw (MSFT)" Date: Fri, 10 Dec 2021 17:45:50 -0800 Subject: [PATCH 026/113] Automate generation of C/C++ API docs (#9997) --- .github/workflows/publish-c-apidocs.yml | 30 +++++++++++++++++++++++++ docs/c_cxx/Doxyfile | 4 ++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish-c-apidocs.yml diff --git a/.github/workflows/publish-c-apidocs.yml b/.github/workflows/publish-c-apidocs.yml new file mode 100644 index 0000000000..db2f88dbc3 --- /dev/null +++ b/.github/workflows/publish-c-apidocs.yml @@ -0,0 +1,30 @@ +name: Publish C/C++ API Docs +on: + workflow_dispatch + +jobs: + publish: + name: Publish C/C++ API docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install doxygen and dependencies + run: | + sudo apt update + sudo apt-get install libclang-9-dev + sudo apt-get install libclang-cpp9 + wget https://www.doxygen.nl/files/doxygen-1.9.2.linux.bin.tar.gz + tar xvzf doxygen-1.9.2.linux.bin.tar.gz + - name: Run doxygen + run: | + mkdir -p build/doxygen + cd docs/c_cxx + ../../doxygen-1.9.2/bin/doxygen + - name: Publish + uses: JamesIves/github-pages-deploy-action@releases/v3 + with: + BRANCH: gh-pages + FOLDER: build/doxygen/html + TARGET_FOLDER: docs/api/c + CLEAN_EXCLUDE: '["_config.yml"]' + \ No newline at end of file diff --git a/docs/c_cxx/Doxyfile b/docs/c_cxx/Doxyfile index 18bcf754cd..888e0a36b3 100644 --- a/docs/c_cxx/Doxyfile +++ b/docs/c_cxx/Doxyfile @@ -150,7 +150,7 @@ INLINE_INHERITED_MEMB = NO # shortest path that makes the file name unique will be used # The default value is: YES. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand @@ -843,7 +843,7 @@ WARN_NO_PARAMDOC = YES # Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. -WARN_AS_ERROR = FAIL_ON_WARNINGS +WARN_AS_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which From 787755328b98d8830c421f3c7865767c9a2ab570 Mon Sep 17 00:00:00 2001 From: Zhang Lei Date: Fri, 10 Dec 2021 17:52:51 -0800 Subject: [PATCH 027/113] Add s8s8 for depthwise qconv 3x3 5x5 (#10008) * Add depthwise conv s8s8 routine for 3x3 5x5 on arm64. And its testcase. * fix some comments. --- .../aarch64/DepthwiseQConvKernelSize9Neon.S | 300 +++++++++++++- .../arm64/DepthwiseQConvKernelSize9Neon.asm | 304 ++++++++++++++- onnxruntime/core/mlas/lib/convsym.cpp | 8 +- onnxruntime/core/mlas/lib/mlasi.h | 7 +- .../core/mlas/lib/qdwconv_kernelsize.cpp | 366 +++++++++++++++++- .../providers/cpu/nn/qlinearconv_op_test.cc | 26 +- 6 files changed, 991 insertions(+), 20 deletions(-) diff --git a/onnxruntime/core/mlas/lib/aarch64/DepthwiseQConvKernelSize9Neon.S b/onnxruntime/core/mlas/lib/aarch64/DepthwiseQConvKernelSize9Neon.S index acfabf5481..2be4b17a17 100644 --- a/onnxruntime/core/mlas/lib/aarch64/DepthwiseQConvKernelSize9Neon.S +++ b/onnxruntime/core/mlas/lib/aarch64/DepthwiseQConvKernelSize9Neon.S @@ -48,7 +48,7 @@ Abstract: Routine Description: This routine is the inner kernel to compute a depthwise quantized convolution - on kernel size 9. + on kernel size 9 for u8s8 Arguments: @@ -72,7 +72,7 @@ Return Value: --*/ - FUNCTION_ENTRY MlasConvSymDepthwiseKernelSize9Arm64 + FUNCTION_ENTRY MlasConvSymDepthwiseKernelSize9Arm64U8S8 stp x19, x20, [sp, #.LMlasConvSymDepthwiseKernelSize9_SavedRegisters_Neg]! stp x21, x22, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x21_x22] @@ -357,4 +357,300 @@ Return Value: ldp x19, x20, [sp], #.LMlasConvSymDepthwiseKernelSize9_SavedRegisters ret + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a depthwise quantized convolution + on kernel size 9 for s8s8 + +Arguments: + + Input (x0) - Supplies the address of the indirection buffer. + + Filter (x1) - Supplies the address of the filter buffer. + + Channels (x2) - Supplies the number of input and output channels. + + Output (x3) - Supplies the address of the output buffer. + + OutputCount (x4)- Supplies the number of image pixels. + + PostProcessParams (x5) - Supplies the address of the post process parameter block. + + KernelFlags (x6) - Supplies additional flags controlling the operation. + +Return Value: + + None. + +--*/ + + FUNCTION_ENTRY MlasConvSymDepthwiseKernelSize9Arm64S8S8 + + stp x19, x20, [sp, #.LMlasConvSymDepthwiseKernelSize9_SavedRegisters_Neg]! + stp x21, x22, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x21_x22] + stp x23, x24, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x23_x24] + stp x25, x26, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x25_x26] + stp x27, x28, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x27_x28] + stp d8, d9, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d8_d9] + stp d10, d11, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d10_d11] + stp d12, d13, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d12_d13] + stp d14, d15, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d14_d15] + + ldr x9, [x5, #.LConvSymDepthwisePostProcessParams_Bias] + ldr x8, [x5, #.LConvSymDepthwisePostProcessParams_Scale] + add x5, x5, #.LConvSymDepthwisePostProcessParams_ZeroPoint + ins v12.d[0], x1 // Filter + ins v13.d[0], x9 // Bias + ins v13.d[1], x8 // Scale + ld1r {v0.8h}, [x5] // zero point + + tbnz x6, #.LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE_BIT_INDEX, .LMlasConvSymDepthwiseKernelSize9S8S8_SkipPerTensorScaleInit + ld1r {v1.4s}, [x8] // load scale value + mov v2.16b, v1.16b + mov v3.16b, v1.16b + mov v4.16b, v1.16b + +.LMlasConvSymDepthwiseKernelSize9S8S8_SkipPerTensorScaleInit: + + add x9, x3, x2 // x9 <---- Ouput1 + cbz x4, .LMlasConvSymDepthwiseKernelSize9S8S8_Exit + +.LMlasConvSymDepthwiseKernelSize9S8S8_OutputLoop: + ldp x20, x21, [x0], #72 // input ptrs for Output0 + ldp x22, x23, [x0, #-56] + sub x4, x4, #1 + ldp x24, x25, [x0, #-40] + ldp x26, x27, [x0, #-24] + ldur x28, [x0, #-8] + + cbz x4, .LMlasConvSymDepthwiseKernelSize9S8S8_Dup_Inputs + ldp x10, x11, [x0], #72 // input ptrs for Output0 + ldp x12, x13, [x0, #-56] + sub x4, x4, #1 + ldp x14, x15, [x0, #-40] + ldp x16, x17, [x0, #-24] + ldur x19, [x0, #-8] + b .LMlasConvSymDepthwiseKernelSize9S8S8_Loaded_Input + +.LMlasConvSymDepthwiseKernelSize9S8S8_Dup_Inputs: + mov x9, x3 // Output1 <-- Output0 + mov x10, x20 + mov x11, x21 + mov x12, x22 + mov x13, x23 + mov x14, x24 + mov x15, x25 + mov x16, x26 + mov x17, x27 + mov x19, x28 + +.LMlasConvSymDepthwiseKernelSize9S8S8_Loaded_Input: + + eor x8, x8, x8 // Processed channels + umov x1, v12.D[0] // filter + umov x5, v13.D[0] // bias + umov x7, v13.D[1] // scale + + cmp x8, x2 // Save one register by not using count down to zero here + bhs .LMlasConvSymDepthwiseKernelSize9S8S8_Finish_Channels16_Loop + +.LMlasConvSymDepthwiseKernelSize9S8S8_Channels16_Loop: + ld1 {v10.16b}, [x1], x2 // vk0 + ldr q16, [x20, x8] // out0 vi0 + ldr q17, [x10, x8] // out1 vi0 + ld1 {v6.4s, v7.4s, v8.4s, v9.4s}, [x5], #64 // bias vacc 0-15 for outs + ld1 {v11.16b}, [x1], x2 // vk1 + ldr q18, [x21, x8] // out0 vi1 + ldr q19, [x11, x8] // out1 vi1 + + ld1 {v14.16b}, [x1], x2 // vk2 + + ldr q20, [x22, x8] // out0 vi2 + smull v24.8h, v10.8b, v16.8b + smull2 v25.8h, v10.16b, v16.16b + ldr q21, [x12, x8] // out1 vi2 + smull v26.8h, v10.8b, v17.8b + ld1 {v15.16b}, [x1], x2 // vk3 + smull2 v27.8h, v10.16b, v17.16b + ldr q22, [x23, x8] // out0 vi3 + smull v28.8h, v11.8b, v18.8b + smull2 v29.8h, v11.16b, v18.16b + ldr q23, [x13, x8] // out1 vi3 + smull v30.8h, v11.8b, v19.8b + smull2 v31.8h, v11.16b, v19.16b + + ld1 {v10.16b}, [x1], x2 // vk4 + + smlal v24.8h, v14.8b, v20.8b + smlal2 v25.8h, v14.16b, v20.16b + smlal v26.8h, v14.8b, v21.8b + smlal2 v27.8h, v14.16b, v21.16b + smlal v28.8h, v15.8b, v22.8b + smlal2 v29.8h, v15.16b, v22.16b + smlal v30.8h, v15.8b, v23.8b + smlal2 v31.8h, v15.16b, v23.16b + ld1 {v11.16b}, [x1], x2 // vk5 + + saddw v16.4s, v6.4s, v24.4h // dup acc for out1 + saddw2 v17.4s, v7.4s, v24.8h + saddw v18.4s, v8.4s, v25.4h + saddw2 v19.4s, v9.4s, v25.8h + + ldr q20, [x24, x8] // out0 vi4 + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + ldr q21, [x14, x8] // out1 vi4 + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + ldr q22, [x25, x8] // out0 vi5 + saddw v16.4s, v16.4s, v28.4h + saddw2 v17.4s, v17.4s, v28.8h + ldr q23, [x15, x8] // out1 vi5 + saddw v18.4s, v18.4s, v29.4h + saddw2 v19.4s, v19.4s, v29.8h + ld1 {v14.16b}, [x1], x2 // vk6 + + saddw v6.4s, v6.4s, v30.4h + saddw2 v7.4s, v7.4s, v30.8h + ld1 {v15.16b}, [x1], x2 // vk7 + saddw v8.4s, v8.4s, v31.4h + saddw2 v9.4s, v9.4s, v31.8h + + smull v24.8h, v10.8b, v20.8b + smull2 v25.8h, v10.16b, v20.16b + smull v26.8h, v10.8b, v21.8b + smull2 v27.8h, v10.16b, v21.16b + smull v28.8h, v11.8b, v22.8b + smull2 v29.8h, v11.16b, v22.16b + smull v30.8h, v11.8b, v23.8b + smull2 v31.8h, v11.16b, v23.16b + + ldr q20, [x26, x8] // out0 vi6 + ldr q21, [x16, x8] // out1 vi6 + ldr q22, [x27, x8] // out0 vi7 + ldr q23, [x17, x8] // out1 vi7 + + tbz x6, #.LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE_BIT_INDEX, .LDonePerChannelScaleLoad_MlasConvSymDepthwiseKernelSize9S8S8 + ld1 {v1.4s, v2.4s, v3.4s, v4.4s}, [x7], #64 // scales 0-15 for outs + +.LDonePerChannelScaleLoad_MlasConvSymDepthwiseKernelSize9S8S8: + ldr q10, [x1] // vk8 + + smlal v24.8h, v14.8b, v20.8b + smlal2 v25.8h, v14.16b, v20.16b + smlal v26.8h, v14.8b, v21.8b + smlal2 v27.8h, v14.16b, v21.16b + smlal v28.8h, v15.8b, v22.8b + smlal2 v29.8h, v15.16b, v22.16b + smlal v30.8h, v15.8b, v23.8b + smlal2 v31.8h, v15.16b, v23.16b + + saddw v16.4s, v16.4s, v24.4h + saddw2 v17.4s, v17.4s, v24.8h + saddw v18.4s, v18.4s, v25.4h + saddw2 v19.4s, v19.4s, v25.8h + ldr q20, [x28, x8] // out0 vi8 + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + ldr q21, [x19, x8] // out1 vi8 + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + + saddw v16.4s, v16.4s, v28.4h + saddw2 v17.4s, v17.4s, v28.8h + saddw v18.4s, v18.4s, v29.4h + saddw2 v19.4s, v19.4s, v29.8h + + saddw v6.4s, v6.4s, v30.4h + saddw2 v7.4s, v7.4s, v30.8h + saddw v8.4s, v8.4s, v31.4h + saddw2 v9.4s, v9.4s, v31.8h + + smull v24.8h, v10.8b, v20.8b + smull2 v25.8h, v10.16b, v20.16b + smull v26.8h, v10.8b, v21.8b + smull2 v27.8h, v10.16b, v21.16b + + saddw v16.4s, v16.4s, v24.4h + saddw2 v17.4s, v17.4s, v24.8h + saddw v18.4s, v18.4s, v25.4h + saddw2 v19.4s, v19.4s, v25.8h + + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + + scvtf v16.4s, v16.4s // Requantize + scvtf v17.4s, v17.4s + scvtf v18.4s, v18.4s + scvtf v19.4s, v19.4s + scvtf v6.4s, v6.4s + scvtf v7.4s, v7.4s + scvtf v8.4s, v8.4s + scvtf v9.4s, v9.4s + + fmul v16.4s, v16.4s, v1.4s + fmul v17.4s, v17.4s, v2.4s + fmul v18.4s, v18.4s, v3.4s + fmul v19.4s, v19.4s, v4.4s + fmul v6.4s, v6.4s, v1.4s + fmul v7.4s, v7.4s, v2.4s + fmul v8.4s, v8.4s, v3.4s + fmul v9.4s, v9.4s, v4.4s + + fcvtns v16.4s, v16.4s + fcvtns v17.4s, v17.4s + fcvtns v18.4s, v18.4s + fcvtns v19.4s, v19.4s + fcvtns v6.4s, v6.4s + fcvtns v7.4s, v7.4s + fcvtns v8.4s, v8.4s + fcvtns v9.4s, v9.4s + + sqxtn v16.4h, v16.4s // +zp, narrow and combine + sqxtn v18.4h, v18.4s + sqxtn v6.4h, v6.4s + sqxtn v8.4h, v8.4s + sqxtn2 v16.8h, v17.4s + sqxtn2 v18.8h, v19.4s + sqxtn2 v6.8h, v7.4s + sqxtn2 v8.8h, v9.4s + sqadd v16.8h, v16.8h, v0.8h + sqadd v18.8h, v18.8h, v0.8h + sqadd v6.8h, v6.8h, v0.8h + sqadd v8.8h, v8.8h, v0.8h + sqxtn v16.8b, v16.8h + sqxtn2 v16.16b, v18.8h + sqxtn v6.8b, v6.8h + sqxtn2 v6.16b, v8.8h + + str q16, [x3, x8] + str q6, [x9, x8] + add x8, x8, #16 + umov x1, v12.D[0] // filter + cmp x8, x2 + add x1, x1, x8 + blo .LMlasConvSymDepthwiseKernelSize9S8S8_Channels16_Loop + +.LMlasConvSymDepthwiseKernelSize9S8S8_Finish_Channels16_Loop: + add x3, x3, x2, LSL #1 + add x9, x9, x2, LSL #1 + cbnz x4, .LMlasConvSymDepthwiseKernelSize9S8S8_OutputLoop + +.LMlasConvSymDepthwiseKernelSize9S8S8_Exit: + ldp d14, d15, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d14_d15] + ldp d12, d13, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d12_d13] + ldp d10, d11, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d10_d11] + ldp d8, d9, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_d8_d9] + ldp x27, x28, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x27_x28] + ldp x25, x26, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x25_x26] + ldp x23, x24, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x23_x24] + ldp x21, x22, [sp, #.LMlasConvSymDepthwiseKernelSize9_backup_x21_x22] + ldp x19, x20, [sp], #.LMlasConvSymDepthwiseKernelSize9_SavedRegisters + ret + .end diff --git a/onnxruntime/core/mlas/lib/arm64/DepthwiseQConvKernelSize9Neon.asm b/onnxruntime/core/mlas/lib/arm64/DepthwiseQConvKernelSize9Neon.asm index 2db99ccde1..335e11be1e 100644 --- a/onnxruntime/core/mlas/lib/arm64/DepthwiseQConvKernelSize9Neon.asm +++ b/onnxruntime/core/mlas/lib/arm64/DepthwiseQConvKernelSize9Neon.asm @@ -49,7 +49,7 @@ Abstract: Routine Description: This routine is the inner kernel to compute a depthwise quantized convolution - on kernel size 9. + on kernel size 9 for U8S8. Arguments: @@ -73,7 +73,7 @@ Return Value: --*/ - LEAF_ENTRY MlasConvSymDepthwiseKernelSize9Arm64 + LEAF_ENTRY MlasConvSymDepthwiseKernelSize9Arm64U8S8 PROLOG_SAVE_REG_PAIR x19, x20, #MlasConvSymDepthwiseKernelSize9_SavedRegisters_Neg ! PROLOG_SAVE_REG_PAIR x21, x22, #MlasConvSymDepthwiseKernelSize9_backup_x21_x22 @@ -358,7 +358,305 @@ MlasConvSymDepthwiseKernelSize9_Exit EPILOG_RESTORE_REG_PAIR x19, x20, #MlasConvSymDepthwiseKernelSize9_SavedRegisters ! EPILOG_RETURN - LEAF_END MlasConvSymDepthwiseKernelSize9Arm64 + LEAF_END MlasConvSymDepthwiseKernelSize9Arm64U8S8 + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a depthwise quantized convolution + on kernel size 9 for S8S8. + +Arguments: + + Input (x0) - Supplies the address of the indirection buffer. + + Filter (x1) - Supplies the address of the filter buffer. + + Channels (x2) - Supplies the number of input and output channels. + + Output (x3) - Supplies the address of the output buffer. + + OutputCount (x4)- Supplies the number of image pixels. + + PostProcessParams (x5) - Supplies the address of the post process parameter block. + + KernelFlags (x6) - Supplies additional flags controlling the operation. + +Return Value: + + None. + +--*/ + + LEAF_ENTRY MlasConvSymDepthwiseKernelSize9Arm64S8S8 + + PROLOG_SAVE_REG_PAIR x19, x20, #MlasConvSymDepthwiseKernelSize9_SavedRegisters_Neg ! + PROLOG_SAVE_REG_PAIR x21, x22, #MlasConvSymDepthwiseKernelSize9_backup_x21_x22 + PROLOG_SAVE_REG_PAIR x23, x24, #MlasConvSymDepthwiseKernelSize9_backup_x23_x24 + PROLOG_SAVE_REG_PAIR x25, x26, #MlasConvSymDepthwiseKernelSize9_backup_x25_x26 + PROLOG_SAVE_REG_PAIR x27, x28, #MlasConvSymDepthwiseKernelSize9_backup_x27_x28 + PROLOG_SAVE_REG_PAIR d8, d9, #MlasConvSymDepthwiseKernelSize9_backup_d8_d9 + PROLOG_SAVE_REG_PAIR d10, d11, #MlasConvSymDepthwiseKernelSize9_backup_d10_d11 + PROLOG_SAVE_REG_PAIR d12, d13, #MlasConvSymDepthwiseKernelSize9_backup_d12_d13 + PROLOG_SAVE_REG_PAIR d14, d15, #MlasConvSymDepthwiseKernelSize9_backup_d14_d15 + + ldr x9, [x5, #ConvSymDepthwisePostProcessParams_Bias] + ldr x8, [x5, #ConvSymDepthwisePostProcessParams_Scale] + add x5, x5, #ConvSymDepthwisePostProcessParams_ZeroPoint + ins v12.d[0], x1 // Filter + ins v13.d[0], x9 // Bias + ins v13.d[1], x8 // Scale + ld1r {v0.8h}, [x5] // v0.8h <--- vector for output zero point + + tbnz x6, #MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE_BIT_INDEX, MlasConvSymDepthwiseKernelSize9S8S8_SkipPerTensorScaleInit + ld1r {v1.4s}, [x8] // load and dup scale value + mov v2.16b, v1.16b + mov v3.16b, v1.16b + mov v4.16b, v1.16b + +MlasConvSymDepthwiseKernelSize9S8S8_SkipPerTensorScaleInit + + add x9, x3, x2 // x9 <---- Ouput1, x3 is Ouput0 + cbz x4, MlasConvSymDepthwiseKernelSize9S8S8_Exit + +MlasConvSymDepthwiseKernelSize9S8S8_OutputLoop + ldp x20, x21, [x0], #72 // input ptrs for Output0 + ldp x22, x23, [x0, #-56] + sub x4, x4, #1 + ldp x24, x25, [x0, #-40] + ldp x26, x27, [x0, #-24] + ldur x28, [x0, #-8] + + cbz x4, MlasConvSymDepthwiseKernelSize9S8S8_Dup_Inputs + ldp x10, x11, [x0], #72 // input ptrs for Output0 + ldp x12, x13, [x0, #-56] + sub x4, x4, #1 + ldp x14, x15, [x0, #-40] + ldp x16, x17, [x0, #-24] + ldur x19, [x0, #-8] + b MlasConvSymDepthwiseKernelSize9S8S8_Loaded_Input + +MlasConvSymDepthwiseKernelSize9S8S8_Dup_Inputs + mov x9, x3 // Output1 <-- Output0 + mov x10, x20 + mov x11, x21 + mov x12, x22 + mov x13, x23 + mov x14, x24 + mov x15, x25 + mov x16, x26 + mov x17, x27 + mov x19, x28 + +MlasConvSymDepthwiseKernelSize9S8S8_Loaded_Input + + eor x8, x8, x8 // Processed channels + umov x1, v12.d[0] // filter + umov x5, v13.d[0] // bias + umov x7, v13.d[1] // scale + + cmp x8, x2 // Save one register by not using count down to zero here + bhs MlasConvSymDepthwiseKernelSize9S8S8_Finish_Channels16_Loop + +MlasConvSymDepthwiseKernelSize9S8S8_Channels16_Loop + ld1 {v10.16b}, [x1], x2 // vk0 + ldr q16, [x20, x8] // out0 vi0 + ldr q17, [x10, x8] // out1 vi0 + ld1 {v6.4s, v7.4s, v8.4s, v9.4s}, [x5], #64 // bias vacc 0-15 for outs + ld1 {v11.16b}, [x1], x2 // vk1 + ldr q18, [x21, x8] // out0 vi1 + ldr q19, [x11, x8] // out1 vi1 + + ld1 {v14.16b}, [x1], x2 // vk2 + + ldr q20, [x22, x8] // out0 vi2 + smull v24.8h, v10.8b, v16.8b + smull2 v25.8h, v10.16b, v16.16b + ldr q21, [x12, x8] // out1 vi2 + smull v26.8h, v10.8b, v17.8b + ld1 {v15.16b}, [x1], x2 // vk3 + smull2 v27.8h, v10.16b, v17.16b + ldr q22, [x23, x8] // out0 vi3 + smull v28.8h, v11.8b, v18.8b + smull2 v29.8h, v11.16b, v18.16b + ldr q23, [x13, x8] // out1 vi3 + smull v30.8h, v11.8b, v19.8b + smull2 v31.8h, v11.16b, v19.16b + + ld1 {v10.16b}, [x1], x2 // vk4 + + smlal v24.8h, v14.8b, v20.8b + smlal2 v25.8h, v14.16b, v20.16b + smlal v26.8h, v14.8b, v21.8b + smlal2 v27.8h, v14.16b, v21.16b + smlal v28.8h, v15.8b, v22.8b + smlal2 v29.8h, v15.16b, v22.16b + smlal v30.8h, v15.8b, v23.8b + smlal2 v31.8h, v15.16b, v23.16b + ld1 {v11.16b}, [x1], x2 // vk5 + + saddw v16.4s, v6.4s, v24.4h // dup acc for out1 + saddw2 v17.4s, v7.4s, v24.8h + saddw v18.4s, v8.4s, v25.4h + saddw2 v19.4s, v9.4s, v25.8h + + ldr q20, [x24, x8] // out0 vi4 + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + ldr q21, [x14, x8] // out1 vi4 + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + ldr q22, [x25, x8] // out0 vi5 + saddw v16.4s, v16.4s, v28.4h + saddw2 v17.4s, v17.4s, v28.8h + ldr q23, [x15, x8] // out1 vi5 + saddw v18.4s, v18.4s, v29.4h + saddw2 v19.4s, v19.4s, v29.8h + ld1 {v14.16b}, [x1], x2 // vk6 + + saddw v6.4s, v6.4s, v30.4h + saddw2 v7.4s, v7.4s, v30.8h + ld1 {v15.16b}, [x1], x2 // vk7 + saddw v8.4s, v8.4s, v31.4h + saddw2 v9.4s, v9.4s, v31.8h + + smull v24.8h, v10.8b, v20.8b + smull2 v25.8h, v10.16b, v20.16b + smull v26.8h, v10.8b, v21.8b + smull2 v27.8h, v10.16b, v21.16b + smull v28.8h, v11.8b, v22.8b + smull2 v29.8h, v11.16b, v22.16b + smull v30.8h, v11.8b, v23.8b + smull2 v31.8h, v11.16b, v23.16b + + ldr q20, [x26, x8] // out0 vi6 + ldr q21, [x16, x8] // out1 vi6 + ldr q22, [x27, x8] // out0 vi7 + ldr q23, [x17, x8] // out1 vi7 + tbz x6, #MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE_BIT_INDEX, DonePerChannelScaleLoad_MlasConvSymDepthwiseKernelSize9S8S8 + ld1 {v1.4s, v2.4s, v3.4s, v4.4s}, [x7], #64 // scales 0-15 for outs + +DonePerChannelScaleLoad_MlasConvSymDepthwiseKernelSize9S8S8 + ldr q10, [x1] // vk8 + + smlal v24.8h, v14.8b, v20.8b + smlal2 v25.8h, v14.16b, v20.16b + smlal v26.8h, v14.8b, v21.8b + smlal2 v27.8h, v14.16b, v21.16b + smlal v28.8h, v15.8b, v22.8b + smlal2 v29.8h, v15.16b, v22.16b + smlal v30.8h, v15.8b, v23.8b + smlal2 v31.8h, v15.16b, v23.16b + + saddw v16.4s, v16.4s, v24.4h + saddw2 v17.4s, v17.4s, v24.8h + saddw v18.4s, v18.4s, v25.4h + saddw2 v19.4s, v19.4s, v25.8h + ldr q20, [x28, x8] // out0 vi8 + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + ldr q21, [x19, x8] // out1 vi8 + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + + + saddw v16.4s, v16.4s, v28.4h + saddw2 v17.4s, v17.4s, v28.8h + saddw v18.4s, v18.4s, v29.4h + saddw2 v19.4s, v19.4s, v29.8h + + saddw v6.4s, v6.4s, v30.4h + saddw2 v7.4s, v7.4s, v30.8h + saddw v8.4s, v8.4s, v31.4h + saddw2 v9.4s, v9.4s, v31.8h + + smull v24.8h, v10.8b, v20.8b + smull2 v25.8h, v10.16b, v20.16b + smull v26.8h, v10.8b, v21.8b + smull2 v27.8h, v10.16b, v21.16b + + saddw v16.4s, v16.4s, v24.4h + saddw2 v17.4s, v17.4s, v24.8h + saddw v18.4s, v18.4s, v25.4h + saddw2 v19.4s, v19.4s, v25.8h + + saddw v6.4s, v6.4s, v26.4h + saddw2 v7.4s, v7.4s, v26.8h + saddw v8.4s, v8.4s, v27.4h + saddw2 v9.4s, v9.4s, v27.8h + + scvtf v16.4s, v16.4s // Requantize + scvtf v17.4s, v17.4s + scvtf v18.4s, v18.4s + scvtf v19.4s, v19.4s + scvtf v6.4s, v6.4s + scvtf v7.4s, v7.4s + scvtf v8.4s, v8.4s + scvtf v9.4s, v9.4s + + fmul v16.4s, v16.4s, v1.4s + fmul v17.4s, v17.4s, v2.4s + fmul v18.4s, v18.4s, v3.4s + fmul v19.4s, v19.4s, v4.4s + fmul v6.4s, v6.4s, v1.4s + fmul v7.4s, v7.4s, v2.4s + fmul v8.4s, v8.4s, v3.4s + fmul v9.4s, v9.4s, v4.4s + + fcvtns v16.4s, v16.4s + fcvtns v17.4s, v17.4s + fcvtns v18.4s, v18.4s + fcvtns v19.4s, v19.4s + fcvtns v6.4s, v6.4s + fcvtns v7.4s, v7.4s + fcvtns v8.4s, v8.4s + fcvtns v9.4s, v9.4s + + sqxtn v16.4h, v16.4s // +zp, narrow and combine + sqxtn v18.4h, v18.4s + sqxtn v6.4h, v6.4s + sqxtn v8.4h, v8.4s + sqxtn2 v16.8h, v17.4s + sqxtn2 v18.8h, v19.4s + sqxtn2 v6.8h, v7.4s + sqxtn2 v8.8h, v9.4s + sqadd v16.8h, v16.8h, v0.8h + sqadd v18.8h, v18.8h, v0.8h + sqadd v6.8h, v6.8h, v0.8h + sqadd v8.8h, v8.8h, v0.8h + sqxtn v16.8b, v16.8h + sqxtn2 v16.16b, v18.8h + sqxtn v6.8b, v6.8h + sqxtn2 v6.16b, v8.8h + + str q16, [x3, x8] + str q6, [x9, x8] + add x8, x8, #16 + umov x1, v12.d[0] // filter's beginning + cmp x8, x2 + add x1, x1, x8 + blo MlasConvSymDepthwiseKernelSize9S8S8_Channels16_Loop + +MlasConvSymDepthwiseKernelSize9S8S8_Finish_Channels16_Loop + add x3, x3, x2, LSL #1 + add x9, x9, x2, LSL #1 + cbnz x4, MlasConvSymDepthwiseKernelSize9S8S8_OutputLoop + +MlasConvSymDepthwiseKernelSize9S8S8_Exit + EPILOG_RESTORE_REG_PAIR d14, d15, #MlasConvSymDepthwiseKernelSize9_backup_d14_d15 + EPILOG_RESTORE_REG_PAIR d12, d13, #MlasConvSymDepthwiseKernelSize9_backup_d12_d13 + EPILOG_RESTORE_REG_PAIR d10, d11, #MlasConvSymDepthwiseKernelSize9_backup_d10_d11 + EPILOG_RESTORE_REG_PAIR d8, d9, #MlasConvSymDepthwiseKernelSize9_backup_d8_d9 + EPILOG_RESTORE_REG_PAIR x27, x28, #MlasConvSymDepthwiseKernelSize9_backup_x27_x28 + EPILOG_RESTORE_REG_PAIR x25, x26, #MlasConvSymDepthwiseKernelSize9_backup_x25_x26 + EPILOG_RESTORE_REG_PAIR x23, x24, #MlasConvSymDepthwiseKernelSize9_backup_x23_x24 + EPILOG_RESTORE_REG_PAIR x21, x22, #MlasConvSymDepthwiseKernelSize9_backup_x21_x22 + EPILOG_RESTORE_REG_PAIR x19, x20, #MlasConvSymDepthwiseKernelSize9_SavedRegisters ! + EPILOG_RETURN + + LEAF_END MlasConvSymDepthwiseKernelSize9Arm64S8S8 + END diff --git a/onnxruntime/core/mlas/lib/convsym.cpp b/onnxruntime/core/mlas/lib/convsym.cpp index ad20c47446..1033b1d0c0 100644 --- a/onnxruntime/core/mlas/lib/convsym.cpp +++ b/onnxruntime/core/mlas/lib/convsym.cpp @@ -421,13 +421,13 @@ MlasConvSymDepthwise( PostProcessParams.Scale = Params.Scale; if (Params.KernelSize == 9) { MlasConvSymDepthwiseKernelSize9Arm64( - (const uint8_t *const *)Params.InputIndirection, (int8_t const*)Params.Filter, Params.OutputChannels, - (uint8_t*)Params.Output, Params.OutputCount, &PostProcessParams, KernelFlags + Params.InputIndirection, (int8_t const*)Params.Filter, Params.OutputChannels, + Params.Output, Params.OutputCount, &PostProcessParams, KernelFlags, Params.InputIsSigned ); } else { MlasConvSymDepthwiseKernelSize25Arm( - (const uint8_t *const *)Params.InputIndirection, (int8_t const*)Params.Filter, Params.OutputChannels, - (uint8_t*)Params.Output, Params.OutputCount, &PostProcessParams, KernelFlags + Params.InputIndirection, (int8_t const*)Params.Filter, Params.OutputChannels, + Params.Output, Params.OutputCount, &PostProcessParams, KernelFlags, Params.InputIsSigned ); } return; diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h index a41dacf448..427c0559c1 100644 --- a/onnxruntime/core/mlas/lib/mlasi.h +++ b/onnxruntime/core/mlas/lib/mlasi.h @@ -735,13 +735,14 @@ struct MLAS_CONV_SYM_POST_PROCESS_PARAMS { typedef void (MLASCALL MLAS_CONV_SYM_DEPTHWISE_ROUTINE_KERNELSIZE)( - uint8_t const* const* InputIndirection, + void const* const* InputIndirection, int8_t const* Filter, size_t Channels, - uint8_t* Output, + void* Output, size_t OutputCount, MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, - unsigned KernelFlags + unsigned KernelFlags, + bool InputIsSigned ); // diff --git a/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp b/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp index ce53eb3cd4..ce7f30a1ad 100644 --- a/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp +++ b/onnxruntime/core/mlas/lib/qdwconv_kernelsize.cpp @@ -45,11 +45,9 @@ Abstract: #if defined(MLAS_TARGET_ARM64) -extern "C" { - +static void -MLASCALL -MlasConvSymDepthwiseKernelSize25Arm( +MlasConvSymDepthwiseKernelSize25ArmU8S8( uint8_t const* const* InputIndirection, int8_t const* Filter, size_t Channels, @@ -330,6 +328,366 @@ MlasConvSymDepthwiseKernelSize25Arm( } } +void +MLASCALL +MlasConvSymDepthwiseKernelSize25ArmS8S8( + int8_t const* const* InputIndirection, + int8_t const* Filter, + size_t Channels, + int8_t* Output, + size_t OutputCount, + MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, + unsigned KernelFlags + ) +{ + const int16x8_t voutput_zero_point = vld1q_dup_s16((int16_t const*)&PostProcessParams->OutputZeroPoint); + float32x4_t vscale_0123, vscale_4567, vscale_89AB, vscale_CDEF; + const bool is_per_channel = ((KernelFlags & MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE) != 0); + // Init them anyway due to some compiler will generate uninitialized warnings. + vscale_0123 = vscale_4567 = vscale_89AB = vscale_CDEF = vld1q_dup_f32(PostProcessParams->Scale); + while (OutputCount-- > 0) { + const int8_t* i00 = InputIndirection[0]; + const int8_t* i01 = InputIndirection[1]; + const int8_t* i02 = InputIndirection[2]; + const int8_t* i03 = InputIndirection[3]; + const int8_t* i04 = InputIndirection[4]; + const int8_t* i05 = InputIndirection[5]; + const int8_t* i06 = InputIndirection[6]; + const int8_t* i07 = InputIndirection[7]; + const int8_t* i08 = InputIndirection[8]; + const int8_t* i09 = InputIndirection[9]; + + const int8_t* i10 = InputIndirection[10]; + const int8_t* i11 = InputIndirection[11]; + const int8_t* i12 = InputIndirection[12]; + const int8_t* i13 = InputIndirection[13]; + const int8_t* i14 = InputIndirection[14]; + const int8_t* i15 = InputIndirection[15]; + const int8_t* i16 = InputIndirection[16]; + const int8_t* i17 = InputIndirection[17]; + const int8_t* i18 = InputIndirection[18]; + const int8_t* i19 = InputIndirection[19]; + + const int8_t* i20 = InputIndirection[20]; + const int8_t* i21 = InputIndirection[21]; + const int8_t* i22 = InputIndirection[22]; + const int8_t* i23 = InputIndirection[23]; + const int8_t* i24 = InputIndirection[24]; + + InputIndirection += 25; + int32_t const* bias = PostProcessParams->Bias; + float const* scale = PostProcessParams->Scale; + for (size_t c = 0; c < Channels; c += 16) { + int8_t const* w = Filter + c; + int32x4_t vacc_0123 = vld1q_s32(bias); bias += 4; + int32x4_t vacc_4567 = vld1q_s32(bias); bias += 4; + int32x4_t vacc_89AB = vld1q_s32(bias); bias += 4; + int32x4_t vacc_CDEF = vld1q_s32(bias); bias += 4; + + // kernel pixel 0, 1 + const int8x16_t vi00 = vld1q_s8(i00); i00 += 16; + const int8x16_t vk00 = vld1q_s8(w); w += Channels; + int16x8_t vprod_01234567 = vmull_s8(vget_low_s8(vi00), vget_low_s8(vk00)); + int16x8_t vprod_89ABCDEF = vmull_s8(vget_high_s8(vi00), vget_high_s8(vk00)); + + const int8x16_t vi01 = vld1q_s8(i01); i01 += 16; + const int8x16_t vk01 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi01), vget_low_s8(vk01)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi01), vget_high_s8(vk01)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 2, 3 + const int8x16_t vi02 = vld1q_s8(i02); i02 += 16; + const int8x16_t vk02 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi02), vget_low_s8(vk02)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi02), vget_high_s8(vk02)); + + const int8x16_t vi03 = vld1q_s8(i03); i03 += 16; + const int8x16_t vk03 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi03), vget_low_s8(vk03)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi03), vget_high_s8(vk03)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 4, 5 + const int8x16_t vi04 = vld1q_s8(i04); i04 += 16; + const int8x16_t vk04 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi04), vget_low_s8(vk04)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi04), vget_high_s8(vk04)); + + const int8x16_t vi05 = vld1q_s8(i05); i05 += 16; + const int8x16_t vk05 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi05), vget_low_s8(vk05)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi05), vget_high_s8(vk05)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 6, 7 + const int8x16_t vi06 = vld1q_s8(i06); i06 += 16; + const int8x16_t vk06 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi06), vget_low_s8(vk06)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi06), vget_high_s8(vk06)); + + const int8x16_t vi07 = vld1q_s8(i07); i07 += 16; + const int8x16_t vk07 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi07), vget_low_s8(vk07)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi07), vget_high_s8(vk07)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 8, 9 + const int8x16_t vi08 = vld1q_s8(i08); i08 += 16; + const int8x16_t vk08 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi08), vget_low_s8(vk08)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi08), vget_high_s8(vk08)); + + const int8x16_t vi09 = vld1q_s8(i09); i09 += 16; + const int8x16_t vk09 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi09), vget_low_s8(vk09)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi09), vget_high_s8(vk09)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 10, 11 + const int8x16_t vi10 = vld1q_s8(i10); i10 += 16; + const int8x16_t vk10 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi10), vget_low_s8(vk10)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi10), vget_high_s8(vk10)); + + const int8x16_t vi11 = vld1q_s8(i11); i11 += 16; + const int8x16_t vk11 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi11), vget_low_s8(vk11)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi11), vget_high_s8(vk11)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 12, 13 + const int8x16_t vi12 = vld1q_s8(i12); i12 += 16; + const int8x16_t vk12 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi12), vget_low_s8(vk12)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi12), vget_high_s8(vk12)); + + const int8x16_t vi13 = vld1q_s8(i13); i13 += 16; + const int8x16_t vk13 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi13), vget_low_s8(vk13)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi13), vget_high_s8(vk13)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 14, 15 + const int8x16_t vi14 = vld1q_s8(i14); i14 += 16; + const int8x16_t vk14 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi14), vget_low_s8(vk14)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi14), vget_high_s8(vk14)); + + const int8x16_t vi15 = vld1q_s8(i15); i15 += 16; + const int8x16_t vk15 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi15), vget_low_s8(vk15)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi15), vget_high_s8(vk15)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 16, 17 + const int8x16_t vi16 = vld1q_s8(i16); i16 += 16; + const int8x16_t vk16 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi16), vget_low_s8(vk16)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi16), vget_high_s8(vk16)); + + const int8x16_t vi17 = vld1q_s8(i17); i17 += 16; + const int8x16_t vk17 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi17), vget_low_s8(vk17)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi17), vget_high_s8(vk17)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 18, 19 + const int8x16_t vi18 = vld1q_s8(i18); i18 += 16; + const int8x16_t vk18 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi18), vget_low_s8(vk18)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi18), vget_high_s8(vk18)); + + const int8x16_t vi19 = vld1q_s8(i19); i19 += 16; + const int8x16_t vk19 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi19), vget_low_s8(vk19)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi19), vget_high_s8(vk19)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 20, 21 + const int8x16_t vi20 = vld1q_s8(i20); i20 += 16; + const int8x16_t vk20 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi20), vget_low_s8(vk20)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi20), vget_high_s8(vk20)); + + const int8x16_t vi21 = vld1q_s8(i21); i21 += 16; + const int8x16_t vk21 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi21), vget_low_s8(vk21)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi21), vget_high_s8(vk21)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 22, 23 + const int8x16_t vi22 = vld1q_s8(i22); i22 += 16; + const int8x16_t vk22 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmull_s8(vget_low_s8(vi22), vget_low_s8(vk22)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi22), vget_high_s8(vk22)); + + const int8x16_t vi23 = vld1q_s8(i23); i23 += 16; + const int8x16_t vk23 = vld1q_s8(w); w += Channels; + vprod_01234567 = vmlal_s8(vprod_01234567, vget_low_s8(vi23), vget_low_s8(vk23)); + vprod_89ABCDEF = vmlal_s8(vprod_89ABCDEF, vget_high_s8(vi23), vget_high_s8(vk23)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + // kernel pixel 24 + const int8x16_t vi24 = vld1q_s8(i24); i24 += 16; + const int8x16_t vk24 = vld1q_s8(w); // w += Channels; no need to add + vprod_01234567 = vmull_s8(vget_low_s8(vi24), vget_low_s8(vk24)); + vprod_89ABCDEF = vmull_s8(vget_high_s8(vi24), vget_high_s8(vk24)); + + vacc_0123 = vaddw_s16(vacc_0123, vget_low_s16(vprod_01234567)); + vacc_4567 = vaddw_s16(vacc_4567, vget_high_s16(vprod_01234567)); + vacc_89AB = vaddw_s16(vacc_89AB, vget_low_s16(vprod_89ABCDEF)); + vacc_CDEF = vaddw_s16(vacc_CDEF, vget_high_s16(vprod_89ABCDEF)); + + if (is_per_channel) { + vscale_0123 = vld1q_f32(scale); scale += 4; + vscale_4567 = vld1q_f32(scale); scale += 4; + vscale_89AB = vld1q_f32(scale); scale += 4; + vscale_CDEF = vld1q_f32(scale); scale += 4; + } + + // requantize + vacc_0123 = vcvtnq_s32_f32(vmulq_f32(vcvtq_f32_s32(vacc_0123), vscale_0123)); + vacc_4567 = vcvtnq_s32_f32(vmulq_f32(vcvtq_f32_s32(vacc_4567), vscale_4567)); + vacc_89AB = vcvtnq_s32_f32(vmulq_f32(vcvtq_f32_s32(vacc_89AB), vscale_89AB)); + vacc_CDEF = vcvtnq_s32_f32(vmulq_f32(vcvtq_f32_s32(vacc_CDEF), vscale_CDEF)); + + const int16x8_t vacc_01234567 = vqaddq_s16(vqmovn_high_s32(vqmovn_s32(vacc_0123), vacc_4567), voutput_zero_point); + const int16x8_t vacc_89ABCDEF = vqaddq_s16(vqmovn_high_s32(vqmovn_s32(vacc_89AB), vacc_CDEF), voutput_zero_point); + int8x16_t vout = vqmovn_high_s16(vqmovn_s16(vacc_01234567), vacc_89ABCDEF); + + vst1q_s8(Output, vout); + Output += 16; + } + } +} + +extern "C" { + +void +MLASCALL +MlasConvSymDepthwiseKernelSize25Arm( + void const* const* InputIndirection, + int8_t const* Filter, + size_t Channels, + void* Output, + size_t OutputCount, + MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, + unsigned KernelFlags, + bool IsInputSigned + ) +{ + if (IsInputSigned) { + MlasConvSymDepthwiseKernelSize25ArmS8S8( + (int8_t const* const*)InputIndirection, Filter, Channels, (int8_t*)Output, OutputCount, + PostProcessParams, KernelFlags + ); + } else { + MlasConvSymDepthwiseKernelSize25ArmU8S8( + (uint8_t const* const*)InputIndirection, Filter, Channels, (uint8_t*)Output, OutputCount, + PostProcessParams, KernelFlags + ); + } +} + +void +MLASCALL +MlasConvSymDepthwiseKernelSize9Arm64U8S8( + uint8_t const* const* InputIndirection, + int8_t const* Filter, + size_t Channels, + uint8_t* Output, + size_t OutputCount, + MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, + unsigned KernelFlags + ); + +void +MLASCALL +MlasConvSymDepthwiseKernelSize9Arm64S8S8( + int8_t const* const* InputIndirection, + int8_t const* Filter, + size_t Channels, + int8_t* Output, + size_t OutputCount, + MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, + unsigned KernelFlags + ); + +void +MLASCALL +MlasConvSymDepthwiseKernelSize9Arm64( + void const* const* InputIndirection, + int8_t const* Filter, + size_t Channels, + void* Output, + size_t OutputCount, + MLAS_CONV_SYM_POST_PROCESS_PARAMS const* PostProcessParams, + unsigned KernelFlags, + bool IsInputSigned + ) +{ + if (IsInputSigned) { + MlasConvSymDepthwiseKernelSize9Arm64S8S8( + (int8_t const* const*)InputIndirection, Filter, Channels, (int8_t*)Output, OutputCount, + PostProcessParams, KernelFlags + ); + } else { + MlasConvSymDepthwiseKernelSize9Arm64U8S8( + (uint8_t const* const*)InputIndirection, Filter, Channels, (uint8_t*)Output, OutputCount, + PostProcessParams, KernelFlags + ); + } +} + } #endif diff --git a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc index f718f80993..178e13aff3 100644 --- a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc @@ -885,11 +885,12 @@ TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_NoBias) { } } -TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize) { +template +void TestQLinearConv2dDepthwiseKernelsize() { for (int64_t channels : std::initializer_list{16, 64}) { for (const auto& kd : std::initializer_list>{{3LL, 3LL}, {1LL, 9LL}, {5LL, 5LL}}) { for (int with_bias : std::initializer_list{0, 1}) { - QLinearConvOpTester test; + QLinearConvOpTester test; test.GenerateRandomInput({1, channels, 17, 17}, .03f, 12); test.GenerateRandomWeights({channels, 1, kd.first, kd.second}, .10f, 0); if (with_bias) { @@ -904,11 +905,16 @@ TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize) { } } -TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize_PerChannel) { +TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize) { + TestQLinearConv2dDepthwiseKernelsize(); +} + +template +void TestQLinearConv2dDepthwiseKernelsizePerChannel() { for (int64_t channels : std::initializer_list{32, 96}) { for (const auto& kd : std::initializer_list>{{3LL, 3LL}, {5LL, 5LL}, {25LL, 1LL}}) { for (int with_bias : std::initializer_list{0, 1}) { - QLinearConvOpTester test; + QLinearConvOpTester test; test.GenerateRandomInput({1, channels, 37, 37}, .03f, 12); test.GenerateRandomWeights({channels, 1, kd.first, kd.second}, .10f, 0); std::vector weight_scales; @@ -928,6 +934,10 @@ TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize_PerChannel) { } } +TEST(QLinearConvTest, Conv2D_U8S8_Depthwise_Kernelsize_PerChannel) { + TestQLinearConv2dDepthwiseKernelsizePerChannel(); +} + TEST(QLinearConvTest, Conv2D_U8U8_Depthwise) { for (int64_t channels : std::initializer_list{3, 8, 13, 24, 31, 64}) { QLinearConvOpTester test; @@ -1394,6 +1404,14 @@ TEST(QLinearConvTest, Conv2D_S8S8_Requantize_Bias_PerChannel) { } } +TEST(QLinearConvTest, Conv2D_S8S8_Depthwise_Kernelsize) { + TestQLinearConv2dDepthwiseKernelsize(); +} + +TEST(QLinearConvTest, Conv2D_S8S8_Depthwise_Kernelsize_PerChannel) { + TestQLinearConv2dDepthwiseKernelsizePerChannel(); +} + #ifndef ENABLE_TRAINING // Prepacking is enabled only on non-training builds TEST(QLinearConvTest, SharedPrepackedWeights) { QuantizedTensor X({0.45246148109436035f, 0.15498268604278564f, 0.11199361085891724f, -0.39421093463897705f, From d0b08af37a07cc6ad270e4af0a89d6047ad1fe4c Mon Sep 17 00:00:00 2001 From: George Nash Date: Fri, 10 Dec 2021 21:50:13 -0800 Subject: [PATCH 028/113] Implementation of QAttention for the DNNL execution provider (#10004) * Add QAttention to DNNL EP Add QAttention to DNNL EP (limited support and disable for gpu) update ONEDNN version to 2.4.4 bug fix in getcapability add memory debug print Signed-off-by: Wang * Address Code Review + MatMulInteger Fix clean up code and add comments fix matmulinteger and add fusion rule to enable initialized vector weight zero points of 0s update DNNL_TAG to v2.5 Signed-off-by: Wang * Linux Compile Fix + rollback ONEDNN to 2.4.4 Signed-off-by: Zhaoyang Wang * Fix QAttention Debug build Signed-off-by: Wang * Fix QAttention build if USE_DNNL not specified Signed-off-by: George Nash Co-authored-by: Wang Co-authored-by: MTC <63478620+jeyblu@users.noreply.github.com> --- cmake/external/dnnl.cmake | 2 +- .../providers/dnnl/dnnl_execution_provider.cc | 6 + .../providers/dnnl/dnnl_node_capability.cc | 143 +++++- .../providers/dnnl/dnnl_node_capability.h | 15 +- .../core/providers/dnnl/dnnl_op_manager.cc | 1 + .../subgraph/dnnl_dynamicquantizelinear.cc | 11 + .../dnnl/subgraph/dnnl_qattention.cc | 430 ++++++++++++++++++ .../providers/dnnl/subgraph/dnnl_qattention.h | 39 ++ .../dnnl/subgraph/dnnl_subgraph_primitive.cc | 127 +++++- .../dnnl/subgraph/dnnl_subgraph_primitive.h | 9 +- .../subgraph/dnnl_subgraph_transformer.cc | 61 +++ .../dnnl/subgraph/dnnl_subgraph_transformer.h | 1 + .../contrib_ops/quantize_attention_op_test.cc | 162 ++++++- 13 files changed, 975 insertions(+), 32 deletions(-) create mode 100644 onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc create mode 100644 onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.h diff --git a/cmake/external/dnnl.cmake b/cmake/external/dnnl.cmake index 6a51a3d5dd..953bcfaee7 100644 --- a/cmake/external/dnnl.cmake +++ b/cmake/external/dnnl.cmake @@ -2,7 +2,7 @@ include (ExternalProject) set(DNNL_URL https://github.com/oneapi-src/onednn) # If DNNL_TAG is updated, check if MKLML_VERSION and platform.cmake.patch need to be updated. -set(DNNL_TAG v2.3) +set(DNNL_TAG v2.4.4) if(WIN32) set(DNNL_SHARED_LIB dnnl.dll) diff --git a/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc b/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc index f2574cbb9e..c767d27cd8 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc @@ -200,6 +200,9 @@ std::vector> DNNLExecutionProvider::GetCapabi for (const auto* input : node->InputDefs()) { // if the node input was not produced by this subgraph, add it to the subgraph inputs. + if (!input->Exists()) { + continue; + } if (node_outputs.count(input) == 0) { if (subgraph_inputs.count(input) == 0) { subgraph_inputs.insert(input); @@ -210,6 +213,9 @@ std::vector> DNNLExecutionProvider::GetCapabi const auto& output_defs = node->OutputDefs(); for (const auto* output_def : output_defs) { + if (!output_def->Exists()) { + continue; + } node_outputs.insert(output_def); // if output is overall graph output we need to produce it. if (graph_outputs.count(output_def) != 0) { diff --git a/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc b/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc index 16d65b7e2b..d4c72840dd 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc @@ -282,7 +282,7 @@ bool DnnlMatMulNodeCapability::IsDimensionSupported(const Node* node) const { bool DnnlMatMulIntegerNodeCapability::Supported(const Node* node, const GraphViewer& graph_viewer) const { ORT_UNUSED_PARAMETER(graph_viewer); if (!IsTypeSupported(node)) return false; - if (!IsDimensionSupported(node)) return false; + if (!IsDimensionSupported(node,graph_viewer)) return false; // if weight is u8, onednn doesn't support auto node_inputs = node->InputDefs(); @@ -297,14 +297,77 @@ bool DnnlMatMulIntegerNodeCapability::Supported(const Node* node, const GraphVie return true; } -bool DnnlMatMulIntegerNodeCapability::IsDimensionSupported(const Node* node) const { +//assume weight zp is s8 since u8 will get rejected and weight zp matches weight data type +bool DnnlMatMulIntegerNodeCapability::IsWeightZeroPointConstantZero(const NodeArg* node_arg, const GraphViewer& graph_viewer) const { + const ONNX_NAMESPACE::TensorProto* tensor_proto = nullptr; + // if node_arg is not initializer + if (!graph_viewer.GetInitializedTensor(node_arg->Name(), tensor_proto)) { + return false; + } + // if node_arg is not initializer + if (tensor_proto == nullptr) { + return false; + } + + const auto& dims = tensor_proto->dims(); + auto dim_size = tensor_proto->dims_size(); + int num_elements = 1; + for (int i = 0; i < dim_size; i++) { + num_elements *= int(dims[i]); + } + + //check if weight zp is all zeros + bool all_zero = true; + std::vector unpacked_tensor; + //delibrately make a vector of 1s instead of 0s + unpacked_tensor.resize(num_elements, 1); + ORT_THROW_IF_ERROR(onnxruntime::utils::UnpackTensor(*tensor_proto, tensor_proto->has_raw_data() ? tensor_proto->raw_data().data() : nullptr, tensor_proto->has_raw_data() ? tensor_proto->raw_data().size() : 0, reinterpret_cast(unpacked_tensor.data()), num_elements)); + + //check if the initializer zero point contains all zeros + for (const auto& val : unpacked_tensor) { + if (val != 0) { + all_zero = false; + break; + } + } + + //if initializer zero point is not all zeros, reject it + //TODO: if initializer zero point is a vector of a unique value, we can still compute it + if (!all_zero) { + return false; + } + return true; +} + +bool DnnlMatMulIntegerNodeCapability::IsDimensionSupported(const Node* node, const GraphViewer& graph_viewer) const { auto node_inputs = node->InputDefs(); - //if shape nullptr, attempt to run it (no gaurantee) + //do not support other than single zero point (not per column) + if (node_inputs.size() > 2) { + if (node_inputs.size() >= 3 && node_inputs[2] && node_inputs[2]->Exists()) { + if (node_inputs[2]->Shape() != nullptr && node_inputs[2]->Shape()->dim_size() >= 1) { + return false; + } + } + + if (node_inputs.size() >= 4 && node_inputs[3] && node_inputs[3]->Exists()) { + if (node_inputs[3]->Shape() != nullptr) { + auto dim_size = node_inputs[3]->Shape()->dim_size(); + if (dim_size >= 1) { + // non scalar zero point, but if the weight zp is constant of 0s, still accept it and let the fusion rule remove the zero point + if (!IsWeightZeroPointConstantZero(node_inputs[3], graph_viewer)) { + return false; + } + } + } + } + } + + //if shape nullptr, not enough information to reject it. attempt to run it (no gaurantee) if (node_inputs[0]->Shape() == nullptr || node_inputs[1]->Shape() == nullptr) { return true; } - + // if matmul src and weight have shape but have dim value of 0, reject it if ((node_inputs[0]->Shape() != nullptr && node_inputs[0]->Shape()->dim_size() >= 2) && (node_inputs[1]->Shape() != nullptr && node_inputs[1]->Shape()->dim_size() >= 2)) { for (const auto& dim : node_inputs[0]->Shape()->dim()) { @@ -321,21 +384,6 @@ bool DnnlMatMulIntegerNodeCapability::IsDimensionSupported(const Node* node) con return false; } - //do not support other than single zero point (not per column) - if (node_inputs.size() > 2) { - if (node_inputs.size() >= 3 && node_inputs[2] && node_inputs[2]->Exists()) { - if (node_inputs[2]->Shape() != nullptr && node_inputs[2]->Shape()->dim_size() >= 1) { - return false; - } - } - - if (node_inputs.size() >= 4 && node_inputs[3] && node_inputs[3]->Exists()) { - if (node_inputs[3]->Shape() != nullptr && node_inputs[3]->Shape()->dim_size() >= 1) { - return false; - } - } - } - return true; } @@ -777,4 +825,61 @@ bool DnnlErfNodeCapability::IsErfPartOfGelu(const Node* node, const GraphViewer& } +// DnnlQAttentionNodeCapability class +//------------------------------------- +bool DnnlQAttentionNodeCapability::Supported(const Node* node, const GraphViewer& graph_viewer) const { + ORT_UNUSED_PARAMETER(graph_viewer); + if (!IsTypeSupported(node)) return false; + if (!IsDimensionSupported(node)) return false; + auto node_inputs = node->InputDefs(); + auto node_outputs = node->OutputDefs(); + //if have 9th input (past state) and 9th input Exists + if (node_inputs.size() == 9 && node_inputs[8]->Exists()) { + return false; + } + //if have 2nd output (present state) and 2nd output Exists, return false + if (node_outputs.size() == 2 && node_outputs[1]->Exists()) { + return false; + } + //qattention doesn't support unidriectional + const NodeAttributes& attributes = node->GetAttributes(); + auto attr = attributes.find("unidirectional"); + if (attr != attributes.end()) { + if (attr->second().i() == 1) { + return false; + } + } + //only support scalar input scale and weight scale + if(!IsScalar(node_inputs[3]) || !IsScalar(node_inputs[4])){ + return false; + } + //only support 2D raw mask + if(node_inputs.size() >= 6 && node_inputs[5]->Exists() && node_inputs[5]->Shape() != nullptr && node_inputs[5]->Shape()->dim_size() != 2){ + return false; + } + //only support scalar input zero point + if(node_inputs.size() >= 7 && node_inputs[6]->Exists() && !IsScalar(node_inputs[6])){ + return false; + } + //only support scalar weight zero point + if(node_inputs.size() >= 8 && node_inputs[7]->Exists() && !IsScalar(node_inputs[7])){ + return false; + } + + //qattention is disabled on gpu due to the following onednn bugs + //1. flipped zero points in int8 matmul + //2. unsupported runtime input source0 scaling in binary + //3. f32 matmul on submemory gives wrong result + if (dnnl_engine_get_count(dnnl_engine_kind_t::dnnl_gpu)) { + return false; + } + return true; +} + +bool DnnlQAttentionNodeCapability::IsDimensionSupported(const Node* node) const { + ORT_UNUSED_PARAMETER(node); + return true; +} + + } // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/dnnl_node_capability.h b/onnxruntime/core/providers/dnnl/dnnl_node_capability.h index cc8e06e6c6..0e3a3ef131 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_node_capability.h +++ b/onnxruntime/core/providers/dnnl/dnnl_node_capability.h @@ -199,7 +199,8 @@ class DnnlMatMulIntegerNodeCapability : public DnnlDefaultNodeCapability { bool Supported(const Node* node, const GraphViewer& graph_viewer) const override; private: - bool IsDimensionSupported(const Node* node) const; + bool IsDimensionSupported(const Node* node, const GraphViewer& graph_viewer) const; + bool IsWeightZeroPointConstantZero(const NodeArg* node, const GraphViewer& graph_viewer) const; }; /** @@ -329,4 +330,16 @@ class DnnlErfNodeCapability : public DnnlDefaultNodeCapability { DnnlBinaryNodeCapability _binary; }; + +class DnnlQAttentionNodeCapability : public DnnlDefaultNodeCapability { + public: + DnnlQAttentionNodeCapability() : DnnlDefaultNodeCapability({type_float32, + type_int8, + type_uint8}) {} + bool Supported(const Node* node, const GraphViewer& graph_viewer) const override; + + private: + bool IsDimensionSupported(const Node* node) const; +}; + } // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc b/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc index 636ddb1959..fa58933a47 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc @@ -30,6 +30,7 @@ DnnlOpManager::DnnlOpManager() { dnnl_ops_map_.emplace(std::make_pair("MaxPool", std::unique_ptr(new DnnlPoolNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Mul", std::unique_ptr(new DnnlBinaryNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Pow", std::unique_ptr(new DnnlPowNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("QAttention", std::unique_ptr(new DnnlQAttentionNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("ReduceMean", std::unique_ptr(new DnnlReduceMeanNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Relu", std::unique_ptr(new DnnlElementwiseCapability()))); dnnl_ops_map_.emplace(std::make_pair("Reshape", std::unique_ptr(new DnnlReshapeNodeCapability()))); diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_dynamicquantizelinear.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_dynamicquantizelinear.cc index 3eafae3873..6527b0b36c 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_dynamicquantizelinear.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_dynamicquantizelinear.cc @@ -77,7 +77,9 @@ void DnnlDynamicQuantizeLinear::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlN max_reduction_args[DNNL_ARG_ATTR_MULTIPLE_POST_OP(1) | DNNL_ARG_SRC_1] = min_reduction_dst_mem; //compute min first since max_reduction needs min dst as post op arg + // compute x min sp.AddPrimitive(min_reduction_prim, min_reduction_args); + // compute y scale f32 sp.AddPrimitive(max_reduction_prim, max_reduction_args); @@ -100,6 +102,8 @@ void DnnlDynamicQuantizeLinear::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlN auto y_zero_point_dst_mem = dnnl::memory(y_zero_point_pd.dst_desc(), eng); std::unordered_map y_zero_point_args = {{DNNL_ARG_SRC_0, min_reduction_dst_mem}, {DNNL_ARG_SRC_1, y_scale_mem}, {DNNL_ARG_DST, y_zero_point_dst_mem}}; + //y zero point f32 + //np.clip(round((0 - x_min) / Y_Scale), 0, 255) sp.AddPrimitive(y_zero_point_prim, y_zero_point_args); @@ -121,6 +125,9 @@ void DnnlDynamicQuantizeLinear::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlN auto y_mem = dnnl::memory(y_pd.dst_desc(), eng); std::unordered_map y_args = {{DNNL_ARG_SRC_0, x_memory}, {DNNL_ARG_SRC_1, y_scale_mem}, {DNNL_ARG_DST, y_mem}}; y_args[DNNL_ARG_ATTR_MULTIPLE_POST_OP(1) | DNNL_ARG_SRC_1] = y_zero_point_dst_mem; + + // x/y -> round() -> + y_zp -> clip 0,255 + // quantized output tensor f32 sp.AddPrimitive(y_prim, y_args); @@ -128,6 +135,8 @@ void DnnlDynamicQuantizeLinear::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlN sp.SetMemory(node.Output(OUT_Y_SCALE), y_scale_mem, false, true); //data type change for y_zp and set memory + //data type change is needed for onnxruntime spec + //zp for onednn is currently in s32, any downstream node might need to convert from u8 to s32 auto y_zero_point_dst_md_uint8 = ChangeMemoryDescDataType(y_zero_point_dst_mem.get_desc(), dnnl::memory::data_type::u8); auto y_zero_point_dst_mem_uint8 = dnnl::memory(y_zero_point_dst_md_uint8, eng); sp.AddPrimitive(dnnl::reorder(y_zero_point_dst_mem, y_zero_point_dst_mem_uint8), {{DNNL_ARG_FROM, y_zero_point_dst_mem}, {DNNL_ARG_TO, y_zero_point_dst_mem_uint8}}); @@ -171,6 +180,8 @@ void DnnlDynamicQuantizeLinear::WriteZeroToMem(dnnl::memory& mem) { dnnl::stream s{mem.get_engine()}; //mem now contains all zero dnnl::reorder(cpu_memory, mem).execute(s, cpu_memory, mem); + //wait for reorder to complete + s.wait(); } } diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc new file mode 100644 index 0000000000..d3f2361a0b --- /dev/null +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc @@ -0,0 +1,430 @@ +// Copyright(C) 2021 Intel Corporation +// Licensed under the MIT License + +#include "dnnl_qattention.h" +#include "dnnl_subgraph.h" +#include "dnnl_subgraph_primitive.h" +#include + +namespace onnxruntime { +namespace ort_dnnl { + +DnnlQAttention::DnnlQAttention() {} + +//compute a total scale memory from input and weight scale +dnnl::memory DnnlQAttention::ComputeTotalScale(DnnlSubgraphPrimitive& sp, DnnlNode& node) { + auto eng = sp.GetEngine(); + bool has_input_scale = node.Input(INPUT_SCALE).Exists(); + bool has_weights_scale = node.Input(WEIGHTS_SCALE).Exists(); + auto input_scale_mem = has_input_scale ? sp.GetMemory(node.Input(INPUT_SCALE)) : dnnl::memory(); + auto weights_scale_mem = has_weights_scale ? sp.GetMemory(node.Input(WEIGHTS_SCALE)) : dnnl::memory(); + + if (input_scale_mem && weights_scale_mem) { + //force descriptor to be 1 dim, will fail if product of dims not equal 1 + auto src_0_md = input_scale_mem.get_desc().reshape({1}); + auto src_1_md = weights_scale_mem.get_desc().reshape({1}); + auto dst_md = src_1_md; + auto binary_d = dnnl::binary::desc(dnnl::algorithm::binary_mul, src_0_md, src_1_md, dst_md); + auto binary_pd = dnnl::binary::primitive_desc(binary_d, eng); + + auto binary_src0_mem = sp.GetMemoryAndReshape(node.Input(INPUT_SCALE), binary_pd.src0_desc(), eng); + auto binary_src1_mem = sp.GetMemoryAndReshape(node.Input(WEIGHTS_SCALE), binary_pd.src1_desc(), eng); + auto binary_dst_mem = dnnl::memory(binary_pd.dst_desc(), eng); + auto binary_prim = dnnl::binary(binary_pd); + sp.AddPrimitive(binary_prim, {{DNNL_ARG_SRC_0, binary_src0_mem}, + {DNNL_ARG_SRC_1, binary_src1_mem}, + {DNNL_ARG_DST, binary_dst_mem}}); + return binary_dst_mem; + } else if (input_scale_mem) { + return sp.GetMemoryAndReshape(node.Input(INPUT_SCALE), input_scale_mem.get_desc().reshape({1}), eng); + } else if (weights_scale_mem) { + return sp.GetMemoryAndReshape(node.Input(WEIGHTS_SCALE), weights_scale_mem.get_desc().reshape({1}), eng); + } else { + return dnnl::memory(); + } +} + +/* +input_tensor weight_tensor + + \ / + + \ / + + \ / + + \ / + + matmulinteger + with input and weight zero point, + input and weight scale and bias + | + + | + + | QKV + + | + + slice + + / | \ + + / | \ + + / | \ + + / | \ + + |Q |K |V + + | | | + + reshape reshape reshape + + | | | + + permute permute permute + + | | | + + | transpose | + + \ | | + + \ | | + + \ | | + + \ | | + + matmul | + + | | + + | | + + sqrt(head_dim) | | + + \ | | + + \ | | + + \ | | + + div | + + | | + + (mask) | + + | / + + softmax / + + | / + + matmul + + | + + permute + + | + + reshape + + | + + output +*/ +/* +limitations + scalar input zp + scalar weight zp + scalar input scale + scalar weight scale + 2D raw mask + no past and present input +*/ +void DnnlQAttention::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node) { + auto eng = sp.GetEngine(); + + dnnl::memory QKV_mem; + { + //prepare zero points for int8 matmul primitive + dnnl::primitive_attr matmul_attr; + bool has_input_zero_point = node.Input(INPUT_ZP).Exists(); + bool has_weights_zero_point = node.Input(WEIGHTS_ZP).Exists(); + + // (input-input_zero_point)*(weight-weight_zero_point) + { + //set input zp + if (has_input_zero_point) { + matmul_attr.set_zero_points(DNNL_ARG_SRC, 0, {DNNL_RUNTIME_S32_VAL}); + } + + //set weight zp + if (has_weights_zero_point) { + matmul_attr.set_zero_points(DNNL_ARG_WEIGHTS, 0, {DNNL_RUNTIME_S32_VAL}); + } + } + + dnnl::memory::desc input_md; + dnnl::memory::desc weights_md; + + { + auto input_md_ori = sp.GetMemory(node.Input(INPUT)).get_desc(); + auto weights_md_ori = sp.GetMemory(node.Input(WEIGHTS)).get_desc(); + + auto weights_dims = weights_md_ori.dims(); + weights_dims.insert(weights_dims.begin(), 1); + + input_md = dnnl::memory::desc(input_md_ori.dims(), input_md_ori.data_type(), dnnl::memory::format_tag::any); + weights_md = dnnl::memory::desc(weights_dims, weights_md_ori.data_type(), dnnl::memory::format_tag::any); + } + + dnnl::memory::desc QKV_md; + { + //the output of int8 matmul is always 3 dims and consists of Q,K,V values + auto QKV_dims = input_md.dims(); + QKV_dims[2] = weights_md.dims()[2]; + //use format any for optimization + QKV_md = dnnl::memory::desc(QKV_dims, dnnl::memory::data_type::f32, dnnl::memory::format_tag::any); + } + + auto matmul_d = dnnl::matmul::desc(input_md, weights_md, QKV_md); + auto matmul_pd = dnnl::matmul::primitive_desc(matmul_d, matmul_attr, eng); + // (input-input_zero_point)*(weight-weight_zero_point) + auto matmul_prim = dnnl::matmul(matmul_pd); + + auto matmul_src_mem = sp.GetMemoryAndReshape(node.Input(INPUT), matmul_pd.src_desc(), eng); + auto matmul_weights_mem = sp.GetMemoryAndReshape(node.Input(WEIGHTS), matmul_pd.weights_desc(), eng); + QKV_mem = dnnl::memory(matmul_pd.dst_desc(), eng); + + std::unordered_map mem_map({{DNNL_ARG_SRC, matmul_src_mem}, + {DNNL_ARG_WEIGHTS, matmul_weights_mem}, + {DNNL_ARG_DST, QKV_mem}}); + + if (has_input_zero_point) { + auto zp_mem_desc = dnnl::memory::desc({1}, dnnl::memory::data_type::s32, {1}); + auto tensor = node.Input(INPUT_ZP); + auto zp_mem = sp.GetMemoryAndReshape(tensor, zp_mem_desc, eng); + mem_map[DNNL_ARG_ATTR_ZERO_POINTS | DNNL_ARG_SRC] = zp_mem; + } + + if (has_weights_zero_point) { + auto zp_mem_desc = dnnl::memory::desc({1}, dnnl::memory::data_type::s32, {1}); + auto tensor = node.Input(WEIGHTS_ZP); + auto zp_mem = sp.GetMemoryAndReshape(tensor, zp_mem_desc, eng); + mem_map[DNNL_ARG_ATTR_ZERO_POINTS | DNNL_ARG_WEIGHTS] = zp_mem; + } + + //(input-input_zero_point)*(weight-weight_zero_point) + sp.AddPrimitive(matmul_prim, mem_map); + } + + //in place binary add with source0 scaling + { + //compute a total scale from input scale and weight scale + //i_scale * w_scale if both exist + auto total_scale_mem = ComputeTotalScale(sp, node); + + auto bias_md = sp.GetMemory(node.Input(BIAS)).get_desc(); + bias_md = bias_md.reshape({1, 1, bias_md.dims()[0]}); + auto QKV_desc = QKV_mem.get_desc(); + + //always broadcast from bias to QKV + auto binary_d = dnnl::binary::desc(dnnl::algorithm::binary_add, QKV_desc, bias_md, QKV_desc); + + dnnl::primitive_attr binary_attr; + //scale source 0, matmul output + if (total_scale_mem) { + binary_attr.set_scales(DNNL_ARG_SRC_0, 0, {DNNL_RUNTIME_F32_VAL}); + } + + auto binary_pd = dnnl::binary::primitive_desc(binary_d, binary_attr, eng); + auto binary_prim = dnnl::binary(binary_pd); + + auto bias_mem = sp.GetMemoryAndReshape(node.Input(BIAS), binary_pd.src1_desc(), eng); + + std::unordered_map binary_mem_map({{DNNL_ARG_SRC_0, QKV_mem}, + {DNNL_ARG_SRC_1, bias_mem}, + {DNNL_ARG_DST, QKV_mem}}); + + if (total_scale_mem) { + binary_mem_map[DNNL_ARG_ATTR_INPUT_SCALES | DNNL_ARG_SRC_0] = total_scale_mem; + } + + sp.AddPrimitive(binary_prim, binary_mem_map); + } + + //parse some dim information for permute and reshape + //eg, 8,512,2034 = 8,512,(3,12,64) + auto batch_size = QKV_mem.get_desc().dims()[0]; + auto sequence_length = QKV_mem.get_desc().dims()[1]; + auto num_heads = GetNumHeads(node); + auto hidden_size = QKV_mem.get_desc().dims()[2] / 3; + auto head_size = hidden_size / num_heads; + + //slice QKV into submemories + auto Q_md = QKV_mem.get_desc().submemory_desc({batch_size, sequence_length, hidden_size}, {0, 0, 0}); + auto K_md = QKV_mem.get_desc().submemory_desc({batch_size, sequence_length, hidden_size}, {0, 0, hidden_size}); + auto V_md = QKV_mem.get_desc().submemory_desc({batch_size, sequence_length, hidden_size}, {0, 0, hidden_size * 2}); + + //split QKV last dim to num_heads, hidden_dim + Q_md = Q_md.reshape({batch_size, sequence_length, num_heads, head_size}); + K_md = K_md.reshape({batch_size, sequence_length, num_heads, head_size}); + V_md = V_md.reshape({batch_size, sequence_length, num_heads, head_size}); + + //permute K and QV + Q_md = Q_md.permute_axes({0, 2, 1, 3}); + //K is different as it needs to be tranposed + K_md = K_md.permute_axes({0, 3, 1, 2}); + V_md = V_md.permute_axes({0, 2, 1, 3}); + + bool has_mask_index = node.Input(MASK_INDEX).Exists(); + auto mask_index_mem = dnnl::memory(); // mask_index will reside in this memory + + //prepare mask for calculating attention probs + //mask size has to be 2D batch_size, max_sequence_length + //if tensor has values 50,60,70,80 and the mask is 1,1,0,0 + //mask will be converted to 0,0,-10000,-10000 (10000*x-10000) + //the resulted "masked" tensor will be 50,60,-9930,-9920 (softmax will then evalute large magnitude negative number to be 0) + //need a reorder of data type from s32 to f32 to let mask to have the same data type as QK result + if (has_mask_index) { + auto mask_index_mem_desc = sp.GetMemory(node.Input(MASK_INDEX)).get_desc(); + + auto linear_d = dnnl::eltwise_forward::desc(dnnl::prop_kind::forward_inference, dnnl::algorithm::eltwise_linear, mask_index_mem_desc, 10000.0f, -10000.0f); + auto linear_pd = dnnl::eltwise_forward::primitive_desc(linear_d, eng); + + auto mask_index_ori_mem = sp.GetMemoryAndReshape(node.Input(MASK_INDEX), linear_pd.src_desc(), eng); + assert(linear_pd.dst_desc().data_type() == dnnl::memory::data_type::s32); + auto mask_index_mem_unbroadcasted = dnnl::memory(linear_pd.dst_desc(), eng); + + auto linear_prim = dnnl::eltwise_forward(linear_pd); + //mask = 10000*mask-10000 + sp.AddPrimitive(linear_prim, {{DNNL_ARG_SRC, mask_index_ori_mem}, {DNNL_ARG_DST, mask_index_mem_unbroadcasted}}); + + dnnl::memory mask_index_mem_unbroadcasted_f32; + { + auto md = mask_index_mem_unbroadcasted.get_desc(); + auto dims = md.dims(); + auto strides = md.data.format_desc.blocking.strides; + dnnl::memory::dims strides_vec; + for (size_t i = 0; i < dims.size(); i++) { + strides_vec.push_back(strides[i]); + } + auto mask_index_md_unbroadcasted_f32 = dnnl::memory::desc(dims, dnnl::memory::data_type::f32, strides_vec); + mask_index_mem_unbroadcasted_f32 = dnnl::memory(mask_index_md_unbroadcasted_f32, eng); + sp.AddPrimitive(dnnl::reorder(mask_index_mem_unbroadcasted, mask_index_mem_unbroadcasted_f32), + {{DNNL_ARG_FROM, mask_index_mem_unbroadcasted}, + {DNNL_ARG_TO, mask_index_mem_unbroadcasted_f32}}); + } + + //unsqueeze the mem for broadcasting + auto mask_index_dims = mask_index_mem_unbroadcasted_f32.get_desc().dims(); + //not symetric, simply broadcasting + //eg 8,512 -> 8,1,1,512 + //eg 8,1,1,512 -> 8,12,512,512 + mask_index_dims.insert(mask_index_dims.begin() + 1, 1); + mask_index_dims.insert(mask_index_dims.begin() + 2, 1); + auto mask_index_broadcasted_md = mask_index_mem_unbroadcasted_f32.get_desc().reshape(mask_index_dims); + //set mask_index_mem + mask_index_mem = dnnl::memory(mask_index_broadcasted_md, eng, nullptr); + dnnl::stream s(eng); + mask_index_mem.set_data_handle(mask_index_mem_unbroadcasted_f32.get_data_handle(), s); + s.wait(); + } + + dnnl::memory QK_mem; + //matmul Q and K (transpose) with mask as binary post op followed by binary div (normalization) and in place softmax. + //softmax((Q * K(T) + MASK ) / sqrt(head_dim)) + { + dnnl::primitive_attr QK_attr; + { + auto scales = std::vector({float(1 / std::sqrt(head_size))}); + QK_attr.set_output_scales(0, scales); + + if (mask_index_mem) { + dnnl::post_ops add_bias; + add_bias.append_binary(dnnl::algorithm::binary_add, mask_index_mem.get_desc()); + QK_attr.set_post_ops(add_bias); + } + } + + auto QK_md = dnnl::memory::desc({batch_size, num_heads, sequence_length, sequence_length}, dnnl::memory::data_type::f32, dnnl::memory::format_tag::any); + auto QK_d = dnnl::matmul::desc(Q_md, K_md, QK_md); + auto QK_pd = dnnl::matmul::primitive_desc(QK_d, QK_attr, eng); + auto QK_prim = dnnl::matmul(QK_pd); + + QK_mem = dnnl::memory(QK_pd.dst_desc(), eng); + { + //QKV_mem is used as both input and weight but since matmul is defined on submemory, computation will be applied to correct submemory + std::unordered_map QK_mem_map({{DNNL_ARG_SRC, QKV_mem}, + {DNNL_ARG_WEIGHTS, QKV_mem}, + {DNNL_ARG_DST, QK_mem}}); + if (mask_index_mem) { + QK_mem_map[DNNL_ARG_ATTR_MULTIPLE_POST_OP(0) | DNNL_ARG_SRC_1] = mask_index_mem; + } + sp.AddPrimitive(QK_prim, QK_mem_map); + } + + //apply softmax in place to produce attention prob + { + auto softmax_desc = dnnl::softmax_forward::desc(dnnl::prop_kind::forward_inference, QK_mem.get_desc(), 3); + auto softmax_pd = dnnl::softmax_forward::primitive_desc(softmax_desc, eng); + auto softmax_prim = dnnl::softmax_forward::primitive(softmax_pd); + + //QK = softmax(QK) in place + sp.AddPrimitive(softmax_prim, {{DNNL_ARG_SRC, QK_mem}, {DNNL_ARG_DST, QK_mem}}); + } + } + + //matmul attention_probs with V to produce the final attended result + dnnl::memory QAttention_dst_mem; + { + //format acbd in order to work with subsequent permute and merge to produce ort format memory + auto QAttention_dst_md = dnnl::memory::desc({batch_size, num_heads, sequence_length, head_size}, dnnl::memory::data_type::f32, dnnl::memory::format_tag::acbd); + + auto Prob_V_d = dnnl::matmul::desc(QK_mem.get_desc(), V_md, QAttention_dst_md); + auto Prob_V_pd = dnnl::matmul::primitive_desc(Prob_V_d, eng); + auto Prob_V_prim = dnnl::matmul(Prob_V_pd); + + QAttention_dst_mem = dnnl::memory(Prob_V_pd.dst_desc(), eng); + std::unordered_map Prob_V_mem_map({{DNNL_ARG_SRC, QK_mem}, + {DNNL_ARG_WEIGHTS, QKV_mem}, + {DNNL_ARG_DST, QAttention_dst_mem}}); + //prob * V + sp.AddPrimitive(Prob_V_prim, Prob_V_mem_map); + } + + //permute and merge axes through reshape + { + auto QAttention_dst_md_BNSH = QAttention_dst_mem.get_desc(); + //swap axes + auto QAttention_dst_md_BSNH = QAttention_dst_md_BNSH.permute_axes({0, 2, 1, 3}); + //merge axes + auto QAttention_dst_md_BSH = QAttention_dst_md_BSNH.reshape({batch_size, sequence_length, hidden_size}); + auto QAttention_dst_mem_correct_shape = dnnl::memory(QAttention_dst_md_BSH, eng, nullptr); + sp.AddReshape(QAttention_dst_mem, QAttention_dst_mem_correct_shape); + //needs to copy if it outputs for subgraph + sp.SetMemory(node.Output(OUTPUT), QAttention_dst_mem_correct_shape, true); + } +} + + +//obtain the number of heads for qattention node +dnnl::memory::dim DnnlQAttention::GetNumHeads(DnnlNode& node) { + auto attr = node.Attributes().find("num_heads"); + if (attr != node.Attributes().end()) { + return attr->second().i(); + } else { + //num_heads should always exists as an attribute in qattention + ORT_THROW("NUM_HEADS NOT EXIST"); + } +} + + +} // namespace ort_dnnl +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.h b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.h new file mode 100644 index 0000000000..c86f7f6fb7 --- /dev/null +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.h @@ -0,0 +1,39 @@ +// Copyright(C) 2021 Intel Corporation +// Licensed under the MIT License + +#pragma once +#include "dnnl_subgraph.h" +#include "dnnl_subgraph_primitive.h" + +namespace onnxruntime { +namespace ort_dnnl { + +class DnnlQAttention { + public: + enum InputTensors : int { + INPUT = 0, + WEIGHTS = 1, + BIAS = 2, + INPUT_SCALE = 3, + WEIGHTS_SCALE = 4, + MASK_INDEX = 5, + INPUT_ZP = 6, + WEIGHTS_ZP = 7, + PAST = 8 // not suppoted + }; + + enum OutputTensors : int { + OUTPUT = 0, + PRESENT = 1 // not supported + }; + + DnnlQAttention(); + void CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node); + + private: + dnnl::memory ComputeTotalScale(DnnlSubgraphPrimitive& sp, DnnlNode& node); + dnnl::memory::dim GetNumHeads(DnnlNode& node); +}; + +} // namespace ort_dnnl +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc index 909a8f6c75..583e6151b5 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc @@ -15,6 +15,7 @@ #include "dnnl_matmul_integer.h" #include "dnnl_pool.h" #include "dnnl_pow.h" +#include "dnnl_qattention.h" #include "dnnl_reducemean.h" #include "dnnl_reshape.h" #include "dnnl_softmax.h" @@ -30,6 +31,10 @@ #include "dnnl_relugrad.h" #endif +#include +#include + + namespace onnxruntime { namespace ort_dnnl { @@ -38,6 +43,78 @@ inline bool Contains(const Map& map, const Key& key) { return map.find(key) != map.end(); } + +void DnnlSubgraphPrimitive::PrintMemory(const dnnl::memory& mem) { + auto md = mem.get_desc(); + auto dt = md.data_type(); + auto dims = md.dims(); + if (Product(dims) > 50) { + printf("tensor too long ignore printing \n"); + return; + } + dnnl::memory to_mem; + if (!IsMemoryInExpectedOrtFormat(md)|| mem.get_engine().get_kind() != dnnl::engine::kind::cpu) { + printf("\n print memory reorder started \n"); + dnnl::memory::desc to_md = dnnl::memory::desc(md.dims(), md.data_type(), GetDnnlFormat(md.dims().size())); + to_mem = dnnl::memory(to_md, GetCPUEngine()); + auto stream = dnnl::stream(mem.get_engine()); + dnnl::reorder(mem, to_mem).execute(stream, {{DNNL_ARG_FROM, mem}, {DNNL_ARG_TO, to_mem}}); + stream.wait(); + printf("\n print memory reorder ended \n"); + } else { + to_mem = mem; + } + + if (dt == dnnl::memory::data_type::f32) { + std::vector data_vec(Product(dims)); + auto dh = to_mem.get_data_handle(); + for (size_t i = 0; i < to_mem.get_desc().get_size(); ++i) { + ((char*)data_vec.data())[i] = ((char*)dh)[i]; + } + + for (auto& data : data_vec) { + printf("%.6f \n", data); + } + printf("\n"); + } + else if (dt == dnnl::memory::data_type::u8) { + std::vector data_vec(Product(dims)); + auto dh = to_mem.get_data_handle(); + for (size_t i = 0; i < to_mem.get_desc().get_size(); ++i) { + ((char*)data_vec.data())[i] = ((char*)dh)[i]; + } + + for (auto& data : data_vec) { + printf("%" PRIu8 "\n", data); + } + printf("\n"); + } else if (dt == dnnl::memory::data_type::s8) { + std::vector data_vec(Product(dims)); + auto dh = to_mem.get_data_handle(); + for (size_t i = 0; i < to_mem.get_desc().get_size(); ++i) { + ((char*)data_vec.data())[i] = ((char*)dh)[i]; + } + + for (auto& data : data_vec) { + printf("%" PRIi8 "\n", data); + } + printf("\n"); + } else if (dt == dnnl::memory::data_type::s32) { + std::vector data_vec(Product(dims)); + auto dh = to_mem.get_data_handle(); + for (size_t i = 0; i < to_mem.get_desc().get_size(); ++i) { + ((char*)data_vec.data())[i] = ((char*)dh)[i]; + } + + for (auto& data : data_vec) { + printf("%" PRIi32 "\n", data); + } + printf("\n"); + } else { + ORT_THROW("Cannot print such data type"); + } +} + int Product(dnnl::memory::dims d) { int result = 1; for (const auto& e : d) @@ -79,6 +156,8 @@ void DnnlSubgraphPrimitive::AddKernels() { DnnlPool().CreatePrimitive(*this, node); } else if (node.OpType() == "Pow") { DnnlPow().CreatePrimitive(*this, node); + } else if (node.OpType() == "QAttention") { + DnnlQAttention().CreatePrimitive(*this, node); } else if (node.OpType() == "ReduceMean") { DnnlReduceMean().CreatePrimitive(*this, node); } else if (node.OpType() == "Reshape") { @@ -427,12 +506,25 @@ dnnl::memory DnnlSubgraphPrimitive::GetMemoryAndReshape(const DnnlTensor& tensor auto mem_from_dims = mem_from.get_desc().dims(); auto mem_to_dims = mem_to.get_desc().dims(); if (Product(mem_from_dims) != Product(mem_to_dims)) { + LOGS_DEFAULT(ERROR) << mem_from_dims; + LOGS_DEFAULT(ERROR) << mem_to_dims; throw std::invalid_argument("not a valid reshape, inconsistent dim product"); } - auto mem_from_reshape = dnnl::memory(mem_desc, mem_from.get_engine(), nullptr); + //keep the same data type from mem_from but reshape the dims with mem_desc + auto mem_from_reshape_md = mem_from.get_desc(); + if (transpose) { + //hard coded to transpose 2 dimensional matrix + //TODO: expand to arbitrary permutation or transpose on given 2 dims for higher dimensional tensors + mem_from_reshape_md = mem_from_reshape_md.permute_axes({1, 0}); + } + mem_from_reshape_md = mem_from_reshape_md.reshape(mem_desc.dims()); + auto mem_from_reshape = dnnl::memory(mem_from_reshape_md, mem_from.get_engine(), nullptr); if (is_constant) { // if constant, do reshape now LOGS_DEFAULT(INFO) << "reshaped now"; - mem_from_reshape.set_data_handle(mem_from.get_data_handle()); + //use the stream as a hint to make sure data handle gets set + dnnl::stream s{eng}; + mem_from_reshape.set_data_handle(mem_from.get_data_handle(),s); + s.wait(); } else { AddReshape(mem_from, mem_from_reshape); } @@ -506,34 +598,55 @@ void DnnlSubgraphPrimitive::AddReshape(dnnl::memory src, dnnl::memory dst) { reshapes_.push_back({src, dst}); } -void DnnlSubgraphPrimitive::AddPrimitive(dnnl::primitive prim, std::unordered_map mem_map) { +void DnnlSubgraphPrimitive::AddPrimitive(dnnl::primitive prim, std::unordered_map mem_map, std::vector items_to_print) { net_.push_back(prim); net_args_.push_back(mem_map); + for (auto e : items_to_print) { + items_to_print_.push_back({int(net_.size() - 1), e}); + } } onnxruntime::common::Status DnnlSubgraphPrimitive::Predict(const std::unordered_map& inputs, const std::unordered_map& outputs) { + + auto stream = GetStream(); + for (auto& input : inputs) { if (Contains(inputs_, input.first)) { - inputs_.at(input.first).set_data_handle(input.second.buffer); + inputs_.at(input.first).set_data_handle(input.second.buffer, stream); + stream.wait(); } } for (auto& output : outputs) { if (Contains(outputs_, output.first)) { - outputs_.at(output.first).set_data_handle(output.second.buffer); + outputs_.at(output.first).set_data_handle(output.second.buffer, stream); + stream.wait(); } } // reshapes (eg, unsqueeze) // it is safe to set data handle because all external data handles have been set and onednn managed memory data handles will not change for (auto& reshape_pair : reshapes_) { - reshape_pair.second.set_data_handle(reshape_pair.first.get_data_handle()); + reshape_pair.second.set_data_handle(reshape_pair.first.get_data_handle(),stream); + stream.wait(); } - auto stream = GetStream(); + for (size_t i = 0; i < net_.size(); ++i) { net_.at(i).execute(stream, net_args_.at(i)); stream.wait(); + + //for debug memory purpose + /* + for (auto e : items_to_print_) { + auto net_index = e.first; + auto net_arg_index = e.second; + if (net_index == i) { + PrintMemory(net_args_.at(i)[net_arg_index]); + } + } + */ + } return Status::OK(); diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.h b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.h index 4e77be231a..0e0b7eaf35 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.h +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.h @@ -48,7 +48,9 @@ class DnnlSubgraphPrimitive { //obtain a dnnl::memory with specified name, memory descriptor and engine, will perform extra reorder/reshape if necessary before returning dnnl::memory GetMemoryAndReshape(const DnnlTensor& tensor, dnnl::memory::desc mem_desc, dnnl::engine eng, bool transpose = false); //add dnnl primitive and memory map to subgraph primitive - void AddPrimitive(dnnl::primitive prim, std::unordered_map mem_map); + //when you add primitive, you can optionally specify a vector of indexes to be printed in runtime for debug purpose + //eg, sp.AddPrimitve(prim,mem_map,{DNNL_ARG_SRC}) + void AddPrimitive(dnnl::primitive prim, std::unordered_map mem_map, std::vector items_to_print = {}); //add a reshape (e.g. squeeze, unsqueeze) to subgraph primitive void AddReshape(dnnl::memory src, dnnl::memory dst); bool HasMemory(std::string memory_name, dnnl::memory::desc mem_desc, dnnl::engine eng); @@ -106,6 +108,11 @@ class DnnlSubgraphPrimitive { dnnl::engine gpu_engine_; OrtMutex mutex_; + + //for memory debug purpose + std::vector> items_to_print_; + void PrintMemory(const dnnl::memory& mem); + }; } // namespace ort_dnnl diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.cc index 049fa7d694..799f76a9a6 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License #include "dnnl_subgraph_transformer.h" +#include "core/providers/shared_library/provider_api.h" #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES #endif @@ -16,6 +17,7 @@ void DnnlGraphTransformer::Apply(DnnlSubgraph& subgraph) { MatMulAdd(subgraph); Gelu(subgraph); FastGelu(subgraph); + RemoveMatMulIntegerZP(subgraph); } //resolve a fusion by replacing old_indices nodes with a new_node @@ -746,5 +748,64 @@ void DnnlGraphTransformer::MatMulAdd(DnnlSubgraph& subgraph) { } } +void DnnlGraphTransformer::RemoveMatMulIntegerZP(DnnlSubgraph& subgraph) { + size_t max_index = subgraph.GetMaxNodeIndex(); + for (size_t index = 0; index < max_index; index++) { + auto dnnl_node = subgraph.GetDnnlNode(index); + + //look for matmulint + if (dnnl_node == nullptr || dnnl_node->OpType() != "MatMulInteger") { + continue; + } + + //if B zero point exists + if (!(dnnl_node->InputCount() >= 4 && dnnl_node->Input(3).Exists())) { + continue; + } + + auto b_zero_point = dnnl_node->Input(3); + const ONNX_NAMESPACE::TensorProto* tensor_proto = nullptr; + if (!subgraph.GetInitializedTensor(b_zero_point.Name(), tensor_proto)) { + continue; + } + + if (tensor_proto == nullptr) { + continue; + } + + const auto& dims = tensor_proto->dims(); + auto dim_size = tensor_proto->dims_size(); + int num_elements = 1; + for (int i = 0; i < dim_size; i++) { + num_elements *= int(dims[i]); + } + + //check if b_zp is all zeros, assume data is s8 since only s8 weight is supported in onednn + bool all_zero = true; + std::vector unpacked_tensor; + unpacked_tensor.resize(num_elements,1); + ORT_THROW_IF_ERROR(onnxruntime::utils::UnpackTensor(*tensor_proto, tensor_proto->has_raw_data() ? tensor_proto->raw_data().data() : nullptr, tensor_proto->has_raw_data() ? tensor_proto->raw_data().size() : 0, reinterpret_cast(unpacked_tensor.data()), num_elements)); + for (const auto& val : unpacked_tensor) { + if (val != 0) { + all_zero = false; + break; + } + } + + + if (!all_zero) { + continue; + } + + if (debug_log_) { + LOGS_DEFAULT(ERROR) << "Remove weight ZP of [" << dnnl_node->Name() << "]"; + } + //remove b_zero_point's consumer matmulint + b_zero_point.RemoveConsumer(DnnlNodeArg(dnnl_node, 3, false)); + //detach b_zero_point from matmulint node + dnnl_node->Inputs()[3] = nullptr; + } +} + } // namespace ort_dnnl } // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.h b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.h index bb5be16156..58fa73d771 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.h +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_transformer.h @@ -26,6 +26,7 @@ class DnnlGraphTransformer { bool IsInitilizedWithExpectedValue(DnnlSubgraph& subgraph, DnnlTensor& input_arg, float expected_value); void ConvRelu(DnnlSubgraph& subgraph); void MatMulAdd(DnnlSubgraph& subgraph); + void RemoveMatMulIntegerZP(DnnlSubgraph& subgraph); // This function checks a few things // - the node in question has a single output // - The output of the node is only consumed by a one other node diff --git a/onnxruntime/test/contrib_ops/quantize_attention_op_test.cc b/onnxruntime/test/contrib_ops/quantize_attention_op_test.cc index 7979020856..33f9d56a7f 100644 --- a/onnxruntime/test/contrib_ops/quantize_attention_op_test.cc +++ b/onnxruntime/test/contrib_ops/quantize_attention_op_test.cc @@ -18,10 +18,10 @@ namespace test { enum class EP : char { CPU, - CUDA + CUDA, + DNNL }; - // input: [batch_size, sequence_length, hidden_size] // weights: [hidden_size, 3 * hidden_size] // bias: [3 * hidden_size] @@ -54,6 +54,12 @@ void RunQAttention(const std::vector& input_data, std::vector weights_dims = {input_hidden_size, static_cast(3 * hidden_size)}; std::vector bias_dims = {static_cast(3 * hidden_size)}; std::vector mask_index_dims = {batch_size}; + if constexpr (ep == EP::DNNL) { + //onednn only supports raw mask + if (mask_index_data.size() == static_cast(batch_size * sequence_length)) { + mask_index_dims = {batch_size, sequence_length}; + } + } std::vector output_dims = {batch_size, sequence_length, hidden_size}; if (input_quant_params.scale != 0.0f) { @@ -103,10 +109,14 @@ void RunQAttention(const std::vector& input_data, std::vector> execution_providers; execution_providers.push_back(DefaultCudaExecutionProvider()); tester.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}, nullptr, &execution_providers); - } else { + } else if constexpr (ep == EP::CPU) { std::vector> execution_providers; execution_providers.push_back(DefaultCpuExecutionProvider()); tester.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}, nullptr, &execution_providers); + } else { // onednn ep + std::vector> execution_providers; + execution_providers.push_back(DefaultDnnlExecutionProvider()); + tester.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}, nullptr, &execution_providers); } } @@ -140,6 +150,49 @@ static void RunQAttentionCUDA( } } +static void RunQAttentionDNNL( + const std::vector& input_data, + const std::vector& weights_data, + const std::vector& bias_data, + const std::vector& mask_index_data, // onednn only support raw mask data + const std::vector& output_data, + int batch_size, + int sequence_length, + int hidden_size, + int number_of_heads, + bool use_special_quantize_parameter = true, + bool is_unidirectional = false, + int input_hidden_size = 0) { + // Return without running code if USE_DNNL is not defined +#ifdef USE_DNNL + quantization::Params input_quant_params(/*scale=*/0.0f, /*zero_point=*/0); + quantization::Params weights_quant_params(/*scale=*/0.0f, /*zero_point=*/0); + if (use_special_quantize_parameter) { + input_quant_params.scale = 0.1f; + weights_quant_params.scale = 0.1f; + input_quant_params.zero_point = 128; + weights_quant_params.zero_point = 1; + } + + RunQAttention( + input_data, weights_data, bias_data, mask_index_data, output_data, input_quant_params, weights_quant_params, + batch_size, sequence_length, hidden_size, number_of_heads, is_unidirectional, false, input_hidden_size); +#else + ORT_UNUSED_PARAMETER(input_data); + ORT_UNUSED_PARAMETER(weights_data); + ORT_UNUSED_PARAMETER(bias_data); + ORT_UNUSED_PARAMETER(mask_index_data); + ORT_UNUSED_PARAMETER(output_data); + ORT_UNUSED_PARAMETER(batch_size); + ORT_UNUSED_PARAMETER(sequence_length); + ORT_UNUSED_PARAMETER(hidden_size); + ORT_UNUSED_PARAMETER(number_of_heads); + ORT_UNUSED_PARAMETER(use_special_quantize_parameter); + ORT_UNUSED_PARAMETER(is_unidirectional); + ORT_UNUSED_PARAMETER(input_hidden_size); +#endif +} + static void RunQAttentionU8U8( const std::vector& input_data, const std::vector& weights_data, @@ -217,8 +270,43 @@ static void RunQAttentionAll( RunQAttentionCUDA(input_data, weight_data, bias_data, mask_index_data, output_data, batch_size, sequence_length, hidden_size, number_of_heads, use_special_quantize_parameter, is_unidirectional, use_float16, input_hidden_size); + RunQAttentionDNNL(input_data, weight_data, bias_data, mask_index_data, output_data, + batch_size, sequence_length, hidden_size, number_of_heads, + use_special_quantize_parameter, is_unidirectional, input_hidden_size); } +//ONEDNN EP only supports 2D raw mask +#ifdef USE_DNNL +TEST(QAttentionTest, QAttentionDNNLBatch1) { + int batch_size = 1; + int sequence_length = 2; + int hidden_size = 4; + int number_of_heads = 2; + + std::vector input_data = { + 0.8f, -0.5f, 0.0f, 1.f, + 0.5f, 0.2f, 0.3f, -0.6f}; + + std::vector weight_data = { + 0.1f, -0.2f, 0.3f, 1.0f, 1.1f, 0.3f, 0.5f, 0.2f, 0.3f, -0.6f, 1.5f, 2.0f, + 0.5f, 0.1f, 0.4f, 1.6f, 1.0f, 2.0f, 0.4f, 0.8f, 0.9f, 0.1f, -1.3f, 0.7f, + 0.3f, 0.2f, 4.0f, 2.2f, 1.6f, 1.1f, 0.7f, 0.2f, 0.4f, 1.0f, 1.2f, 0.5f, + 0.2f, 0.1f, 0.4f, 1.6f, 2.4f, 3.3f, 2.1f, 4.2f, 8.4f, 0.0f, 2.1f, 3.2f}; + + std::vector bias_data = { + -0.5f, 0.6f, 1.2f, 2.1f, 0.5f, 0.7f, 0.2f, 1.2f, 0.5f, 0.4f, 0.3f, 1.2f}; + + std::vector mask_index_data = {1L, 1L}; + + std::vector output_data = { + 3.1495983600616455f, 0.10843668878078461f, 4.25f, 5.6499996185302734f, + 3.9696791172027588f, 0.073143675923347473f, 4.2499995231628418f, 5.6499991416931152f}; + + RunQAttentionDNNL(input_data, weight_data, bias_data, mask_index_data, output_data, + batch_size, sequence_length, hidden_size, number_of_heads); +} +#endif // USE_DNNL + TEST(QAttentionTest, QAttentionBatch1) { int batch_size = 1; int sequence_length = 2; @@ -313,6 +401,42 @@ TEST(QAttentionTest, QAttentionBatch2) { batch_size, sequence_length, hidden_size, number_of_heads); } +//ONEDNN EP only support 2D raw mask +#ifdef USE_DNNL +TEST(QAttentionTest, QAttentionDNNLBatch2) { + int batch_size = 2; + int sequence_length = 2; + int hidden_size = 4; + int number_of_heads = 2; + + std::vector input_data = { + 0.8f, -0.5f, 0.0f, 1.f, + 0.5f, 0.2f, 0.3f, -0.6f, + 0.8f, -0.5f, 0.0f, 1.f, + 0.5f, 0.2f, 0.3f, -0.6f}; + + std::vector weight_data = { + 0.1f, -0.2f, 0.3f, 1.0f, 1.1f, 0.3f, 0.5f, 0.2f, 0.3f, -0.6f, 1.5f, 2.0f, + 0.5f, 0.1f, 0.4f, 1.6f, 1.0f, 2.0f, 0.4f, 0.8f, 0.9f, 0.1f, -1.3f, 0.7f, + 0.3f, 0.2f, 4.0f, 2.2f, 1.6f, 1.1f, 0.7f, 0.2f, 0.4f, 1.0f, 1.2f, 0.5f, + 0.2f, 0.1f, 0.4f, 1.6f, 2.4f, 3.3f, 2.1f, 4.2f, 8.4f, 0.0f, 2.1f, 3.2f}; + + std::vector bias_data = { + -0.5f, 0.6f, 1.2f, 2.1f, 0.5f, 0.7f, 0.2f, 1.2f, 0.5f, 0.4f, 0.3f, 1.2f}; + + std::vector mask_index_data = {1L, 1L, 1L, 1L}; + + std::vector output_data = { + 3.1495983600616455f, 0.10843668878078461f, 4.25f, 5.6499996185302734f, + 3.9696791172027588f, 0.073143675923347473f, 4.2499995231628418f, 5.6499991416931152f, + 3.1495983600616455f, 0.10843668878078461f, 4.25f, 5.6499996185302734f, + 3.9696791172027588f, 0.073143675923347473f, 4.2499995231628418f, 5.6499991416931152f}; + + RunQAttentionDNNL(input_data, weight_data, bias_data, mask_index_data, output_data, + batch_size, sequence_length, hidden_size, number_of_heads); +} +#endif // USE_DNNL + TEST(QAttentionTest, QAttentionMaskPartialSequence) { int batch_size = 1; int sequence_length = 2; @@ -343,6 +467,38 @@ TEST(QAttentionTest, QAttentionMaskPartialSequence) { batch_size, sequence_length, hidden_size, number_of_heads); } +//oneDNN EP only supports 2D raw mask +#ifdef USE_DNNL +TEST(QAttentionTest, QAttentionDNNLMaskPartialSequence) { + int batch_size = 1; + int sequence_length = 2; + int hidden_size = 4; + int number_of_heads = 2; + + std::vector input_data = { + 0.8f, -0.5f, 0.0f, 1.f, + 0.5f, 0.2f, 0.3f, -0.6f}; + + std::vector weight_data = { + 0.1f, -0.2f, 0.3f, 1.0f, 1.1f, 0.3f, 0.5f, 0.2f, 0.3f, -0.6f, 1.5f, 2.0f, + 0.5f, 0.1f, 0.4f, 1.6f, 1.0f, 2.0f, 0.4f, 0.8f, 0.9f, 0.1f, -1.3f, 0.7f, + 0.3f, 0.2f, 4.0f, 2.2f, 1.6f, 1.1f, 0.7f, 0.2f, 0.4f, 1.0f, 1.2f, 0.5f, + 0.2f, 0.1f, 0.4f, 1.6f, 2.4f, 3.3f, 2.1f, 4.2f, 8.4f, 0.0f, 2.1f, 3.2f}; + + std::vector bias_data = { + -0.5f, 0.6f, 1.2f, 2.1f, 0.5f, 0.7f, 0.2f, 1.2f, 0.5f, 0.4f, 0.3f, 1.2f}; + + std::vector mask_index_data = {1L, 0L}; + + std::vector output_data = { + 8.6899995803833008f, -0.13000002503395081f, 4.25f, 5.6499996185302734f, + 8.6899995803833008f, -0.13000002503395081f, 4.2499995231628418f, 5.6499991416931152f}; + + RunQAttentionDNNL(input_data, weight_data, bias_data, mask_index_data, output_data, + batch_size, sequence_length, hidden_size, number_of_heads); +} +#endif // USE_DNNL + TEST(QAttentionTest, QAttentionMaskExceedSequence) { int batch_size = 1; int sequence_length = 2; From 777a80fbc15eaf1b79e06b86dcd57cdf1d156f50 Mon Sep 17 00:00:00 2001 From: Abhishek Jindal Date: Mon, 13 Dec 2021 13:23:46 -0800 Subject: [PATCH 029/113] Abjindal/eager onnx operators fix (#9968) * adding view operator changes * adding the slice operator definition * moving to opgen script for slice op and removing redundant steps in view op and reshape_copy * adding for at definition * adding for at::infer_size definition * changing template style for reshape_copy to ensure int64_t type --- .../orttraining/eager/opgen/opgen/atenops.py | 2 +- orttraining/orttraining/eager/ort_aten.cpp | 18 ++++++++----- orttraining/orttraining/eager/ort_aten.h | 27 +++++++++++++++++++ orttraining/orttraining/eager/ort_ops.cpp | 20 -------------- orttraining/orttraining/eager/ort_ops.h | 18 ++++++++++++- 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/orttraining/orttraining/eager/opgen/opgen/atenops.py b/orttraining/orttraining/eager/opgen/opgen/atenops.py index 5da6ac607f..f8cda84df4 100644 --- a/orttraining/orttraining/eager/opgen/opgen/atenops.py +++ b/orttraining/orttraining/eager/opgen/opgen/atenops.py @@ -34,7 +34,6 @@ ops = { 'aten::_reshape_alias': SignatureOnly(), 'aten::view': SignatureOnly(), 'aten::_copy_from_and_resize' : SignatureOnly(), - 'aten::addmm': Gemm('mat1', 'mat2', 'self', alpha='alpha', beta='beta'), 'aten::t': Transpose('self'), 'aten::mm': MatMul('self', 'mat2'), @@ -52,6 +51,7 @@ ops = { 'aten::gelu_backward' : GeluGrad('grad', 'self'), 'aten::max' : ReduceMax('self', keepdims=1), 'aten::min' : ReduceMin('self', keepdims=1), + 'aten::slice.Tensor' : Slice('self', 'start', 'end', 'dim', 'step'), 'aten::ne.Scalar':MakeTorchFallback(), 'aten::ne.Scalar_out': MakeTorchFallback(), diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index 00969e1339..a698fccb69 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -5,6 +5,7 @@ #include "ort_tensor.h" #include #include +#include namespace torch_ort { namespace eager { @@ -173,6 +174,14 @@ bool IsSupportedType(at::IntArrayRef arrary, const std::vector& std::find(valid_types.begin(), valid_types.end(), at::kLong) != valid_types.end(); } +bool IsSupportedType(int64_t val, const std::vector& valid_types){ + return std::find(valid_types.begin(), valid_types.end(), at::kLong) != valid_types.end(); +} + +bool IsSupportedType(c10::optional val, const std::vector& valid_types){ + return IsSupportedType(val.value(), valid_types); +} + //#pragma endregion //#pragma region Hand-Implemented ATen Ops @@ -250,23 +259,18 @@ at::Tensor _reshape_alias( reshape_copy( invoker, create_ort_value(invoker, self), - at::infer_size( - size, - self.numel())), + size), self.options()); } at::Tensor view(const at::Tensor& self, at::IntArrayRef size) { ORT_LOG_FN(self, size); - auto& invoker = GetORTInvoker(self.device()); return aten_tensor_from_ort( reshape_copy( invoker, create_ort_value(invoker, self), - at::infer_size( - size, - self.numel())), + size), self.options()); } diff --git a/orttraining/orttraining/eager/ort_aten.h b/orttraining/orttraining/eager/ort_aten.h index b91c9ab381..a63f914b30 100644 --- a/orttraining/orttraining/eager/ort_aten.h +++ b/orttraining/orttraining/eager/ort_aten.h @@ -34,6 +34,29 @@ OrtValue create_ort_value( OrtValue create_ort_value(const at::Tensor& tensor); +// Create 1-dimensional ORT tensor from a given value +template +OrtValue create_ort_value( + onnxruntime::ORTInvoker& invoker, + const T val) { + OrtValue ort_val; + CreateMLValue( + invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), + onnxruntime::DataTypeImpl::GetType(), + {1,}, + &ort_val); + auto* ort_tensor = ort_val.GetMutable(); + CopyVectorToTensor(invoker, {val}, *ort_tensor); + return ort_val; +} + +template +OrtValue create_ort_value( + onnxruntime::ORTInvoker& invoker, + c10::optional val) { + return create_ort_value(invoker, val.value()); +} + template OrtValue create_ort_value( onnxruntime::ORTInvoker& invoker, @@ -79,5 +102,9 @@ bool IsSupportedType(at::Tensor tensor, const std::vector& valid bool IsSupportedType(at::IntArrayRef arrary, const std::vector& valid_types); +bool IsSupportedType(int64_t val, const std::vector& valid_types); + +bool IsSupportedType(c10::optional val, const std::vector& valid_types); + } // namespace eager } // namespace torch_ort \ No newline at end of file diff --git a/orttraining/orttraining/eager/ort_ops.cpp b/orttraining/orttraining/eager/ort_ops.cpp index 5d83d728c9..2cc98b356b 100644 --- a/orttraining/orttraining/eager/ort_ops.cpp +++ b/orttraining/orttraining/eager/ort_ops.cpp @@ -8,26 +8,6 @@ namespace torch_ort { namespace eager { -OrtValue reshape_copy( - onnxruntime::ORTInvoker& invoker, - const OrtValue& input, - std::vector shape) { - - // TODO: actual reshape on buffer - const onnxruntime::Tensor& input_tensor = input.Get(); - auto new_shape = at::infer_size(shape, input_tensor.Shape().Size()); - OrtValue shape_tensor; - //todo: avoid the copy on this small shape vector; - auto element_type = onnxruntime::DataTypeImpl::GetType(); - CreateMLValue(invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), - element_type, {(int64_t)new_shape.size(),}, &shape_tensor); - auto* ort_shape_tensor = shape_tensor.GetMutable(); - CopyVectorToTensor(invoker, new_shape, *ort_shape_tensor); - std::vector result(1); - ORT_THROW_IF_ERROR(invoker.Invoke("Reshape", {input, shape_tensor}, result, nullptr)); - return result[0]; -} - void copy(onnxruntime::ORTInvoker& invoker, const OrtValue& src, OrtValue& dst){ auto& ort_ep = invoker.GetCurrentExecutionProvider(); diff --git a/orttraining/orttraining/eager/ort_ops.h b/orttraining/orttraining/eager/ort_ops.h index cb78d011b0..13f7c30be4 100644 --- a/orttraining/orttraining/eager/ort_ops.h +++ b/orttraining/orttraining/eager/ort_ops.h @@ -3,16 +3,32 @@ #pragma once +#include "ort_util.h" #include #include namespace torch_ort { namespace eager { +template class V> OrtValue reshape_copy( onnxruntime::ORTInvoker& invoker, const OrtValue& input, - std::vector shape); + V shape) { + // TODO: actual reshape on buffer + const onnxruntime::Tensor& input_tensor = input.Get(); + auto new_shape = at::infer_size(shape, input_tensor.Shape().Size()); + OrtValue shape_tensor; + //todo: avoid the copy on this small shape vector; + auto element_type = onnxruntime::DataTypeImpl::GetType(); + CreateMLValue(invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), + element_type, {(int64_t)new_shape.size(),}, &shape_tensor); + auto* ort_shape_tensor = shape_tensor.GetMutable(); + CopyVectorToTensor(invoker, new_shape, *ort_shape_tensor); + std::vector result(1); + ORT_THROW_IF_ERROR(invoker.Invoke("Reshape", {input, shape_tensor}, result, nullptr)); + return result[0]; +} OrtValue add(onnxruntime::ORTInvoker& invoker, const OrtValue& A, From 5d821b5bd9d1db0660975c4bd2416975a629f852 Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Mon, 13 Dec 2021 13:26:56 -0800 Subject: [PATCH 030/113] Address null dereference warning in div_grad_impl.cu. (#10010) --- .../training_ops/cuda/math/div_grad.cc | 6 +- .../training_ops/cuda/math/div_grad_impl.cu | 64 +++++++++---------- .../training_ops/cuda/math/div_grad_impl.h | 6 +- .../training_ops/rocm/math/div_grad.cc | 6 +- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/orttraining/orttraining/training_ops/cuda/math/div_grad.cc b/orttraining/orttraining/training_ops/cuda/math/div_grad.cc index 46c55cd5ff..67b225f751 100644 --- a/orttraining/orttraining/training_ops/cuda/math/div_grad.cc +++ b/orttraining/orttraining/training_ops/cuda/math/div_grad.cc @@ -205,13 +205,13 @@ Status DivGrad::ComputeInternal(OpKernelContext* context) const { ImplDivGrad( Stream(), prepare.output_rank_or_simple_broadcast, - &prepare.lhs_padded_strides, + prepare.lhs_padded_strides, prepare_a_data, - &prepare.rhs_padded_strides, + prepare.rhs_padded_strides, prepare_b_data, prepare_dy_data, dy_shape.Size(), - &prepare.fdm_output_strides, + prepare.fdm_output_strides, reinterpret_cast(da_data_ref), reinterpret_cast(db_data_ref)); diff --git a/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.cu b/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.cu index 1e64b1e110..56520337fe 100644 --- a/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.cu +++ b/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.cu @@ -434,114 +434,114 @@ template void ImplDivGrad( cudaStream_t stream, int32_t output_rank, - const TArray* a_padded_strides, + const TArray& a_padded_strides, const T* a_data, - const TArray* b_padded_strides, + const TArray& b_padded_strides, const T* b_data, const T* dy_data, size_t count, - const TArray* fdm_output_strides, + const TArray& fdm_output_strides, T* da_output_data, T* db_output_data) { int blocksPerGrid = (int)(ceil(static_cast(count) / GridDim::maxThreadsPerBlock)); CUDA_LONG N = static_cast(count); - if (a_padded_strides && a_padded_strides->Size() && b_padded_strides && b_padded_strides->Size()) { + if (a_padded_strides.Size() && b_padded_strides.Size()) { if (da_output_data && db_output_data) _DivGrad<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, db_output_data, N); else if (da_output_data) _DivGrad_A<<>>( output_rank, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, N); else _DivGrad_B<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, db_output_data, N); - } else if (a_padded_strides && a_padded_strides->Size()) { + } else if (a_padded_strides.Size()) { if (da_output_data && db_output_data) _DivGrad<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, db_output_data, N); else if (da_output_data) _DivGrad_A<<>>( output_rank, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, N); else _DivGrad_B<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, db_output_data, N); } else { if (da_output_data && db_output_data) _DivGrad<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, db_output_data, N); else if (da_output_data) _DivGrad_A<<>>( output_rank, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, da_output_data, N); else _DivGrad_B<<>>( output_rank, - *a_padded_strides, + a_padded_strides, a_data, - *b_padded_strides, + b_padded_strides, b_data, dy_data, - *fdm_output_strides, + fdm_output_strides, db_output_data, N); } @@ -551,13 +551,13 @@ void ImplDivGrad( template void ImplDivGrad( \ cudaStream_t stream, \ int32_t output_rank, \ - const TArray* a_padded_strides, \ + const TArray& a_padded_strides, \ const T* a_data, \ - const TArray* b_padded_strides, \ + const TArray& b_padded_strides, \ const T* b_data, \ const T* dy_data, \ size_t count, \ - const TArray* fdm_output_strides, \ + const TArray& fdm_output_strides, \ T* da_output_data, \ T* db_output_data); \ template void ImplDivGradRhsPerChannelBatch1( \ diff --git a/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.h b/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.h index 947535277f..a356eafc9f 100644 --- a/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.h +++ b/orttraining/orttraining/training_ops/cuda/math/div_grad_impl.h @@ -45,13 +45,13 @@ template void ImplDivGrad( cudaStream_t stream, int32_t output_rank, - const TArray* a_padded_strides, + const TArray& a_padded_strides, const T* a_data, - const TArray* b_padded_strides, + const TArray& b_padded_strides, const T* b_data, const T* dy_data, size_t count, - const TArray* fdm_output_strides, + const TArray& fdm_output_strides, T* da_output_data, T* db_output_data); } // namespace cuda diff --git a/orttraining/orttraining/training_ops/rocm/math/div_grad.cc b/orttraining/orttraining/training_ops/rocm/math/div_grad.cc index 1b04424455..301780db30 100644 --- a/orttraining/orttraining/training_ops/rocm/math/div_grad.cc +++ b/orttraining/orttraining/training_ops/rocm/math/div_grad.cc @@ -205,13 +205,13 @@ Status DivGrad::ComputeInternal(OpKernelContext* context) const { ImplDivGrad( Stream(), prepare.output_rank_or_simple_broadcast, - &prepare.lhs_padded_strides, + prepare.lhs_padded_strides, prepare_a_data, - &prepare.rhs_padded_strides, + prepare.rhs_padded_strides, prepare_b_data, prepare_dy_data, dy_shape.Size(), - &prepare.fdm_output_strides, + prepare.fdm_output_strides, reinterpret_cast(da_data_ref), reinterpret_cast(db_data_ref)); From ad99dff2980285ff064d9c846b0ac3d47f14bbfb Mon Sep 17 00:00:00 2001 From: Rajalakshmi Srinivasaraghavan Date: Fri, 10 Dec 2021 22:08:44 -0600 Subject: [PATCH 031/113] POWER10: Update builtins for DGEMM This patch changes builtin names in DGEMM based on endianness order. Also changing some casting style in SGEMM and DGEMM code for POWER10. --- .../mlas/lib/power/DgemmKernelPOWER10.cpp | 103 ++++++++++-------- .../mlas/lib/power/SgemmKernelPOWER10.cpp | 76 ++++++------- 2 files changed, 93 insertions(+), 86 deletions(-) diff --git a/onnxruntime/core/mlas/lib/power/DgemmKernelPOWER10.cpp b/onnxruntime/core/mlas/lib/power/DgemmKernelPOWER10.cpp index 11638bc33f..560df1e618 100644 --- a/onnxruntime/core/mlas/lib/power/DgemmKernelPOWER10.cpp +++ b/onnxruntime/core/mlas/lib/power/DgemmKernelPOWER10.cpp @@ -60,35 +60,42 @@ MlasDgemmComputeBlockMMA( MLAS_FLOAT64X2 BElements[4]; typedef __vector unsigned char vec_t; __vector_pair A2pair, Apair; -#if (defined(__GNUC__) && (__GNUC__ == 10 && __GNUC_MINOR__ <= 2)) - __builtin_mma_assemble_pair (&Apair, (vec_t)ABroadcast[1], (vec_t)ABroadcast[0]); +#if (defined(__GNUC__) && (__GNUC__ == 10 && __GNUC_MINOR__ <= 3)) +#if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + __builtin_mma_assemble_pair (&Apair, reinterpret_cast(ABroadcast[1]), reinterpret_cast(ABroadcast[0])); if (CountM == 8) { - __builtin_mma_assemble_pair (&A2pair, (vec_t)A2Broadcast[1], (vec_t)A2Broadcast[0]); - } -#elif (defined(__GNUC__) && (__GNUC__ == 11 && __GNUC_MINOR__ <= 2)) - Apair = *((__vector_pair *)((void *)&ABroadcast[0])); - if (CountM == 8) { - A2pair = *((__vector_pair *)((void *)&A2Broadcast[0])); + __builtin_mma_assemble_pair (&A2pair, reinterpret_cast(A2Broadcast[1]), reinterpret_cast(A2Broadcast[0])); } #else - __builtin_vsx_assemble_pair (&Apair, (vec_t)ABroadcast[1], (vec_t)ABroadcast[0]); + __builtin_mma_assemble_pair (&Apair, reinterpret_cast(ABroadcast[0]), reinterpret_cast(ABroadcast[1])); if (CountM == 8) { - __builtin_vsx_assemble_pair (&A2pair, (vec_t)A2Broadcast[1], (vec_t)A2Broadcast[0]); + __builtin_mma_assemble_pair (&A2pair, reinterpret_cast(A2Broadcast[0]), reinterpret_cast(A2Broadcast[1])); + } +#endif +#elif (defined(__GNUC__) && (__GNUC__ == 11 && __GNUC_MINOR__ <= 2)) + Apair = *reinterpret_cast<__vector_pair *>(&ABroadcast[0]); + if (CountM == 8) { + A2pair = *reinterpret_cast<__vector_pair *>(&A2Broadcast[0]); + } +#else + __builtin_vsx_build_pair (&Apair, reinterpret_cast(ABroadcast[0]), reinterpret_cast(ABroadcast[1])); + if (CountM == 8) { + __builtin_vsx_build_pair (&A2pair, reinterpret_cast(A2Broadcast[0]), reinterpret_cast(A2Broadcast[1])); } #endif BElements[0] = MlasLoadFloat64x2(B); BElements[1] = MlasLoadFloat64x2(B + 2); BElements[2] = MlasLoadFloat64x2(B + 4); BElements[3] = MlasLoadFloat64x2(B + 6); - __builtin_mma_xvf64gerpp (&acc[0], Apair, (vec_t)BElements[0]); - __builtin_mma_xvf64gerpp (&acc[1], Apair, (vec_t)BElements[1]); - __builtin_mma_xvf64gerpp (&acc[2], Apair, (vec_t)BElements[2]); - __builtin_mma_xvf64gerpp (&acc[3], Apair, (vec_t)BElements[3]); + __builtin_mma_xvf64gerpp (&acc[0], Apair, reinterpret_cast(BElements[0])); + __builtin_mma_xvf64gerpp (&acc[1], Apair, reinterpret_cast(BElements[1])); + __builtin_mma_xvf64gerpp (&acc[2], Apair, reinterpret_cast(BElements[2])); + __builtin_mma_xvf64gerpp (&acc[3], Apair, reinterpret_cast(BElements[3])); if (CountM == 8) { - __builtin_mma_xvf64gerpp (&acc[4], A2pair, (vec_t)BElements[0]); - __builtin_mma_xvf64gerpp (&acc[5], A2pair, (vec_t)BElements[1]); - __builtin_mma_xvf64gerpp (&acc[6], A2pair, (vec_t)BElements[2]); - __builtin_mma_xvf64gerpp (&acc[7], A2pair, (vec_t)BElements[3]); + __builtin_mma_xvf64gerpp (&acc[4], A2pair, reinterpret_cast(BElements[0])); + __builtin_mma_xvf64gerpp (&acc[5], A2pair, reinterpret_cast(BElements[1])); + __builtin_mma_xvf64gerpp (&acc[6], A2pair, reinterpret_cast(BElements[2])); + __builtin_mma_xvf64gerpp (&acc[7], A2pair, reinterpret_cast(BElements[3])); } } template @@ -108,10 +115,10 @@ struct MlasDgemmStoreVectorMMA { MLAS_FLOAT64X2 *rowC; if (ZeroMode) { - rowC = (MLAS_FLOAT64X2 *) &C[Row * ldc + VectorCount]; + rowC = reinterpret_cast(&C[Row * ldc + VectorCount]); rowC[0] = Result[Row] * AlphaBroadcast; } else { - rowC = (MLAS_FLOAT64X2 *) &C[Row * ldc + VectorCount]; + rowC = reinterpret_cast(&C[Row * ldc + VectorCount]); rowC[0] += Result[Row] * AlphaBroadcast; } } @@ -238,22 +245,22 @@ MlasDgemmMMAProcessCount( // // Store the entire output block. // - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[2]); + __builtin_mma_disassemble_acc (Result, &acc[2]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[3]); + __builtin_mma_disassemble_acc (Result, &acc[3]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[6]); + __builtin_mma_disassemble_acc (Result, &acc[6]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[7]); + __builtin_mma_disassemble_acc (Result, &acc[7]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); } } else { @@ -263,60 +270,60 @@ MlasDgemmMMAProcessCount( // if (CountN >= 6) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[2]); + __builtin_mma_disassemble_acc (Result, &acc[2]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[6]); + __builtin_mma_disassemble_acc (Result, &acc[6]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 6 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[7]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[7]); } } if (CountN - 6 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[3]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[3]); } } else if (CountN >= 4) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 4 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[6]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[6]); } } if (CountN - 4 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[2]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[2]); } } else if (CountN >= 2) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 2 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[5]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[5]); } } if (CountN - 2 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[1]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[1]); } } else { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[0]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[0]); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[4]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[4]); } } diff --git a/onnxruntime/core/mlas/lib/power/SgemmKernelPOWER10.cpp b/onnxruntime/core/mlas/lib/power/SgemmKernelPOWER10.cpp index bc08af0cd7..3dfe061c72 100644 --- a/onnxruntime/core/mlas/lib/power/SgemmKernelPOWER10.cpp +++ b/onnxruntime/core/mlas/lib/power/SgemmKernelPOWER10.cpp @@ -68,15 +68,15 @@ MlasSgemmComputeBlockMMA( BElements[1] = MlasLoadFloat32x4(B + 4); BElements[2] = MlasLoadFloat32x4(B + 8); BElements[3] = MlasLoadFloat32x4(B + 12); - __builtin_mma_xvf32gerpp (&acc[0], (vec_t) ABroadcast, (vec_t )BElements[0]); - __builtin_mma_xvf32gerpp (&acc[1], (vec_t) ABroadcast, (vec_t )BElements[1]); - __builtin_mma_xvf32gerpp (&acc[2], (vec_t) ABroadcast, (vec_t )BElements[2]); - __builtin_mma_xvf32gerpp (&acc[3], (vec_t) ABroadcast, (vec_t )BElements[3]); + __builtin_mma_xvf32gerpp (&acc[0], reinterpret_cast(ABroadcast), reinterpret_cast(BElements[0])); + __builtin_mma_xvf32gerpp (&acc[1], reinterpret_cast(ABroadcast), reinterpret_cast(BElements[1])); + __builtin_mma_xvf32gerpp (&acc[2], reinterpret_cast(ABroadcast), reinterpret_cast(BElements[2])); + __builtin_mma_xvf32gerpp (&acc[3], reinterpret_cast(ABroadcast), reinterpret_cast(BElements[3])); if (CountM == 8) { - __builtin_mma_xvf32gerpp (&acc[4], (vec_t) A2Broadcast, (vec_t )BElements[0]); - __builtin_mma_xvf32gerpp (&acc[5], (vec_t) A2Broadcast, (vec_t )BElements[1]); - __builtin_mma_xvf32gerpp (&acc[6], (vec_t) A2Broadcast, (vec_t )BElements[2]); - __builtin_mma_xvf32gerpp (&acc[7], (vec_t) A2Broadcast, (vec_t )BElements[3]); + __builtin_mma_xvf32gerpp (&acc[4], reinterpret_cast(A2Broadcast), reinterpret_cast(BElements[0])); + __builtin_mma_xvf32gerpp (&acc[5], reinterpret_cast(A2Broadcast), reinterpret_cast(BElements[1])); + __builtin_mma_xvf32gerpp (&acc[6], reinterpret_cast(A2Broadcast), reinterpret_cast(BElements[2])); + __builtin_mma_xvf32gerpp (&acc[7], reinterpret_cast(A2Broadcast), reinterpret_cast(BElements[3])); } } template @@ -96,10 +96,10 @@ struct MlasSgemmStoreVectorMMA { MLAS_FLOAT32X4 *rowC; if (ZeroMode) { - rowC = (MLAS_FLOAT32X4 *) &C[Row * ldc + VectorCount]; + rowC = reinterpret_cast(&C[Row * ldc + VectorCount]); rowC[0] = Result[Row] * AlphaBroadcast; } else { - rowC = (MLAS_FLOAT32X4 *) &C[Row * ldc + VectorCount]; + rowC = reinterpret_cast(&C[Row * ldc + VectorCount]); rowC[0] += Result[Row] * AlphaBroadcast; } } @@ -218,22 +218,22 @@ MlasSgemmMMAProcessCount( // // Store the entire output block. // - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[2]); + __builtin_mma_disassemble_acc (Result, &acc[2]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[3]); + __builtin_mma_disassemble_acc (Result, &acc[3]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[6]); + __builtin_mma_disassemble_acc (Result, &acc[6]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[7]); + __builtin_mma_disassemble_acc (Result, &acc[7]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); } } else { @@ -243,60 +243,60 @@ MlasSgemmMMAProcessCount( // if (CountN >= 12) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[2]); + __builtin_mma_disassemble_acc (Result, &acc[2]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[6]); + __builtin_mma_disassemble_acc (Result, &acc[6]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 12 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[7]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[7]); } } if (CountN - 12 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[3]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[3]); } } else if (CountN >= 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[1]); + __builtin_mma_disassemble_acc (Result, &acc[1]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); - __builtin_mma_disassemble_acc ((void *)Result, &acc[5]); + __builtin_mma_disassemble_acc (Result, &acc[5]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 8 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[6]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[6]); } } if (CountN - 8 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[2]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[2]); } } else if (CountN >= 4) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[0]); + __builtin_mma_disassemble_acc (Result, &acc[0]); MlasLoopUnroll>()(Result, C, ldc, AlphaBroadcast, ZeroMode); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Result, &acc[4]); + __builtin_mma_disassemble_acc (Result, &acc[4]); MlasLoopUnroll>()(Result, C + (ldc*4), ldc, AlphaBroadcast, ZeroMode); if (CountN - 4 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[5]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[5]); } } if (CountN - 4 > 0) { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[1]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[1]); } } else { - __builtin_mma_disassemble_acc ((void *)Accumulators[0], &acc[0]); + __builtin_mma_disassemble_acc (Accumulators[0], &acc[0]); if (CountM == 8) { - __builtin_mma_disassemble_acc ((void *)Accumulators[1], &acc[4]); + __builtin_mma_disassemble_acc (Accumulators[1], &acc[4]); } } From c82160bbd0e74a446dab17440dec87cdaaab5d6f Mon Sep 17 00:00:00 2001 From: Gani Nazirov Date: Mon, 13 Dec 2021 14:36:15 -0800 Subject: [PATCH 032/113] Add AtenOp at:bitwise_or (#9662) * Add AtenOp at:bitwise_or * Specify overload name for bitwise_or * undo unnecessary import * set output element type to BOOL * Add broadcasting support * Fix test Co-authored-by: Gani Nazirov Co-authored-by: Gani Nazirov --- .../python/tools/symbolic_shape_infer.py | 11 ++++++ .../ortmodule/_custom_op_symbolic_registry.py | 4 +++ .../python/orttraining_test_ortmodule_api.py | 35 +++++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/onnxruntime/python/tools/symbolic_shape_infer.py b/onnxruntime/python/tools/symbolic_shape_infer.py index cd5d30638e..ad878b4ed8 100755 --- a/onnxruntime/python/tools/symbolic_shape_infer.py +++ b/onnxruntime/python/tools/symbolic_shape_infer.py @@ -189,6 +189,7 @@ class SymbolicShapeInference: } self.aten_op_dispatcher_ = { 'aten::embedding': self._infer_Gather, + 'aten::bitwise_or': self._infer_aten_bitwise_or, 'aten::diagonal': self._infer_aten_diagonal, 'aten::max_pool2d_with_indices': self._infer_aten_pool2d, 'aten::multinomial': self._infer_aten_multinomial, @@ -1080,6 +1081,16 @@ class SymbolicShapeInference: helper.make_tensor_value_info(o, vi.type.tensor_type.elem_type, get_shape_from_sympy_shape(sympy_shape))) + def _infer_aten_bitwise_or(self, node): + shape0 = self._get_shape(node, 0) + shape1 = self._get_shape(node, 1) + new_shape = self._broadcast_shapes(shape0, shape1) + t0 = self.known_vi_[node.input[0]] + vi = self.known_vi_[node.output[0]] + vi.CopyFrom( + helper.make_tensor_value_info(node.output[0], t0.type.tensor_type.elem_type, + new_shape)) + def _infer_aten_diagonal(self, node): sympy_shape = self._get_sympy_shape(node, 0) rank = len(sympy_shape) diff --git a/orttraining/orttraining/python/training/ortmodule/_custom_op_symbolic_registry.py b/orttraining/orttraining/python/training/ortmodule/_custom_op_symbolic_registry.py index 3527e643ea..f193129a0a 100644 --- a/orttraining/orttraining/python/training/ortmodule/_custom_op_symbolic_registry.py +++ b/orttraining/orttraining/python/training/ortmodule/_custom_op_symbolic_registry.py @@ -73,6 +73,10 @@ def embedding(g, weight, indices, padding_idx, scale_grad_by_freq, sparse): output.setType(output_type) return output +@register_symbolic('bitwise_or') +def bitwise_or(g, self, other): + return g.op("com.microsoft::ATenOp", self, other, + name_s='aten::bitwise_or', overload_name_s='Tensor') @register_symbolic('diagonal') def diagonal(g, self, offset, dim1, dim2): diff --git a/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py b/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py index 595540a78a..0964e47f21 100644 --- a/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py +++ b/orttraining/orttraining/test/python/orttraining_test_ortmodule_api.py @@ -664,7 +664,7 @@ def test_gradient_correctness(): _test_helpers.assert_gradients_match_and_reset_gradient(ort_model, pt_model) @pytest.mark.parametrize("device", ['cpu', 'cuda']) -@pytest.mark.parametrize("indices", ([[ 2, 3, -1, -1],[0, 1, -1, -1]], +@pytest.mark.parametrize("indices", ([[ 2, 3, -1, -1],[0, 1, -1, -1]], [[ 2, 3, 4, 4],[ 0, 1, 4, 4]])) def test_scatternd_correctness(device, indices): class NeuralNetScatterND(torch.nn.Module): @@ -685,7 +685,7 @@ def test_scatternd_correctness(device, indices): rerouted_output = torch.tensor([[0.],[0.],[0.],[0.],[0.]], device=device) dispatch_mask = torch.tensor(indices, device=device) expert_output = torch.tensor([[[0.3817],[0.9625],[0.9625],[0.9625]],[[0.3817],[0.9625],[0.9625],[0.9625]]], device=device) - + pt_prediction = run_step(pt_model, rerouted_output, dispatch_mask, expert_output) ort_prediction = run_step(ort_model, rerouted_output, dispatch_mask, expert_output) _test_helpers.assert_values_are_close(ort_prediction, pt_prediction, atol=1e-5) @@ -1035,6 +1035,35 @@ def test_gradient_correctness_argmax_unfold(): _test_helpers.assert_values_are_close(ort_prediction, pt_prediction) _test_helpers.assert_gradients_match_and_reset_gradient(ort_model, pt_model) +@pytest.mark.parametrize("high", [1, 2, 10]) +def test_correctness_argmax_bitwise_or(high): + N, D, H, M = 16, 256, 128, 4 + device = 'cuda' + + class NeuralNetBitwiseOr(torch.nn.Module): + def __init__(self, high): + super(NeuralNetBitwiseOr, self).__init__() + self.other = torch.randint(0, high, (N, D, H), device=device) + + def forward(self, input): + return torch.bitwise_or(self.other, input) + + pt_model = NeuralNetBitwiseOr(high).to(device) + ort_model = ORTModule(copy.deepcopy(pt_model)) + + def run_step(model, input): + prediction = model(input) + return prediction + + for _ in range(10): + # this also tests broadcasting + pt_input = torch.randint(-10, 10, (M, N, D, H), device=device) + ort_input = copy.deepcopy(pt_input) + pt_prediction = run_step(pt_model, pt_input) + ort_prediction = run_step(ort_model, ort_input) + + _test_helpers.assert_values_are_close(ort_prediction, pt_prediction) + @pytest.mark.parametrize("offset", [-1, 0, 1]) @pytest.mark.parametrize("dim1, dim2", ([0, 1], [0, 2], [1, 2], [2, 0])) def test_gradient_correctness_argmax_diagonal(offset, dim1, dim2): @@ -4534,7 +4563,7 @@ def test_sigmoid_grad_opset13(): os.environ["ORTMODULE_ONNX_OPSET_VERSION"] = old_opset assert ortmodule.ONNX_OPSET_VERSION == 13 ortmodule.ONNX_OPSET_VERSION = old_opst_cst - + @pytest.mark.parametrize("opset_version", [12, 13, 14]) def test_opset_version_change(opset_version): device = 'cuda' From 7b63d1102b0fbbe79cdd55ad4daea0ffaa841ff1 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Mon, 13 Dec 2021 23:28:21 +0000 Subject: [PATCH 033/113] Fix some warnings in orttraining code (#10009) --- .../core/framework/distributed_run_context.h | 2 +- .../orttraining/core/framework/pipeline.cc | 23 +- .../orttraining/core/framework/pipeline.h | 10 +- .../core/graph/gradient_builder.cc | 2 +- .../orttraining/core/graph/graph_augmenter.h | 2 +- .../core/graph/pipeline_transformer.cc | 26 +- .../core/graph/training_op_defs.cc | 4 +- .../graph/zero_optimizer_graph_builder.cc | 2 +- .../core/optimizer/gist_encode_decode.cc | 2 +- .../core/optimizer/gist_encode_decode.h | 2 +- .../core/optimizer/megatron_transformer.cc | 2 +- .../orttraining/core/session/tensor_helper.cc | 2 +- .../core/session/training_session.cc | 4 +- .../core/session/training_session.h | 2 +- orttraining/orttraining/models/bert/main.cc | 2 +- orttraining/orttraining/models/gpt2/main.cc | 2 +- orttraining/orttraining/models/mnist/main.cc | 2 +- .../mnist/mnist_reader/mnist_reader.hpp | 2 +- .../mnist_reader/mnist_reader_common.hpp | 8 +- .../models/runner/training_runner.cc | 2 +- .../orttraining/models/runner/training_util.h | 2 +- .../test/distributed/partition_utils.hpp | 2 +- .../distributed/pipeline_schedule_test.cc | 8 +- .../test/gradient/event_op_test.cc | 8 +- .../test/gradient/gradient_ops_test.cc | 14 +- .../test/gradient/optimizer_ops_test.cc | 308 +++++++++--------- .../orttraining/test/graph/bert_toy_fetches.h | 6 +- .../test/graph/gradient_graph_builder_test.cc | 6 +- .../test/model/data_loader_test.cc | 12 +- .../training_ops/cpu/loss/cross_entropy.cc | 4 +- .../cpu/loss/softmax_cross_entropy_loss.cc | 6 +- 31 files changed, 244 insertions(+), 235 deletions(-) diff --git a/orttraining/orttraining/core/framework/distributed_run_context.h b/orttraining/orttraining/core/framework/distributed_run_context.h index 617c7c962f..fd6d151a6f 100644 --- a/orttraining/orttraining/core/framework/distributed_run_context.h +++ b/orttraining/orttraining/core/framework/distributed_run_context.h @@ -58,7 +58,7 @@ struct DistributedRunConfig { }; // This function returns the corresponding pipeline stage id for the given world rank. -inline int32_t GetPipelineStageId(const int32_t world_rank, +constexpr inline int32_t GetPipelineStageId(const int32_t world_rank, const int32_t horizontal_parallel_size, const int32_t data_parallel_size) { return world_rank / (data_parallel_size * horizontal_parallel_size); diff --git a/orttraining/orttraining/core/framework/pipeline.cc b/orttraining/orttraining/core/framework/pipeline.cc index 0ff29bdde1..5d4495cabd 100644 --- a/orttraining/orttraining/core/framework/pipeline.cc +++ b/orttraining/orttraining/core/framework/pipeline.cc @@ -11,7 +11,10 @@ #include #include #include - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace training { namespace pipeline { @@ -98,7 +101,7 @@ PipelineScheduler::PipelineScheduler( CreateComputeSchedule(); - const size_t num_events_per_slot_compute_side = 2; + constexpr size_t num_events_per_slot_compute_side = 2; std::vector compute_default_events(num_events_per_slot_compute_side, -1); InsertEvents(compute_table_, num_events_per_slot_compute_side, compute_default_events); @@ -107,7 +110,7 @@ PipelineScheduler::PipelineScheduler( // Change the pipeline stage ID to actual MPI rank in Send and Recv. MapStageIdToMpiRank(); - const size_t num_events_per_slot_side = 1; + constexpr size_t num_events_per_slot_side = 1; std::vector default_events(num_events_per_slot_side, -1); InsertEvents(compute_commute_table_, num_events_per_slot_side, default_events); } @@ -138,16 +141,16 @@ std::ostream& operator<<(std::ostream& stream, const PipelineSlot& slot) { return stream; } -void PipelineSlot::SetWaitedEvent(const std::vector events) { - waited_events_ = std::move(events); +void PipelineSlot::SetWaitedEvent(const std::vector& events) { + waited_events_ = events; } std::vector PipelineSlot::GetWaitedEvent() const { return waited_events_; } -void PipelineSlot::SetRecordedEvent(const std::vector events) { - recorded_events_ = std::move(events); +void PipelineSlot::SetRecordedEvent(const std::vector& events) { + recorded_events_ = events; } std::vector PipelineSlot::GetRecordedEvent() const { @@ -298,7 +301,7 @@ void PipelineScheduler::CreateFullSchedule() { } // Get the only action in this slot. - const auto action = slot.GetFrontAction(); + const auto& action = slot.GetFrontAction(); const int batch = action.batch; // Stage of upstream compute in compute-only table. @@ -319,7 +322,7 @@ void PipelineScheduler::CreateFullSchedule() { const auto upstream_slot = compute_table_.at(upstream_t).at(upstream_s); // Get the only action in upstream slot. - const auto upstream_action = upstream_slot.GetFrontAction(); + const auto& upstream_action = upstream_slot.GetFrontAction(); // Time of upstream compute in full table. const auto upstream_compute_time = upstream_action.full_table_time; @@ -479,7 +482,7 @@ std::vector PipelineScheduler::TryGetEvent( for (int t = 0; static_cast(t) < compute_commute_table_.size(); ++t) { const auto slot = compute_commute_table_.at(t).at(stage_id); for (int a = 0; static_cast(a) < slot.NumActions(); ++a) { - auto task = slot[a]; + auto& task = slot[a]; if (task.batch != batch_id) { continue; } diff --git a/orttraining/orttraining/core/framework/pipeline.h b/orttraining/orttraining/core/framework/pipeline.h index b5a58857cd..58b7f58338 100644 --- a/orttraining/orttraining/core/framework/pipeline.h +++ b/orttraining/orttraining/core/framework/pipeline.h @@ -125,9 +125,9 @@ class PipelineSlot { // Print this structure following a fixed-length format. // It assumes there are at most 2 actions per slot. friend std::ostream& operator<<(std::ostream& stream, const PipelineSlot& slot); - void SetWaitedEvent(const std::vector event); + void SetWaitedEvent(const std::vector& event); std::vector GetWaitedEvent() const; - void SetRecordedEvent(const std::vector event); + void SetRecordedEvent(const std::vector& event); std::vector GetRecordedEvent() const; std::vector GetTasks() { return tasks_; } @@ -322,13 +322,13 @@ struct PipelineTensorNames { struct PipelineContext { // Number of pipeline stages. - int num_pipeline_stages; + int num_pipeline_stages = 0; // Id of stage handled by this process. Currently, it matches the MPI's rank. - int pipeline_stage_id; + int pipeline_stage_id = 0; // The number of micro-batches per pipeline round. // Only the last step among num_gradient_accumulation_steps steps may call // optimizer to update the model. - int num_pipeline_micro_batches; + int num_pipeline_micro_batches = 0; // Names of scheduling event in graph's input list and // names of event ops' outputs. If an event name is an // empty string, it means no event should be waited or recorded. diff --git a/orttraining/orttraining/core/graph/gradient_builder.cc b/orttraining/orttraining/core/graph/gradient_builder.cc index 342132e5c3..10987beb0d 100755 --- a/orttraining/orttraining/core/graph/gradient_builder.cc +++ b/orttraining/orttraining/core/graph/gradient_builder.cc @@ -623,7 +623,7 @@ IMPLEMENT_GRADIENT_BUILDER(GetTransposeGradient) { if (attributes.empty()) { const TensorShapeProto& input_shape = I(0).type_proto->tensor_type().shape(); if (input_shape.dim_size() > 0) { // input_shape is available - int n = input_shape.dim_size() - 1; + size_t n = static_cast(input_shape.dim_size()) - 1; bw_perm.resize(n + 1); std::generate(bw_perm.begin(), bw_perm.end(), [&n] { return n--; }); new_attributes.push_back(MakeAttribute("perm", bw_perm)); diff --git a/orttraining/orttraining/core/graph/graph_augmenter.h b/orttraining/orttraining/core/graph/graph_augmenter.h index 3a6d7a4099..eb146ca0e8 100644 --- a/orttraining/orttraining/core/graph/graph_augmenter.h +++ b/orttraining/orttraining/core/graph/graph_augmenter.h @@ -29,7 +29,7 @@ struct ArgDef { }; struct OpDef { - OpDef() {} + OpDef() : opset_version(-1) {} OpDef(const std::string& type, const std::string& domain = kOnnxDomain, const int opset_version = 9) : type(type), domain(domain), diff --git a/orttraining/orttraining/core/graph/pipeline_transformer.cc b/orttraining/orttraining/core/graph/pipeline_transformer.cc index e2ea8ffb3d..f4415f1803 100644 --- a/orttraining/orttraining/core/graph/pipeline_transformer.cc +++ b/orttraining/orttraining/core/graph/pipeline_transformer.cc @@ -1238,13 +1238,13 @@ void UpdateInputsOfConsumers(Graph& graph, // Checks whether the tensor is produced and consumed in the forward stage of // the computation. -bool IsForwardComputation(const int producer_stage, const int consumer_stage) { +constexpr bool IsForwardComputation(const int producer_stage, const int consumer_stage) { return producer_stage < consumer_stage; }; // Checks whether the tensor is produced and consumed in the backward stage of // the computation. -bool IsBackwardComputation(const int producer_stage, const int consumer_stage) { +constexpr bool IsBackwardComputation(const int producer_stage, const int consumer_stage) { return producer_stage > consumer_stage; }; @@ -1423,7 +1423,7 @@ common::Status SplitGraphWithOperatorToStageMap(Graph& graph, for (auto& message : messages) { auto current_stage = message.first; - auto next_stage = message.second; + int next_stage = message.second; // for each pair of stages, record the inserted input/output args. std::vector send_input_args; @@ -1465,7 +1465,7 @@ common::Status SplitGraphWithOperatorToStageMap(Graph& graph, // Update the inputs of the next_stage consumers with the right replicas. UpdateInputsOfConsumers(graph, tensor_replicas, op_to_stage, next_stage); - const int num_attributes = 2; // two attributes: tag and element_types + constexpr int num_attributes = 2; // two attributes: tag and element_types NodeAttributes attributes; attributes.reserve(num_attributes); attributes[tag.name()] = tag; @@ -1488,7 +1488,8 @@ common::Status SplitGraphWithOperatorToStageMap(Graph& graph, "Stage cannot send message to itself."); if (current_stage < next_stage) { send_nodes.at(current_stage) = &send_node; - receive_nodes.at(next_stage - 1) = &receive_node; + assert(next_stage > 0); + receive_nodes.at(static_cast(next_stage) - 1) = &receive_node; } // TODO(jufranc): consider backward sends and receives. // else if (current_stage > next_stage) { @@ -1565,8 +1566,11 @@ void GenerateSubgraph(Graph& graph, const int num_stages, Status ApplyPipelinePartitionToMainGraph(Graph& graph, const std::map& op_to_stage, const int pipeline_stage_id, - const int num_stages, + const int num_stages_input, const std::vector& rank_ids) { + if (num_stages_input <= 0) + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "invalid value of num_stages"); + const size_t num_stages = static_cast(num_stages_input); // TODO(jufranc): in order to support more general pipeline shapes, we need to // do some analysis on the graph and assignment of operators to stages, to // find which messages will be sent. For now, we assume that 1) there are @@ -1574,10 +1578,10 @@ Status ApplyPipelinePartitionToMainGraph(Graph& graph, // partition of training graphs, we need to let tensors be copied from s+1 to // s, as well. std::vector stage_to_rank(num_stages); - ORT_ENFORCE(static_cast(rank_ids.size()) == num_stages); + ORT_ENFORCE(rank_ids.size() == num_stages); std::vector> messages; - for (int s = 0; s < num_stages - 1; ++s) { - messages.emplace_back(s, s + 1); + for (size_t s = 0; s < num_stages - 1; ++s) { + messages.emplace_back(static_cast(s), static_cast(s + 1)); stage_to_rank.at(s) = rank_ids.at(s); } stage_to_rank.at(num_stages - 1) = rank_ids.at(num_stages - 1); @@ -1607,7 +1611,7 @@ Status ApplyPipelinePartitionToMainGraph(Graph& graph, // Split the graph into disconnected sub-graphs given the mapping of // operations to stages. ORT_RETURN_IF_ERROR(SplitGraphWithOperatorToStageMap(graph, op_to_stage, - num_stages, messages, + static_cast(num_stages), messages, send_nodes, recv_nodes, stage_to_rank)); @@ -1615,7 +1619,7 @@ Status ApplyPipelinePartitionToMainGraph(Graph& graph, ORT_RETURN_IF_ERROR(HandleSharedInitializer(graph, send_nodes, recv_nodes)); std::set visited_outputs; - GenerateSubgraph(graph, num_stages, op_to_stage, pipeline_stage_id, + GenerateSubgraph(graph, static_cast(num_stages), op_to_stage, pipeline_stage_id, send_nodes, recv_nodes, node_topology_list, visited_outputs); graph.SetOutputs({visited_outputs.begin(), visited_outputs.end()}); diff --git a/orttraining/orttraining/core/graph/training_op_defs.cc b/orttraining/orttraining/core/graph/training_op_defs.cc index 749032ea9d..5289227ad3 100644 --- a/orttraining/orttraining/core/graph/training_op_defs.cc +++ b/orttraining/orttraining/core/graph/training_op_defs.cc @@ -463,8 +463,8 @@ OpSchema& RegisterLambOpSchema(OpSchema&& op_schema) { "Constrain update count to 64-bit integer") .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { // Handle update count, the first output. - const size_t step_input_index = 4; - const size_t step_output_index = 0; + constexpr size_t step_input_index = 4; + constexpr size_t step_output_index = 0; auto input_type = ctx.getInputType(step_input_index); if (input_type != nullptr) { propagateElemTypeFromInputToOutput(ctx, step_input_index, step_output_index); diff --git a/orttraining/orttraining/core/graph/zero_optimizer_graph_builder.cc b/orttraining/orttraining/core/graph/zero_optimizer_graph_builder.cc index 3072592389..c7d4bb51c7 100644 --- a/orttraining/orttraining/core/graph/zero_optimizer_graph_builder.cc +++ b/orttraining/orttraining/core/graph/zero_optimizer_graph_builder.cc @@ -329,7 +329,7 @@ static Status ModifyParametersForOptimizerPartitioning( // Note: the alignment here needs to be kept in-sync with the alignment in nccl_kernels.cc const int data_parallel_group_rank = opt_graph_config.data_parallel_group_rank; const int data_parallel_group_size = opt_graph_config.data_parallel_group_size; - const int64_t alignment = data_parallel_group_size * 32; + const int64_t alignment = static_cast(data_parallel_group_size) * 32; const int64_t padded_count = total_count + alignment - (total_count % alignment); const int64_t rank_count = padded_count / data_parallel_group_size; const int64_t rank_start = data_parallel_group_rank * rank_count; diff --git a/orttraining/orttraining/core/optimizer/gist_encode_decode.cc b/orttraining/orttraining/core/optimizer/gist_encode_decode.cc index 8baea5a1ad..cd50ab87a8 100644 --- a/orttraining/orttraining/core/optimizer/gist_encode_decode.cc +++ b/orttraining/orttraining/core/optimizer/gist_encode_decode.cc @@ -134,7 +134,7 @@ bool GistEncodeDecode::AddEncodeDecode(Graph& graph, Node& curr_node, std::strin auto element_type = curr_node_output_arg->TypeAsProto()->tensor_type().elem_type(); output_type.set_i(static_cast(element_type)); - const int num_attributes = 1; // one attribute: decoder's output data type + constexpr int num_attributes = 1; // one attribute: decoder's output data type NodeAttributes attributes; attributes.reserve(num_attributes); attributes[output_type.name()] = output_type; diff --git a/orttraining/orttraining/core/optimizer/gist_encode_decode.h b/orttraining/orttraining/core/optimizer/gist_encode_decode.h index 8b087c151d..4730bc9000 100644 --- a/orttraining/orttraining/core/optimizer/gist_encode_decode.h +++ b/orttraining/orttraining/core/optimizer/gist_encode_decode.h @@ -32,7 +32,7 @@ class GistEncodeDecode : public RewriteRule { {"MatMul", {"Shape"}}, {"Relu", {"ReluGrad", "Shape", "Reshape"}}}; - GistEncodeDecode() noexcept : RewriteRule("GistEncodeDecode") {} + GistEncodeDecode() noexcept : RewriteRule("GistEncodeDecode"), compression_type_() {} GistEncodeDecode(int op_type, std::string compr_type) noexcept : RewriteRule("GistEncodeDecode"), operator_type(op_type), compression_type_(std::move(compr_type)) {} private: diff --git a/orttraining/orttraining/core/optimizer/megatron_transformer.cc b/orttraining/orttraining/core/optimizer/megatron_transformer.cc index b24a283b03..7e7ebe54a8 100644 --- a/orttraining/orttraining/core/optimizer/megatron_transformer.cc +++ b/orttraining/orttraining/core/optimizer/megatron_transformer.cc @@ -160,7 +160,7 @@ bool MegatronTransformer::PartitionWeightByColumn(const Graph& graph, const Node return false; } - if (column_count % (horizontal_parallel_size_ * stride) != 0) { + if (column_count % (static_cast(horizontal_parallel_size_) * stride) != 0) { LOGS_DEFAULT(WARNING) << "last dim " << column_count << " is not divisible by horizontal_parallel_size_ times stride " << (horizontal_parallel_size_ * stride) << ", not supported currently."; diff --git a/orttraining/orttraining/core/session/tensor_helper.cc b/orttraining/orttraining/core/session/tensor_helper.cc index fa5bc3971d..6957e1b552 100644 --- a/orttraining/orttraining/core/session/tensor_helper.cc +++ b/orttraining/orttraining/core/session/tensor_helper.cc @@ -103,7 +103,7 @@ void CopyToCpuTensor(Tensor& dst, const Tensor& src) { // For a tensor with shape [D1, D2, D3], the linear index of element at (x, y, z) is // i = x * (D2 * D3) + y * D3 + z. If we append one dimension to form a new shape [D1, D2, D3, D4], // the new linear index at (x, y, z, u) can be computed using i * D4 + u. -size_t UpdateLinearIndex(const size_t linear_index, const size_t new_axis_index, const size_t new_axis_dim) { +constexpr size_t UpdateLinearIndex(const size_t linear_index, const size_t new_axis_index, const size_t new_axis_dim) { return linear_index * new_axis_dim + new_axis_index; } diff --git a/orttraining/orttraining/core/session/training_session.cc b/orttraining/orttraining/core/session/training_session.cc index afecdc7eb0..9c02f78516 100644 --- a/orttraining/orttraining/core/session/training_session.cc +++ b/orttraining/orttraining/core/session/training_session.cc @@ -126,7 +126,7 @@ Status SetupOptimizerParams( // check if shared initial optimizer states have been provided const auto optim_state_it = init_optimizer_states.find(onnxruntime::training::SHARED_OPTIMIZER_STATES_KEY); if (optim_state_it != init_optimizer_states.end()) { - opt_graph_config.shared_optimizer_states = std::move(optim_state_it->second); + opt_graph_config.shared_optimizer_states = optim_state_it->second; } opt_node_configs_result = std::move(opt_node_configs); @@ -1846,7 +1846,7 @@ void PipelineTrainingSession::CreatePipelineEvents( common::Status PipelineTrainingSession::RunWithPipeline(const RunOptions& run_options, IOBinding& io_binding) { const size_t num_steps = pipeline_context_.num_pipeline_micro_batches; const size_t stage_id = pipeline_context_.pipeline_stage_id; - const bool training_mode = true; + constexpr bool training_mode = true; std::vector> sub_io_bindings(num_steps); diff --git a/orttraining/orttraining/core/session/training_session.h b/orttraining/orttraining/core/session/training_session.h index 3571167df7..fb184051bc 100644 --- a/orttraining/orttraining/core/session/training_session.h +++ b/orttraining/orttraining/core/session/training_session.h @@ -45,7 +45,7 @@ class TrainingSession : public InferenceSession { }; TrainingSession(const SessionOptions& session_options, const Environment& env) - : InferenceSession(session_options, env) {} + : InferenceSession(session_options, env), is_mixed_precision_enabled_(false) {} virtual ~TrainingSession(){}; /** diff --git a/orttraining/orttraining/models/bert/main.cc b/orttraining/orttraining/models/bert/main.cc index 0273511c6d..4c494cafce 100644 --- a/orttraining/orttraining/models/bert/main.cc +++ b/orttraining/orttraining/models/bert/main.cc @@ -800,7 +800,7 @@ static Status RunPerformanceTest(const BertParameters& params, const Environment } static Status RunTraining(const BertParameters& params, const Environment& env) { - const size_t max_num_files_preload = 2; + constexpr size_t max_num_files_preload = 2; auto runner = std::make_unique(params, env, session_options); ORT_RETURN_IF_ERROR(runner->Initialize()); diff --git a/orttraining/orttraining/models/gpt2/main.cc b/orttraining/orttraining/models/gpt2/main.cc index 685926b882..1499818733 100644 --- a/orttraining/orttraining/models/gpt2/main.cc +++ b/orttraining/orttraining/models/gpt2/main.cc @@ -442,7 +442,7 @@ static Status RunPerformanceTest(const GPT2Parameters& params, const Environment } static Status RunTraining(const GPT2Parameters& params, const Environment& env) { - const size_t max_num_files_preload = 2; + constexpr size_t max_num_files_preload = 2; auto runner = std::make_unique(params, env); ORT_RETURN_IF_ERROR(runner->Initialize()); diff --git a/orttraining/orttraining/models/mnist/main.cc b/orttraining/orttraining/models/mnist/main.cc index 80176bdb1f..f1a1547617 100644 --- a/orttraining/orttraining/models/mnist/main.cc +++ b/orttraining/orttraining/models/mnist/main.cc @@ -34,7 +34,7 @@ using namespace onnxruntime::training; using namespace onnxruntime::training::tensorboard; using namespace std; -const static int NUM_CLASS = 10; +constexpr static int NUM_CLASS = 10; const static vector IMAGE_DIMS_GEMM = {784}; // for mnist_gemm models const static vector IMAGE_DIMS_CONV = {1, 28, 28}; // for mnist_conv models const static vector LABEL_DIMS = {10}; diff --git a/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader.hpp b/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader.hpp index fdfb9bf932..85d6acc166 100644 --- a/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader.hpp +++ b/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader.hpp @@ -137,7 +137,7 @@ void read_mnist_image_file(Container& images, const std::string& path, st for (size_t i = 0; i < count; ++i) { images.push_back(func()); - for (size_t j = 0; j < rows * columns; ++j) { + for (size_t j = 0; j < static_cast(rows) * columns; ++j) { auto pixel = *image_buffer++; images[i][j] = static_cast(pixel); } diff --git a/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader_common.hpp b/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader_common.hpp index b481887fac..f5d7d82cfd 100644 --- a/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader_common.hpp +++ b/orttraining/orttraining/models/mnist/mnist_reader/mnist_reader_common.hpp @@ -43,7 +43,7 @@ inline std::unique_ptr read_mnist_file(const std::string& path, uint32_t return {}; } - auto size = file.tellg(); + std::streampos size = file.tellg(); std::unique_ptr buffer(new char[size]); //Read the entire file at once @@ -58,18 +58,18 @@ inline std::unique_ptr read_mnist_file(const std::string& path, uint32_t return {}; } - auto count = read_header(buffer, 1); + uint32_t count = read_header(buffer, 1); if (magic == 0x803) { auto rows = read_header(buffer, 2); auto columns = read_header(buffer, 3); - if (size < count * rows * columns + 16) { + if (size < static_cast(count) * rows * columns + 16) { std::cout << "The file is not large enough to hold all the data, probably corrupted" << std::endl; return {}; } } else if (magic == 0x801) { - if (size < count + 8) { + if (size < static_cast(count) + static_cast(8)) { std::cout << "The file is not large enough to hold all the data, probably corrupted" << std::endl; return {}; } diff --git a/orttraining/orttraining/models/runner/training_runner.cc b/orttraining/orttraining/models/runner/training_runner.cc index 44e61cbfa3..4a1ce258e8 100644 --- a/orttraining/orttraining/models/runner/training_runner.cc +++ b/orttraining/orttraining/models/runner/training_runner.cc @@ -758,7 +758,7 @@ Status TrainingRunner::TrainingLoop(IDataLoader& training_data_loader, IDataLoad const size_t stabilized_perf_total_step_count = std::min(static_cast(128), params_.num_train_steps); const size_t stabilized_perf_start_step = params_.num_train_steps - stabilized_perf_total_step_count; double stabilized_total_time{0}; - const size_t end_to_end_perf_start_step = 128; + constexpr size_t end_to_end_perf_start_step = 128; auto end_to_end_start = std::chrono::high_resolution_clock::now(); bool end_to_end_measurement_started = false; diff --git a/orttraining/orttraining/models/runner/training_util.h b/orttraining/orttraining/models/runner/training_util.h index 5fa73be7a6..342be22c84 100644 --- a/orttraining/orttraining/models/runner/training_util.h +++ b/orttraining/orttraining/models/runner/training_util.h @@ -316,7 +316,7 @@ class PolyScheduler : public LearningRateScheduler { return cur_ratio / warmp_ratio; } - const float degree = 0.5f; + constexpr float degree = 0.5f; return std::pow(1.f - cur_ratio, degree); } }; diff --git a/orttraining/orttraining/test/distributed/partition_utils.hpp b/orttraining/orttraining/test/distributed/partition_utils.hpp index e2cad09daa..9d3de0cf6a 100644 --- a/orttraining/orttraining/test/distributed/partition_utils.hpp +++ b/orttraining/orttraining/test/distributed/partition_utils.hpp @@ -491,7 +491,7 @@ common::Status SplitGraph(Graph& graph, } } } - const int num_attributes = 2; // two attributes: tag and element_types + constexpr int num_attributes = 2; // two attributes: tag and element_types NodeAttributes attributes; attributes.reserve(num_attributes); attributes[tag.name()] = tag; diff --git a/orttraining/orttraining/test/distributed/pipeline_schedule_test.cc b/orttraining/orttraining/test/distributed/pipeline_schedule_test.cc index d07a8f902a..e87454d06f 100644 --- a/orttraining/orttraining/test/distributed/pipeline_schedule_test.cc +++ b/orttraining/orttraining/test/distributed/pipeline_schedule_test.cc @@ -26,8 +26,8 @@ void TestPipelineScheduler(const int num_batches, const int num_stages, std::vec const auto backward_send_wait = schedule.GetBackwardSendWaitedEvent(b, s); const auto backward_send_record = schedule.GetBackwardSendRecordedEvent(b, s); - const auto batch_stride = 6; - const auto stage_stride = 2; + constexpr auto batch_stride = 6; + constexpr auto stage_stride = 2; EXPECT_EQ(forward_recv_wait, baseline_events.at(stage_stride * s + 0).at(batch_stride * b + 0)) << " batch " << b << " stage " << s; EXPECT_EQ(forward_recv_record, baseline_events.at(stage_stride * s + 0).at(batch_stride * b + 1)) << " batch " << b << " stage " << s; EXPECT_EQ(forward_compute_wait, baseline_events.at(stage_stride * s + 0).at(batch_stride * b + 2)) << " batch " << b << " stage " << s; @@ -46,8 +46,8 @@ void TestPipelineScheduler(const int num_batches, const int num_stages, std::vec } TEST(Pipeline, ScheduleB5S3) { - const int num_batches = 5; - const int num_stages = 3; + constexpr int num_batches = 5; + constexpr int num_stages = 3; // The event baselines at different stages are the same. // The first 4 events are for the first computation on that stage. diff --git a/orttraining/orttraining/test/gradient/event_op_test.cc b/orttraining/orttraining/test/gradient/event_op_test.cc index 881ed4fa5d..a3109b83a8 100644 --- a/orttraining/orttraining/test/gradient/event_op_test.cc +++ b/orttraining/orttraining/test/gradient/event_op_test.cc @@ -78,7 +78,7 @@ void wait_event_multiple_inputs_and_outputs(int64_t event_id) { } TEST(Synchronization, RecordAndWaitEvent) { - const int64_t event_id = static_cast(1736); + constexpr int64_t event_id = static_cast(1736); record_event(event_id); wait_event(event_id); } @@ -88,13 +88,13 @@ TEST(Synchronization, WaitNullEvent) { } TEST(Synchronization, RecordAndWaitEventMultipleInputsAndOutputs) { - const int64_t event_id = static_cast(995); + constexpr int64_t event_id = static_cast(995); record_event_multiple_inputs_and_outputs(event_id); wait_event_multiple_inputs_and_outputs(event_id); } TEST(Synchronization, WaitAndRecordEvent) { - const int64_t event_id = static_cast(1228); + constexpr int64_t event_id = static_cast(1228); std::thread waiting_thread(wait_event, event_id); std::this_thread::sleep_for(std::chrono::milliseconds(5)); std::thread recording_thread(record_event, event_id); @@ -104,7 +104,7 @@ TEST(Synchronization, WaitAndRecordEvent) { } TEST(Synchronization, WaitAndRecordEventMany) { - const size_t event_count = 16; + constexpr size_t event_count = 16; for (int i = 0; i < 8; ++i) { std::thread thread_pool[2 * event_count]; for (int j = 0; j < static_cast(event_count); ++j) { diff --git a/orttraining/orttraining/test/gradient/gradient_ops_test.cc b/orttraining/orttraining/test/gradient/gradient_ops_test.cc index 4535cd5e3f..84e35add8c 100644 --- a/orttraining/orttraining/test/gradient/gradient_ops_test.cc +++ b/orttraining/orttraining/test/gradient/gradient_ops_test.cc @@ -355,7 +355,7 @@ TEST(GradientCheckerTest, PowGrad) { void RunMatMulGradTests(const OpDef& op_def) { float max_error; - const float error_tolerance = 1e-1f; + constexpr float error_tolerance = 1e-1f; GradientChecker gradient_checker; const std::vector attributes = {}; @@ -508,7 +508,7 @@ TEST(GradientCheckerTest, TanhGrad) { // failing random seed with error_tolerance of 1.5e-2f: 322298223 void RunGemmGradTests(const OpDef& op_def) { float max_error; - const float error_tolerance = 2e-2f; + constexpr float error_tolerance = 2e-2f; GradientChecker gradient_checker; const std::vector attributes = {}; @@ -729,7 +729,7 @@ TEST(GradientCheckerTest, MaxPoolGrad) { float max_error; GradientChecker gradient_checker; OpDef op_def{"MaxPool"}; - const float error_tolerance = 1e-3f; + constexpr float error_tolerance = 1e-3f; //maxpool_1d_default { ASSERT_STATUS_OK(gradient_checker.ComputeGradientError(op_def, {{2, 2, 9}}, {{2, 2, 8}}, &max_error, @@ -778,7 +778,7 @@ TEST(GradientCheckerTest, GlobalAveragePoolGrad) { float max_error; GradientChecker gradient_checker; OpDef op_def{"GlobalAveragePool"}; - const float error_tolerance = 1e-3f; + constexpr float error_tolerance = 1e-3f; //globalaveragepool { @@ -1642,7 +1642,7 @@ void TestSparseSoftmaxCrossEntropyGrad(const TensorShape& index_shape, const std GradientChecker gradient_checker; OpDef op_def{"SparseSoftmaxCrossEntropy"}; - const int64_t D = 7; + constexpr int64_t D = 7; std::function transformer_index = [](float x) { return std::fmod(std::fabs(x) * 5.0f, 7.0f); }; std::function transformer_weight = [](float x) { return std::fmod(std::fabs(x), 2.0f); }; @@ -2761,8 +2761,8 @@ TEST(GradientCheckerTest, TriluGrad) { float max_error; GradientChecker gradient_checker; OpDef op_def{"Trilu", kMSDomain, 1}; - const int M = 3; - const int N = 4; + constexpr int M = 3; + constexpr int N = 4; TensorShape shape = {M, N}; TensorInfo x_info(shape); TensorInfo k_info({1}, false, nullptr, DataTypeImpl::GetTensorType()); diff --git a/orttraining/orttraining/test/gradient/optimizer_ops_test.cc b/orttraining/orttraining/test/gradient/optimizer_ops_test.cc index d435882978..35fd4bc7d9 100644 --- a/orttraining/orttraining/test/gradient/optimizer_ops_test.cc +++ b/orttraining/orttraining/test/gradient/optimizer_ops_test.cc @@ -917,20 +917,20 @@ void run_lamb_mix_precision_test( TEST(OptimizerTest, LambOptimizerTestVector) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f, 2.0f}; const std::vector g = {3.0f, 4.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -951,19 +951,19 @@ TEST(OptimizerTest, LambOptimizerTestVector) { TEST(OptimizerTest, LambOptimizerTestVectorWithZeroWeight) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {0.0f, 0.0f}; const std::vector g = {1.0f, -1.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -984,21 +984,21 @@ TEST(OptimizerTest, LambOptimizerTestVectorWithZeroWeight) { TEST(OptimizerTest, LambOptimizerRatioMin) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {-1.0f, 1.0f}; const std::vector g = {1.0f, -1.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; - const float ratio_min = -std::numeric_limits::infinity(); - const float ratio_max = 0.1f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; + constexpr float ratio_min = -std::numeric_limits::infinity(); + constexpr float ratio_max = 0.1f; run_multi_tensor_lamb_test( {shape}, @@ -1022,21 +1022,21 @@ TEST(OptimizerTest, LambOptimizerRatioMin) { TEST(OptimizerTest, LambOptimizerRatioMax) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {0.0001f, -0.0001f}; const std::vector g = {1.0f, -1.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; - const float ratio_min = 1.0f; - const float ratio_max = std::numeric_limits::infinity(); + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; + constexpr float ratio_min = 1.0f; + constexpr float ratio_max = std::numeric_limits::infinity(); run_multi_tensor_lamb_test( {shape}, @@ -1060,20 +1060,20 @@ TEST(OptimizerTest, LambOptimizerRatioMax) { TEST(OptimizerTest, LambOptimizerTestBiasCorrectionFirst) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f, 2.0f}; const std::vector g = {3.0f, 4.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; - const int64_t step = 1; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr int64_t step = 1; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -1094,20 +1094,20 @@ TEST(OptimizerTest, LambOptimizerTestBiasCorrectionFirst) { TEST(OptimizerTest, LambOptimizerTestBiasCorrectionThird) { // Input tensors and attributes. const std::vector shape = {2}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f, 2.0f}; const std::vector g = {3.0f, 4.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; - const int64_t step = 3; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr int64_t step = 3; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -1129,20 +1129,20 @@ TEST(OptimizerTest, LambOptimizerTestBiasCorrectionThird) { TEST(OptimizerTest, LambOptimizerTest4DTensor) { // Input tensors and attributes. const std::vector shape = {2, 1, 1, 1}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f, 2.0f}; const std::vector g = {3.0f, 4.0f}; const std::vector m = {-1.0f, -2.0f}; const std::vector v = {2.0f, 1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -1164,20 +1164,20 @@ TEST(OptimizerTest, LambOptimizerTest4DTensor) { TEST(OptimizerTest, LambOptimizerTest2by3Tensor) { // Input tensors and attributes. const std::vector shape = {2, 3}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f, 2.0f, 1.0f, 1.0f, 2.0f, 2.0f}; const std::vector g = {3.0f, 4.0f, 3.0f, 3.0f, 4.0f, 4.0f}; const std::vector m = {-1.0f, -2.0f, 2.0f, 1.0f, 1.0f, -2.0f}; const std::vector v = {1.0f, 1.0f, 5.0f, 5.0f, 6.0f, 6.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, eta, @@ -1199,19 +1199,19 @@ TEST(OptimizerTest, LambOptimizerTest2by3Tensor) { TEST(OptimizerTest, LambOptimizerTestScalar) { // Input tensors and attributes. const std::vector shape = {(int64_t)1}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f}; const std::vector g = {3.0f}; const std::vector m = {-10.0f}; const std::vector v = {1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; // Intermediate and output buffers of the optimizer. std::vector m_new = {0.0f}; @@ -1239,24 +1239,24 @@ TEST(OptimizerTest, LambOptimizerTestScalar) { TEST(OptimizerTest, LambOptimizerTestScalar_NonDefaultMaxNormClipping) { // Input tensors and attributes. const std::vector shape = {(int64_t)1}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f}; const std::vector g = {3.0f}; const std::vector m = {-10.0f}; const std::vector v = {1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 0.1f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 0.1f; // Intermediate and output buffers of the optimizer. std::vector m_new = {0.0f}; std::vector v_new = {0.0f}; std::vector w_new = {0.0f}; - const int64_t step = 0; - const float loss_scale = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.0f; const float scaled_g_norm = g[0]; run_multi_tensor_lamb_test( {shape}, @@ -1278,19 +1278,19 @@ TEST(OptimizerTest, LambOptimizerTestScalar_NonDefaultMaxNormClipping) { TEST(OptimizerTest, LambOptimizerTestScalarScaling) { // Input tensors and attributes. const std::vector shape = {(int64_t)1}; - const float eta = 0.5f; + constexpr float eta = 0.5f; const std::vector w = {1.0f}; const std::vector g = {3.0f}; const std::vector m = {-10.0f}; const std::vector v = {1.0f}; - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 8.f; - const float scaled_g_norm = 4.f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 8.f; + constexpr float scaled_g_norm = 4.f; // Intermediate and output buffers of the optimizer. std::vector m_new = {0.0f}; @@ -1331,11 +1331,11 @@ TEST(OptimizerTest, LambOptimizerTestExternalBaseline) { 4.2659229e+01f, 1.1438165e+02f, 9.3179581e+01f, 4.7399229e-01f, 3.4129276e+01f, 9.0019435e-02f, 1.4493006e+01f, 3.9455612e+01f, 9.3025581e+01f, 1.6000764e+0f}; - const float lambda = 0.1f; - const float alpha = 0.1f; - const float beta = 0.01f; - const float epsilon = 0.1f; - const float max_norm = 1.0f; + constexpr float lambda = 0.1f; + constexpr float alpha = 0.1f; + constexpr float beta = 0.01f; + constexpr float epsilon = 0.1f; + constexpr float max_norm = 1.0f; std::vector w_new = { 0.02979828f, 0.13677707f, -0.22708717f, -0.20361158f, -0.15338624f, 0.1081504f, @@ -1376,11 +1376,11 @@ TEST(OptimizerTest, LambOptimizerTestExternalBaselineDouble) { 4.2659229e+01, 1.1438165e+02, 9.3179581e+01, 4.7399229e-01, 3.4129276e+01, 9.0019435e-02, 1.4493006e+01, 3.9455612e+01, 9.3025581e+01, 1.6000764e+0}; - const float lambda = 0.1f; - const float alpha = 0.1f; - const float beta = 0.01f; - const float epsilon = 0.1f; - const float max_norm = 1.0f; + constexpr float lambda = 0.1f; + constexpr float alpha = 0.1f; + constexpr float beta = 0.01f; + constexpr float epsilon = 0.1f; + constexpr float max_norm = 1.0f; std::vector w_new = { 0.02979828, 0.13677707, -0.22708717, -0.20361158, -0.15338624, 0.1081504, @@ -1412,12 +1412,12 @@ TEST(OptimizerTest, LambOptimizerTest5DTensorMixPrecision32_16) { const std::vector m = {1.0f, 2.0f, -0.25f, 1.1f, 1.0f, 2.0f, -0.21f, 1.1f}; const std::vector v = {1.5f, 1.0f, 1.1f, 0.76f, 1.5f, 1.0f, 1.5f, 0.76f}; - const float lambda = 1.5f; - const float alpha = 1.5f; - const float beta = 1.5f; - const float epsilon = 1.0f; - const float max_norm = 1.0f; - const float loss_scale = 1.0f; + constexpr float lambda = 1.5f; + constexpr float alpha = 1.5f; + constexpr float beta = 1.5f; + constexpr float epsilon = 1.0f; + constexpr float max_norm = 1.0f; + constexpr float loss_scale = 1.0f; run_lamb_mix_precision_test( shape, eta, w, g, m, v, lambda, alpha, beta, epsilon, max_norm); @@ -1436,12 +1436,12 @@ TEST(OptimizerTest, LambOptimizerTestSimpleBaselineMixPrecision32_16) { const std::vector m = {1.0f, 1.0f}; const std::vector v = {0.0f, 0.0f}; - const float lambda = 0.0f; - const float alpha = 1.0f; - const float beta = 1.0f; - const float epsilon = 1.0f; - const float max_norm = 1.0f; - const float loss_scale = 1.0f; + constexpr float lambda = 0.0f; + constexpr float alpha = 1.0f; + constexpr float beta = 1.0f; + constexpr float epsilon = 1.0f; + constexpr float max_norm = 1.0f; + constexpr float loss_scale = 1.0f; run_lamb_mix_precision_test( shape, eta, w, g, m, v, lambda, alpha, beta, epsilon, max_norm); @@ -1461,12 +1461,12 @@ TEST(OptimizerTest, LambOptimizerTestBaselineMixPrecision32_16) { const std::vector m = {0.87f, -0.94f}; const std::vector v = {0.12f, 0.28f}; - const float lambda = 0.25f; - const float alpha = 0.9f; - const float beta = 0.95f; - const float epsilon = 0.33f; - const float max_norm = 1.0f; - const float loss_scale = 1.0f; + constexpr float lambda = 0.25f; + constexpr float alpha = 0.9f; + constexpr float beta = 0.95f; + constexpr float epsilon = 0.33f; + constexpr float max_norm = 1.0f; + constexpr float loss_scale = 1.0f; run_lamb_mix_precision_test( shape, eta, w, g, m, v, @@ -1487,12 +1487,12 @@ TEST(OptimizerTest, LambOptimizerTestScalarMixPrecision32_16) { const std::vector m = {0.87f}; const std::vector v = {0.12f}; - const float lambda = 0.25f; - const float alpha = 0.9f; - const float beta = 0.95f; - const float epsilon = 0.33f; - const float max_norm = 1.0f; - const float loss_scale = 1.0f; + constexpr float lambda = 0.25f; + constexpr float alpha = 0.9f; + constexpr float beta = 0.95f; + constexpr float epsilon = 0.33f; + constexpr float max_norm = 1.0f; + constexpr float loss_scale = 1.0f; run_lamb_mix_precision_test( shape, eta, w, g, m, v, @@ -1513,12 +1513,12 @@ TEST(OptimizerTest, LambOptimizerTestScalarMixPrecision32_16_NoDefaultMaxNormCli const std::vector m = {0.87f}; const std::vector v = {0.12f}; - const float lambda = 0.25f; - const float alpha = 0.9f; - const float beta = 0.95f; - const float epsilon = 0.33f; - const float max_norm = 0.1f; - const float loss_scale = 1.0f; + constexpr float lambda = 0.25f; + constexpr float alpha = 0.9f; + constexpr float beta = 0.95f; + constexpr float epsilon = 0.33f; + constexpr float max_norm = 0.1f; + constexpr float loss_scale = 1.0f; run_lamb_mix_precision_test( shape, eta, w, g, m, v, @@ -1535,7 +1535,7 @@ TEST(OptimizerTest, LambOptimizerTestLarge) { // Input tensors and attributes. for (const auto& size : {55667, 1944006, 3907584}) { const std::vector shape = {static_cast(size)}; - const float eta = 0.5f; + constexpr float eta = 0.5f; std::vector w(size); std::vector g(size); std::vector m(size); @@ -1551,14 +1551,14 @@ TEST(OptimizerTest, LambOptimizerTestLarge) { v[i] = dist(random_engine); } - const float lambda = 0.5f; - const float alpha = 0.2f; - const float beta = 0.8f; - const float epsilon = 1e-6f; - const float max_norm = 1.0f; - const int64_t step = 0; - const float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr float lambda = 0.5f; + constexpr float alpha = 0.2f; + constexpr float beta = 0.8f; + constexpr float epsilon = 1e-6f; + constexpr float max_norm = 1.0f; + constexpr int64_t step = 0; + constexpr float loss_scale = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( {shape}, @@ -1579,7 +1579,7 @@ TEST(OptimizerTest, LambOptimizerTestLarge) { } TEST(OptimizerTest, LambOptimizerMultiTensorRatio) { - const int group_count = 127; + constexpr int group_count = 127; std::random_device random_device; std::mt19937 random_engine(0); std::uniform_real_distribution dist(0.1f, 1.0f); @@ -1624,9 +1624,9 @@ TEST(OptimizerTest, LambOptimizerMultiTensorRatio) { max_norms[i] = dist(random_engine); } - const int64_t step = 0; + constexpr int64_t step = 0; float loss_scale = 1.f; - const float scaled_g_norm = 1.f; + constexpr float scaled_g_norm = 1.f; run_multi_tensor_lamb_test( shapes, eta, diff --git a/orttraining/orttraining/test/graph/bert_toy_fetches.h b/orttraining/orttraining/test/graph/bert_toy_fetches.h index 12d12ce22a..c2bc1b9982 100644 --- a/orttraining/orttraining/test/graph/bert_toy_fetches.h +++ b/orttraining/orttraining/test/graph/bert_toy_fetches.h @@ -4,13 +4,15 @@ #pragma once #include +#include namespace onnxruntime { namespace test { - +//Avoid this arrary being initialized on stack. +constexpr std::array bert_embeddings_position_embeddings_weight_grad = {-0.009673337, 0.015859816, -0.0060598925, 0.0061725015, 0.0686829, 0.031034196, -0.041214723, 0.04238321, -0.045230567, -0.03455956, 0.037526406, 0.019020742, -0.008562718, -0.030574083, -0.012788322, -0.0008712788, -0.041134313, 0.027024698, -0.012437805, 0.059991226, -0.026614683, -0.06257652, -0.020100333, -0.03510955, 0.05741506, 0.068152145, -0.065179504, 0.038520053, 0.019393224, 0.03954512, 0.006873767, -0.084907904, -0.0050477944, 0.0012708178, 0.0030560307, -0.032130327, -0.0144646885, -0.016298112, -0.042901997, 0.07588, 0.01613088, -0.018301323, -0.010611727, 0.005544794, -0.014955264, -0.016850606, 0.022336477, -0.0030460241, -0.014482946, 0.00859436, -0.014712406, 0.03867981, -0.022954227, 0.015440098, -0.005059921, 0.0035975706, 0.01880927, 0.062380753, 0.02279159, 0.0036130734, 0.029864375, -0.022658946, -0.0069784625, -0.06653513, -0.01116233, 0.021000436, -0.028701056, -0.024398895, 0.011476517, 0.032129377, -0.04200533, 0.05585559, 0.027091827, -0.03708192, -0.029153917, 0.014818583, -0.03863439, -0.03299714, 0.026062695, 0.027578063, -0.033457935, 0.023994414, -0.00042527216, 0.020991987, -0.043016825, 0.03330429, -0.0051043453, -0.061040144, 0.02476727, 0.07664442, -0.0109203905, 0.046167813, 0.05265824, -0.009806289, -0.032828216, -0.053807136, -0.018357445, -0.0060726395, 0.012883636, -0.03604291, -0.020931121, -0.017016709, -0.06521842, 0.09689566, 0.010757825, -0.014480298, -0.011673617, 0.014982184, -0.011422393, -0.015741495, 0.021494215, -0.013776923, -0.017716365, 0.02294489, -0.00073889084, 0.036582764, -0.013822639, 0.0075510093, -0.015371518, 0.012141101, 0.009292599, 0.0632079, 0.023068016, -0.0034772623, 0.033849746, -0.009428004, -0.0021826755, -0.07218023, -0.00040298235, 0.008162888, -0.009084097, -0.025772562, 0.01697198, 0.0096272295, -0.05384024, 0.054271728, 0.0061686123, -0.012313863, -0.010857888, 0.011092398, -0.017863888, -0.023245087, 0.0147367595, 0.0022649313, -0.0307159, 0.004318953, 0.0035282676, 0.026500994, -0.029873395, 0.0049419748, -0.007642911, -0.02280794, 0.016169535, 0.059451614, 0.015289053, 0.021232026, 0.042667653, -0.0034166733, -0.014750072, -0.05480911, 0.0012827339, -0.00061177486, 0.008855328, -0.014449824, -0.008173137, -0.033359475, -0.06602954, 0.074186556, -0.0031156093, 0.0009635263, -0.0151721025, 0.007254398, 0.015830085, 0.009578684, -0.0053947777, -0.020233134, -0.016644966, 0.002484738, -0.019542504, 0.026349604, -0.017563643, -0.005398605, 0.0013201954, 0.034780584, 0.007976923, 0.054721735, 0.015226502, -0.001414868, 0.030154174, 0.011785319, 0.0033271122, -0.07897424, 0.01796715, -0.00018319988, 0.006205301, -0.019297902, 0.03912447, 0.0022418862, -0.048669476, 0.031012537, -0.0155599145, -0.01757, -0.0011392199, 0.016611777, 0.008555129, -0.017760677, -0.02604977, 0.014489464, -0.041648414, -0.017570462, 0.005586198, 0.03271513, -0.04649407, -0.038035538, 2.2510882e-05, -0.006990753, 0.043797504, 0.0970251, 0.0041649155, 0.020328937, 0.058848612, -0.008414367, -0.026458042, -0.06685481, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; static std::unordered_map> BERT_TOY_FETCHES = { //{"bert.embeddings.word_embeddings.weight_grad", {-0.017997999, -0.0047609806, 0.02464902, 0.028866263, 0.06591338, -0.05280977, -0.015370297, -0.012939942, 0.1371909, 0.08751389, 0.10818711, -0.019497797, -0.124962315, -0.1390562, 0.0661109, -0.019681724, -0.0032118761, 0.035696458, -0.08522252, 0.073210604, 0.03514969, 0.08053599, -0.03981568, 0.15768975, -0.1312564, 0.040767364, -0.06651594, 0.028433047, 0.043564245, -0.14705648, -0.035812557, -0.097510085, -0.025216235, 0.03342244, 0.03669464, 0.06126017, -0.10674235, -0.1621022, -0.010083556, 0.21157412, 0.05871246, 0.041555528, 0.07938622, -0.09024606, -0.02048279, -0.074269846, 0.08034445, -0.03423263, 0.04937596, 0.15147208, -0.068053015, -0.006273485, 0.077712014, 0.016324375, -0.13125984, 0.18183258, -0.0948589, 0.059835963, -0.09484588, 0.13196367, 0.16222662, -0.16240467, -0.01710342, -0.33551815, 0.021870147, -0.05047953, -0.034049097, 0.10182176, -0.09652015, -0.07168065, -0.019474177, 0.03104914, 0.072005704, 0.11224386, 0.023698522, -0.02095791, -0.13240159, -0.07948492, 0.063462, 0.07139883, 0.045547854, 0.10343336, -0.10592225, -0.013620282, 0.001788301, 0.019976346, -0.0020458638, 0.11173366, -0.049213164, 0.1023489, -0.09264092, 0.23402038, 0.09820575, -0.10847656, -0.06425326, -0.2733843, 0.0005777818, -0.00045715677, -0.00036173555, -0.0019640834, 0.0023077715, 0.0030269173, 0.0003216554, -0.0030540985, -0.0027387138, -0.0018896874, -0.0018313668, 0.0021082622, 0.0017220074, 0.0034250775, -0.0020885947, 0.0004703794, -0.0013641947, -0.003513737, 0.0018311203, -0.00090747076, -0.0013901574, -0.00074905565, 0.0025276195, -0.004190179, 0.0025550844, -0.001550093, 0.002385542, -0.004288953, -0.003978176, 0.004741103, 0.0012243219, 0.007092811, 0.0004932773, -3.407813e-05, -0.00041131352, -0.0018486764, 0.0013772693, 0.002977006, 0.00041388161, -0.00239666, -0.0027103948, -0.0026874242, -0.0026495266, 0.0011283782, 0.003614702, 0.0033591266, -0.0027252282, -0.00023112007, -0.0006990151, -0.0031920846, 0.0027318746, -0.0008869279, -0.0014932441, -0.00097284024, 0.0021366049, -0.0044928645, 0.0029478169, -0.0015973442, 0.0024006946, -0.0042834366, -0.0033588875, 0.0043437476, 0.0014113806, 0.0073353034, 0.00017268088, 0.0031279165, -0.008860842, -0.0015794376, 0.013640765, 0.017180406, -0.0033492814, -0.008177296, -0.0034932198, -0.007944155, -0.0063837077, 0.009710049, 0.002658482, -0.007252613, -0.008321298, 0.00687512, -0.009124297, -0.0019735715, 0.01227461, -0.0017833582, -0.00959424, -0.008270413, 0.0011829312, -0.020918233, 0.011265653, 0.012732341, -0.005953829, 0.0063472833, 0.01442773, 0.006419024, -0.0063098064, 0.0012746053, 0.000528592, 0.00020003058, -0.00047659109, -0.0020373329, 0.0012807047, 0.0029113134, 0.00028292075, -0.0021702966, -0.00314715, -0.0022823475, -0.0021989467, 0.0012647263, 0.002920366, 0.0034114283, -0.002363095, -9.816287e-05, -0.0008505247, -0.003039885, 0.0023686404, -0.0006314916, -0.001354714, -0.0012804912, 0.0017260184, -0.0042897323, 0.0028488827, -0.0020556434, 0.0024493027, -0.0038287458, -0.0032441246, 0.004484013, 0.0013376187, 0.007334718, -0.0105609605, 0.002379478, -0.009890937, -0.007801132, -0.012611928, 0.007029334, -0.002073091, 0.017913174, 0.010763435, -0.0063913055, -0.011892688, 0.0038930303, -0.0021932116, -0.0033742958, 0.0073220404, 0.0026410208, -0.0014802462, 0.011934996, 0.0061264015, -0.0043084286, 0.002516053, 0.013429475, -0.0037857764, -0.011030935, -0.0010085821, -3.7435908e-05, 0.0007489199, 0.0019895714, -0.0012069133, 0.004092823, 6.465707e-05, -0.0031965435, 0.0068118717, -0.0017017848, 0.011209353, -0.006382887, 0.000779508, -0.011595065, -0.0061810985, 0.0053741224, -0.005813627, -0.00042509334, 0.003855044, -0.0044160755, 0.0051464587, 0.011198121, -3.800541e-05, -0.0073320214, -0.0010064199, -0.011198526, -0.006249857, 0.007254719, -0.0022802218, -0.007081021, 0.0023023842, 0.009914208, 0.0050682398, 0.0015795352, 0.014859522, -0.010059243, -0.009821922, 5.437061e-06, 0.0020397988, 0.0041845436, 0.00060743524, 0.0035826403, -0.006658481, 0.00040580076, 0.01827403, 0.0146418195, -0.0017762181, -0.0052374043, -0.009580359, -0.0092817955, 0.005359125, 0.0057464866, -0.0019206754, -0.0047812895, -0.0034107158, 0.0015538285, -0.0088595655, 0.0065265233, 0.004471723, 0.004160745, -0.0076062633, -0.009591796, -0.0026515983, -0.017235313, 0.011589448, 0.0059728855, -0.01137335, 0.00735884, -0.0011644405, 0.013250465, 0.0011195687, -0.0034921002, 0.002805762, -0.00078478764, 0.008399065, -0.0038660385, -0.0010680065, -0.00809041, 0.00032422598, 0.0018995679, -0.0027532256, -0.0008429906, 0.0041832067, -0.008892417, 0.0059295064, 0.007870191, 0.0007508416, 0.0014074097, -0.0027645924, -0.016193701, -0.004957792, 0.003047731, 0.0012398185, -0.007731399, 0.0065540858, 0.010207696, 0.007732143, -0.0019069482, 0.007129186, -0.01141508, -0.0061322916, -0.004303914, -0.0008273189, 0.01305048, 0.00840299, 0.0041872566, -0.026471771, -0.0049715447, 0.027991377, 0.031558234, -0.0137341255, -0.020456806, 0.0022966114, -0.012054471, -0.022880767, 0.020292591, 0.00937961, -0.010463325, -0.01744223, 0.023348125, -0.020582287, -0.009090931, 0.025472654, -0.009804816, -0.025231019, -0.015752604, 0.010408943, -0.029697021, 0.020585395, 0.03790528, -0.015790287, 0.017945189, 0.04353926, -0.0017329226, -0.023595314, -0.003561283, -0.012905441, 0.008261291, -0.01975705, -0.0055251857, 0.00807631, 0.022083543, -0.010032209, 0.0101967305, 0.0065506864, -0.008186438, -0.018430836, 0.011856037, -0.0022082834, -0.013759101, -0.0021272686, 0.012042769, -0.014718293, 0.01167841, 0.016556803, -0.008750132, -0.0086417645, 0.0075992853, -0.0026043323, -0.028571844, 0.008125619, 0.016735548, -0.015955037, 0.013859228, 0.02121318, 0.012950463, -0.010491186, -0.0051214993, 0.0062633515, -0.0008233592, 0.0052910135, -0.0031190286, 0.0022047765, -0.008960088, -0.0036846313, 0.00087062386, -0.005445968, -0.002036477, 0.0004928082, -0.00269337, 0.006775616, 0.008721391, -0.0026300899, -0.006383828, 0.0019511494, -0.0076960707, -0.0063039046, 0.0042754905, 0.00040666747, -0.0042483783, 0.0019962972, 0.009262519, 0.004271232, 0.0019832584, 0.007568662, -0.008556543, -0.007411748, 0.0019751554, 0.0044261077, 0.0012573618, -5.0236147e-05, 0.0004824708, -0.0003333637, -0.0023520116, 0.0011478316, 0.0029662782, 0.00043794548, -0.0024023955, -0.0024753264, -0.0027765166, -0.002534986, 0.001345078, 0.0034824368, 0.0034430146, -0.0022662533, -0.00047193168, -0.0010801108, -0.003035931, 0.0031154254, -8.620613e-05, -0.001197993, -0.0008512347, 0.001933374, -0.0050755795, 0.002749757, -0.0027894161, 0.0028318304, -0.004384431, -0.0032763379, 0.0041905027, 0.0015910206, 0.007723295, 0.0005058864, 0.0031011272, -0.0074441275, -0.0015969422, 0.011513259, 0.013829162, -0.0016811059, -0.007419233, -0.002532541, -0.0079213325, -0.006160722, 0.0065652085, 0.0048664967, -0.0030768446, -0.008791905, 0.006305258, -0.008027553, -0.0015898008, 0.010005744, -0.0023492612, -0.008704776, -0.006143772, 0.0032253554, -0.016667034, 0.0091037275, 0.009391894, -0.0053318273, 0.0030660476, 0.00925546, 0.006078029, -0.0059509566, 0.0045770695, 0.0009995685, 0.00025790065, -0.00019580893, -0.0018566272, 0.0014472016, 0.002930538, 0.00050319685, -0.0020250285, -0.0033410026, -0.0031543304, -0.0021884134, 0.0015806631, 0.0033400243, 0.0034468751, -0.002491601, 0.00017304737, -0.001472922, -0.0029364377, 0.002639563, -0.0013256792, -0.0010594288, -0.0019129892, 0.001116221, -0.004886509, 0.0032135549, -0.0024254278, 0.0031459422, -0.004506496, -0.0036794618, 0.005542942, 0.0009883041, 0.008132616, -0.0011791522, 0.0023498351, -0.017501524, -0.010245141, -0.0025315527, 0.01148621, -0.012133535, 0.0016164572, 0.01055537, -0.0045963144, -0.02479096, 0.012457934, -5.1175943e-05, -0.0053539854, 0.0023723466, 0.009812681, -0.00492046, -0.0011487806, 0.015497501, -0.0042472202, -0.009950717, 0.011498252, 0.005137325, -0.016925538, 0.0016070234, 0.01426754, 0.0053370185, 0.006548403, 0.023479931, -0.005615459, -0.008669028, -0.004163283, -0.0050874106, 0.003956187, -0.014153139, -0.007844644, 0.008767871, 0.01511938, -0.008699781, 0.0048352266, 0.0024225372, -0.008664474, -0.009789825, 0.008774918, -0.0022714443, -0.006716069, 0.003631292, 0.0022454392, -0.01198203, 0.009634381, 0.012620629, -0.0015550813, -0.0062024663, 0.0046314243, -0.0051125707, -0.02144919, 0.008063468, 0.0095093995, -0.0010837247, 0.005946186, 0.010121394, 0.0067899553, -0.0071534347, 0.0006956016, 0.00031053132, 0.00010009212, -0.0002713576, -0.0019830703, 0.0012846666, 0.0027884827, 0.00050163764, -0.0022867846, -0.0030478789, -0.0024151385, -0.0021119115, 0.0011772054, 0.0031079187, 0.0030648473, -0.0022979607, -0.0002854559, -0.0007576107, -0.0031713017, 0.002610994, -0.000696833, -0.00113486, -0.0013523436, 0.0017056016, -0.0044626216, 0.0030272282, -0.0019895262, 0.002754993, -0.0042606164, -0.0030335283, 0.0042788293, 0.0013481595, 0.007497611, 0.00012572232, 5.194668e-05, -0.00011011079, -0.0017609808, 0.0014765817, 0.0026604726, 0.00077376695, -0.002651739, -0.0029076503, -0.002388567, -0.002244884, 0.0012056415, 0.0030024243, 0.0031733247, -0.0023766996, -0.00022431949, -0.00089091813, -0.003066816, 0.002722234, -0.000672551, -0.0011986885, -0.0013419244, 0.0017522471, -0.0046956344, 0.0029729404, -0.0017498368, 0.0028988635, -0.004392909, -0.0030258638, 0.0044696294, 0.00095764594, 0.007456648, 0.00014177138, 0.00038814277, 6.0722778e-05, -0.0016874018, 0.0010870569, 0.002512887, 0.00022265618, -0.002045031, -0.0029475964, -0.002325779, -0.0020622243, 0.0010454506, 0.002790152, 0.0029184874, -0.0020371294, -0.0001643055, -0.00077473803, -0.0025504264, 0.0024385536, -0.0006069909, -0.0007726869, -0.0014944752, 0.00093590247, -0.0042603845, 0.0027731438, -0.002029966, 0.0028363827, -0.0037331586, -0.0026346755, 0.004446668, 0.000739507, 0.006789486, 0.00032489188, 0.00026472542, -0.00017765928, -0.0017790806, 0.0004905447, 0.0027610848, 0.00053608685, -0.00175061, -0.0028320563, -0.0030973144, -0.0027286555, 0.0009836373, 0.0034077333, 0.0033763817, -0.0021585596, -0.00022196748, -0.0008464739, -0.0028755472, 0.0029746194, -0.00038144802, -0.0006132301, -0.0012783832, 0.001596144, -0.0053242757, 0.003168238, -0.0025237408, 0.0027740581, -0.0036173074, -0.0030177657, 0.0042912867, 0.0010891238, 0.0071855197, 0.0007120421, -2.2641163e-05, -0.00026424718, -0.0017066523, 0.0016475988, 0.0027217942, 0.0004691225, -0.0022624992, -0.0030432239, -0.002266623, -0.0017497039, 0.0015257796, 0.0025341224, 0.003251937, -0.0022221827, 0.00014392762, -0.0011856278, -0.0031288674, 0.002139735, -0.00092574797, -0.0013115163, -0.0013905306, 0.0018050171, -0.004222772, 0.0027052392, -0.0019097182, 0.0024739217, -0.0039873687, -0.0033327325, 0.004651979, 0.0010950787, 0.0070553594, -0.0028286173, 0.0017260195, -0.005937449, -0.0062424066, -0.013732733, 0.0015369668, -0.0057753823, 0.014663625, 0.010353247, -0.001825939, -0.014814697, 0.0027218522, -0.0035032071, -0.0015626256, 0.003517409, -0.000625875, -0.0014146453, -0.00025081984, 0.0060319556, -0.003364539, 0.00053494796, 0.014046713, -0.0014372639, -0.0065907454, -0.005231567, 0.0023598687, 0.014506616, -0.0024606339, 0.0014762101, -0.00040364405, -0.00073817524, 0.005265533, 0.0010220557, 0.0001971465, -0.00036500333, -0.0019238009, 0.0011529202, 0.0031026807, 0.00016898673, -0.0018007541, -0.0036109725, -0.0026924345, -0.0020625987, 0.0014608776, 0.0032813998, 0.0037394143, -0.002487677, 0.00010553931, -0.0010358612, -0.003001938, 0.0025230115, -0.001152096, -0.001204791, -0.001632759, 0.0011607257, -0.00446887, 0.002712753, -0.0024873903, 0.0026712872, -0.0038129413, -0.003546096, 0.0049029053, 0.0012964087, 0.007787875, 0.004531431, 0.0010632295, 0.0065595675, -0.006128853, -0.0009529692, -0.005964753, -0.016935773, 0.0016966017, -0.0022358145, 0.0013705886, -0.0128247375, 0.0062058694, 0.013967339, 0.0037530835, -0.009879645, -0.0033048312, -0.0009216337, -0.016504247, 0.004376841, 0.0034217308, -0.0071402974, -0.010982947, 0.007931545, 0.00352226, 0.001530919, 0.016663602, 0.012201151, -0.012602225, 0.020105971, -0.00022901082, -0.0030633751, 0.0007693842, 0.0029380822, -0.0026568323, 0.016330669, -0.004509992, -0.0041817413, -0.012929777, -0.007516841, 0.006911585, -0.0071876454, 0.0017941797, 0.00441558, -0.002995059, 0.00718584, 0.009401257, -0.0028873177, -0.008895685, 0.0050527602, -0.012256122, -0.009901932, 0.0096671805, -0.00018837489, -0.009238906, 0.00443279, 0.013705594, 0.0024146324, 0.002559394, 0.0143875405, -0.016104946, -0.006818282, 0.00092426245, 0.0062893876, -0.00014128862, -0.0059506055, 0.0030407128, -0.008121954, -0.0056651114, -0.0057642516, 0.006066872, -0.0026214411, 0.011021394, 0.006489616, -0.006335371, -0.009145317, 0.000823457, -0.0036655932, 0.0005924662, 0.0066564083, 0.0015874241, -0.0014039365, 0.0031718707, 0.0019350144, -0.0018479283, 0.002676228, 0.012149602, -0.00045101054, -0.010574754, 0.0002328374, -0.0017135155, 0.0018285497, 0.0006901184, -0.0021719113, 0.0024393334, 0.0018509721, 0.0021798215, 0.0009045607, -0.00014353337, -0.0005710391, -0.001732552, 0.0011271932, 0.003058374, 0.00019974685, -0.002250302, -0.003242995, -0.0023937346, -0.0024623529, 0.0014151139, 0.0026704576, 0.0035118842, -0.0024394814, 0.00038889388, -0.00084656716, -0.0029779724, 0.0021623059, -0.00079764647, -0.001117069, -0.0012453439, 0.0014935898, -0.004455296, 0.0030645332, -0.0017849146, 0.0024523397, -0.0035439185, -0.0034855672, 0.0047375336, 0.00092360895, 0.00738015, 0.006498468, -0.0036738052, 0.015163693, -0.0032198017, -0.0038915896, -0.015590584, -0.0071808156, 0.0072833896, -0.009669926, 0.0019102332, 0.005329475, -0.004685795, 0.008856878, 0.013108819, -0.0047105346, -0.007908343, 0.0020216857, -0.014218248, -0.0101794675, 0.010269184, 0.00065064564, -0.0075155194, 0.0041810796, 0.017486095, 0.0019205527, -0.0005795059, 0.014528455, -0.01579994, -0.009410718, 0.002655998, 0.008186263, -0.0018163193, 0.0014517346, 0.0030464854, -0.0070022643, -0.0031184065, 0.011362275, 0.0135162715, -0.0019787536, -0.008839537, -0.0048693754, -0.006094599, -0.0032701096, 0.0065285023, 0.0015069502, -0.0066526253, -0.0053364984, 0.006757874, -0.0074259327, -0.0052304124, 0.008923695, 0.0036826187, -0.0074168947, -0.0060998, -0.000952567, -0.017319065, 0.010477784, 0.009642714, -0.0013285489, 0.0028037834, 0.010637073, 0.002626013, -0.0027156211, 0.0026872386, 0.0070796628, -0.004015685, 0.018252838, -0.005500131, -0.0030805182, -0.018460536, -0.006066921, 0.009861857, -0.009575605, 0.004493556, 0.005666292, -0.0042706714, 0.008039122, 0.01348949, -0.0061355587, -0.008347623, 0.0030476507, -0.014059008, -0.012263626, 0.011053927, -0.0026091768, -0.0061571607, 0.0051128604, 0.018477913, 0.0019429584, 0.0007641193, 0.017233212, -0.015567182, -0.0126112215, 0.0019196854, 0.0073890155, -0.0051035318, 0.013073606, -0.008676069, 0.027437733, -0.005685153, -0.0048312936, -0.026390534, -0.011164489, 0.011887408, -0.015330074, 0.0053473106, 0.009824971, -0.008717217, 0.005872364, 0.020612434, -0.005883364, -0.011607226, 0.005767056, -0.021538887, -0.01832333, 0.017283997, -0.004239528, -0.0075377068, 0.0067623206, 0.024929691, 0.0030266875, 0.0017495112, 0.02600819, -0.021826088, -0.012778719, -0.0012914892, 0.01106718, -0.0048292875, 0.00021744988, 0.00020400426, -0.0003899804, -0.0022355018, 0.0018636945, 0.00296149, 0.0005221443, -0.0029992016, -0.0026512255, -0.0025319613, -0.0022274074, 0.0019068689, 0.0030309039, 0.0029857045, -0.0021062512, -0.00030563938, -0.0013976512, -0.003301596, 0.0028855286, -0.00052367215, -0.0013300345, -0.0010916467, 0.0019230269, -0.0047303173, 0.0030915274, -0.0023702714, 0.003067196, -0.005083602, -0.003443625, 0.004344103, 0.0016761471, 0.008039798, 0.0007844258, 0.00018137062, -0.00026568296, -0.0016601755, 0.0015186438, 0.0026420844, 0.00044743757, -0.0018867227, -0.0029778176, -0.0025416857, -0.0017308115, 0.0012217582, 0.002964157, 0.0031193872, -0.002326102, -9.0942376e-05, -0.0010594765, -0.0030576172, 0.0022836637, -0.000799529, -0.0013622262, -0.0013374407, 0.0018372526, -0.003995214, 0.0026487047, -0.001931988, 0.002098946, -0.003827079, -0.0032731576, 0.004345106, 0.0012305259, 0.0068002017, -0.012095545, 0.0028447057, -0.011966242, -0.015485612, -0.012576111, 0.013168669, -0.004160457, 0.022843808, 0.011991228, -0.0066644144, -0.011322565, 0.0063444674, -0.01410116, -0.010019832, 0.021117568, 9.187611e-05, -0.0013327657, 0.007169055, 0.009690575, 0.0040669907, -0.00133698, 0.021052241, -0.0039060686, -0.016885206, -0.0001965065, -0.0023331102, 0.0093584545, 0.00517774, -0.0043187155, -0.006356013, 0.0022162802, -0.002076353, -0.006446152, 0.0022565834, -0.0076454924, -0.00688087, -0.0070316866, 0.0053669894, -0.0012992597, 0.012064027, 0.0053672497, -0.005618355, -0.0076277144, 0.0014238689, -0.0037624568, -0.0027487723, 0.0075502866, 0.00069311843, -0.0015383572, 0.005713947, 0.004286565, 0.00071826146, 0.00025243452, 0.01146758, -0.0012699093, -0.009170919, -0.00020232564, -0.00383274, 0.0050374167, 0.00063570053, -0.0021549957, 0.0022287932, 0.0016783312, 0.0004888545, 0.002160338, 0.0038629004, -0.018004075, -0.0007131769, 0.02627013, 0.030016804, -0.008935516, -0.015536835, -0.009336805, -0.01127727, -0.010575434, 0.017461088, 0.0018116187, -0.011612832, -0.012800287, 0.014068774, -0.016989125, -0.004491312, 0.020586193, 0.002007278, -0.018472012, -0.017422924, 0.004329747, -0.030969044, 0.019137893, 0.024521464, -0.015964137, 0.015525371, 0.028104406, 0.0064570718, -0.008641956, -0.0045783324, 0.00617041, -0.0026711277, 0.011749748, -0.003963517, 0.0011188284, -0.008836435, -0.005742355, 0.0024842399, -0.008207357, -0.00028740184, 0.0025962994, -0.0018317796, 0.004489007, 0.010197395, -0.004232771, -0.006659869, 0.0006331989, -0.009419889, -0.005410017, 0.0070336685, -0.002251401, -0.0045380453, 0.0019859136, 0.0058261915, 0.0032648887, 0.0015069069, 0.013948778, -0.011478152, -0.007854606, 0.0032449178, 0.005022601, 0.0021117325, 0.0073805666, 0.002741469, -0.00014032266, -0.0042117606, 0.011156526, 0.004212981, -0.006665513, -0.0035549821, -0.0048597767, -0.008110461, -0.0021172522, 0.0013150764, 0.0034373142, 0.0019314543, -0.003959178, 0.0028005647, -0.00539309, -0.007574683, -0.0007533694, 0.005529741, -0.009072944, -0.0088231, 0.0033268996, -0.0059645716, 0.010441644, 0.010647985, 0.0029428673, 0.0010002612, 0.0038903921, 0.0015763335, -0.0032595065, 0.00012843218, -0.0061714235, 0.0019848756, -0.005874614, -0.006823655, -0.00512793, 0.004651658, -0.0016947184, 0.009745433, 0.005077403, -0.0039926767, -0.005937856, 0.0014031938, -0.0040240777, -0.0013959282, 0.006641321, 0.00048554863, -0.0019189396, 0.0025871636, 0.004949557, 0.00014530394, 0.00053653936, 0.00818183, 7.3530246e-05, -0.007692029, 0.0013642919, -0.0038802335, 0.004378024, -0.00073609594, -0.0024526988, 0.0014981793, 0.00090616435, 0.0031128596, 0.0034960525, -0.003684109, 0.012981877, -0.00423304, -0.004241525, -0.020383097, -0.011061333, 0.017700456, -0.0048262905, -0.004518502, -0.0029783815, -0.0020763755, 0.0088201305, 0.012674342, -0.004360376, -0.011975977, 0.00012832135, -0.00019296655, -0.009745534, 0.0052810255, -0.0012431666, 0.0005855025, 0.0014335308, 0.013187029, 0.0017999185, 0.012313552, 0.012351981, -0.013758875, -0.0050439537, 0.005234618, 0.0044922917, -0.008157127, 0.0010181325, 0.00012998244, -0.00019041084, -0.0018755132, 0.0008456255, 0.0030351516, -0.00031106573, -0.0014172043, -0.0031141555, -0.0028611033, -0.0020896685, 0.0012336723, 0.0027907055, 0.0029900768, -0.0020033405, 0.00020887637, -0.0007251832, -0.002925036, 0.0020099108, -0.0006732843, -0.00061546906, -0.0014423747, 0.0014687421, -0.004121246, 0.0028496573, -0.0021314549, 0.0022465729, -0.003013876, -0.003157397, 0.004369162, 0.0008920046, 0.006579509, 0.0002171929, 0.00024984716, -0.00019656037, -0.0021869547, 0.0016142554, 0.0024871952, 0.0005504462, -0.0021825775, -0.0020713354, -0.0024767125, -0.002174399, 0.00095172337, 0.003066495, 0.002730869, -0.002273328, -0.00047589117, -0.0006951919, -0.0024075068, 0.0024506943, -0.0005932778, -0.0012856632, -0.000804952, 0.0017992416, -0.0037865844, 0.0021470482, -0.0012703429, 0.002133891, -0.0040236544, -0.0029842865, 0.0040183268, 0.0010475848, 0.0064244103, 0.0054374957, -0.00034064212, 0.0043755705, -0.0038957987, 0.013612418, 0.0031713133, -0.011317272, -0.0025447651, -0.009932272, -0.0038655351, -0.00089407945, 0.0047235214, 0.008902721, 0.0019546235, -0.010988165, 0.00013108776, -0.0066782306, -0.010234417, 0.002174427, 0.006218289, -0.008708478, -0.016405452, 0.004499079, -0.0033556325, 0.010011815, 0.018780885, 0.0015382974, -0.0046784524, 0.010967234, 0.0038234438, -0.0019304641, -0.0045525716, 0.0004951601, -5.812235e-05, -0.00030713706, -0.0017293785, 0.001609722, 0.002715414, 0.00040386102, -0.002164093, -0.0029733859, -0.002576011, -0.0019755312, 0.0013737179, 0.0026233296, 0.002786489, -0.0020019233, -3.5301615e-05, -0.0008951753, -0.0032184815, 0.002233079, -0.00067864044, -0.00069875957, -0.0008629871, 0.0017969247, -0.0040618163, 0.0029859033, -0.0016509062, 0.0020643836, -0.004133572, -0.003486413, 0.004202718, 0.0013308781, 0.006886054, -2.6471036e-05, 3.0252344e-05, -0.00010333983, -0.0019170424, 0.0018193807, 0.0028218506, -6.978916e-05, -0.0027228256, -0.0030869239, -0.0016953195, -0.0015853535, 0.0015186599, 0.0019162893, 0.0028057958, -0.0016957158, -4.035469e-05, -0.0007545946, -0.0033340857, 0.00193638, -0.00043753252, -0.0009664256, -0.000999663, 0.0018938314, -0.0037964573, 0.0027999375, -0.0017857992, 0.0024231416, -0.0041455724, -0.0029776935, 0.0041433456, 0.0013523796, 0.0066797165, 0.000905996, -7.686917e-05, -0.00079697307, -0.0019986823, 0.0014579074, 0.0034682117, 0.00019557869, -0.0029555075, -0.004044311, -0.0020280434, -0.0027051398, 0.0018344714, 0.0029887734, 0.0041516987, -0.002808541, 0.00037369103, -0.00097277743, -0.0034884268, 0.0025252393, -0.00095002906, -0.0017743057, -0.0014373888, 0.001625231, -0.004907643, 0.003430385, -0.0019271915, 0.0028683352, -0.004206646, -0.0037165, 0.005199824, 0.0012826094, 0.008487024, -0.004150607, 0.0053722784, -0.006493363, 9.54268e-05, 0.016380653, 0.016911916, 0.0013577422, -0.005345783, -0.009025032, -0.0075583756, 0.0043393546, 0.0061504757, 0.00018994813, -0.0037113111, -0.005069843, 0.00424993, -0.008633678, 0.004823947, 0.0062819757, 0.0025253133, -0.0059226397, -0.012286134, -0.00076790457, -0.016947294, 0.0127494205, 0.005501068, -0.017886098, 0.0073890034, 0.0013947466, 0.0112460945, -0.00055652414, -0.0026047076, -0.00021909301, 2.1232743e-05, 2.111515e-06, -0.0017520738, 0.0014491577, 0.0027099485, 0.0006047261, -0.0027359193, -0.0026827862, -0.0021999339, -0.00224807, 0.0009353834, 0.00293704, 0.003033272, -0.0024646244, -0.0005621152, -0.00068372133, -0.0035252145, 0.0028055804, -0.00018824104, -0.0012673639, -0.001238738, 0.0020090698, -0.0046917414, 0.003384725, -0.0019347088, 0.0030888957, -0.0045490437, -0.0027450926, 0.0039386945, 0.0012418695, 0.0075267707, -0.00048685318, 0.0032050323, -0.0023975158, 0.00014976528, 0.024089929, 0.013015091, -0.0074903853, -0.0008408498, -0.016083915, -0.008722074, 0.0082209045, 0.0062642386, 0.0019960036, -0.0039535845, -0.009605093, -0.0019010922, -0.010570506, -0.00030217832, 0.0036756378, 0.009644123, -0.0036832122, -0.02181431, -0.0041279467, -0.012327228, 0.018967424, 0.010756321, -0.016836679, 0.0055831256, 0.0032254949, 0.013985716, 0.005566305, -0.007201682, 0.00056333025, -0.00027411422, -0.00017052304, -0.0016560657, 0.001567519, 0.0029629918, 0.000678718, -0.0027026318, -0.0029078547, -0.0023922592, -0.0023347768, 0.0015239465, 0.0025536825, 0.0035639883, -0.0024720326, 0.00012644277, -0.0011780494, -0.0033140026, 0.002509107, -0.0007816692, -0.0012339482, -0.0013395188, 0.0020148966, -0.0049744933, 0.0030158134, -0.0017933924, 0.0028926379, -0.004127897, -0.003460374, 0.0047097593, 0.00091159204, 0.0075191753, -0.008614111, 0.0033545352, -0.005901906, -0.008597089, -0.0053662965, 0.00631929, -0.003156506, 0.013949568, 0.008407091, -0.0064625656, -0.0101375235, 0.0033526947, -0.008583939, -0.0022829266, 0.009111658, -0.00032367796, -0.0010312267, 0.006857365, 0.0038495301, -0.0012925735, -0.0013691601, 0.016282737, -0.0007180128, -0.012214411, 0.0013006628, -0.0004802189, 0.0040819203, 0.0038045952, -0.004507603, 0.0014228737, -0.00062317925, -0.00043159164, -0.00013682639, 0.0006417796, 0.00010499196, -0.001882964, 0.0011848513, 0.0023646397, 0.0010044038, -0.0020150202, -0.002918872, -0.0030254924, -0.001937288, 0.0012847328, 0.0033513582, 0.003063031, -0.0018612022, -0.00044757064, -0.001367261, -0.0027930166, 0.0031647137, -0.00048700455, -0.00050759525, -0.0013548138, 0.0012297498, -0.0052111433, 0.0027917896, -0.0029739058, 0.0030564922, -0.004625508, -0.0031280087, 0.0046553984, 0.0011713073, 0.007604249, 0.00051626266, -0.0003727846, 0.010244895, -0.00027303374, 0.005420945, -0.005561035, -0.0013095019, 0.0056455834, -0.014264873, -0.0037528411, 0.010772455, -0.0029793133, 0.0038901463, 0.007742432, -0.0019125149, -0.008382822, -0.0027669664, -0.0021567608, -0.007778302, 0.010245836, -0.00018230302, -0.008106121, -0.00013649254, 0.003807947, 0.00729113, -0.0035887316, 0.001633589, -0.008506564, -0.015274648, 0.010944845, 0.007684721, 0.0014648172, -0.0006952957, 0.003324689, 0.00071915885, 0.00248506, 0.016352946, 0.005280583, -0.00623929, 0.0018299418, -0.017918559, -0.007810682, 0.009660777, 0.0024407834, 0.0051533226, 0.0013164964, -0.007824114, -0.0037405496, -0.0037006158, -0.0026986594, -0.003241396, 0.016547903, -0.005873247, -0.020156447, -0.00041608175, -0.0043239878, 0.011550491, 0.008607218, -0.0075063016, 0.0012833863, -0.0033852458, 0.015302398, 0.0036514045, -0.009976092, -0.0094582625, 0.0019136795, -0.003816244, -0.0052521913, -0.005640759, 0.0064002993, 0.00021061004, 0.010246283, 0.004138455, -0.006357912, -0.006858885, 0.0023797571, -0.0028282825, -0.006424657, 0.0024597507, 0.0022808323, -0.0021765903, 0.0070077986, 0.004929678, -0.0017881694, 0.0022599087, 0.010701381, -0.0020467085, -0.012945915, 0.0012482868, 0.0018977162, 0.0045550587, -0.0027382753, -0.00016925554, 0.0035170163, 5.08097e-05, 0.0023047836, -0.0001387084, 0.00062005135, -0.00034675517, -0.0021051473, 0.0014323776, 0.0029199328, 0.0001469545, -0.002789509, -0.003140024, -0.002252282, -0.0024742507, 0.0014305915, 0.003456727, 0.0031863616, -0.002305421, -0.00046394134, -0.0009285136, -0.0032664395, 0.0029427893, -0.00023294397, -0.0015098042, -0.0012337321, 0.0016271105, -0.004712121, 0.0033915045, -0.0024254979, 0.0029926978, -0.004756955, -0.0028415914, 0.0044336487, 0.0015355654, 0.007807323, 0.00028486573, 9.294309e-05, 4.0304094e-05, -0.0018306443, 0.0014418224, 0.0026542696, 0.00092525635, -0.0023723934, -0.003042804, -0.002500411, -0.0018443377, 0.0015972295, 0.0027765457, 0.0035999904, -0.0021237715, 6.741664e-05, -0.0014306328, -0.0031477315, 0.0026800074, -0.00083089457, -0.001097284, -0.0014429512, 0.0018545598, -0.0052308724, 0.0026084112, -0.0024868692, 0.003054095, -0.004203107, -0.003381156, 0.0049214726, 0.0008281477, 0.0075385203, -0.0061326004, 0.0011841397, -0.002454173, -0.0053115925, -0.0075385757, 0.0023974972, -0.0026829182, 0.009395979, 0.0027879267, -0.0017060591, -0.006408508, 0.003156234, -0.00018888433, 0.00068803993, 0.0016600527, 0.0009081654, 0.0006970008, 0.0051394235, 0.004264407, -0.00047725654, -0.0007000485, 0.005949711, 0.0014616111, -0.0029483407, -0.0015934717, -0.002841943, 0.0034673843, -0.0019618473, -0.0028674968, 0.0039176866, 0.0018821673, -0.003143711, 0.0073068347, 0.0006083162, 0.005683525, -0.0026827771, 0.009803878, -0.0020681322, -0.009741264, 0.0003039497, -0.00820354, -0.005031355, 0.0006829422, 0.0013402709, 0.006167438, 0.004092201, -0.008320164, -0.0020070244, -0.00592449, -0.0077979052, -0.0011069793, 0.006044103, -0.008538142, -0.010993669, 0.001328527, -0.0012411003, 0.008381294, 0.013316455, 0.005269571, -0.004019792, 0.006347267, 0.0050116275, -0.00088575564, -0.0031261123, 0.0038324357, 0.001947425, -0.011934128, -0.0023514028, 0.018996991, 0.020850126, -0.0040943353, -0.015292408, -0.005557739, -0.008844888, -0.004829569, 0.014093887, 0.0013900932, -0.013033763, -0.007995188, 0.013022985, -0.011064979, -0.0015339954, 0.013059825, 0.005284045, -0.01853649, -0.010443499, 0.00091607013, -0.02471719, 0.013506429, 0.020138633, -0.0063441116, 0.010747587, 0.01715109, 0.0054799058, -0.008125365, -0.005718482, -0.009523921, 0.004031453, -0.0043424107, -0.003965478, -0.00019951258, 0.006821734, 0.00093463383, 0.014619145, -0.0016787152, -0.007243811, 0.0010624749, 0.0025674915, -0.004014319, -0.003234878, 0.004924042, -0.0012636965, -0.0040291576, 0.011717852, 0.003439488, 0.000371299, 0.0023751222, 0.0047646966, -0.0061449977, -0.011830248, 0.003249052, -0.004387985, -0.0071940525, 0.0016704071, -0.010485041, 0.013278592, 0.0042915833, -0.00058084494, -0.0074431146, 0.002333594, -0.0044081504, -0.008538434, -0.0075355805, 0.006104965, -0.001696859, 0.013865607, 0.004817524, -0.004306097, -0.0061886236, 0.0030608429, -0.0053610126, -0.0034890578, 0.007023988, 0.00031803636, -0.0028853614, 0.002532902, 0.0073304162, -0.00022468361, 0.000890851, 0.011014395, -0.001742674, -0.009258183, 0.0015422989, -0.0026274761, 0.003436381, -0.0010076303, -0.0032337934, 0.0005153236, 0.0014766905, 0.0036829172, -0.0061524822, 0.003731187, -0.015731474, -0.008085394, 0.0034807553, 0.016666021, -0.0064078295, 0.011071627, 0.0053878175, -0.007938213, -0.01083292, 0.0046372036, -0.0064755073, -0.0109631345, 0.005120757, 0.006312319, -0.010849294, 0.0057520308, 0.012223036, -0.0003140926, -0.008738218, 0.00982214, -0.0008818145, -0.022325821, 0.007838352, 0.007786551, -0.00024441, 0.008915944, 0.009170739, 0.0073079867, -0.005996983, -0.00328688, -0.006478942, 0.0016677654, -0.0053655775, -0.0074758073, -0.0069488916, 0.0047094105, -0.00090135884, 0.010370271, 0.004697619, -0.003948996, -0.0060759704, 0.0026943653, -0.0021532092, -0.0030956096, 0.0061715445, -0.000721114, -0.0029683285, 0.0047956416, 0.00649931, 0.0012805233, -0.00013637933, 0.010223877, -0.0023562838, -0.009451093, 0.0017906576, -0.0031774002, 0.0043046363, -0.0015691991, -0.003608795, 0.0039020905, 0.0005805611, 0.0027446835, -0.00027131848, 0.00034115725, 0.00015209209, -0.0016027483, 0.0009736757, 0.002345623, 0.00046584496, -0.0021532534, -0.002658103, -0.002475076, -0.0020159201, 0.0006034886, 0.0030376115, 0.0026023618, -0.0020206363, -0.00057931466, -0.00044583468, -0.0032225975, 0.002752818, -4.5936205e-05, -0.0008346307, -0.001210664, 0.002005679, -0.004408803, 0.003163653, -0.0021388005, 0.0026233909, -0.0039162305, -0.0024325135, 0.0035766829, 0.0012032001, 0.0065851025, -0.0041269287, 3.8468395e-05, 0.012427676, 0.00072730705, 0.0026115472, -0.0028470296, 0.0018645965, 0.006869727, -0.01077577, -0.0046981173, 0.010191354, -0.004546391, 0.0023100844, 0.0051555317, -0.0025883974, -0.002750759, 0.003066292, 2.0972919e-05, -0.0133760115, 0.01112469, 0.0012076324, -0.00996091, 0.00080124324, 0.002630883, 0.009449447, -0.0019397092, -0.0048384313, -0.00887307, -0.01576715, 0.009321123, 0.00793182, -0.0006617177, -0.0015204092, -0.002257922, 0.009030065, -0.0065865116, -0.0068558613, -0.010703899, -0.007219209, 0.016506331, -0.0021291971, 0.0011076706, -0.0018946701, -0.0017234617, 0.0027753932, 0.007608528, -0.0013772841, -0.0058183316, -0.00061465346, -0.001643983, -0.0037227229, 0.0048146225, -0.0008683875, 0.003066254, -0.00012366218, 0.0063434625, -0.0007604037, 0.0025837978, 0.013119856, -0.008245062, -0.008330839, 0.0055369684, 0.004306605, -0.0044030794, -0.0005743736, 0.001633583, 0.0041283104, -0.0010327334, 0.0045357114, 0.0040169964, -0.01845359, 0.01787856, -0.0034726663, -0.011659045, 0.008757364, 0.0009508793, 0.00741224, 0.0011030843, 0.00019457843, -0.0067174044, -0.016203582, 0.004426266, -0.0057167253, 0.013904303, -0.014548311, -0.012974346, -0.00028885272, -0.006254177, 0.016611833, 0.012248037, -0.0013852103, -0.003556108, 0.0042706225, 0.011828274, -0.0008948139, -0.0101687, 0.0014333529, 0.0012203243, -0.007598101, -0.0013477553, 0.012916556, 0.014260517, -0.0026293506, -0.008697799, -0.0058313264, -0.0058960486, -0.0053016627, 0.0070755845, 0.0036021685, -0.0040959623, -0.0064903297, 0.007466141, -0.008120704, -0.002459073, 0.009160128, -8.1901846e-05, -0.009597266, -0.006663139, 0.0008669612, -0.018750664, 0.008916349, 0.010690635, -0.003958025, 0.0029481016, 0.011524303, 0.0065623783, -0.0061902506, 0.005065857, -0.003409793, 0.002675483, -0.0039979583, -0.008161323, -0.005341731, 0.0033950328, -0.0028700826, 0.011468841, 0.004381638, -0.006028867, -0.007526343, 0.0036363895, -0.0038420435, 0.0007636803, 0.0068401145, -0.0031548336, 9.681657e-05, 0.0044379663, 0.0025413653, 0.0007811419, 0.000721812, 0.011469119, -0.0019921695, -0.008517038, -0.00012775627, -0.0012729589, 0.0053620148, -0.0014820083, -0.00461486, 0.001567703, 0.0036551727, -0.0014545261, 0.0002785001, -7.354087e-05, -0.00010248562, -0.0021608046, 0.0015937504, 0.0029274093, 0.00022074276, -0.0025149076, -0.0024873049, -0.0023078294, -0.0020453834, 0.0015194869, 0.0023359528, 0.0030427503, -0.0020016623, -0.00011978096, -0.0010572306, -0.0030333973, 0.0023379484, -0.0005352641, -0.0009927752, -0.0011600476, 0.0017491049, -0.0043684472, 0.002673278, -0.0019570505, 0.0029216507, -0.004052729, -0.0032503027, 0.0042403103, 0.0011351603, 0.007244899, -0.0058104615, 0.0020212007, -0.0066293525, -0.0073043164, -0.006554282, 0.0063734986, -0.0024966279, 0.0108885495, 0.006038948, -0.005249802, -0.00740461, 0.0013969456, -0.004723888, -0.001597235, 0.008390436, 0.0007247033, -0.0015648092, 0.0034749403, 0.004875688, 0.00017023474, 0.00015530875, 0.009726595, 2.8161914e-05, -0.008569835, 0.0008847199, -0.0032705776, 0.0052673314, 0.0005036001, -0.0030402658, 0.00016908161, 0.00040699553, 0.002719127, 0.00287232, 0.0026079598, -0.0068108784, -0.0019630392, 0.011233251, 0.010630335, -0.0025589848, -0.008222715, -0.0018606959, -0.0069654398, -0.0036020782, 0.0065878225, 0.001872299, -0.0019083449, -0.005323045, 0.0060045263, -0.0060108053, -0.0008941792, 0.006578467, -0.00056490983, -0.009410191, -0.005366108, 0.004692808, -0.013129914, 0.006326678, 0.008627204, -0.0027896813, 0.003855089, 0.007853349, 0.0031688404, -0.0031783637, -0.0023515709, 0.00024021795, 0.00013818666, 9.926234e-07, -0.0019419164, 0.0008458862, 0.0026998576, 0.00030665076, -0.0021104359, -0.0030192088, -0.0024569705, -0.002197013, 0.00090178725, 0.0028140298, 0.0029296803, -0.0021665262, -0.00031466343, -0.00065998116, -0.0030184037, 0.0026766844, -0.00034797308, -0.00092976086, -0.0019310719, 0.0011536151, -0.0047201863, 0.003471278, -0.002243467, 0.0034915255, -0.0037933562, -0.0026063381, 0.004207296, 0.00088558, 0.0076940064, 0.00976639, 0.0012086492, 0.0059515224, -0.0070492914, 0.012216285, -0.0042864224, -0.011265295, 0.00046861032, -0.012975898, -0.00085321534, 0.0030651095, 0.0035063615, 0.0057007656, 0.004605801, -0.005518389, -0.0012383781, -0.0063414588, -0.009968158, -0.0034043372, 0.013751285, -0.0117279, -0.013165627, 0.003967019, 0.003285985, 0.0075388155, 0.012254449, 0.00999081, -0.004329881, -0.00062858686, 0.0039661373, 0.00020441483, -0.008695564, -0.01117609, 0.0051179174, -0.01054573, -0.00862269, -0.0001401736, 0.016393416, -0.0052109514, 0.011858048, 0.0070129866, -0.0071242573, -0.010223047, 0.007985684, -0.0058464087, -0.009671124, 0.0043712957, 0.009066492, -0.007892078, 0.005985814, 0.008875767, -0.0023036376, -0.0048503755, 0.0071969936, 0.00018193678, -0.018898902, 0.0053178957, 0.008020586, -0.0038169418, 0.004626607, 0.0077785766, 0.001279098, -0.006098298, 0.0013515842, 0.006084554, -0.0046298667, 0.012680999, -0.0029684287, -0.0007275047, -0.01416393, -0.0066415207, 0.0076148678, -0.012155773, 0.002249981, 0.003698237, -0.004086202, 0.007294273, 0.012837814, -0.005056043, -0.0083685545, 0.0020243768, -0.0141644, -0.008069392, 0.009523456, -0.0006808713, -0.0060532964, 0.0054370137, 0.01542493, 0.0028928653, -0.0017622622, 0.013623863, -0.012950126, -0.010562262, 0.004182653, 0.006721361, 0.0007491871, 0.0043796003, -0.0019682185, 0.010981401, -0.0049833846, 0.0010528283, -0.007814195, -0.0045218384, 0.0021779584, -0.0067053447, 0.0011345851, 0.0025229445, -0.0015875715, 0.003778784, 0.0099495575, -0.0036062005, -0.004838287, 0.0013654598, -0.009582941, -0.0055645313, 0.0068218396, -0.002254496, -0.0033479072, 0.0034241003, 0.006149572, 0.003176182, 0.00021456694, 0.012853925, -0.00998006, -0.008737063, 0.0006867277, 0.004581357, 0.00024064211, 0.004225611, -0.0039556744, 0.011068136, -0.0035598301, -0.003771848, -0.009636549, -0.0031346534, 0.005866414, -0.008012846, -0.0007873754, 0.0024980842, -0.0016793059, 0.0036911294, 0.00828741, -0.00081296556, -0.004232429, 0.002127821, -0.012094717, -0.0059817396, 0.008802259, -0.0014865159, -0.0033026005, 0.0028502916, 0.008467596, 0.00384959, -0.0019855474, 0.009558726, -0.011924317, -0.00827813, 0.002316501, 0.006087031, 0.0049404376, 0.000887439, 0.00024858388, -0.0006157966, -0.0020909945, 0.0014784355, 0.0027916492, 0.0006724892, -0.0021008619, -0.0031865085, -0.0028533407, -0.002183182, 0.0017606411, 0.0029095726, 0.0035133876, -0.0022565946, 0.00032649765, -0.0014774983, -0.002876361, 0.002388194, -0.0009255558, -0.001121002, -0.001313985, 0.0014981374, -0.004686612, 0.0028620013, -0.0022985658, 0.0025133858, -0.0041368143, -0.003921854, 0.0052632536, 0.0011294718, 0.0078023886, 0.0007176959, 0.0006130941, -0.00036587688, -0.002111317, 0.000968499, 0.0028141902, -0.00017481088, -0.0014777328, -0.0030019938, -0.0025163568, -0.00211287, 0.0011453836, 0.0033463112, 0.0031255658, -0.0021719516, -0.00021565935, -0.0007925009, -0.0023929777, 0.002282394, -0.00084536144, -0.0013481308, -0.0015172648, 0.0011673993, -0.0038060755, 0.0024868245, -0.002131548, 0.002220585, -0.0033059937, -0.0028072158, 0.0044355355, 0.0012144556, 0.0065577035, 0.00033517976, 9.205692e-05, -0.00035893387, -0.0021329136, 0.0019009656, 0.0031388283, 0.00068071, -0.0029915946, -0.0030564284, -0.002665488, -0.0025471158, 0.0018062338, 0.0028803947, 0.003413861, -0.0024480945, -0.00015156186, -0.0014702755, -0.0035685312, 0.00291666, -0.00024742063, -0.0011735357, -0.001100023, 0.0017956098, -0.00533945, 0.0035853868, -0.0022697477, 0.0031322509, -0.0051302193, -0.0037659626, 0.0049262284, 0.0012584337, 0.008554495, -0.008918012, -0.002425724, -0.005380002, -0.0081583625, 0.0036556402, 0.0075651505, -0.009634226, 0.010840105, -0.0052590333, -0.0043396205, -0.00547905, 0.008068219, -0.0040829703, -0.0015390515, 0.0050701685, -0.003271369, -0.008273071, 0.011609446, 0.016119251, -0.00089563953, 0.002220049, 0.0037887713, -0.006672847, -0.010564556, 0.00056258147, 0.005155004, 0.00085339986, -0.0027339035, 0.0026953637, 0.004081999, -0.0027544494, 0.008096734, 0.0007499301, 2.9910013e-06, -0.00028399844, -0.0018324471, 0.0018256695, 0.002815859, 0.0006350474, -0.0026182, -0.003018003, -0.0023773946, -0.001920138, 0.0016878507, 0.0029521151, 0.0035132496, -0.0024823623, 0.00019045219, -0.001333904, -0.0031975012, 0.0024487718, -0.0011463219, -0.0017153688, -0.0012139737, 0.0022270998, -0.00451566, 0.0026316296, -0.0018780424, 0.0024978225, -0.004276236, -0.0037086862, 0.0048947614, 0.0011506982, 0.007294288, 0.0048748427, -0.0019554335, -0.0064288783, 0.0019329989, 0.014184961, 0.014422169, -0.0012565384, -0.011728388, -0.0074450313, -0.011684989, -0.0039037722, 0.012410587, 0.006467982, -0.0015258256, -0.0142733, 0.004957086, -0.0064462987, 0.00019889465, 0.008680752, 0.00097585755, -0.015874006, -0.010952647, 0.0041848253, -0.020912226, 0.013163977, 0.0194663, -0.004548863, 0.0023031244, 0.013726455, 0.0049346574, -0.0066488404, -0.0013004369, -0.00042701283, -0.00011169558, -3.6875074e-06, -0.0021161041, 0.0015416857, 0.0026218528, 0.0004946421, -0.0029119428, -0.0026743447, -0.0016082572, -0.0019589171, 0.0009542701, 0.0024671415, 0.002911989, -0.0021694428, -0.0005767482, -0.0003681543, -0.0032621045, 0.0025553675, -0.00035983368, -0.0014328742, -0.0012571189, 0.002063522, -0.004186249, 0.002871655, -0.0014956872, 0.0030899472, -0.0043049706, -0.0025391937, 0.0036900516, 0.001305988, 0.0071962285, 0.0002698057, 7.167885e-05, -0.00035575274, -0.0018463661, 0.0009735834, 0.0027338217, 0.0006053451, -0.0019731661, -0.0025991148, -0.0027744377, -0.0025126273, 0.00072156, 0.003428927, 0.0031567204, -0.002448692, -0.0004075608, -0.00057270785, -0.0030838777, 0.0026818882, -0.00047162175, -0.0012358986, -0.0010987468, 0.0022459626, -0.004585875, 0.0030824183, -0.0017394223, 0.0022945576, -0.0038800354, -0.0030308093, 0.0039874185, 0.0013819047, 0.006981118, -0.0012621798, 0.003073403, 0.0063935937, -0.012122964, -0.020222409, -0.009257796, -0.014305391, 0.03304799, 0.014500761, -0.012157507, -0.009399721, -0.009370865, -0.007807347, 0.007644711, 0.01974464, -0.005240816, -0.004368141, 0.011490372, -0.016266968, 0.011638305, -0.010275215, 0.02725153, -0.0029485947, -0.005270232, -0.0002522301, 0.007406287, 0.020192744, -0.0038480558, -0.009051812, 0.0008786861, 0.00014271855, -0.009977501, 0.00056362385, 0.0002541869, -0.00017798167, -0.0018467816, 0.001176424, 0.002708821, 0.00029104188, -0.0019082995, -0.0029174404, -0.0024369, -0.0021025524, 0.0007645086, 0.003366295, 0.002969441, -0.0025625841, -0.00036104332, -0.0004759863, -0.0028440186, 0.0025115765, -0.0006406618, -0.0012999126, -0.0011924814, 0.0015906399, -0.0039258962, 0.0026490246, -0.0016946257, 0.0022309604, -0.0037268954, -0.002888752, 0.0040505, 0.0010705611, 0.0068052113, -0.0010498636, -1.1601282e-05, 0.009884488, -0.0006051408, 0.0064786514, -0.004522288, -0.00086696853, 0.010882683, -0.0117623275, -0.0027444311, 0.012794863, -0.005642911, 0.00088609615, 0.007871915, -0.0042518745, -0.008205962, -0.0049285907, -0.0055895234, -0.0071403156, 0.007744984, 0.0036990524, -0.0080992365, 0.0005835998, 0.003571454, 0.009005109, -0.0052454197, -0.0031528373, -0.0074669383, -0.014977699, 0.010891873, 0.0093957465, 0.0025734142, 0.0071177953, -0.0076645967, 0.020112816, -0.00277334, -0.0034811117, -0.015971873, -0.008886022, 0.008515522, -0.008860389, -0.003919972, 0.00481707, -0.0013749637, 0.012228667, 0.013997253, -0.009086096, -0.008974741, -0.0012351132, -0.011276664, -0.0059794215, 0.0056286333, -0.0026417505, -0.014663347, 0.00079001463, 0.01451754, 0.0071595605, 0.010945, 0.010404471, -0.016760224, -0.0020245765, 0.0031603759, 0.0032848846, 0.0028946009, 0.00023738416, 0.00023473105, -0.00023828138, -0.0019542684, 0.0011541618, 0.0029781389, 0.0001236063, -0.0022027353, -0.0029665183, -0.0023489108, -0.0023407072, 0.001300514, 0.0030227746, 0.0035676167, -0.0023048955, -0.00012695957, -0.00082963856, -0.0031259519, 0.0025817784, -0.00038753994, -0.0012521402, -0.0010352802, 0.0017939192, -0.004601099, 0.0027301228, -0.0022969123, 0.0025228932, -0.003754175, -0.0031607966, 0.0043361154, 0.001191885, 0.007151171, 4.765373e-05, 8.49162e-05, -0.00030616947, -0.0020987298, 0.0010782973, 0.0027658641, 0.00066828955, -0.0024185868, -0.0025131786, -0.0025361623, -0.0025745623, 0.0011082533, 0.0030848933, 0.003322216, -0.002311526, -0.000278804, -0.00083664584, -0.0030040694, 0.0027401147, -0.00043859895, -0.0011914689, -0.0012279397, 0.0020578373, -0.004929436, 0.002900225, -0.0019654573, 0.0029045823, -0.003931063, -0.0030519066, 0.0042608585, 0.0011615361, 0.007428766, 0.0048490902, -0.002046424, 0.009946775, -0.0025807964, 0.0017161572, -0.005522685, -0.0064416286, 0.0005553493, -0.0065212683, -0.0037706855, 0.0002262711, -0.0013042956, 0.0064022215, 0.0070120655, -0.0008063016, -0.006950697, 0.0015051803, -0.005627674, -0.006767653, 0.008283224, -0.0024362984, -0.0062195435, 0.0021256383, 0.002203463, 0.003911863, 0.0034642387, 0.010521481, -0.010883953, -0.005703448, 0.0030239613, 0.0048005404, 0.0030358345, 0.000699086, 0.002387962, -0.009527735, 0.00047607673, 0.013156721, 0.014392342, -0.003462933, -0.008891825, -0.0034365351, -0.007584933, -0.0064538894, 0.007981909, 0.0064665005, -0.004707016, -0.010545989, 0.0048757573, -0.010051727, 0.0024295235, 0.010745063, -0.0051900363, -0.009149147, -0.006747576, 0.00040342426, -0.019604793, 0.008964578, 0.012419404, -0.00788454, 0.0024741958, 0.015829409, 0.011045376, -0.005910063, 0.004401397, 0.0002830573, 0.00017908934, 3.1403073e-05, -0.00158511, 0.0011116801, 0.002752691, 0.00043098384, -0.002157847, -0.0027189802, -0.0028915491, -0.002165893, 0.0011739561, 0.0033160357, 0.0031427022, -0.002184738, -0.00028342355, -0.0010671854, -0.0034092586, 0.0028737355, -0.00045730677, -0.0010408729, -0.0013769083, 0.002178974, -0.0050255377, 0.0031380267, -0.0024970465, 0.002816115, -0.0041632126, -0.0029921732, 0.0041289153, 0.0013363411, 0.007123341}}, - {"bert.embeddings.position_embeddings.weight_grad", {-0.009673337, 0.015859816, -0.0060598925, 0.0061725015, 0.0686829, 0.031034196, -0.041214723, 0.04238321, -0.045230567, -0.03455956, 0.037526406, 0.019020742, -0.008562718, -0.030574083, -0.012788322, -0.0008712788, -0.041134313, 0.027024698, -0.012437805, 0.059991226, -0.026614683, -0.06257652, -0.020100333, -0.03510955, 0.05741506, 0.068152145, -0.065179504, 0.038520053, 0.019393224, 0.03954512, 0.006873767, -0.084907904, -0.0050477944, 0.0012708178, 0.0030560307, -0.032130327, -0.0144646885, -0.016298112, -0.042901997, 0.07588, 0.01613088, -0.018301323, -0.010611727, 0.005544794, -0.014955264, -0.016850606, 0.022336477, -0.0030460241, -0.014482946, 0.00859436, -0.014712406, 0.03867981, -0.022954227, 0.015440098, -0.005059921, 0.0035975706, 0.01880927, 0.062380753, 0.02279159, 0.0036130734, 0.029864375, -0.022658946, -0.0069784625, -0.06653513, -0.01116233, 0.021000436, -0.028701056, -0.024398895, 0.011476517, 0.032129377, -0.04200533, 0.05585559, 0.027091827, -0.03708192, -0.029153917, 0.014818583, -0.03863439, -0.03299714, 0.026062695, 0.027578063, -0.033457935, 0.023994414, -0.00042527216, 0.020991987, -0.043016825, 0.03330429, -0.0051043453, -0.061040144, 0.02476727, 0.07664442, -0.0109203905, 0.046167813, 0.05265824, -0.009806289, -0.032828216, -0.053807136, -0.018357445, -0.0060726395, 0.012883636, -0.03604291, -0.020931121, -0.017016709, -0.06521842, 0.09689566, 0.010757825, -0.014480298, -0.011673617, 0.014982184, -0.011422393, -0.015741495, 0.021494215, -0.013776923, -0.017716365, 0.02294489, -0.00073889084, 0.036582764, -0.013822639, 0.0075510093, -0.015371518, 0.012141101, 0.009292599, 0.0632079, 0.023068016, -0.0034772623, 0.033849746, -0.009428004, -0.0021826755, -0.07218023, -0.00040298235, 0.008162888, -0.009084097, -0.025772562, 0.01697198, 0.0096272295, -0.05384024, 0.054271728, 0.0061686123, -0.012313863, -0.010857888, 0.011092398, -0.017863888, -0.023245087, 0.0147367595, 0.0022649313, -0.0307159, 0.004318953, 0.0035282676, 0.026500994, -0.029873395, 0.0049419748, -0.007642911, -0.02280794, 0.016169535, 0.059451614, 0.015289053, 0.021232026, 0.042667653, -0.0034166733, -0.014750072, -0.05480911, 0.0012827339, -0.00061177486, 0.008855328, -0.014449824, -0.008173137, -0.033359475, -0.06602954, 0.074186556, -0.0031156093, 0.0009635263, -0.0151721025, 0.007254398, 0.015830085, 0.009578684, -0.0053947777, -0.020233134, -0.016644966, 0.002484738, -0.019542504, 0.026349604, -0.017563643, -0.005398605, 0.0013201954, 0.034780584, 0.007976923, 0.054721735, 0.015226502, -0.001414868, 0.030154174, 0.011785319, 0.0033271122, -0.07897424, 0.01796715, -0.00018319988, 0.006205301, -0.019297902, 0.03912447, 0.0022418862, -0.048669476, 0.031012537, -0.0155599145, -0.01757, -0.0011392199, 0.016611777, 0.008555129, -0.017760677, -0.02604977, 0.014489464, -0.041648414, -0.017570462, 0.005586198, 0.03271513, -0.04649407, -0.038035538, 2.2510882e-05, -0.006990753, 0.043797504, 0.0970251, 0.0041649155, 0.020328937, 0.058848612, -0.008414367, -0.026458042, -0.06685481, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}, + {"bert.embeddings.position_embeddings.weight_grad", std::vector(bert_embeddings_position_embeddings_weight_grad.begin(), bert_embeddings_position_embeddings_weight_grad.end())}, {"bert.embeddings.token_type_embeddings.weight_grad", {0.009861492, -0.0030909847, 0.013591753, -0.0023054278, 0.0058707986, -0.014464747, -0.0106031615, 0.007915597, -0.009053563, -0.0013863116, 0.005876172, -0.0033882926, 0.0043475777, 0.007257924, -0.0038289824, -0.006026322, -0.0012537953, -0.014294342, -0.011831209, 0.012194967, -0.0066924756, -0.010392958, 0.0039682346, 0.012561913, 0.007764792, 0.014275922, 0.008866439, -0.0067554764, 0.0024840808, -0.0033924747, 0.00055338116, -0.0086305225, -0.0044082655, 0.0022550726, -0.0078732725, -0.010640278, -0.0035971017, 0.0050297854, -0.009478568, 0.02547815, 0.012840041, -0.014007731, -0.008483045, 0.00537509, -0.012330426, -0.007031329, 0.010881772, 0.0048693954, -0.0056274254, 0.0077398717, -0.0015601134, 0.004838918, -0.011368475, 0.013950618, 0.0004504691, -0.011796904, 0.009869196, 0.02464096, 0.0003120536, 0.011567634, 0.010819629, -0.013375202, -0.009553628, -0.019786898, -0.026015956, 0.007938246, -0.026507601, -0.016323723, -0.01762755, 0.008817102, -0.026307564, 0.07222123, 0.018280337, -0.017263245, -0.020372959, 0.011089225, -0.01700878, -0.02449326, 0.019908598, 0.010436715, -0.017543968, 0.043500975, 0.009581541, 0.0041474975, -0.007507718, 0.027453853, -0.01756276, -0.020918682, 0.0032237307, 0.02903208, -0.013957954, 0.026368175, 0.02175815, 0.015069164, -0.0069283857, -0.05248654, 0.002168084, -0.00076877, 0.033151057, -0.013395623, -0.009311788, -0.024175376, -0.027121916, 0.032945216, 0.00074468297, -0.0053926758, -0.00017712219, -0.007199483, 0.0018561464, 0.009962061, 0.0064980076, -0.005447127, 0.0077884914, -0.015541087, -0.03484179, 0.030410945, -0.0071777566, -0.011565301, 0.007086238, 0.02244132, 0.013890794, 0.03238161, 0.015618763, -0.01798315, 0.0043046186, -0.017706642, 0.0022910896, -0.025733516, -0.009361861, 0.0031651908, 0.0027392562, -0.011642157, -0.0009564422, 0.001929264, -0.02544681, 0.032623984, 0.0016172249, -0.008757899, -0.003987152, 0.0077234055, -0.004132104, -0.017210549, 0.0028588213, -0.0026315348, -0.0029040503, 0.0019831192, -0.0015297756, 0.02294194, -0.009355533, -0.0046804277, -0.0012767883, -0.0051029613, 0.006177634, 0.03733815, 0.009306993, 0.0028611373, 0.02068811, -0.004864044, -0.0023681577, -0.037745994, -0.0041679516, 0.0015863172, -0.011717057, -0.005759027, -0.020311277, 0.00059181603, -0.011084055, 0.025824577, 0.019760914, -0.004142615, -0.01865638, 0.0026359046, -0.007735245, -0.005057967, 0.011681769, -0.0011424775, -0.004564693, 0.012951258, 0.0035222718, -0.003770749, -0.0009590378, 0.025996549, -0.0054898895, -0.0063981796, -0.009731363, 0.0039464016, 0.012707899, 0.00507726, 0.00625598, -0.002550175, -0.001164134, -0.008136647, 0.019111477, 0.005232859, 0.00495644, -0.004493946, 0.040123954, 0.0056162644, -0.03494628, 1.5479978e-05, -0.018604254, -0.008570064, 0.0029622077, 0.013375602, 0.003567865, -0.006246203, -0.021691928, 0.0043489044, -0.024660675, -0.013252768, 0.0038702954, 0.019245835, -0.033295676, -0.035311338, 0.0036338756, -0.011085553, 0.023488289, 0.05734553, 0.00078753894, 0.014398817, 0.039275408, 0.0026983707, -0.012919213, -0.038977116, 0.011858848, -0.003789204, 0.03332205, -0.015602473, -0.011496974, -0.03384818, -0.030712858, 0.034600638, -0.002576483, 0.0012814915, 0.011114152, -0.004078648, 0.009274085, 0.0179973, 0.007753067, -0.02269656, 0.005634091, -0.024006244, -0.026878338, 0.030132083, -0.0053250273, -0.022222953, 0.0032629974, 0.04098449, 0.0069683744, 0.02097217, 0.029564144, -0.019065196, -0.00511802, -0.019226434, 0.010999532, -0.029075911, -0.0008958073, 0.012643614, -0.05608506, -0.0072923894, 0.03937384, 0.059201065, -0.026361523, -0.0056958366, 0.011968542, -0.029491989, -0.02934218, 0.034619153, -0.013516829, -0.043380026, 0.003062591, 0.03267098, -0.034817535, 0.020511298, 0.035271104, 0.0023437233, -0.03587846, -0.0008190819, -0.0036933934, -0.07043845, 0.024075866, 0.060118526, -0.030619277, 0.05139529, 0.06954001, 0.0002973769, -0.025799345, -0.042965792, -0.019094355, 0.009590443, -0.007524764, -0.018022511, -0.0010530767, 0.005520784, -0.022753326, 0.05464682, 0.009793585, -0.005350517, 0.00027782447, 0.0052585956, -0.025627, -0.018606981, 0.016900247, -0.0020661352, -0.012528236, 0.00990032, -0.0013183856, 0.018476557, -0.001738183, 0.014049713, -0.0052055884, -0.008190643, 0.007980933, 0.01682345, -0.007466244, 0.01589565, 0.0066708564, -0.0013899824, 0.005107644, -0.03895749, -0.02189229, 0.0011266377, -0.0051833233, -0.020826835, -0.003332233, -0.00069175195, -0.037941422, 0.06965829, -0.0020412884, -0.012649458, 7.325434e-05, 0.009350402, -0.019709898, -0.015626293, 0.025077896, -0.009718373, -0.028073281, 0.02625593, 0.0055859196, 0.02481181, -0.005582753, 0.016053593, -0.0184639, -0.005281822, 0.011261847, 0.03434932, 0.0023175273, 0.009324018, 0.011064678, 0.0008713681, -0.0078909835, -0.032276582, -0.0025375588, 0.0007278591, -0.002141838, -0.0065759663, -0.00084148254, 0.0039617633, -0.010956049, 0.010969842, 0.0049345572, -0.004988917, -0.0034721987, 0.0018704375, -0.0036845226, -0.008076904, 0.0043729916, 0.0055188355, -0.0070880814, 0.00372977, 0.00034216698, 0.011311488, -0.009379438, 0.0029336133, -0.00018810271, -0.005563192, 0.00487982, 0.014203299, 0.0034711012, 0.0036783838, 0.011073518, -0.003862137, -0.0033037951, -0.015319267, -0.0059544602, 0.0077692666, -0.016279053, -0.0045934273, 0.026160419, 0.025655879, -0.015384896, 0.011700445, -0.005675628, -0.012599562, -0.0027165916, 0.01200662, -0.007479347, -0.02187929, -0.003792433, 0.0123486705, -0.021392513, 0.013935043, 0.0118260365, 0.009300662, -0.021519313, -0.010708839, -0.004828757, -0.031539194, 0.019091932, 0.037005752, -0.024503669, 0.024372987, 0.030933201, 0.0109671345, -0.0128225265, -0.029404549, 0.0047040824, 0.0031992306, -0.0057427445, 0.0030587176, 0.030159438, 0.0116053, -0.012182528, -0.0036444906, -0.013380468, -0.008974118, 0.00894435, 0.007580188, 0.0061287405, -0.009802819, -0.010905828, 0.0022288924, -0.01800173, 0.01182248, 0.0013798233, 0.009910165, -0.016020667, -0.01940729, -0.004925746, -0.016917888, 0.016901165, 0.02416109, -0.014958901, 0.009879685, 0.015272818, 0.014554979, -0.0068978188, -0.019728122, 0.0060340688, -0.0010410581, -0.001194492, -0.003636451, -0.00107297, -0.007724184, -0.009635925, 0.017968059, 0.0007841219, -0.00678654, -0.0023096113, -0.0026166206, -0.000832575, -0.0011826847, 0.0024341317, -0.004546971, -0.013568386, 0.008887105, 0.0008107559, 0.0015832921, -0.010033727, 0.008138211, -0.009574367, -0.004400424, 0.004787254, 0.019033518, 0.006824797, 0.0071763312, 0.006221891, 0.009308463, -0.00994106, -0.009893951, 0.015196445, -0.007118376, 0.03964389, -0.007868402, 0.020599354, -0.038666364, -0.048962843, 0.043257277, -0.033149265, 0.0057367184, 0.019187208, -0.0042767012, 0.019828873, 0.015786614, -0.030813446, -0.01174179, -0.017199056, -0.022331137, -0.032972716, 0.043932386, -0.018505244, -0.038241245, 0.0008711538, 0.046217036, 0.027597895, 0.055955917, 0.006168975, -0.013221774, 0.0161911, 0.01020639, 0.0076408144, -0.06894969}}, {"bert.embeddings.LayerNorm.weight_grad", {-0.0021369501, -0.0015581558, 0.0010946481, 0.002412255, 0.003989072, 0.0027359652, -0.00016151473, -0.00083480123, -0.0029047574, -0.0021610183, 0.0012508894, -0.0003233871, -0.0023219283, -0.00026789223, -0.0027552636, -0.00035624453, 0.0016456329, -0.00014724248, -0.0029568055, -0.0003587525, 0.0051661264, -0.00451526, -0.0005047021, -0.0020318907, 0.0007076218, 0.0031790552, 0.00027941455, -0.0021429544, -0.0024273228, 0.0014925286, 9.05974e-05, 0.0068187974}}, {"bert.embeddings.LayerNorm.bias_grad", {-0.0008091579, 0.0013487801, -0.00048883504, -0.004919336, 0.0029671811, 0.00020613123, -0.01184393, 0.0145161515, -1.0306255e-05, -0.004469541, -0.0013056969, 0.0028809786, -0.002462303, -0.004241116, 0.0016550634, 7.1290444e-05, -0.0064726267, 0.0024780787, -0.0013171267, 0.008034047, -0.0065535754, -0.0011969577, -0.0018098808, -0.0025135726, 0.005807951, 0.015669605, 0.0002959183, 0.004252731, 0.008501033, -8.851112e-05, -0.0022631388, -0.015858471}}, diff --git a/orttraining/orttraining/test/graph/gradient_graph_builder_test.cc b/orttraining/orttraining/test/graph/gradient_graph_builder_test.cc index 774e04153d..3a76f21d3a 100644 --- a/orttraining/orttraining/test/graph/gradient_graph_builder_test.cc +++ b/orttraining/orttraining/test/graph/gradient_graph_builder_test.cc @@ -183,7 +183,7 @@ TEST(GradientGraphBuilderTest, TrainingSession_Basic) { TEST(GradientGraphBuilderTest, GraphTransformation_WithGist) { // Setup training session configuration auto config = MakeBasicTrainingConfig(); - const int op_type_max = 9; + constexpr int op_type_max = 9; const vector compr_type_vec = {"GistBinarize", "GistPack8", "GistPack16", "GistPackMsfp15"}; PathString backprop_model_file; @@ -1299,7 +1299,7 @@ void OverwritePipelineRank(const TrainingSession::TrainingConfiguration& config, TEST(GradientGraphBuilderTest, PipelineOnlinePartition_bert_tiny) { const auto model_path = ORT_TSTR("testdata/bert_toy_optimized.onnx"); - const size_t total_partition_count = 3; + constexpr size_t total_partition_count = 3; TrainingSession::TrainingConfiguration::PipelineConfiguration pipe{}; pipe.do_partition = true; @@ -1867,7 +1867,7 @@ TEST(GradientGraphBuilderTest, TrainingSession_WithPipeline) { const std::vector start_ids = {100, 200, 300}; const std::vector expected_end_ids = {112, 212, 312}; const size_t num_stages = start_ids.size(); - const int num_batches = 6; + constexpr int num_batches = 6; std::vector plan(num_batches); PipelineBatchPlanner planner; planner.GenerateOneFWOneBWTimeline(num_stages, num_batches); diff --git a/orttraining/orttraining/test/model/data_loader_test.cc b/orttraining/orttraining/test/model/data_loader_test.cc index 18f955f9ed..70a04cc2f0 100644 --- a/orttraining/orttraining/test/model/data_loader_test.cc +++ b/orttraining/orttraining/test/model/data_loader_test.cc @@ -89,8 +89,8 @@ void CheckDataSetValue(DataSet* data_set, uint32_t expected_value) { } // namespace TEST(TrainingDataLoaderTest, SingleDataLoader_RandomDataSet) { - const int batch_size = 2; - const int num_of_batch = 1; + constexpr int batch_size = 2; + constexpr int num_of_batch = 1; std::vector tensor_names = {"input1", "input2", "input3"}; @@ -101,7 +101,7 @@ TEST(TrainingDataLoaderTest, SingleDataLoader_RandomDataSet) { onnx::TensorProto_DataType_FLOAT, onnx::TensorProto_DataType_INT64}; - const size_t num_of_perf_samples = num_of_batch * batch_size; + constexpr size_t num_of_perf_samples = num_of_batch * batch_size; auto random_data = std::make_shared(num_of_perf_samples, tensor_names, tensor_shapes, tensor_types); SingleDataLoader data_loader(random_data, tensor_names); ASSERT_EQ(1, data_loader.NumShards()); @@ -110,7 +110,7 @@ TEST(TrainingDataLoaderTest, SingleDataLoader_RandomDataSet) { } TEST(TrainingDataLoaderTest, DataLoader_OneSingleFile) { - const size_t max_num_files_preload = 3; + constexpr size_t max_num_files_preload = 3; const MapStringToString input_name_map = {{"a", "a"}, {"b", "b"}, {"c", "c"}}; TemporaryDirectory tmp_dir{ORT_TSTR("training_data_loader_test_dir")}; const PathString& train_data_dir = ConcatPathComponent(tmp_dir.Path(), ORT_TSTR("single_file")); @@ -128,7 +128,7 @@ TEST(TrainingDataLoaderTest, DataLoader_OneSingleFile) { } TEST(TrainingDataLoaderTest, DataLoader_OneSingleFileFailParsing) { - const size_t max_num_files_preload = 3; + constexpr size_t max_num_files_preload = 3; const MapStringToString input_name_map = {{"a_invalid", "a"}, {"b", "b"}, {"c", "c"}}; TemporaryDirectory tmp_dir{ORT_TSTR("training_data_loader_test_dir")}; const PathString& train_data_dir = ConcatPathComponent(tmp_dir.Path(), ORT_TSTR("single_file")); @@ -178,7 +178,7 @@ void TestDataLoaderWithMultipleFiles( } // namespace TEST(TrainingDataLoaderTest, DataLoader_MultipleFiles_InitializeDataSetIndex) { - const size_t start_index = 2; + constexpr size_t start_index = 2; TestDataLoaderWithMultipleFiles(3, 2, &start_index); } diff --git a/orttraining/orttraining/training_ops/cpu/loss/cross_entropy.cc b/orttraining/orttraining/training_ops/cpu/loss/cross_entropy.cc index 698502572c..d331ca1aea 100644 --- a/orttraining/orttraining/training_ops/cpu/loss/cross_entropy.cc +++ b/orttraining/orttraining/training_ops/cpu/loss/cross_entropy.cc @@ -203,7 +203,7 @@ Status SparseSoftmaxCrossEntropy::Compute(OpKernelContext* context) const { const TensorShape weight_shape{weight.Shape()}; ORT_ENFORCE(weight_shape == label_shape, "The shape of weight and label is different"); const float* weight_data = weight.template Data(); - for (int i = 0; i < n; i++) { + for (ptrdiff_t i = 0; i < n; i++) { loss_sample[i] = -log_prob_data[i * d + label_data[i]] * weight_data[i]; } @@ -217,7 +217,7 @@ Status SparseSoftmaxCrossEntropy::Compute(OpKernelContext* context) const { *loss_data /= sum_weight; } } else { - for (int i = 0; i < n; i++) { + for (ptrdiff_t i = 0; i < n; i++) { loss_sample[i] = -log_prob_data[i * d + label_data[i]]; } // Sum loss over n samples diff --git a/orttraining/orttraining/training_ops/cpu/loss/softmax_cross_entropy_loss.cc b/orttraining/orttraining/training_ops/cpu/loss/softmax_cross_entropy_loss.cc index adfd742dbf..5fc3ae1b49 100644 --- a/orttraining/orttraining/training_ops/cpu/loss/softmax_cross_entropy_loss.cc +++ b/orttraining/orttraining/training_ops/cpu/loss/softmax_cross_entropy_loss.cc @@ -173,7 +173,7 @@ Status SoftmaxCrossEntropyLoss::Compute(OpKernelContext* context) const // Compute weighed loss for each sample while summing weights for unignored target/label values. if (reduction_ == ReductionType::MEAN) { - for (int i = 0; i < n_d; i++) { + for (ptrdiff_t i = 0; i < n_d; i++) { if (ignore_index == label_data[i]) { loss_sample[i] = 0; } else { @@ -182,7 +182,7 @@ Status SoftmaxCrossEntropyLoss::Compute(OpKernelContext* context) const } } } else { - for (int i = 0; i < n_d; i++) { + for (ptrdiff_t i = 0; i < n_d; i++) { if (ignore_index == label_data[i]) { loss_sample[i] = 0; } else { @@ -203,7 +203,7 @@ Status SoftmaxCrossEntropyLoss::Compute(OpKernelContext* context) const } else { // Compute loss for each sample while counting unignored target/label values. int unignored_samples = 0; - for (int i = 0; i < n_d; i++) { + for (ptrdiff_t i = 0; i < n_d; i++) { if (ignore_index == label_data[i]) { loss_sample[i] = 0; } else { From 6de2a878cbdda075662ee2ea92444c59814f9d30 Mon Sep 17 00:00:00 2001 From: Sunghoon <35605090+hanbitmyths@users.noreply.github.com> Date: Mon, 13 Dec 2021 19:02:10 -0800 Subject: [PATCH 034/113] [js/react_native] Fix a broken manual build (#10012) * Fix a broken manual build * Keep the same file structures --- js/README.md | 6 ++--- .../project.pbxproj | 4 ---- js/react_native/example/ios/Podfile | 5 +++- .../project.pbxproj | 10 +++++--- js/react_native/onnxruntime-mobile-c.podspec | 23 ++++++++++++------- .../onnxruntime-react-native.podspec | 2 ++ 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/js/README.md b/js/README.md index 1055d92725..69b66dcc6d 100644 --- a/js/README.md +++ b/js/README.md @@ -379,17 +379,17 @@ By default, ONNX Runtime React Native leverages ONNX Runtime Mobile package with python tools/ci_build/github/apple/build_ios_framework.py tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json --config MinSizeRel --include_ops_by_config tools/ci_build/github/android/mobile_package.required_operators.config ``` - It creates `onnxruntime.framework` in `build/iOS_framework/framework_out` directory. Create an archive file of `onnxruntime.framework` directory as follows and copy to `/js/react_native/local_pods` directory. + It creates `Headers`, `LICENSE`, and `onnxruntime.xcframework` in `build/iOS_framework/framework_out` directory. From `framework_out` directory, create an archive file named `onnxruntime-mobile-c.zip` as follows and copy to `/js/react_native/local_pods` directory. ```sh - zip -r onnxruntime-mobile-c.zip onnxruntime.framework + zip -r onnxruntime-mobile-c.zip . ``` 4. To verify, open iOS Simulator and run this command from `/js/react_native/ios`. Change a destination to specify a running iOS Simulator. ```sh pod install - xcodebuild test -workspace OnnxruntimeModule.xcworkspace -scheme OnnxruntimeModuleTest -destination 'platform=iOS Simulator,name=iPhone 11,OS=14.5' + xcodebuild test -workspace OnnxruntimeModule.xcworkspace -scheme OnnxruntimeModuleTest -destination 'platform=iOS Simulator,name=iPhone 11,OS=15.0' ``` 4. Test an example for Android and iOS. In Windows, open Android Emulator first. diff --git a/js/react_native/example/ios/OnnxruntimeModuleExample.xcodeproj/project.pbxproj b/js/react_native/example/ios/OnnxruntimeModuleExample.xcodeproj/project.pbxproj index a79a06abdf..43a2dafa43 100644 --- a/js/react_native/example/ios/OnnxruntimeModuleExample.xcodeproj/project.pbxproj +++ b/js/react_native/example/ios/OnnxruntimeModuleExample.xcodeproj/project.pbxproj @@ -240,8 +240,6 @@ "${BUILT_PRODUCTS_DIR}/ReactCommon/ReactCommon.framework", "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", "${BUILT_PRODUCTS_DIR}/glog/glog.framework", - "${PODS_ROOT}/onnxruntime-mobile-c/onnxruntime.framework", - "${BUILT_PRODUCTS_DIR}/onnxruntime-react-native/onnxruntime_react_native.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -266,8 +264,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/onnxruntime.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/onnxruntime_react_native.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/js/react_native/example/ios/Podfile b/js/react_native/example/ios/Podfile index 86f4afd679..d497c6e229 100644 --- a/js/react_native/example/ios/Podfile +++ b/js/react_native/example/ios/Podfile @@ -9,7 +9,10 @@ target 'OnnxruntimeModuleExample' do use_react_native!(:path => config["reactNativePath"]) use_frameworks! - pod 'onnxruntime-mobile-c', :podspec => '../../onnxruntime-mobile-c.podspec' + + if File.exist?('../../local_pods/onnxruntime-mobile-c.zip') + pod 'onnxruntime-mobile-c', :podspec => '../../onnxruntime-mobile-c.podspec' + end pod 'onnxruntime-react-native', :path => '../..' inherit! :search_paths diff --git a/js/react_native/ios/OnnxruntimeModule.xcodeproj/project.pbxproj b/js/react_native/ios/OnnxruntimeModule.xcodeproj/project.pbxproj index 3792eece99..55e1f08e6d 100644 --- a/js/react_native/ios/OnnxruntimeModule.xcodeproj/project.pbxproj +++ b/js/react_native/ios/OnnxruntimeModule.xcodeproj/project.pbxproj @@ -237,7 +237,7 @@ "${PODS_ROOT}/Target Support Files/Pods-OnnxruntimeModuleTest/Pods-OnnxruntimeModuleTest-frameworks.sh", "${BUILT_PRODUCTS_DIR}/DoubleConversion/DoubleConversion.framework", "${BUILT_PRODUCTS_DIR}/FBReactNativeSpec/FBReactNativeSpec.framework", - "${BUILT_PRODUCTS_DIR}/Folly/folly.framework", + "${BUILT_PRODUCTS_DIR}/RCT-Folly/folly.framework", "${BUILT_PRODUCTS_DIR}/RCTTypeSafety/RCTTypeSafety.framework", "${BUILT_PRODUCTS_DIR}/React-Core/React.framework", "${BUILT_PRODUCTS_DIR}/React-CoreModules/CoreModules.framework", @@ -253,10 +253,12 @@ "${BUILT_PRODUCTS_DIR}/React-jsi/jsi.framework", "${BUILT_PRODUCTS_DIR}/React-jsiexecutor/jsireact.framework", "${BUILT_PRODUCTS_DIR}/React-jsinspector/jsinspector.framework", + "${BUILT_PRODUCTS_DIR}/React-logger/logger.framework", + "${BUILT_PRODUCTS_DIR}/React-perflogger/reactperflogger.framework", "${BUILT_PRODUCTS_DIR}/ReactCommon/ReactCommon.framework", "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", + "${BUILT_PRODUCTS_DIR}/fmt/fmt.framework", "${BUILT_PRODUCTS_DIR}/glog/glog.framework", - "${PODS_ROOT}/onnxruntime-mobile-c/onnxruntime.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -278,10 +280,12 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsi.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsireact.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsinspector.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/logger.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/reactperflogger.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fmt.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/onnxruntime.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/js/react_native/onnxruntime-mobile-c.podspec b/js/react_native/onnxruntime-mobile-c.podspec index 22754a18cb..41400be8ce 100644 --- a/js/react_native/onnxruntime-mobile-c.podspec +++ b/js/react_native/onnxruntime-mobile-c.podspec @@ -5,17 +5,24 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json"))) Pod::Spec.new do |spec| spec.name = "onnxruntime-mobile-c" spec.version = package["version"] - spec.summary = "ONNX Runtime C/C++ Package" + spec.summary = "ONNX Runtime Mobile C/C++ Pod" spec.description = <<-DESC - ONNX Runtime C/C++ framework pod. - DESC + A pod for the ONNX Runtime Mobile C/C++ library. + DESC spec.homepage = "https://github.com/microsoft/onnxruntime" - spec.license = { :type => 'MIT' } + spec.license = { :type => "MIT", :file => "LICENSE" } spec.authors = { "ONNX Runtime" => "onnxruntime@microsoft.com" } - spec.platform = :ios, '13.0' + spec.platform = :ios, '11.0' # if you are going to use a file as the spec.source, add 'file:' before your file path spec.source = { :http => 'file:' + __dir__ + '/local_pods/onnxruntime-mobile-c.zip' } - spec.vendored_frameworks = 'onnxruntime.framework' - spec.source_files = 'onnxruntime.framework/Headers/*.h' -end + spec.vendored_frameworks = "onnxruntime.xcframework" + spec.static_framework = true + spec.weak_framework = [ "CoreML" ] + spec.source_files = "Headers/*.h" + spec.preserve_paths = [ "LICENSE" ] + spec.library = "c++" + spec.pod_target_xcconfig = { + "OTHER_CPLUSPLUSFLAGS" => "-fvisibility=hidden -fvisibility-inlines-hidden", + } +end \ No newline at end of file diff --git a/js/react_native/onnxruntime-react-native.podspec b/js/react_native/onnxruntime-react-native.podspec index 27b56dd6dc..6e3e55b34c 100644 --- a/js/react_native/onnxruntime-react-native.podspec +++ b/js/react_native/onnxruntime-react-native.podspec @@ -3,6 +3,8 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) Pod::Spec.new do |spec| + spec.static_framework = true + spec.name = "onnxruntime-react-native" spec.version = package["version"] spec.summary = package["description"] From 7e55a942cd6d06421d9a1f90d52dbfaf19bd4da1 Mon Sep 17 00:00:00 2001 From: Suffian Khan Date: Mon, 13 Dec 2021 20:39:58 -0800 Subject: [PATCH 035/113] Add torch 1.10 requirements for rocm (#10028) --- .../stage1/requirements-torch1.10.0_rocm.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements-torch1.10.0_rocm.txt diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements-torch1.10.0_rocm.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements-torch1.10.0_rocm.txt new file mode 100644 index 0000000000..1fe2939f03 --- /dev/null +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements-torch1.10.0_rocm.txt @@ -0,0 +1,12 @@ +# transformers requires sklearn +--pre +-f https://download.pytorch.org/whl/rocm4.2/torch_stable.html +torch==1.10.0 +pandas +sklearn +numpy==1.19.5 +transformers==v4.3.2 +tensorboard>=2.2.0,<2.5.0 +h5py +wget +setuptools>=41.4.0 From cd0af7ad447a116b6084d0dac2044fb91d8d0f5d Mon Sep 17 00:00:00 2001 From: Chen Fu <1316708+chenfucn@users.noreply.github.com> Date: Mon, 13 Dec 2021 21:14:45 -0800 Subject: [PATCH 036/113] Symmetric quantized convolution kernel ARM64 (#9772) Adding a symmetric quantized convolution kernel for ARM64 Note: Indirect conv performs worse for shallow convs (input channels are small). This is much more so for low end pre-dot CPUs, where only 128 or deeper conv is faster with indirect conv. With DOT-CPUs, 32 deep conv is already faster Co-authored-by: Chen Fu --- cmake/onnxruntime_mlas.cmake | 4 + cmake/onnxruntime_webassembly.cmake | 2 +- onnxruntime/core/common/cpuid_info.cc | 8 +- .../mlas/lib/aarch64/AssembleDotProduct.h | 1 + .../mlas/lib/aarch64/ConvSymU8KernelDot.S | 628 +++++++++++++++++ .../mlas/lib/aarch64/ConvSymU8KernelNeon.S | 454 +++++++++++++ .../mlas/lib/arm64/ConvSymU8KernelDot.asm | 631 ++++++++++++++++++ .../mlas/lib/arm64/ConvSymU8KernelNeon.asm | 436 ++++++++++++ onnxruntime/core/mlas/lib/convsym.cpp | 41 +- onnxruntime/core/mlas/lib/mlasi.h | 43 +- onnxruntime/core/mlas/lib/platform.cpp | 8 +- onnxruntime/core/mlas/lib/pooling.cpp | 2 +- onnxruntime/core/mlas/lib/threading.cpp | 4 +- onnxruntime/test/mlas/unittest/test_main.cpp | 2 +- onnxruntime/test/mlas/unittest/test_util.h | 2 +- .../providers/cpu/nn/qlinearconv_op_test.cc | 22 +- 16 files changed, 2259 insertions(+), 29 deletions(-) create mode 100644 onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelDot.S create mode 100644 onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelNeon.S create mode 100644 onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelDot.asm create mode 100644 onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelNeon.asm diff --git a/cmake/onnxruntime_mlas.cmake b/cmake/onnxruntime_mlas.cmake index 12d1e271a9..263f580977 100644 --- a/cmake/onnxruntime_mlas.cmake +++ b/cmake/onnxruntime_mlas.cmake @@ -47,6 +47,8 @@ function(setup_mlas_source_for_windows) ) set(mlas_platform_preprocess_srcs + ${MLAS_SRC_DIR}/arm64/ConvSymU8KernelDot.asm + ${MLAS_SRC_DIR}/arm64/ConvSymU8KernelNeon.asm ${MLAS_SRC_DIR}/arm64/DepthwiseConvsymKernelNeon.asm ${MLAS_SRC_DIR}/arm64/DepthwiseQConvKernelSize9Neon.asm ${MLAS_SRC_DIR}/arm64/QgemmU8X8KernelNeon.asm @@ -268,6 +270,8 @@ else() if(ARM64 AND MLAS_SOURCE_IS_NOT_SET ) enable_language(ASM) set(mlas_platform_srcs + ${MLAS_SRC_DIR}/aarch64/ConvSymU8KernelDot.S + ${MLAS_SRC_DIR}/aarch64/ConvSymU8KernelNeon.S ${MLAS_SRC_DIR}/aarch64/DepthwiseConvSymKernelNeon.S ${MLAS_SRC_DIR}/aarch64/DepthwiseQConvKernelSize9Neon.S ${MLAS_SRC_DIR}/aarch64/QgemmU8X8KernelNeon.S diff --git a/cmake/onnxruntime_webassembly.cmake b/cmake/onnxruntime_webassembly.cmake index 588c1e9da9..99db7cb7c6 100644 --- a/cmake/onnxruntime_webassembly.cmake +++ b/cmake/onnxruntime_webassembly.cmake @@ -13,7 +13,7 @@ add_executable(onnxruntime_webassembly if (NOT onnxruntime_ENABLE_WEBASSEMBLY_THREADS) add_compile_definitions( - MLAS_NO_ONNXRUNTIME_THREADPOOL + BUILD_MLAS_NO_ONNXRUNTIME ) # Override re2 compiler options to remove -pthread diff --git a/onnxruntime/core/common/cpuid_info.cc b/onnxruntime/core/common/cpuid_info.cc index 226f1a08c0..fbc8fb03a5 100644 --- a/onnxruntime/core/common/cpuid_info.cc +++ b/onnxruntime/core/common/cpuid_info.cc @@ -95,12 +95,16 @@ CPUIDInfo::CPUIDInfo() { } #endif -#if defined(CPUIDINFO_ARCH_ARM) && defined(CPUINFO_SUPPORTED) +#if defined(CPUIDINFO_ARCH_ARM) +#ifdef CPUINFO_SUPPORTED // only works on ARM linux or android, does not work on Windows is_hybrid_ = cpuinfo_get_uarchs_count() > 1; has_arm_neon_dot_ = cpuinfo_has_arm_neon_dot(); - +#elif defined(_WIN32) + // TODO implement hardware feature detection in windows. + is_hybrid_ = true; +#endif #endif } diff --git a/onnxruntime/core/mlas/lib/aarch64/AssembleDotProduct.h b/onnxruntime/core/mlas/lib/aarch64/AssembleDotProduct.h index 59ffe0fc52..3af76acddb 100644 --- a/onnxruntime/core/mlas/lib/aarch64/AssembleDotProduct.h +++ b/onnxruntime/core/mlas/lib/aarch64/AssembleDotProduct.h @@ -83,3 +83,4 @@ Arguments: .inst Instruction .endm + diff --git a/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelDot.S b/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelDot.S new file mode 100644 index 0000000000..a040427c95 --- /dev/null +++ b/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelDot.S @@ -0,0 +1,628 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the MIT License. + +Module Name: + + ConvSymKernelNeonDot.S + +Abstract: + + This module implements the kernels for the symmetric quantized integer + convolution operation. + +--*/ + +#include "asmmacro.h" +#include "AssembleDotProduct.h" + + .equ .LMLAS_CONV_SYM_FLAG_INPUT_DIRECT, 1 + .equ .LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE, 2 + +// +// Stack frame layout for the symmetric convolution kernel. +// d8-d15, x19-x30 need to be preserved if used +// + .equ .LConvSymFrame_SavedRegisters, (8 * 8) + .equ .LConvSymFrame_PostProcessParams, 0 + .LConvSymFrame_SavedRegisters + .equ .LConvSymFrame_KernelFlags, 8 + .LConvSymFrame_SavedRegisters + + .equ .LConvSymPostProcessParams_Bias, 0 + .equ .LConvSymPostProcessParams_Scale, 8 + .equ .LConvSymPostProcessParams_Min, 16 + .equ .LConvSymPostProcessParams_Max, 20 + .equ .LConvSymPostProcessParams_ZeroPoint, 24 + + .text + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a convolution for the elements + of an output row for a set of filter rows. + +Arguments: + + Input (x0) - Points to the input buffer. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then the input buffer points + directly at the input tensor. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is clear, then the input buffer is an + indirection buffer. Every pointer in the indirection buffer points at a + InputChannels length vector (either from the input tensor or a vector of + padding values). These are grouped in batches of length KernelSize. + These batches are then repeated OutputCount times. + + Filter (x1) - Points to the filter buffer. + + Output (x2) - Points the output buffer. + + KernelSize (x3/x9) - Size of the kernel (most commonly. 3x3=9, 5x5=25). + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then kernel size should be 1. + + InputChannels (x4/x7) - Number of input channels. + + OutputChannels (x5) - Number of output channels. + + ChannelCount (x6) - Number of output channels this iteration produces. + + OutputCount (x7) - Number of output elements this iteration produces. + + This implementation requires the count to be no larger than 4. + + PostProcessParams (x8) - Points to the post process parameter block. + + KernelFlags - (w10) Additional flags controlling the operation. + +Return Value: + + None. + +--*/ + FUNCTION_ENTRY MlasConvSymKernelNeonDot + + stp d8,d9,[sp,#-.LConvSymFrame_SavedRegisters]! + ldr x8,[sp,#.LConvSymFrame_PostProcessParams] + ldr w10,[sp,#.LConvSymFrame_KernelFlags] + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp x19,x20,[sp,#48] + + cmp x7,2 // OutputCount < 2 ? + add x16,x2,x5 // x16 -> C1 + lsl x3,x3,#3 // KernelSize * sizeof(int8_t*) + csel x16,x2,x16,lo // if OutputCount < 2 x16/C1 -> C0 + mov x20,x4 + add x4,x4,3 // InputChannels align to 4 + add x17,x16,x5 // x17 -> C2 + ldr x11,[x8,#.LConvSymPostProcessParams_Bias] + csel x17,x16,x17,ls // if OutputCount <= 2 x17/C2 -> C1 + bic x4,x4,3 + cmp x7,4 // OutputCount < 4 ? + add x5,x17,x5 // x5 -> C3 + ldr x19,[x8,#.LConvSymPostProcessParams_Scale] + csel x5,x17,x5,lo // if OutputCount < 4 x5/C3 -> C2 + movi v12.16b,128 // for top bit flipping + +OutputChannelLoop: + ldp q16,q20,[x11],32 // Init accumulators with biases + mov v17.16b,v16.16b + mov v18.16b,v16.16b + ldp q24,q28,[x11],32 + mov v19.16b,v16.16b + mov v21.16b,v20.16b + mov v22.16b,v20.16b + mov v23.16b,v20.16b + mov v25.16b,v24.16b + mov v26.16b,v24.16b + mov v27.16b,v24.16b + mov v29.16b,v28.16b + mov v30.16b,v28.16b + mov v31.16b,v28.16b + mov x9,x3 // restore KernelSize * sizeof(int8_t*) + +KernelSizeLoop: + tst w10,#.LMLAS_CONV_SYM_FLAG_INPUT_DIRECT + beq InputIndirection + +InputDirect: + cmp x16,x2 + mov x12,x0 // x12 -> A0 + add x13,x0,x20 // x13 -> A1 = A0 + input channels + csel x13,x0,x13,eq + cmp x17,x16 + add x14,x0,x20,lsl#1 // x14 -> A2 + csel x14,x13,x14,eq + cmp x5,x17 + add x15,x13,x20,lsl#1 // x15 -> A3 + csel x15,x14,x15,eq + b FinishLoadAPtr + +InputIndirection: + ldr x12,[x0] // x12 -> A0 + cmp x16,x2 + b.eq SkipLoadA1 // C1==C0 -> A0=A1=A2=A3 + cmp x17,x16 + lsl x14,x3,#1 + ldr x13,[x0,x3] // x13 -> A1 + b.eq SkipLoadA2 // C2==C1 -> A1=A2=A3 + cmp x5,x17 + add x15,x3,x3,lsl#1 + ldr x14,[x0,x14] // x14 -> A2 + b.eq SkipLoadA3 // C3==C2 -> A2=A3 + ldr x15,[x0,x15] // x15 -> A3 + b FinishLoadAPtr +SkipLoadA1: + mov x13,x12 +SkipLoadA2: + mov x14,x13 +SkipLoadA3: + mov x15,x14 + +// Register Usage +// B (x1) -> 4x16 +// ---------------------------------------------------------------------------- +// |v4.b[0]..v4.b[12] v5.b[0]..v5.b[12] v6.b[0]..v6.b[12] v7.b[0]..v7.b[12]| +// | ... ... ... ... ... ... ... ... | +// |v4.b[3]..v4.b[15] v5.b[3]..v5.b[15] v6.b[3]..v6.b[15] v7.b[3]..v7.b[15]| +// A 4x4 ---------------------------------------------------------------------------- +// ------------------ ---------------------------------------------------------------------------- +// x12 |v0.b[0]..v0.b[3]| |v16.s[0]_v16.s[3] v20.s[0]_v20.s[3] v24.s[0]_v24.s[3] v28.s[0]_v28.s[3]| x2 +// x13 |v1.b[0]..v1.b[3]| |v17.s[0]_v17.s[3] v21.s[0]_v21.s[3] v25.s[0]_v25.s[3] v29.s[0]_v29.s[3]| x16 +// x14 |v2.b[0]..v2.b[3]| |v18.s[0]_v18.s[3] v22.s[0]_v23.s[3] v26.s[0]_v26.s[3] v30.s[0]_v31.s[3]| x17 +// x15 |v3.b[0]..v3.b[3]| |v19.s[0]_v19.s[3] v23.s[0]_v23.s[3] v27.s[0]_v27.s[3] v31.s[0]_v31.s[3]| x5 +// ------------------ ---------------------------------------------------------------------------- + +FinishLoadAPtr: + subs x7,x4,16 // Need 16 input channels for loop + add x0,x0,8 // indirect A advance to next pointer, prepare for kernel size loop + b.lo InChannels8 + + ldr d0,[x12],8 + ldr q4,[x1],16 + ldr d1,[x13],8 + subs x7,x7,16 + ldr d2,[x14],8 + ldr d3,[x15],8 + ldr q5,[x1],16 + ldr q6,[x1],16 + ldr q7,[x1],16 + b.lo InChLoopEpilogue // Need 32 input channels for main loop + +InputChannelLoop: + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + SdotByElement 16, 4, 0,0 + eor v2.8b,v2.8b,v12.8b + SdotByElement 17, 4, 1,0 + eor v3.8b,v3.8b,v12.8b + ldr d8,[x12],8 + SdotByElement 18, 4, 2,0 + SdotByElement 19, 4, 3,0 + ldr q4,[x1],16 + SdotByElement 20, 5, 0,0 + SdotByElement 21, 5, 1,0 + ldr d9,[x13],8 + SdotByElement 22, 5, 2,0 + SdotByElement 23, 5, 3,0 + ldr q5,[x1],16 + SdotByElement 24, 6, 0,0 + SdotByElement 25, 6, 1,0 + ldr d10,[x14],8 + SdotByElement 26, 6, 2,0 + SdotByElement 27, 6, 3,0 + ldr q6,[x1],16 + SdotByElement 28, 7, 0,0 + SdotByElement 29, 7, 1,0 + ldr d11,[x15],8 + SdotByElement 30, 7, 2,0 + SdotByElement 31, 7, 3,0 + ldr q7,[x1],16 + SdotByElement 16, 4, 0,1 + SdotByElement 17, 4, 1,1 + SdotByElement 18, 4, 2,1 + SdotByElement 19, 4, 3,1 + ldr q4,[x1],16 + SdotByElement 20, 5, 0,1 + SdotByElement 21, 5, 1,1 + SdotByElement 22, 5, 2,1 + SdotByElement 23, 5, 3,1 + ldr q5,[x1],16 + SdotByElement 24, 6, 0,1 + SdotByElement 25, 6, 1,1 + SdotByElement 26, 6, 2,1 + SdotByElement 27, 6, 3,1 + ldr q6,[x1],16 + SdotByElement 28, 7, 0,1 + SdotByElement 29, 7, 1,1 + SdotByElement 30, 7, 2,1 + SdotByElement 31, 7, 3,1 + eor v8.8b,v8.8b,v12.8b + ldr q7,[x1],16 + eor v9.8b,v9.8b,v12.8b + SdotByElement 16, 4, 8,0 + eor v10.8b,v10.8b,v12.8b + SdotByElement 17, 4, 9,0 + ldr d0,[x12],8 + eor v11.8b,v11.8b,v12.8b + SdotByElement 18, 4,10,0 + SdotByElement 19, 4,11,0 + ldr q4,[x1],16 + SdotByElement 20, 5, 8,0 + SdotByElement 21, 5, 9,0 + ldr d1,[x13],8 + SdotByElement 22, 5,10,0 + SdotByElement 23, 5,11,0 + ldr q5,[x1],16 + SdotByElement 24, 6, 8,0 + SdotByElement 25, 6, 9,0 + ldr d2,[x14],8 + SdotByElement 26, 6,10,0 + SdotByElement 27, 6,11,0 + ldr q6,[x1],16 + SdotByElement 28, 7, 8,0 + SdotByElement 29, 7, 9,0 + ldr d3,[x15],8 + SdotByElement 30, 7,10,0 + SdotByElement 31, 7,11,0 + ldr q7,[x1],16 + SdotByElement 16, 4, 8,1 + SdotByElement 17, 4, 9,1 + SdotByElement 18, 4,10,1 + SdotByElement 19, 4,11,1 + ldr q4,[x1],16 + SdotByElement 20, 5, 8,1 + SdotByElement 21, 5, 9,1 + SdotByElement 22, 5,10,1 + SdotByElement 23, 5,11,1 + ldr q5,[x1],16 + SdotByElement 24, 6, 8,1 + SdotByElement 25, 6, 9,1 + SdotByElement 26, 6,10,1 + SdotByElement 27, 6,11,1 + ldr q6,[x1],16 + SdotByElement 28, 7, 8,1 + SdotByElement 29, 7, 9,1 + subs x7,x7,16 // InputChannels -= 16 + SdotByElement 30, 7,10,1 + SdotByElement 31, 7,11,1 + ldr q7,[x1],16 + b.hs InputChannelLoop + +InChLoopEpilogue: + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + SdotByElement 16, 4, 0,0 + eor v2.8b,v2.8b,v12.8b + SdotByElement 17, 4, 1,0 + eor v3.8b,v3.8b,v12.8b + ldr d8,[x12],8 + SdotByElement 18, 4, 2,0 + SdotByElement 19, 4, 3,0 + ldr q4,[x1],16 + SdotByElement 20, 5, 0,0 + SdotByElement 21, 5, 1,0 + ldr d9,[x13],8 + SdotByElement 22, 5, 2,0 + SdotByElement 23, 5, 3,0 + ldr q5,[x1],16 + SdotByElement 24, 6, 0,0 + SdotByElement 25, 6, 1,0 + ldr d10,[x14],8 + SdotByElement 26, 6, 2,0 + SdotByElement 27, 6, 3,0 + ldr q6,[x1],16 + SdotByElement 28, 7, 0,0 + SdotByElement 29, 7, 1,0 + ldr d11,[x15],8 + SdotByElement 30, 7, 2,0 + SdotByElement 31, 7, 3,0 + ldr q7,[x1],16 + SdotByElement 16, 4, 0,1 + SdotByElement 17, 4, 1,1 + SdotByElement 18, 4, 2,1 + SdotByElement 19, 4, 3,1 + ldr q4,[x1],16 + SdotByElement 20, 5, 0,1 + SdotByElement 21, 5, 1,1 + SdotByElement 22, 5, 2,1 + SdotByElement 23, 5, 3,1 + ldr q5,[x1],16 + SdotByElement 24, 6, 0,1 + SdotByElement 25, 6, 1,1 + SdotByElement 26, 6, 2,1 + SdotByElement 27, 6, 3,1 + ldr q6,[x1],16 + SdotByElement 28, 7, 0,1 + SdotByElement 29, 7, 1,1 + SdotByElement 30, 7, 2,1 + SdotByElement 31, 7, 3,1 + eor v8.8b,v8.8b,v12.8b + ldr q7,[x1],16 + eor v9.8b,v9.8b,v12.8b + SdotByElement 16, 4, 8,0 + eor v10.8b,v10.8b,v12.8b + SdotByElement 17, 4, 9,0 + eor v11.8b,v11.8b,v12.8b + SdotByElement 18, 4,10,0 + SdotByElement 19, 4,11,0 + ldr q4,[x1],16 + SdotByElement 20, 5, 8,0 + SdotByElement 21, 5, 9,0 + SdotByElement 22, 5,10,0 + SdotByElement 23, 5,11,0 + ldr q5,[x1],16 + SdotByElement 24, 6, 8,0 + SdotByElement 25, 6, 9,0 + SdotByElement 26, 6,10,0 + SdotByElement 27, 6,11,0 + ldr q6,[x1],16 + SdotByElement 28, 7, 8,0 + SdotByElement 29, 7, 9,0 + SdotByElement 30, 7,10,0 + SdotByElement 31, 7,11,0 + ldr q7,[x1],16 + SdotByElement 16, 4, 8,1 + SdotByElement 17, 4, 9,1 + SdotByElement 18, 4,10,1 + SdotByElement 19, 4,11,1 + SdotByElement 20, 5, 8,1 + SdotByElement 21, 5, 9,1 + SdotByElement 22, 5,10,1 + SdotByElement 23, 5,11,1 + SdotByElement 24, 6, 8,1 + SdotByElement 25, 6, 9,1 + SdotByElement 26, 6,10,1 + SdotByElement 27, 6,11,1 + SdotByElement 28, 7, 8,1 + SdotByElement 29, 7, 9,1 + SdotByElement 30, 7,10,1 + SdotByElement 31, 7,11,1 + + tst x7,15 + b.ne InChannels8 // 4 ~ 12 InputChannels + + subs x9,x9,8 // KernelSize-=1 + b.hi KernelSizeLoop + +Requantize: + tst w10,#.LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE + ldr w13,[x8,#.LConvSymPostProcessParams_ZeroPoint] + beq BroadcastScaleValue + ldp q0,q1,[x19],32 // load scale vector + ldp q2,q3,[x19],32 + b AccumulatorsToFloat + +BroadcastScaleValue: + ld1r {v0.4s},[x19] // load scale Value + mov v1.16b, v0.16b + mov v2.16b, v0.16b + mov v3.16b, v0.16b + +AccumulatorsToFloat: + scvtf v16.4s,v16.4s // convert to float + scvtf v17.4s,v17.4s + scvtf v18.4s,v18.4s + scvtf v19.4s,v19.4s + scvtf v20.4s,v20.4s + scvtf v21.4s,v21.4s + scvtf v22.4s,v22.4s + scvtf v23.4s,v23.4s + scvtf v24.4s,v24.4s + scvtf v25.4s,v25.4s + scvtf v26.4s,v26.4s + scvtf v27.4s,v27.4s + scvtf v28.4s,v28.4s + scvtf v29.4s,v29.4s + scvtf v30.4s,v30.4s + scvtf v31.4s,v31.4s + fmul v16.4s,v16.4s,v0.4s // multiply by scale + fmul v17.4s,v17.4s,v0.4s + fmul v18.4s,v18.4s,v0.4s + fmul v19.4s,v19.4s,v0.4s + fmul v20.4s,v20.4s,v1.4s + fmul v21.4s,v21.4s,v1.4s + fmul v22.4s,v22.4s,v1.4s + fmul v23.4s,v23.4s,v1.4s + fmul v24.4s,v24.4s,v2.4s + fmul v25.4s,v25.4s,v2.4s + fmul v26.4s,v26.4s,v2.4s + fmul v27.4s,v27.4s,v2.4s + fmul v28.4s,v28.4s,v3.4s + fmul v29.4s,v29.4s,v3.4s + fmul v30.4s,v30.4s,v3.4s + fmul v31.4s,v31.4s,v3.4s + fcvtns v16.4s,v16.4s // convert to int + fcvtns v17.4s,v17.4s + fcvtns v18.4s,v18.4s + fcvtns v19.4s,v19.4s + fcvtns v20.4s,v20.4s + fcvtns v21.4s,v21.4s + fcvtns v22.4s,v22.4s + fcvtns v23.4s,v23.4s + fcvtns v24.4s,v24.4s + fcvtns v25.4s,v25.4s + fcvtns v26.4s,v26.4s + fcvtns v27.4s,v27.4s + fcvtns v28.4s,v28.4s + fcvtns v29.4s,v29.4s + fcvtns v30.4s,v30.4s + fcvtns v31.4s,v31.4s + + sqxtn v16.4h,v16.4s + sqxtn v17.4h,v17.4s + sqxtn v18.4h,v18.4s + sqxtn v19.4h,v19.4s + sqxtn v24.4h,v24.4s + sqxtn v25.4h,v25.4s + sqxtn v26.4h,v26.4s + sqxtn v27.4h,v27.4s + dup v4.8h,w13 // zero point + sqxtn2 v16.8h,v20.4s + sqxtn2 v17.8h,v21.4s + sqxtn2 v18.8h,v22.4s + sqxtn2 v19.8h,v23.4s + sqxtn2 v24.8h,v28.4s + sqxtn2 v25.8h,v29.4s + sqxtn2 v26.8h,v30.4s + sqxtn2 v27.8h,v31.4s + sqadd v16.8h,v16.8h,v4.8h + sqadd v17.8h,v17.8h,v4.8h + sqadd v18.8h,v18.8h,v4.8h + sqadd v19.8h,v19.8h,v4.8h + sqadd v24.8h,v24.8h,v4.8h + sqadd v25.8h,v25.8h,v4.8h + sqadd v26.8h,v26.8h,v4.8h + sqadd v27.8h,v27.8h,v4.8h + sqxtun v0.8b,v16.8h + sqxtun v1.8b,v17.8h + sqxtun v2.8b,v18.8h + sqxtun v3.8b,v19.8h + sqxtun2 v0.16b,v24.8h + sqxtun2 v1.16b,v25.8h + subs x6,x6,16 // processed 16 output channels + sqxtun2 v2.16b,v26.8h + sqxtun2 v3.16b,v27.8h + b.lo PartialStore + + st1 {v3.16b},[x5],16 // Store full 4 x 16 + st1 {v2.16b},[x17],16 + sub x0,x0,x3 // Restore pointer to A: a -= ks + st1 {v1.16b},[x16],16 + st1 {v0.16b},[x2],16 + b.hi OutputChannelLoop + +ExitKernel: + ldp x19,x20,[sp,#48] + ldp d12,d13,[sp,#32] + ldp d10,d11,[sp,#16] + ldp d8,d9,[sp],#.LConvSymFrame_SavedRegisters + ret + +InChannels8: + tbz x7,3,InChannels4 + ldr d0,[x12],8 + ldr q4,[x1],16 + ldr d1,[x13],8 + ldr d2,[x14],8 + ldr d3,[x15],8 + eor v0.8b,v0.8b,v12.8b + ldr q5,[x1],16 + eor v1.8b,v1.8b,v12.8b + SdotByElement 16, 4, 0,0 + SdotByElement 17, 4, 1,0 + eor v2.8b,v2.8b,v12.8b + ldp q6, q7, [x1], 32 + eor v3.8b,v3.8b,v12.8b + SdotByElement 18, 4, 2,0 + SdotByElement 19, 4, 3,0 + SdotByElement 20, 5, 0,0 + SdotByElement 21, 5, 1,0 + SdotByElement 22, 5, 2,0 + SdotByElement 23, 5, 3,0 + SdotByElement 24, 6, 0,0 + SdotByElement 25, 6, 1,0 + ldp q4, q5, [x1], 32 + SdotByElement 26, 6, 2,0 + SdotByElement 27, 6, 3,0 + SdotByElement 28, 7, 0,0 + SdotByElement 29, 7, 1,0 + SdotByElement 30, 7, 2,0 + SdotByElement 31, 7, 3,0 + SdotByElement 16, 4, 0,1 + SdotByElement 17, 4, 1,1 + ldp q6, q7, [x1], 32 + SdotByElement 18, 4, 2,1 + SdotByElement 19, 4, 3,1 + SdotByElement 20, 5, 0,1 + SdotByElement 21, 5, 1,1 + SdotByElement 22, 5, 2,1 + SdotByElement 23, 5, 3,1 + SdotByElement 24, 6, 0,1 + SdotByElement 25, 6, 1,1 + SdotByElement 26, 6, 2,1 + SdotByElement 27, 6, 3,1 + SdotByElement 28, 7, 0,1 + SdotByElement 29, 7, 1,1 + SdotByElement 30, 7, 2,1 + SdotByElement 31, 7, 3,1 + tbz x7,2,SkipInCh4 + +InChannels4: + ldr s0,[x12],4 + ldr q4,[x1],16 + ldr s1,[x13],4 + ldr s2,[x14],4 + ldr s3,[x15],4 + eor v0.8b,v0.8b,v12.8b + ldr q5, [x1], 16 + eor v1.8b,v1.8b,v12.8b + SdotByElement 16, 4, 0,0 + SdotByElement 17, 4, 1,0 + eor v2.8b,v2.8b,v12.8b + ldp q6, q7, [x1], 32 + eor v3.8b,v3.8b,v12.8b + SdotByElement 18, 4, 2,0 + SdotByElement 19, 4, 3,0 + SdotByElement 20, 5, 0,0 + SdotByElement 21, 5, 1,0 + SdotByElement 22, 5, 2,0 + SdotByElement 23, 5, 3,0 + SdotByElement 24, 6, 0,0 + SdotByElement 25, 6, 1,0 + SdotByElement 26, 6, 2,0 + SdotByElement 27, 6, 3,0 + SdotByElement 28, 7, 0,0 + SdotByElement 29, 7, 1,0 + SdotByElement 30, 7, 2,0 + SdotByElement 31, 7, 3,0 + +SkipInCh4: + subs x9,x9,8 // ks -= 1 + b.hi KernelSizeLoop + b Requantize + +PartialStore: + tbz x6,3,LT8Store + str d3,[x5],8 // no less than 8 channels + str d2,[x17],8 + dup d3,v3.d[1] + dup d2,v2.d[1] + str d1,[x16],8 + str d0,[x2],8 + dup d1,v1.d[1] + dup d0,v0.d[1] +LT8Store: + tbz x6,2,LT4Store + str s3,[x5],4 + str s2,[x17],4 + dup s3,v3.s[1] + dup s2,v2.s[1] + str s1,[x16],4 + str s0,[x2],4 + dup s1,v1.s[1] + dup s0,v0.s[1] +LT4Store: + tbz x6,1, LT2Store + str h3,[x5],2 + str h2,[x17],2 + dup h3,v3.h[1] + dup h2,v2.h[1] + str h1,[x16],2 + str h0,[x2],2 + dup h1,v1.h[1] + dup h0,v0.h[1] +LT2Store: + tbz x6,0,ExitKernel + str b3,[x5] + str b2,[x17] + str b1,[x16] + str b0,[x2] + b ExitKernel + + .end diff --git a/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelNeon.S b/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelNeon.S new file mode 100644 index 0000000000..4cb68827f0 --- /dev/null +++ b/onnxruntime/core/mlas/lib/aarch64/ConvSymU8KernelNeon.S @@ -0,0 +1,454 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the MIT License. + +Module Name: + + ConvSymKernelNeon.s + +Abstract: + + This module implements the kernels for the symmetric quantized integer + convolution operation. + +--*/ + +#include "asmmacro.h" + + .equ .LMLAS_CONV_SYM_FLAG_INPUT_DIRECT, 1 + .equ .LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE, 2 + +// +// Stack frame layout for the symmetric convolution kernel. +// d8-d15, x19-x30 need to be preserved if used +// + .equ .LConvSymFrame_SavedNeonRegisters, (8 * 8) + .equ .LConvSymFrame_SavedRegisters, .LConvSymFrame_SavedNeonRegisters + .equ .LConvSymFrame_PostProcessParams, 0 + .LConvSymFrame_SavedRegisters + .equ .LConvSymFrame_KernelFlags, 8 + .LConvSymFrame_SavedRegisters + + .equ .LConvSymPostProcessParams_Bias, 0 + .equ .LConvSymPostProcessParams_Scale, 8 + .equ .LConvSymPostProcessParams_Min, 16 + .equ .LConvSymPostProcessParams_Max, 20 + .equ .LConvSymPostProcessParams_ZeroPoint, 24 + + .text + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a convolution for the elements + of an output row for a set of filter rows. + +Arguments: + + Input (x0) - Supplies the address of the input buffer. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then the input buffer points + directly at the input tensor. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is clear, then the input buffer is an + indirection buffer. Every pointer in the indirection buffer points at a + InputChannels length vector (either from the input tensor or a vector of + padding values). These are grouped in batches of length KernelSize. + These batches are then repeated OutputCount times. + + Filter (x1) - Supplies the address of the filter buffer. + + Output (x2) - Supplies the address of the output buffer. + + KernelSize (x3) - Supplies the size of the kernel. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then kernel size should be 1. + + InputChannels (x4) - Supplies the number of input channels. + + This implementation requires the count to be a multiple of 8. + + OutputChannels (x5) - Supplies the number of output channels. + + ChannelCount (x6) - Supplies the number of channels this iteration produces. + + This implementation requires the count to be 8. + + OutputCount (x7) - Supplies the number of output elements this iteration produces. + + This implementation requires the count to be 1 or 2. + + PostProcessParams - Supplies the address of the post process parameter block. + + KernelFlags - Supplies additional flags controlling the operation. + +Return Value: + + None. + +--*/ + FUNCTION_ENTRY MlasConvSymKernelNeon + + stp d8,d9,[sp,#-64]! + ldr x8,[sp,#.LConvSymFrame_PostProcessParams] + ldrb w10,[sp,#.LConvSymFrame_KernelFlags] + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + mov x9,x3 // save kernel size + ldr x11,[x8,#.LConvSymPostProcessParams_Bias] + mov x16,x4 // save input channels + ldr x12,[x8,#.LConvSymPostProcessParams_Scale] + cmp x7,2 // if OutputCount < 2 + add x5,x2,x5 // c1 = c0 + ldc + add x4,x4,7 // kc = (kc + 7) & ~7 + csel x5,x2,x5,lo // if OutputCount < 2 c1 = c0 + bic x4,x4,7 + ldp s16,s18,[x11],8 // init accumulators with bias + ldp s20,s22,[x11],8 + ldp s24,s26,[x11],8 + ldp s28,s30,[x11],8 + mov v17.16b,v16.16b + mov v19.16b,v18.16b + mov v21.16b,v20.16b + mov v23.16b,v22.16b + mov v25.16b,v24.16b + mov v27.16b,v26.16b + mov v29.16b,v28.16b + mov v31.16b,v30.16b + +// Nested loops, inner loop: input channel; outter loop: kernel size +// Each inner iteration processes 8 input channels, 2 output pixels, 8 output channels. +// +// B 8x8 +// ------------------------------------------------------------------ +// |v4.b[0] v5.b[0] v4.b[0] v5.b[0] v4.b[0] v5.b[0] v4.b[0] v5.b[0] | +// | ... ... ... ... ... ... ... ... | +// |v4.b[7] v5.b[7] v4.b[7] v5.b[7] v4.b[7] v5.b[7] v4.b[7] v5.b[7] | +// A 2x8 ------------------------------------------------------------------ +// ------------------ ------------------------------------------------------------------ +// x13-> |v0.b[0]..v0.b[7]| |v16.4s v18.4s v20.4s v22.4s v24.4s v26.4s v28.4s v30.4s | +// x15-> |v1.b[0]..v1.b[7]| |v17.4s v19.4s v21.4s v23.4s v25.4s v27.4s v29.4s v31.4s | +// ------------------ ------------------------------------------------------------------ +// When Input Channels greater than 16, unroll: +// A registers v6 v7, +// B registers v8 v9 +// + +.LConvSym.KernelSizeLoop: + + # Load next 2 A pointers + tst w10,#.LMLAS_CONV_SYM_FLAG_INPUT_DIRECT + ldr d4,[x1] + ldr d5,[x1,8] + beq .LConvSym.InputIndirection + +.LConvSym.InputDirect: + mov x13,x0 // x13 -> A0 + add x15,x0,x16 // x15 -> A1 = A0 + input channels + b .LConvSym.BlockLoopPrologue + +.LConvSym.InputIndirection: + cmp x7,2 // test if OutputCount < 2 + ldr x13,[x0] // x13 -> A0 + blo .LConvSym.SkipLoadA1 + ldr x15,[x0,x3,lsl#3] // x15 -> A1 +.LConvSym.SkipLoadA1: + +.LConvSym.BlockLoopPrologue: + cmp x7,2 // test if OutputCount < 2 + add x0,x0,8 // indirect A advance to next pointer, prepare for kernel size loop + csel x15,x13,x15,lo // if OutputCount < 2 x15 -> A0 + subs x14,x4,16 // input channel - 16 + movi v12.8b,128 + blo .LConvSym.8InputChannels // less than 16 deep, no unroll + + ldr d0,[x13],8 + ldr d1,[x15],8 + ldr d8,[x1,64] + ldr d9,[x1,72] + ldr d6,[x13],8 + subs x14,x14,16 // input channel - 16 + ldr d7,[x15],8 + blo .LConvSym.BlockLoopEpilogue // need 32 input channel for full unrolled loop + +.LConvSym.Blockloop: + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,16] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,24] + eor v6.8b,v6.8b,v12.8b + eor v7.8b,v7.8b,v12.8b + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,80] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,88] + smull v12.8h,v4.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1,32] + sadalp v17.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + ldr d5,[x1,40] + sadalp v19.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,96] + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + ldr d9,[x1,104] + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,48] + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,56] + sadalp v23.4s, v15.8h + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,112] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,120] + smull v12.8h,v4.8b,v0.8b + add x1,x1,128 + sadalp v24.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1] // Read B + sadalp v25.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + ldr d0,[x13],8 // Read A0 + sadalp v26.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + ldr d1,[x15],8 // Read A1 + sadalp v27.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + ldr d5,[x1,8] // Read B + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,64] // Read B + smlal v14.8h,v9.8b,v6.8b + ldr d6,[x13],8 // Read A0 + smlal v15.8h,v9.8b,v7.8b + ldr d7,[x15],8 // Read A1 + sadalp v28.4s,v12.8h + ldr d9,[x1,72] // Read B + sadalp v29.4s,v13.8h + subs x14,x14,16 + sadalp v30.4s,v14.8h + movi v12.8b,128 + sadalp v31.4s,v15.8h + b.hs .LConvSym.Blockloop + +.LConvSym.BlockLoopEpilogue: // remaining 16 input channels + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,16] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,24] + eor v6.8b,v6.8b,v12.8b + eor v7.8b,v7.8b,v12.8b + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,80] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,88] + smull v12.8h,v4.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1,32] + sadalp v17.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + sadalp v19.4s,v11.8h + ldr d5,[x1,40] + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,96] + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + ldr d9,[x1,104] + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,48] + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + sadalp v23.4s,v15.8h + ldr d5,[x1,56] + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,112] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,120] + smull v12.8h,v4.8b,v0.8b + sadalp v24.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + sadalp v25.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v26.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + sadalp v27.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + add x1,x1,128 + + sadalp v28.4s,v12.8h + sadalp v29.4s,v13.8h + sadalp v30.4s,v14.8h + sadalp v31.4s,v15.8h + movi v12.8b,128 + tbnz x14,3,.LConvSym.8InputChannels + + subs x9,x9,1 + b.hi .LConvSym.KernelSizeLoop + +.LConvSym.Requantize: + ldr w11, [x8, #.LConvSymPostProcessParams_ZeroPoint] + tst w10,#.LMLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE + beq .LConvSym.BroadcastScaleValue + ld1 {v4.4s,v5.4s},[x12] // load scale vector + b .LConvSym.AccumulatorsToFloat + +.LConvSym.BroadcastScaleValue: + ld1r {v4.4s},[x12] // load scale Value + mov v5.16b, v4.16b + +.LConvSym.AccumulatorsToFloat: + addp v16.4s,v16.4s,v18.4s + addp v20.4s,v20.4s,v22.4s + addp v24.4s,v24.4s,v26.4s + addp v28.4s,v28.4s,v30.4s + addp v17.4s,v17.4s,v19.4s + addp v21.4s,v21.4s,v23.4s + addp v25.4s,v25.4s,v27.4s + addp v29.4s,v29.4s,v31.4s + addp v0.4s,v16.4s,v20.4s + addp v1.4s,v24.4s,v28.4s + addp v2.4s,v17.4s,v21.4s + addp v3.4s,v25.4s,v29.4s + scvtf v0.4s,v0.4s // convert to float + scvtf v1.4s,v1.4s + scvtf v2.4s,v2.4s + scvtf v3.4s,v3.4s + fmul v0.4s,v0.4s,v4.4s // multiply by scale + fmul v1.4s,v1.4s,v5.4s + fmul v2.4s,v2.4s,v4.4s + fmul v3.4s,v3.4s,v5.4s + fcvtns v0.4s,v0.4s // convert to int + fcvtns v1.4s,v1.4s + dup v9.8h,w11 + fcvtns v2.4s,v2.4s + fcvtns v3.4s,v3.4s + sqxtn v0.4h,v0.4s + sqxtn2 v0.8h,v1.4s + sqxtn v2.4h,v2.4s + sqxtn2 v2.8h,v3.4s + subs x6, x6, 8 + sqadd v0.8h,v0.8h,v9.8h + sqadd v2.8h,v2.8h,v9.8h + sqxtun v0.8b,v0.8h // shorten to int8 + sqxtun2 v0.16b,v2.8h + b.lo .LConvSym.PartialStore + + st1 {v0.d}[1],[x5] // full 2x8 store to c + st1 {v0.8b},[x2] + +.LConvSym.ExitKernel: + ldp d14,d15,[sp,#48] + ldp d12,d13,[sp,#32] + ldp d10,d11,[sp,#16] + ldp d8,d9,[sp],#64 + ret + +.LConvSym.8InputChannels: + ldr d0,[x13] + ldr d1,[x15] + ldr d4,[x1] + ldr d5,[x1,8] + ldr d6,[x1,16] + ldr d7,[x1,24] + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,32] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,40] + smull v12.8h,v6.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v6.8b,v1.8b + ldr d6,[x1,48] + sadalp v17.4s,v3.8h + smull v14.8h,v7.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v7.8b,v1.8b + ldr d7,[x1,56] + sadalp v19.4s,v11.8h + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + sadalp v23.4s,v15.8h + smull v12.8h,v6.8b,v0.8b + sadalp v24.4s,v2.8h + smull v13.8h,v6.8b,v1.8b + sadalp v25.4s,v3.8h + smull v14.8h,v7.8b,v0.8b + sadalp v26.4s,v10.8h + smull v15.8h,v7.8b,v1.8b + sadalp v27.4s,v11.8h + add x1,x1,64 + sadalp v28.4s,v12.8h + sadalp v29.4s,v13.8h + sadalp v30.4s,v14.8h + sadalp v31.4s,v15.8h + + # ks loop + subs x9,x9,1 + b.hi .LConvSym.KernelSizeLoop + b .LConvSym.Requantize + +.LConvSym.PartialStore: + tbz x6,2,.LConvSym.Store2 + st1 {v0.s}[2],[x5],4 + str s0,[x2],4 + EXT v0.16b,v0.16b,v0.16b,4 + +.LConvSym.Store2: + tbz x6, 1, .LConvSym.Store1 + st1 {v0.h}[4], [x5], 2 + str h0, [x2], 2 + EXT v0.16b,v0.16b,v0.16b,2 +.LConvSym.Store1: + tbz x6,0,.LConvSym.ExitKernel + st1 {v0.b}[8],[x5] + str b0,[x2] + b .LConvSym.ExitKernel + + .end diff --git a/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelDot.asm b/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelDot.asm new file mode 100644 index 0000000000..ecb6c6578b --- /dev/null +++ b/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelDot.asm @@ -0,0 +1,631 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the MIT License. + +Module Name: + + ConvSymKernelNeonDot.asm + +Abstract: + + This module implements the kernels for the symmetric quantized integer + convolution operation. + +--*/ + +#include "kxarm64.h" + +#define MLAS_CONV_SYM_FLAG_INPUT_DIRECT 1 +#define MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE 2 + +// +// Stack frame layout for the symmetric convolution kernel. +// d8-d15, x19-x30 need to be preserved if used +// +#define ConvSymFrame_SavedNeonRegisters (8 * 8) +#define ConvSymFrame_SavedRegisters ConvSymFrame_SavedNeonRegisters +#define ConvSymFrame_PostProcessParams 0 + ConvSymFrame_SavedRegisters +#define ConvSymFrame_KernelFlags 8 + ConvSymFrame_SavedRegisters + +#define ConvSymPostProcessParams_Bias 0 +#define ConvSymPostProcessParams_Scale 8 +#define ConvSymPostProcessParams_Min 16 +#define ConvSymPostProcessParams_Max 20 +#define ConvSymPostProcessParams_ZeroPoint 24 + + TEXTAREA + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a convolution for the elements + of an output row for a set of filter rows. + +Arguments: + + Input (x0) - Points to the input buffer. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then the input buffer points + directly at the input tensor. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is clear, then the input buffer is an + indirection buffer. Every pointer in the indirection buffer points at a + InputChannels length vector (either from the input tensor or a vector of + padding values). These are grouped in batches of length KernelSize. + These batches are then repeated OutputCount times. + + Filter (x1) - Points to the filter buffer. + + Output (x2) - Points the output buffer. + + KernelSize (x3/x9) - Size of the kernel (most commonly. 3x3=9, 5x5=25). + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then kernel size should be 1. + + InputChannels (x4/x7) - Number of input channels. + + OutputChannels (x5) - Number of output channels. + + ChannelCount (x6) - Number of output channels this iteration produces. + + OutputCount (x7) - Number of output elements this iteration produces. + + This implementation requires the count to be no larger than 4. + + PostProcessParams (x8) - Points to the post process parameter block. + + KernelFlags - (w10) Additional flags controlling the operation. + +Return Value: + + None. + +--*/ + NESTED_ENTRY MlasConvSymKernelNeonDot + + PROLOG_SAVE_REG_PAIR d8,d9,#-64! + PROLOG_NOP ldr x8,[sp,#ConvSymFrame_PostProcessParams] + PROLOG_NOP ldr w10,[sp,#ConvSymFrame_KernelFlags] + PROLOG_SAVE_REG_PAIR d10,d11,#16 + PROLOG_SAVE_REG_PAIR d12,d13,#32 + PROLOG_SAVE_REG_PAIR x19,x20,#48 + + // compute C pointers: x2, x16, x17, x5 + cmp x7,2 // OutputCount < 2 ? + add x16,x2,x5 // x16 -> C1 + lsl x3,x3,#3 // KernelSize * sizeof(int8_t*) + csel x16,x2,x16,lo // if OutputCount < 2 x16/C1 -> C0 + mov x20,x4 + add x4,x4,3 // InputChannels align to 4 + add x17,x16,x5 // x17 -> C2 + ldr x11,[x8,#ConvSymPostProcessParams_Bias] + csel x17,x16,x17,ls // if OutputCount <= 2 x17/C2 -> C1 + bic x4,x4,3 + cmp x7,4 // OutputCount < 4 ? + add x5,x17,x5 // x5 -> C3 + ldr x19,[x8,#ConvSymPostProcessParams_Scale] + csel x5,x17,x5,lo // if OutputCount < 4 x5/C3 -> C2 + movi v12.16b,128 // for top bit flipping + +OutputChannelLoop + ldp q16,q20,[x11],32 // Init accumulators with biases + mov v17.16b,v16.16b + mov v18.16b,v16.16b + ldp q24,q28,[x11],32 + mov v19.16b,v16.16b + mov v21.16b,v20.16b + mov v22.16b,v20.16b + mov v23.16b,v20.16b + mov v25.16b,v24.16b + mov v26.16b,v24.16b + mov v27.16b,v24.16b + mov v29.16b,v28.16b + mov v30.16b,v28.16b + mov v31.16b,v28.16b + mov x9,x3 // restore KernelSize * sizeof(int8_t*) + +KernelSizeLoop + tst w10,#MLAS_CONV_SYM_FLAG_INPUT_DIRECT + beq InputIndirection + +InputDirect + cmp x16,x2 + mov x12,x0 // x12 -> A0 + add x13,x0,x20 // x13 -> A1 = A0 + input channels + csel x13,x0,x13,eq + cmp x17,x16 + add x14,x0,x20,lsl#1 // x14 -> A2 + csel x14,x13,x14,eq + cmp x5,x17 + add x15,x13,x20,lsl#1 // x15 -> A3 + csel x15,x14,x15,eq + b FinishLoadAPtr + +InputIndirection + ldr x12,[x0] // x12 -> A0 + cmp x16,x2 + b.eq SkipLoadA1 // C1==C0 -> A0=A1=A2=A3 + cmp x17,x16 + lsl x14,x3,#1 + ldr x13,[x0,x3] // x13 -> A1 + b.eq SkipLoadA2 // C2==C1 -> A1=A2=A3 + cmp x5,x17 + add x15,x3,x3,lsl#1 + ldr x14,[x0,x14] // x14 -> A2 + b.eq SkipLoadA3 // C3==C2 -> A2=A3 + ldr x15,[x0,x15] // x15 -> A3 + b FinishLoadAPtr +SkipLoadA1 + mov x13,x12 +SkipLoadA2 + mov x14,x13 +SkipLoadA3 + mov x15,x14 + +// Register Usage +// B (x1) -> 4x16 +// ---------------------------------------------------------------------------- +// |v4.b[0]..v4.b[12] v5.b[0]..v5.b[12] v6.b[0]..v6.b[12] v7.b[0]..v7.b[12]| +// | ... ... ... ... ... ... ... ... | +// |v4.b[3]..v4.b[15] v5.b[3]..v5.b[15] v6.b[3]..v6.b[15] v7.b[3]..v7.b[15]| +// A 4x4 ---------------------------------------------------------------------------- +// ------------------ ---------------------------------------------------------------------------- +// x12 |v0.b[0]..v0.b[3]| |v16.s[0]_v16.s[3] v20.s[0]_v20.s[3] v24.s[0]_v24.s[3] v28.s[0]_v28.s[3]| x2 +// x13 |v1.b[0]..v1.b[3]| |v17.s[0]_v17.s[3] v21.s[0]_v21.s[3] v25.s[0]_v25.s[3] v29.s[0]_v29.s[3]| x16 +// x14 |v2.b[0]..v2.b[3]| |v18.s[0]_v18.s[3] v22.s[0]_v23.s[3] v26.s[0]_v26.s[3] v30.s[0]_v31.s[3]| x17 +// x15 |v3.b[0]..v3.b[3]| |v19.s[0]_v19.s[3] v23.s[0]_v23.s[3] v27.s[0]_v27.s[3] v31.s[0]_v31.s[3]| x5 +// ------------------ ---------------------------------------------------------------------------- + +FinishLoadAPtr + subs x7,x4,16 // Need 16 input channels for loop + add x0,x0,8 // indirect A advance to next pointer, prepare for kernel size loop + b.lo InChannels8 + + ldr d0,[x12],8 + ldr q4,[x1],16 + ldr d1,[x13],8 + subs x7,x7,16 + ldr d2,[x14],8 + ldr d3,[x15],8 + ldr q5,[x1],16 + ldr q6,[x1],16 + ldr q7,[x1],16 + b.lo InChLoopEpilogue // Need 32 input channels for main loop + +InputChannelLoop + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + sdot v16.4s,v4.16b,v0.4b[0] + eor v2.8b,v2.8b,v12.8b + sdot v17.4s,v4.16b,v1.4b[0] + eor v3.8b,v3.8b,v12.8b + ldr d8,[x12],8 + sdot v18.4s,v4.16b,v2.4b[0] + sdot v19.4s,v4.16b,v3.4b[0] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v0.4b[0] + sdot v21.4s,v5.16b,v1.4b[0] + ldr d9,[x13],8 + sdot v22.4s,v5.16b,v2.4b[0] + sdot v23.4s,v5.16b,v3.4b[0] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v0.4b[0] + sdot v25.4s,v6.16b,v1.4b[0] + ldr d10,[x14],8 + sdot v26.4s,v6.16b,v2.4b[0] + sdot v27.4s,v6.16b,v3.4b[0] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v0.4b[0] + sdot v29.4s,v7.16b,v1.4b[0] + ldr d11,[x15],8 + sdot v30.4s,v7.16b,v2.4b[0] + sdot v31.4s,v7.16b,v3.4b[0] + ldr q7,[x1],16 + sdot v16.4s,v4.16b,v0.4b[1] + sdot v17.4s,v4.16b,v1.4b[1] + sdot v18.4s,v4.16b,v2.4b[1] + sdot v19.4s,v4.16b,v3.4b[1] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v0.4b[1] + sdot v21.4s,v5.16b,v1.4b[1] + sdot v22.4s,v5.16b,v2.4b[1] + sdot v23.4s,v5.16b,v3.4b[1] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v0.4b[1] + sdot v25.4s,v6.16b,v1.4b[1] + sdot v26.4s,v6.16b,v2.4b[1] + sdot v27.4s,v6.16b,v3.4b[1] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v0.4b[1] + sdot v29.4s,v7.16b,v1.4b[1] + sdot v30.4s,v7.16b,v2.4b[1] + sdot v31.4s,v7.16b,v3.4b[1] + eor v8.8b,v8.8b,v12.8b + ldr q7,[x1],16 + eor v9.8b,v9.8b,v12.8b + sdot v16.4s,v4.16b,v8.4b[0] + eor v10.8b,v10.8b,v12.8b + sdot v17.4s,v4.16b,v9.4b[0] + ldr d0,[x12],8 + eor v11.8b,v11.8b,v12.8b + sdot v18.4s,v4.16b,v10.4b[0] + sdot v19.4s,v4.16b,v11.4b[0] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v8.4b[0] + sdot v21.4s,v5.16b,v9.4b[0] + ldr d1,[x13],8 + sdot v22.4s,v5.16b,v10.4b[0] + sdot v23.4s,v5.16b,v11.4b[0] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v8.4b[0] + sdot v25.4s,v6.16b,v9.4b[0] + ldr d2,[x14],8 + sdot v26.4s,v6.16b,v10.4b[0] + sdot v27.4s,v6.16b,v11.4b[0] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v8.4b[0] + sdot v29.4s,v7.16b,v9.4b[0] + ldr d3,[x15],8 + sdot v30.4s,v7.16b,v10.4b[0] + sdot v31.4s,v7.16b,v11.4b[0] + ldr q7,[x1],16 + sdot v16.4s,v4.16b,v8.4b[1] + sdot v17.4s,v4.16b,v9.4b[1] + sdot v18.4s,v4.16b,v10.4b[1] + sdot v19.4s,v4.16b,v11.4b[1] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v8.4b[1] + sdot v21.4s,v5.16b,v9.4b[1] + sdot v22.4s,v5.16b,v10.4b[1] + sdot v23.4s,v5.16b,v11.4b[1] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v8.4b[1] + sdot v25.4s,v6.16b,v9.4b[1] + sdot v26.4s,v6.16b,v10.4b[1] + sdot v27.4s,v6.16b,v11.4b[1] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v8.4b[1] + sdot v29.4s,v7.16b,v9.4b[1] + subs x7,x7,16 // InputChannels -= 16 + sdot v30.4s,v7.16b,v10.4b[1] + sdot v31.4s,v7.16b,v11.4b[1] + ldr q7,[x1],16 + b.hs InputChannelLoop + +InChLoopEpilogue + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + sdot v16.4s,v4.16b,v0.4b[0] + eor v2.8b,v2.8b,v12.8b + sdot v17.4s,v4.16b,v1.4b[0] + eor v3.8b,v3.8b,v12.8b + ldr d8,[x12],8 + sdot v18.4s,v4.16b,v2.4b[0] + sdot v19.4s,v4.16b,v3.4b[0] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v0.4b[0] + sdot v21.4s,v5.16b,v1.4b[0] + ldr d9,[x13],8 + sdot v22.4s,v5.16b,v2.4b[0] + sdot v23.4s,v5.16b,v3.4b[0] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v0.4b[0] + sdot v25.4s,v6.16b,v1.4b[0] + ldr d10,[x14],8 + sdot v26.4s,v6.16b,v2.4b[0] + sdot v27.4s,v6.16b,v3.4b[0] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v0.4b[0] + sdot v29.4s,v7.16b,v1.4b[0] + ldr d11,[x15],8 + sdot v30.4s,v7.16b,v2.4b[0] + sdot v31.4s,v7.16b,v3.4b[0] + ldr q7,[x1],16 + sdot v16.4s,v4.16b,v0.4b[1] + sdot v17.4s,v4.16b,v1.4b[1] + sdot v18.4s,v4.16b,v2.4b[1] + sdot v19.4s,v4.16b,v3.4b[1] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v0.4b[1] + sdot v21.4s,v5.16b,v1.4b[1] + sdot v22.4s,v5.16b,v2.4b[1] + sdot v23.4s,v5.16b,v3.4b[1] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v0.4b[1] + sdot v25.4s,v6.16b,v1.4b[1] + sdot v26.4s,v6.16b,v2.4b[1] + sdot v27.4s,v6.16b,v3.4b[1] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v0.4b[1] + sdot v29.4s,v7.16b,v1.4b[1] + sdot v30.4s,v7.16b,v2.4b[1] + sdot v31.4s,v7.16b,v3.4b[1] + eor v8.8b,v8.8b,v12.8b + ldr q7,[x1],16 + eor v9.8b,v9.8b,v12.8b + sdot v16.4s,v4.16b,v8.4b[0] + eor v10.8b,v10.8b,v12.8b + sdot v17.4s,v4.16b,v9.4b[0] + eor v11.8b,v11.8b,v12.8b + sdot v18.4s,v4.16b,v10.4b[0] + sdot v19.4s,v4.16b,v11.4b[0] + ldr q4,[x1],16 + sdot v20.4s,v5.16b,v8.4b[0] + sdot v21.4s,v5.16b,v9.4b[0] + sdot v22.4s,v5.16b,v10.4b[0] + sdot v23.4s,v5.16b,v11.4b[0] + ldr q5,[x1],16 + sdot v24.4s,v6.16b,v8.4b[0] + sdot v25.4s,v6.16b,v9.4b[0] + sdot v26.4s,v6.16b,v10.4b[0] + sdot v27.4s,v6.16b,v11.4b[0] + ldr q6,[x1],16 + sdot v28.4s,v7.16b,v8.4b[0] + sdot v29.4s,v7.16b,v9.4b[0] + sdot v30.4s,v7.16b,v10.4b[0] + sdot v31.4s,v7.16b,v11.4b[0] + ldr q7,[x1],16 + sdot v16.4s,v4.16b,v8.4b[1] + sdot v17.4s,v4.16b,v9.4b[1] + sdot v18.4s,v4.16b,v10.4b[1] + sdot v19.4s,v4.16b,v11.4b[1] + sdot v20.4s,v5.16b,v8.4b[1] + sdot v21.4s,v5.16b,v9.4b[1] + sdot v22.4s,v5.16b,v10.4b[1] + sdot v23.4s,v5.16b,v11.4b[1] + sdot v24.4s,v6.16b,v8.4b[1] + sdot v25.4s,v6.16b,v9.4b[1] + sdot v26.4s,v6.16b,v10.4b[1] + sdot v27.4s,v6.16b,v11.4b[1] + sdot v28.4s,v7.16b,v8.4b[1] + sdot v29.4s,v7.16b,v9.4b[1] + sdot v30.4s,v7.16b,v10.4b[1] + sdot v31.4s,v7.16b,v11.4b[1] + + TST x7,15 + B.NE InChannels8 // 4 ~ 12 InputChannels + + subs x9,x9,8 // KernelSize-=1 + b.hi KernelSizeLoop + +Requantize + tst w10,#MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE + ldr w13,[x8,#ConvSymPostProcessParams_ZeroPoint] + beq BroadcastScaleValue + ldp q0,q1,[x19],32 // load scale vector + ldp q2,q3,[x19],32 + b AccumulatorsToFloat + +BroadcastScaleValue + ld1r {v0.4s},[x19] // load scale Value + mov v1.16b, v0.16b + mov v2.16b, v0.16b + mov v3.16b, v0.16b + +AccumulatorsToFloat + scvtf v16.4s,v16.4s // convert to float + scvtf v17.4s,v17.4s + scvtf v18.4s,v18.4s + scvtf v19.4s,v19.4s + scvtf v20.4s,v20.4s + scvtf v21.4s,v21.4s + scvtf v22.4s,v22.4s + scvtf v23.4s,v23.4s + scvtf v24.4s,v24.4s + scvtf v25.4s,v25.4s + scvtf v26.4s,v26.4s + scvtf v27.4s,v27.4s + scvtf v28.4s,v28.4s + scvtf v29.4s,v29.4s + scvtf v30.4s,v30.4s + scvtf v31.4s,v31.4s + fmul v16.4s,v16.4s,v0.4s // multiply by scale + fmul v17.4s,v17.4s,v0.4s + fmul v18.4s,v18.4s,v0.4s + fmul v19.4s,v19.4s,v0.4s + fmul v20.4s,v20.4s,v1.4s + fmul v21.4s,v21.4s,v1.4s + fmul v22.4s,v22.4s,v1.4s + fmul v23.4s,v23.4s,v1.4s + fmul v24.4s,v24.4s,v2.4s + fmul v25.4s,v25.4s,v2.4s + fmul v26.4s,v26.4s,v2.4s + fmul v27.4s,v27.4s,v2.4s + fmul v28.4s,v28.4s,v3.4s + fmul v29.4s,v29.4s,v3.4s + fmul v30.4s,v30.4s,v3.4s + fmul v31.4s,v31.4s,v3.4s + fcvtns v16.4s,v16.4s // convert to int + fcvtns v17.4s,v17.4s + fcvtns v18.4s,v18.4s + fcvtns v19.4s,v19.4s + fcvtns v20.4s,v20.4s + fcvtns v21.4s,v21.4s + fcvtns v22.4s,v22.4s + fcvtns v23.4s,v23.4s + fcvtns v24.4s,v24.4s + fcvtns v25.4s,v25.4s + fcvtns v26.4s,v26.4s + fcvtns v27.4s,v27.4s + fcvtns v28.4s,v28.4s + fcvtns v29.4s,v29.4s + fcvtns v30.4s,v30.4s + fcvtns v31.4s,v31.4s + + sqxtn v16.4h,v16.4s + sqxtn v17.4h,v17.4s + sqxtn v18.4h,v18.4s + sqxtn v19.4h,v19.4s + sqxtn v24.4h,v24.4s + sqxtn v25.4h,v25.4s + sqxtn v26.4h,v26.4s + sqxtn v27.4h,v27.4s + dup v4.8h,w13 // zero point + sqxtn2 v16.8h,v20.4s + sqxtn2 v17.8h,v21.4s + sqxtn2 v18.8h,v22.4s + sqxtn2 v19.8h,v23.4s + sqxtn2 v24.8h,v28.4s + sqxtn2 v25.8h,v29.4s + sqxtn2 v26.8h,v30.4s + sqxtn2 v27.8h,v31.4s + sqadd v16.8h,v16.8h,v4.8h + sqadd v17.8h,v17.8h,v4.8h + sqadd v18.8h,v18.8h,v4.8h + sqadd v19.8h,v19.8h,v4.8h + sqadd v24.8h,v24.8h,v4.8h + sqadd v25.8h,v25.8h,v4.8h + sqadd v26.8h,v26.8h,v4.8h + sqadd v27.8h,v27.8h,v4.8h + sqxtun v0.8b,v16.8h + sqxtun v1.8b,v17.8h + sqxtun v2.8b,v18.8h + sqxtun v3.8b,v19.8h + sqxtun2 v0.16b,v24.8h + sqxtun2 v1.16b,v25.8h + subs x6,x6,16 // processed 16 output channels + sqxtun2 v2.16b,v26.8h + sqxtun2 v3.16b,v27.8h + b.lo PartialStore + + st1 {v3.16b},[x5],16 // Store full 4 x 16 + st1 {v2.16b},[x17],16 + sub x0,x0,x3 // Restore pointer to A: a -= ks + st1 {v1.16b},[x16],16 + st1 {v0.16b},[x2],16 + b.hi OutputChannelLoop + +ExitKernel + EPILOG_RESTORE_REG_PAIR x19,x20,#48 + EPILOG_RESTORE_REG_PAIR d12,d13,#32 + EPILOG_RESTORE_REG_PAIR d10,d11,#16 + EPILOG_RESTORE_REG_PAIR d8,d9,#64! + EPILOG_RETURN + +InChannels8 + tbz x7,3,InChannels4 + ldr d0,[x12],8 + ldr q4,[x1],16 + ldr d1,[x13],8 + ldr d2,[x14],8 + ldr d3,[x15],8 + eor v0.8b,v0.8b,v12.8b + ldr q5,[x1],16 + eor v1.8b,v1.8b,v12.8b + sdot v16.4s,v4.16b,v0.4b[0] + sdot v17.4s,v4.16b,v1.4b[0] + eor v2.8b,v2.8b,v12.8b + ldp q6,q7,[x1],32 + eor v3.8b,v3.8b,v12.8b + sdot v18.4s,v4.16b,v2.4b[0] + sdot v19.4s,v4.16b,v3.4b[0] + sdot v20.4s,v5.16b,v0.4b[0] + sdot v21.4s,v5.16b,v1.4b[0] + sdot v22.4s,v5.16b,v2.4b[0] + sdot v23.4s,v5.16b,v3.4b[0] + sdot v24.4s,v6.16b,v0.4b[0] + sdot v25.4s,v6.16b,v1.4b[0] + ldp q4,q5,[x1],32 + sdot v26.4s,v6.16b,v2.4b[0] + sdot v27.4s,v6.16b,v3.4b[0] + sdot v28.4s,v7.16b,v0.4b[0] + sdot v29.4s,v7.16b,v1.4b[0] + sdot v30.4s,v7.16b,v2.4b[0] + sdot v31.4s,v7.16b,v3.4b[0] + sdot v16.4s,v4.16b,v0.4b[1] + sdot v17.4s,v4.16b,v1.4b[1] + ldp q6,q7,[x1],32 + sdot v18.4s,v4.16b,v2.4b[1] + sdot v19.4s,v4.16b,v3.4b[1] + sdot v20.4s,v5.16b,v0.4b[1] + sdot v21.4s,v5.16b,v1.4b[1] + sdot v22.4s,v5.16b,v2.4b[1] + sdot v23.4s,v5.16b,v3.4b[1] + sdot v24.4s,v6.16b,v0.4b[1] + sdot v25.4s,v6.16b,v1.4b[1] + sdot v26.4s,v6.16b,v2.4b[1] + sdot v27.4s,v6.16b,v3.4b[1] + sdot v28.4s,v7.16b,v0.4b[1] + sdot v29.4s,v7.16b,v1.4b[1] + sdot v30.4s,v7.16b,v2.4b[1] + sdot v31.4s,v7.16b,v3.4b[1] + tbz x7,2,SkipInCh4 + +InChannels4 + ldr s0,[x12],4 + ldr q4,[x1],16 + ldr s1,[x13],4 + ldr s2,[x14],4 + ldr s3,[x15],4 + eor v0.8b,v0.8b,v12.8b + ldr q5,[x1],16 + eor v1.8b,v1.8b,v12.8b + sdot v16.4s,v4.16b,v0.4b[0] + sdot v17.4s,v4.16b,v1.4b[0] + eor v2.8b,v2.8b,v12.8b + ldp q6,q7,[x1],32 + eor v3.8b,v3.8b,v12.8b + sdot v18.4s,v4.16b,v2.4b[0] + sdot v19.4s,v4.16b,v3.4b[0] + sdot v20.4s,v5.16b,v0.4b[0] + sdot v21.4s,v5.16b,v1.4b[0] + sdot v22.4s,v5.16b,v2.4b[0] + sdot v23.4s,v5.16b,v3.4b[0] + sdot v24.4s,v6.16b,v0.4b[0] + sdot v25.4s,v6.16b,v1.4b[0] + sdot v26.4s,v6.16b,v2.4b[0] + sdot v27.4s,v6.16b,v3.4b[0] + sdot v28.4s,v7.16b,v0.4b[0] + sdot v29.4s,v7.16b,v1.4b[0] + sdot v30.4s,v7.16b,v2.4b[0] + sdot v31.4s,v7.16b,v3.4b[0] + +SkipInCh4 + subs x9,x9,8 // ks -= 1 + b.hi KernelSizeLoop + b Requantize + +PartialStore + tbz x6,3,LT8Store + str d3,[x5],8 // no less than 8 channels + str d2,[x17],8 + dup d3,v3.d[1] + dup d2,v2.d[1] + str d1,[x16],8 + str d0,[x2],8 + dup d1,v1.d[1] + dup d0,v0.d[1] +LT8Store + tbz x6,2,LT4Store + str s3,[x5],4 + str s2,[x17],4 + dup s3,v3.s[1] + dup s2,v2.s[1] + str s1,[x16],4 + str s0,[x2],4 + dup s1,v1.s[1] + dup s0,v0.s[1] +LT4Store + tbz x6,1, LT2Store + str h3,[x5],2 + str h2,[x17],2 + dup h3,v3.h[1] + dup h2,v2.h[1] + str h1,[x16],2 + str h0,[x2],2 + dup h1,v1.h[1] + dup h0,v0.h[1] +LT2Store + tbz x6,0,ExitKernel + str b3,[x5] + str b2,[x17] + str b1,[x16] + str b0,[x2] + b ExitKernel + + NESTED_END MlasConvSymKernelNeonDot + + END diff --git a/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelNeon.asm b/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelNeon.asm new file mode 100644 index 0000000000..5b3c4f5d9e --- /dev/null +++ b/onnxruntime/core/mlas/lib/arm64/ConvSymU8KernelNeon.asm @@ -0,0 +1,436 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the MIT License. + +Module Name: + + ConvSymKernelNeon.s + +Abstract: + + This module implements the kernels for the symmetric quantized integer + convolution operation. + +--*/ + +#include "kxarm64.h" + +#define MLAS_CONV_SYM_FLAG_INPUT_DIRECT 1 +#define MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE 2 + +// +// Stack frame layout for the symmetric convolution kernel. +// d8-d15, x19-x30 need to be preserved if used +// +#define ConvSymFrame_SavedNeonRegisters (8 * 8) +#define ConvSymFrame_SavedRegisters ConvSymFrame_SavedNeonRegisters +#define ConvSymFrame_PostProcessParams 0 + ConvSymFrame_SavedRegisters +#define ConvSymFrame_KernelFlags 8 + ConvSymFrame_SavedRegisters + +#define ConvSymPostProcessParams_Bias 0 +#define ConvSymPostProcessParams_Scale 8 +#define ConvSymPostProcessParams_Min 16 +#define ConvSymPostProcessParams_Max 20 +#define ConvSymPostProcessParams_ZeroPoint 24 + + TEXTAREA + +/*++ + +Routine Description: + + This routine is the inner kernel to compute a convolution for the elements + of an output row for a set of filter rows. + +Arguments: + + Input (x0) - Supplies the address of the input buffer. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then the input buffer points + directly at the input tensor. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is clear, then the input buffer is an + indirection buffer. Every pointer in the indirection buffer points at a + InputChannels length vector (either from the input tensor or a vector of + padding values). These are grouped in batches of length KernelSize. + These batches are then repeated OutputCount times. + + Filter (x1) - Supplies the address of the filter buffer. + + Output (x2) - Supplies the address of the output buffer. + + KernelSize (x3) - Supplies the size of the kernel. + + If MLAS_CONV_SYM_FLAG_INPUT_DIRECT is set, then kernel size should be 1. + + InputChannels (x4) - Supplies the number of input channels. + + This implementation requires the count to be a multiple of 8. + + OutputChannels (x5) - Supplies the number of output channels. + + ChannelCount (x6) - Supplies the number of channels this iteration produces. + + This implementation requires the count to be 8. + + OutputCount (x7) - Supplies the number of output elements this iteration produces. + + This implementation requires the count to be 1 or 2. + + PostProcessParams - Supplies the address of the post process parameter block. + + KernelFlags - Supplies additional flags controlling the operation. + +Return Value: + + None. + +--*/ + NESTED_ENTRY MlasConvSymKernelNeon + + PROLOG_SAVE_REG_PAIR d8,d9,#-64! + PROLOG_NOP ldr x8,[sp,#ConvSymFrame_PostProcessParams] + PROLOG_NOP ldrb w10,[sp,#ConvSymFrame_KernelFlags] + PROLOG_SAVE_REG_PAIR d10,d11,#16 + PROLOG_SAVE_REG_PAIR d12,d13,#32 + PROLOG_SAVE_REG_PAIR d14,d15,#48 + mov x9,x3 // save kernel size + ldr x11,[x8,#ConvSymPostProcessParams_Bias] + mov x16,x4 // save input channels + ldr x12,[x8,#ConvSymPostProcessParams_Scale] + cmp x7,2 // if OutputCount < 2 + add x5,x2,x5 // c1 = c0 + ldc + add x4,x4,7 // kc = (kc + 7) & ~7 + csel x5,x2,x5,lo // if OutputCount < 2 c1 = c0 + bic x4,x4,7 + ldp s16,s18,[x11],8 // init accumulators with bias + ldp s20,s22,[x11],8 + ldp s24,s26,[x11],8 + ldp s28,s30,[x11],8 + mov v17.16b,v16.16b + mov v19.16b,v18.16b + mov v21.16b,v20.16b + mov v23.16b,v22.16b + mov v25.16b,v24.16b + mov v27.16b,v26.16b + mov v29.16b,v28.16b + mov v31.16b,v30.16b + +// Nested loops, inner loop: input channel; outter loop: kernel size +// Each inner iteration processes 8 input channels, 2 output pixels, 8 output channels. +// +// B 8x8 +// ------------------------------------------------------------------ +// |v4.b[0] v5.b[0] v4.b[0] v5.b[0] v4.b[0] v5.b[0] v4.b[0] v5.b[0] | +// | ... ... ... ... ... ... ... ... | +// |v4.b[7] v5.b[7] v4.b[7] v5.b[7] v4.b[7] v5.b[7] v4.b[7] v5.b[7] | +// A 2x8 ------------------------------------------------------------------ +// ------------------ ------------------------------------------------------------------ +// x13-> |v0.b[0]..v0.b[7]| |v16.4s v18.4s v20.4s v22.4s v24.4s v26.4s v28.4s v30.4s | +// x15-> |v1.b[0]..v1.b[7]| |v17.4s v19.4s v21.4s v23.4s v25.4s v27.4s v29.4s v31.4s | +// ------------------ ------------------------------------------------------------------ +// When Input Channels greater than 16, unroll: +// A registers v6 v7, +// B registers v8 v9 +// + +KernelSizeLoop + + // Load next 2 A pointers + tst w10,#MLAS_CONV_SYM_FLAG_INPUT_DIRECT + ldr d4,[x1] + ldr d5,[x1,8] + beq InputIndirection + +InputDirect + mov x13,x0 // x13 -> A0 + add x15,x0,x16 // x15 -> A1 = A0 + input channels + b BlockLoopPrologue + +InputIndirection + cmp x7,2 // test if OutputCount < 2 + ldr x13,[x0] // x13 -> A0 + blo SkipLoadA1 + ldr x15,[x0,x3,lsl#3] // x15 -> A1 +SkipLoadA1 + +BlockLoopPrologue + cmp x7,2 // test if OutputCount < 2 + add x0,x0,8 // indirect A advance to next pointer, prepare for kernel size loop + csel x15,x13,x15,lo // if OutputCount < 2 x15 -> A0 + subs x14,x4,16 // input channel - 16 + movi v12.8b,128 + blo InputChannel8 // less than 16 deep, no unroll + + ldr d0,[x13],8 + ldr d1,[x15],8 + ldr d8,[x1,64] + ldr d9,[x1,72] + ldr d6,[x13],8 + subs x14,x14,16 // input channel - 16 + ldr d7,[x15],8 + blo BlockLoopEpilogue // need 32 input channel for full unrolled loop + +Blockloop + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,16] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,24] + eor v6.8b,v6.8b,v12.8b + eor v7.8b,v7.8b,v12.8b + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,80] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,88] + smull v12.8h,v4.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1,32] + sadalp v17.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + ldr d5,[x1,40] + sadalp v19.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,96] + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + ldr d9,[x1,104] + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,48] + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,56] + sadalp v23.4s, v15.8h + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,112] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,120] + smull v12.8h,v4.8b,v0.8b + add x1,x1,128 + sadalp v24.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1] // Read B + sadalp v25.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + ldr d0,[x13],8 // Read A0 + sadalp v26.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + ldr d1,[x15],8 // Read A1 + sadalp v27.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + ldr d5,[x1,8] // Read B + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,64] // Read B + smlal v14.8h,v9.8b,v6.8b + ldr d6,[x13],8 // Read A0 + smlal v15.8h,v9.8b,v7.8b + ldr d7,[x15],8 // Read A1 + sadalp v28.4s,v12.8h + ldr d9,[x1,72] // Read B + sadalp v29.4s,v13.8h + subs x14,x14,16 + sadalp v30.4s,v14.8h + movi v12.8b,128 + sadalp v31.4s,v15.8h + b.hs Blockloop + +BlockLoopEpilogue // remaining 16 input channels + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,16] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,24] + eor v6.8b,v6.8b,v12.8b + eor v7.8b,v7.8b,v12.8b + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,80] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,88] + smull v12.8h,v4.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + ldr d4,[x1,32] + sadalp v17.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + sadalp v19.4s,v11.8h + ldr d5,[x1,40] + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + ldr d8,[x1,96] + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + ldr d9,[x1,104] + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,48] + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + sadalp v23.4s,v15.8h + ldr d5,[x1,56] + smlal v2.8h,v8.8b,v6.8b + smlal v3.8h,v8.8b,v7.8b + ldr d8,[x1,112] + smlal v10.8h,v9.8b,v6.8b + smlal v11.8h,v9.8b,v7.8b + ldr d9,[x1,120] + smull v12.8h,v4.8b,v0.8b + sadalp v24.4s,v2.8h + smull v13.8h,v4.8b,v1.8b + sadalp v25.4s,v3.8h + smull v14.8h,v5.8b,v0.8b + sadalp v26.4s,v10.8h + smull v15.8h,v5.8b,v1.8b + sadalp v27.4s,v11.8h + smlal v12.8h,v8.8b,v6.8b + smlal v13.8h,v8.8b,v7.8b + smlal v14.8h,v9.8b,v6.8b + smlal v15.8h,v9.8b,v7.8b + add x1,x1,128 + + sadalp v28.4s,v12.8h + sadalp v29.4s,v13.8h + sadalp v30.4s,v14.8h + sadalp v31.4s,v15.8h + movi v12.8b,128 + tbnz x14,3,InputChannel8 + + subs x9,x9,1 + b.hi KernelSizeLoop + +Requantize + ldr w11,[x8,#ConvSymPostProcessParams_ZeroPoint] + tst w10,#MLAS_CONV_SYM_FLAG_PER_CHANNEL_SCALE + beq BroadcastScaleValue + ld1 {v4.4s,v5.4s},[x12] // load scale vector + b AccumulatorsToFloat + +BroadcastScaleValue + ld1r {v4.4s},[x12] // load scale Value + mov v5.16b, v4.16b + +AccumulatorsToFloat + addp v16.4s,v16.4s,v18.4s + addp v20.4s,v20.4s,v22.4s + addp v24.4s,v24.4s,v26.4s + addp v28.4s,v28.4s,v30.4s + addp v17.4s,v17.4s,v19.4s + addp v21.4s,v21.4s,v23.4s + addp v25.4s,v25.4s,v27.4s + addp v29.4s,v29.4s,v31.4s + addp v0.4s,v16.4s,v20.4s + addp v1.4s,v24.4s,v28.4s + addp v2.4s,v17.4s,v21.4s + addp v3.4s,v25.4s,v29.4s + scvtf v0.4s,v0.4s // convert to float + scvtf v1.4s,v1.4s + scvtf v2.4s,v2.4s + scvtf v3.4s,v3.4s + fmul v0.4s,v0.4s,v4.4s // multiply by scale + fmul v1.4s,v1.4s,v5.4s + fmul v2.4s,v2.4s,v4.4s + fmul v3.4s,v3.4s,v5.4s + fcvtns v0.4s,v0.4s // convert to int + fcvtns v1.4s,v1.4s + dup v9.8h,w11 + fcvtns v2.4s,v2.4s + fcvtns v3.4s,v3.4s + sqxtn v0.4h,v0.4s + sqxtn2 v0.8h,v1.4s + sqxtn v2.4h,v2.4s + sqxtn2 v2.8h,v3.4s + sqadd v0.8h,v0.8h,v9.8h + sqadd v2.8h,v2.8h,v9.8h + sqxtun v0.8b,v0.8h // shorten to int8 + sqxtun2 v0.16b,v2.8h + st1 {v0.d}[1],[x5] // full 2x8 store to c + st1 {v0.8b},[x2] + +ExitKernel + EPILOG_RESTORE_REG_PAIR d14,d15,#48 + EPILOG_RESTORE_REG_PAIR d12,d13,#32 + EPILOG_RESTORE_REG_PAIR d10,d11,#16 + EPILOG_RESTORE_REG_PAIR d8,d9,#64! + EPILOG_RETURN + +InputChannel8 + ldr d0,[x13] + ldr d1,[x15] + ldr d4,[x1] + ldr d5,[x1,8] + ldr d6,[x1,16] + ldr d7,[x1,24] + eor v0.8b,v0.8b,v12.8b + eor v1.8b,v1.8b,v12.8b + smull v2.8h,v4.8b,v0.8b + smull v3.8h,v4.8b,v1.8b + ldr d4,[x1,32] + smull v10.8h,v5.8b,v0.8b + smull v11.8h,v5.8b,v1.8b + ldr d5,[x1,40] + smull v12.8h,v6.8b,v0.8b + sadalp v16.4s,v2.8h + smull v13.8h,v6.8b,v1.8b + ldr d6,[x1,48] + sadalp v17.4s,v3.8h + smull v14.8h,v7.8b,v0.8b + sadalp v18.4s,v10.8h + smull v15.8h,v7.8b,v1.8b + ldr d7,[x1,56] + sadalp v19.4s,v11.8h + smull v2.8h,v4.8b,v0.8b + sadalp v20.4s,v12.8h + smull v3.8h,v4.8b,v1.8b + sadalp v21.4s,v13.8h + smull v10.8h,v5.8b,v0.8b + sadalp v22.4s,v14.8h + smull v11.8h,v5.8b,v1.8b + sadalp v23.4s,v15.8h + smull v12.8h,v6.8b,v0.8b + sadalp v24.4s,v2.8h + smull v13.8h,v6.8b,v1.8b + sadalp v25.4s,v3.8h + smull v14.8h,v7.8b,v0.8b + sadalp v26.4s,v10.8h + smull v15.8h,v7.8b,v1.8b + sadalp v27.4s,v11.8h + add x1,x1,64 + sadalp v28.4s,v12.8h + sadalp v29.4s,v13.8h + sadalp v30.4s,v14.8h + sadalp v31.4s,v15.8h + + // ks loop + subs x9,x9,1 + b.hi KernelSizeLoop + b Requantize + + NESTED_END MlasConvSymKernelNeon + + END diff --git a/onnxruntime/core/mlas/lib/convsym.cpp b/onnxruntime/core/mlas/lib/convsym.cpp index 1033b1d0c0..4deecc3553 100644 --- a/onnxruntime/core/mlas/lib/convsym.cpp +++ b/onnxruntime/core/mlas/lib/convsym.cpp @@ -64,6 +64,8 @@ extern "C" { MLAS_CONV_SYM_KERNEL MlasConvSymKernelAvx512Vnni; MLAS_CONV_SYM_DEPTHWISE_KERNEL MlasConvSymDepthwiseKernelAvx512Vnni; #elif defined(MLAS_TARGET_ARM64) + MLAS_CONV_SYM_KERNEL MlasConvSymKernelNeon; + MLAS_CONV_SYM_KERNEL MlasConvSymKernelNeonDot; MLAS_CONV_SYM_DEPTHWISE_KERNEL MlasConvSymDepthwiseKernelNeon; MLAS_CONV_SYM_DEPTHWISE_ROUTINE_KERNELSIZE MlasConvSymDepthwiseKernelSize9Arm64; MLAS_CONV_SYM_DEPTHWISE_ROUTINE_KERNELSIZE MlasConvSymDepthwiseKernelSize25Arm; @@ -153,18 +155,33 @@ const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchAvx512Vnni = { #elif defined(MLAS_TARGET_ARM64) const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchNeon = { - nullptr, + MlasConvSymKernelNeon, MlasConvSymDepthwiseKernelNeon, - 4, // FilterInputChannelPackCount - 16, // FilterOutputChannelPackCount + 8, // FilterInputChannelPackCount + 8, // FilterOutputChannelPackCount 8, // KernelChannelCount - 8, // KernelOutputCount - 4, // KernelInputChannelAlignment + 2, // KernelOutputCount + 8, // KernelInputChannelAlignment 8, // KernelOutputChannelAlignment 16, // KernelDepthwiseChannelCount 4, // KernelDepthwiseOutputCount true }; + +const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchDot = { + MlasConvSymKernelNeonDot, + MlasConvSymDepthwiseKernelNeon, + 4, // FilterInputChannelPackCount + 16, // FilterOutputChannelPackCount + 0, // KernelChannelCount + 4, // KernelOutputCount + 4, // KernelInputChannelAlignment + 1, // KernelOutputChannelAlignment + 16, // KernelDepthwiseChannelCount + 4, // KernelDepthwiseOutputCount + true +}; + #endif // MLAS_TARGET_AMD64 MLAS_FORCEINLINE @@ -229,6 +246,16 @@ MlasConvSymPackWSize( } else { +#ifdef MLAS_TARGET_ARM64 + // TODO!! remove this for functional testing! + // TODO!! is there a way to know whether this is called by tests? + if (InputChannels < 128) { + // Shallow indirect conv runs slower. + // TODO!! for DOT arch, threshold should be 32 for better perf + return 0; + } +#endif + size_t OutputChannelPackCount = ConvSymDispatch->FilterOutputChannelPackCount; if (ConvSymDispatch->Kernel == nullptr || @@ -344,7 +371,9 @@ MlasConvSym( MlasConvSymSetOutputZeroPoint(PostProcessParams, Params.OutputZeroPoint, Params.InputIsSigned); - const size_t KernelChannelCount = ConvSymDispatch->KernelChannelCount; + const size_t KernelChannelCount = (ConvSymDispatch->KernelChannelCount == 0) + ? std::numeric_limits::max() + : ConvSymDispatch->KernelChannelCount; const size_t KernelOutputCount = ConvSymDispatch->KernelOutputCount; const size_t KernelSize = Params.KernelSize; diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h index 427c0559c1..6e0bd775c9 100644 --- a/onnxruntime/core/mlas/lib/mlasi.h +++ b/onnxruntime/core/mlas/lib/mlasi.h @@ -96,14 +96,46 @@ Abstract: // // Select the threading model. // -// N.B. MLAS_NO_ONNXRUNTIME_THREADPOOL is used to build MLAS test code outside +// N.B. BUILD_MLAS_NO_ONNXRUNTIME is used to build MLAS test code outside // of the ONNX Runtime source tree. OpenMP may or may not be enabled in this // configuration. // -#if !defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if !defined(BUILD_MLAS_NO_ONNXRUNTIME) #include "core/platform/threadpool.h" -#endif + +#if defined(MLAS_TARGET_ARM64) && defined(__linux__) + +#include "core/common/cpuid_info.h" +using MLAS_CPUIDINFO = onnxruntime::CPUIDInfo; + +#endif // MLAS_TARGET_ARM64 + +#else // BUILD_MLAS_NO_ONNXRUNTIME + +#if defined(MLAS_TARGET_ARM64) && defined(__linux__) +class MLASCPUIDInfo +{ + public: + static const MLASCPUIDInfo& GetCPUIDInfo() + { + static MLASCPUIDInfo cpuid_info; + return cpuid_info; + } + + // ARM + bool HasArmNeonDot() const { return has_arm_neon_dot_; } + + private: + MLASCPUIDInfo(); + + bool has_arm_neon_dot_{false}; +}; +using MLAS_CPUIDINFO = MLASCPUIDInfo; + +#endif // MLAS_TARGET_ARM64 + +#endif // BUILD_MLAS_NO_ONNXRUNTIME #if defined(_OPENMP) #include @@ -680,6 +712,7 @@ extern const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchAvxVnni; extern const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchAvx512Core; extern const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchAvx512Vnni; extern const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchNeon; +extern const MLAS_CONV_SYM_DISPATCH MlasConvSymDispatchDot; // // Quantized depthwise convolution kernels. @@ -804,6 +837,8 @@ struct MLAS_PLATFORM { uint32_t NchwcBlockSize; uint32_t PreferredBufferAlignment; int32_t MaximumThreadCount; +#elif defined(MLAS_TARGET_ARM64) + static constexpr int32_t MaximumThreadCount = MLAS_MAXIMUM_THREAD_COUNT * 4; #else static constexpr int32_t MaximumThreadCount = MLAS_MAXIMUM_THREAD_COUNT; #endif @@ -851,7 +886,7 @@ MlasGetMaximumThreadCount( MLAS_THREADPOOL* ThreadPool ) { -#if defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if defined(BUILD_MLAS_NO_ONNXRUNTIME) MLAS_UNREFERENCED_PARAMETER(ThreadPool); #if defined(_OPENMP) diff --git a/onnxruntime/core/mlas/lib/platform.cpp b/onnxruntime/core/mlas/lib/platform.cpp index f87a539e2e..9e747ce07a 100644 --- a/onnxruntime/core/mlas/lib/platform.cpp +++ b/onnxruntime/core/mlas/lib/platform.cpp @@ -35,6 +35,11 @@ Abstract: #ifndef HWCAP_ASIMDDP #define HWCAP_ASIMDDP (1 << 20) #endif + +#if defined(BUILD_MLAS_NO_ONNXRUNTIME) +MLASCPUIDInfo::MLASCPUIDInfo() { has_arm_neon_dot_ = ((getauxval(AT_HWCAP) & HWCAP_ASIMDDP) != 0); } +#endif + #endif #endif // MLAS_TARGET_ARM64 @@ -364,13 +369,14 @@ Return Value: #if defined(_WIN32) HasDotProductInstructions = (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != 0); #elif defined(__linux__) - HasDotProductInstructions = ((getauxval(AT_HWCAP) & HWCAP_ASIMDDP) != 0); + HasDotProductInstructions = MLAS_CPUIDINFO::GetCPUIDInfo().HasArmNeonDot(); #else HasDotProductInstructions = false; #endif if (HasDotProductInstructions) { this->GemmU8X8Dispatch = &MlasGemmU8X8DispatchUdot; + this->ConvSymU8S8Dispatch = &MlasConvSymDispatchDot; } #endif // MLAS_TARGET_ARM64 diff --git a/onnxruntime/core/mlas/lib/pooling.cpp b/onnxruntime/core/mlas/lib/pooling.cpp index 649e137182..de56a3a42e 100644 --- a/onnxruntime/core/mlas/lib/pooling.cpp +++ b/onnxruntime/core/mlas/lib/pooling.cpp @@ -1274,7 +1274,7 @@ Return Value: } } -#ifdef MLAS_NO_ONNXRUNTIME_THREADPOOL +#ifdef BUILD_MLAS_NO_ONNXRUNTIME MLAS_UNREFERENCED_PARAMETER(ThreadPool); // // Execute the pooling kernel routine. diff --git a/onnxruntime/core/mlas/lib/threading.cpp b/onnxruntime/core/mlas/lib/threading.cpp index 8769abdf08..317101d8c0 100644 --- a/onnxruntime/core/mlas/lib/threading.cpp +++ b/onnxruntime/core/mlas/lib/threading.cpp @@ -33,7 +33,7 @@ MlasExecuteThreaded( return; } -#if defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if defined(BUILD_MLAS_NO_ONNXRUNTIME) MLAS_UNREFERENCED_PARAMETER(ThreadPool); // @@ -75,7 +75,7 @@ MlasTrySimpleParallel( return; } -#if defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if defined(BUILD_MLAS_NO_ONNXRUNTIME) MLAS_UNREFERENCED_PARAMETER(ThreadPool); // diff --git a/onnxruntime/test/mlas/unittest/test_main.cpp b/onnxruntime/test/mlas/unittest/test_main.cpp index 4b7419cc53..66b5a6a15d 100644 --- a/onnxruntime/test/mlas/unittest/test_main.cpp +++ b/onnxruntime/test/mlas/unittest/test_main.cpp @@ -6,7 +6,7 @@ #include #include -#if !defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if !defined(BUILD_MLAS_NO_ONNXRUNTIME) MLAS_THREADPOOL* GetMlasThreadPool(void) { static MLAS_THREADPOOL* threadpool = new onnxruntime::concurrency::ThreadPool( diff --git a/onnxruntime/test/mlas/unittest/test_util.h b/onnxruntime/test/mlas/unittest/test_util.h index c14f1f57ce..c3d97eb3bb 100644 --- a/onnxruntime/test/mlas/unittest/test_util.h +++ b/onnxruntime/test/mlas/unittest/test_util.h @@ -18,7 +18,7 @@ #else #include #endif -#if !defined(MLAS_NO_ONNXRUNTIME_THREADPOOL) +#if !defined(BUILD_MLAS_NO_ONNXRUNTIME) #include "core/platform/threadpool.h" #endif diff --git a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc index 178e13aff3..e68168efea 100644 --- a/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/qlinearconv_op_test.cc @@ -595,16 +595,6 @@ TEST(QLinearConvTest, Conv2D_U8S8_Sym_M64_C64) { test.Run(); } -TEST(QLinearConvTest, Conv2D_U8S8_Sym_M16_C4) { - QLinearConvOpTester test; - test.GenerateRandomInput({1, 4, 3, 3}, .05f, 4); - test.GenerateRandomWeights({16, 4, 3, 3}, .125f, 0); - test.GenerateRandomBias(); - test.SetPads({0, 0, 0, 0}); - test.SetOutputScaleAndZeroPoint(.55f, 54); - test.Run(); -} - TEST(QLinearConvTest, Conv2D_U8S8_Sym_M16_C4_Bias) { QLinearConvOpTester test; test.GenerateRandomInput({1, 4, 3, 3}, .05f, 4); @@ -645,6 +635,18 @@ TEST(QLinearConvTest, Conv2D_U8S8_Sym_M32_C32_Bias_Pads) { test.Run(); } +TEST(QLinearConvTest, Conv2D_U8S8_Sym_M8_C8) { + // Targeting code processing 8 channels, with odd number + // of output pixels + QLinearConvOpTester test; + test.GenerateRandomInput({1, 8, 3, 5}, .85f, 4); + test.GenerateRandomWeights({8, 8, 3, 3}, .125f, 0); + test.GenerateRandomBias(); + test.SetPads({0, 0, 0, 0}); + test.SetOutputScaleAndZeroPoint(.55f, 54); + test.Run(); +} + TEST(QLinearConvTest, Conv2D_U8S8) { QLinearConvOpTester test; test.GenerateRandomInput({3, 24, 15, 11}, .05f, 4); From a7c2d1cb092db83e427a0e9a27282ae34d8a7029 Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Tue, 14 Dec 2021 13:34:14 +0800 Subject: [PATCH 037/113] bf16 for dlpack (#10016) --- onnxruntime/core/dlpack/dlpack_converter.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/onnxruntime/core/dlpack/dlpack_converter.cc b/onnxruntime/core/dlpack/dlpack_converter.cc index fe9f2385ef..49f62b8e2d 100644 --- a/onnxruntime/core/dlpack/dlpack_converter.cc +++ b/onnxruntime/core/dlpack/dlpack_converter.cc @@ -67,6 +67,10 @@ DLDataType GetDlpackDataType(const OrtValue& ort_value) { dtype.code = DLDataTypeCode::kDLUInt; dtype.bits = sizeof(uint64_t); break; + case ONNX_NAMESPACE::TensorProto_DataType_BFLOAT16: + dtype.code = DLDataTypeCode::kDLBfloat; + dtype.bits = sizeof(BFloat16); + break; default: ORT_THROW("Unexpected data type of ", tensor.GetElementType()); } @@ -158,6 +162,13 @@ MLDataType GetOrtValueDataType(const DLDataType& dtype, bool is_bool_tensor) { default: ORT_THROW("Unsupported kFloat bits " + std::to_string(dtype.bits)); } + case DLDataTypeCode::kDLBfloat: + switch (dtype.bits) { + case 16: + return DataTypeImpl::GetType(); + default: + ORT_THROW("Unsupported kBFloat bits " + std::to_string(dtype.bits)); + } default: ORT_THROW("Unsupported code " + std::to_string(dtype.code)); } From 9e04b7e59b3ee1d0eff70010077f659a4e32a86d Mon Sep 17 00:00:00 2001 From: ashari4 <70242157+ashari4@users.noreply.github.com> Date: Tue, 14 Dec 2021 08:28:12 -0800 Subject: [PATCH 038/113] Remove memcpy in in-place ATen ops (#9913) * Make ops in-place * Add comment --- orttraining/orttraining/eager/opgen/opgen/generator.py | 7 ++++++- orttraining/orttraining/eager/ort_aten.cpp | 5 ++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/orttraining/orttraining/eager/opgen/opgen/generator.py b/orttraining/orttraining/eager/opgen/opgen/generator.py index eaa3a8deef..3a8268eb12 100644 --- a/orttraining/orttraining/eager/opgen/opgen/generator.py +++ b/orttraining/orttraining/eager/opgen/opgen/generator.py @@ -348,6 +348,12 @@ class ORTGen: writer.write(f'std::vector {onnx_op.outputs}') writer.writeline(f'({onnx_op.outputs.count});') + if in_place_param: + assert(onnx_op.outputs.count == 1) + # TODO: This assumes that the first output corresponds to the first input. + # This may not work for more complicated ops. + writer.writeline(f'{onnx_op.outputs}[0] = ort_input_{onnx_op.inputs[0]};') + # Perform the invocation writer.writeline() if onnx_op_index == 0: @@ -404,7 +410,6 @@ class ORTGen: raise Exception(f'"{cpp_func.torch_func.torch_schema}" ' + 'has alias info on its return type but no associated parameter') - writer.writeline(f'copy(invoker, {return_outputs}[0], ort_input_{in_place_param.identifier.value});') writer.writeline(f'return {in_place_param.identifier.value};') def _write_function_registrations( diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index a698fccb69..9493c18f12 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -365,8 +365,8 @@ at::Tensor& zero_(at::Tensor& self){ auto* ort_flag_tensor = flag_val.GetMutable(); CopyVectorToTensor(invoker, {1}, *ort_flag_tensor); - std::vector ort_out(1); - + std::vector ort_out = {ort_in_self}; + auto status = invoker.Invoke( "ZeroGradient", { std::move(ort_in_self), @@ -377,7 +377,6 @@ at::Tensor& zero_(at::Tensor& self){ throw std::runtime_error( "ORT return failure status:" + status.ErrorMessage()); - copy(invoker, ort_out[0], ort_in_self); return self; } From 5be0fa13c0d3fd60ace846c5c2394b16ff6c2e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gin=C3=A9s=20Hidalgo?= Date: Mon, 13 Dec 2021 19:24:00 -0500 Subject: [PATCH 039/113] [DML] Fixed huge bug in ORT_NO_EXCEPTIONS for DML back end, the check is reversed --- .../providers/dml/DmlExecutionProvider/src/ErrorHandling.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ErrorHandling.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ErrorHandling.h index d358a30e7e..c59ad56e43 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ErrorHandling.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ErrorHandling.h @@ -60,13 +60,13 @@ #endif #ifdef ORT_NO_EXCEPTIONS -#define ORT_THROW_HR_IF(hr, condition) ORT_ENFORCE(condition, hr) +#define ORT_THROW_HR_IF(hr, condition) ORT_ENFORCE(!(condition), hr) #else #define ORT_THROW_HR_IF(hr, condition) THROW_HR_IF(hr, condition) #endif #ifdef ORT_NO_EXCEPTIONS -#define ORT_THROW_LAST_ERROR_IF(condition) ORT_ENFORCE(condition) +#define ORT_THROW_LAST_ERROR_IF(condition) ORT_ENFORCE(!(condition)) #else #define ORT_THROW_LAST_ERROR_IF(condition) THROW_LAST_ERROR_IF(condition) #endif From 703becd796ca7359b6424f74e1884e6de1780dd4 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Tue, 14 Dec 2021 12:50:35 -0800 Subject: [PATCH 040/113] Fix a bug in fusion_embedlayer.py (#10022) --- onnxruntime/python/tools/transformers/fusion_embedlayer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/python/tools/transformers/fusion_embedlayer.py b/onnxruntime/python/tools/transformers/fusion_embedlayer.py index ccf6f426f1..25cc133755 100644 --- a/onnxruntime/python/tools/transformers/fusion_embedlayer.py +++ b/onnxruntime/python/tools/transformers/fusion_embedlayer.py @@ -116,7 +116,7 @@ class FusionEmbedLayerNoMask(Fusion): if path1 is None: return False - expand, shape = path1 + expand, shape = path1[0], path1[-1] if shape.input[0] != input_ids: return False From af71da0ac68ad036ae3748c53f47c06bf6ea69b7 Mon Sep 17 00:00:00 2001 From: ashari4 <70242157+ashari4@users.noreply.github.com> Date: Tue, 14 Dec 2021 13:12:37 -0800 Subject: [PATCH 041/113] Yield op supports bf16 (#10035) --- orttraining/orttraining/core/graph/training_op_defs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orttraining/orttraining/core/graph/training_op_defs.cc b/orttraining/orttraining/core/graph/training_op_defs.cc index 5289227ad3..a0b9f707e3 100644 --- a/orttraining/orttraining/core/graph/training_op_defs.cc +++ b/orttraining/orttraining/core/graph/training_op_defs.cc @@ -2955,7 +2955,7 @@ Return true if all elements are true and false otherwise. /*min_arity*/ 0) .Attr("non_differentiable_outputs", "The indices of the module outputs that doesn't have a gradient.", AttributeProto::INTS, OPTIONAL_VALUE) .Attr("full_shape_outputs", "The indices of the module outputs that must have full shape.", AttributeProto::INTS) - .TypeConstraint("T", OpSchema::all_tensor_types(), "Allow inputs and outputs to be any kind of tensor.") + .TypeConstraint("T", OpSchema::all_tensor_types_with_bfloat(), "Allow inputs and outputs to be any kind of tensor.") .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { auto non_differentiable_outputs = ctx.getAttribute("non_differentiable_outputs"); std::unordered_set non_differentiable_outputs_indices{}; From e0a0f385bb10b5a0c98a8dfe52921de64f0bee51 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Tue, 14 Dec 2021 14:41:11 -0800 Subject: [PATCH 042/113] Fix some warnings in mlas (#10034) --- onnxruntime/core/mlas/lib/convolve.cpp | 8 +++++- onnxruntime/core/mlas/lib/dgemm.cpp | 9 +++++-- .../mlas/lib/intrinsics/avx2/qladd_avx2.cpp | 2 +- onnxruntime/core/mlas/lib/mlasi.h | 9 ++++++- onnxruntime/core/mlas/lib/pooling.cpp | 10 +++---- onnxruntime/core/mlas/lib/qgemm.cpp | 10 +++++-- onnxruntime/core/mlas/lib/qgemm.h | 4 +-- .../core/mlas/lib/qgemm_kernel_avx2.cpp | 2 +- .../core/mlas/lib/qgemm_kernel_default.cpp | 2 +- .../core/mlas/lib/qgemm_kernel_sse.cpp | 2 +- onnxruntime/core/mlas/lib/qlgavgpool.cpp | 27 ++++++++++++------- onnxruntime/core/mlas/lib/sgemm.cpp | 8 +++++- 12 files changed, 66 insertions(+), 27 deletions(-) diff --git a/onnxruntime/core/mlas/lib/convolve.cpp b/onnxruntime/core/mlas/lib/convolve.cpp index bc4f05dda4..78eceda4fc 100644 --- a/onnxruntime/core/mlas/lib/convolve.cpp +++ b/onnxruntime/core/mlas/lib/convolve.cpp @@ -1016,7 +1016,10 @@ Return Value: } } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif void MLASCALL MlasConvPrepare( @@ -1289,3 +1292,6 @@ Return Value: *WorkingBufferSize = TargetThreadCount * MLAS_CONV_WORKING_BUFFER_SIZE_PER_THREAD; } } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/onnxruntime/core/mlas/lib/dgemm.cpp b/onnxruntime/core/mlas/lib/dgemm.cpp index c1d20dfba4..3688699843 100644 --- a/onnxruntime/core/mlas/lib/dgemm.cpp +++ b/onnxruntime/core/mlas/lib/dgemm.cpp @@ -803,7 +803,10 @@ Return Value: Data->alpha, A, lda, B, ldb, Data->beta, C, ldc); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif void MLASCALL MlasGemmBatch( @@ -880,5 +883,7 @@ MlasGemmBatch( }); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif #endif diff --git a/onnxruntime/core/mlas/lib/intrinsics/avx2/qladd_avx2.cpp b/onnxruntime/core/mlas/lib/intrinsics/avx2/qladd_avx2.cpp index 30e09e7a4a..8fbee04659 100644 --- a/onnxruntime/core/mlas/lib/intrinsics/avx2/qladd_avx2.cpp +++ b/onnxruntime/core/mlas/lib/intrinsics/avx2/qladd_avx2.cpp @@ -185,7 +185,7 @@ MlasQLinearAddKernelAvx2Helper( if (k > 0) { const __m256i mask = _mm256_cmpgt_epi32(_mm256_set1_epi32(k), _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)); _mm256_maskstore_epi32((int*)OutputC, mask, vc); - OutputC += k * 4; + OutputC += static_cast(k) * 4; } int r = static_cast(n % 4); diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h index 6e0bd775c9..e3f224503c 100644 --- a/onnxruntime/core/mlas/lib/mlasi.h +++ b/onnxruntime/core/mlas/lib/mlasi.h @@ -933,6 +933,11 @@ MlasPartitionWork( // // Helpers to cast a floating point type to and from an integer bit format. // +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(push) + // VC++ suggests we can attempt to make 'MlasBitsOfFp32' constexpr, but it is not valid. + #pragma warning(disable:26497) +#endif MLAS_FORCEINLINE uint32_t @@ -961,7 +966,9 @@ MlasFp32FromBits( u.IntegerValue = IntegerValue; return u.FloatValue; } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif #if defined(MLAS_TARGET_WASM_SCALAR) diff --git a/onnxruntime/core/mlas/lib/pooling.cpp b/onnxruntime/core/mlas/lib/pooling.cpp index de56a3a42e..5abe594685 100644 --- a/onnxruntime/core/mlas/lib/pooling.cpp +++ b/onnxruntime/core/mlas/lib/pooling.cpp @@ -66,7 +66,7 @@ void struct MLAS_MAXIMUM_POOLING { - static float InitialValue() + static constexpr float InitialValue() { return std::numeric_limits::lowest(); } @@ -76,7 +76,7 @@ struct MLAS_MAXIMUM_POOLING return MlasBroadcastFloat32x4(InitialValue()); } - static float Reduce(float Reduction, float Value) + static constexpr float Reduce(float Reduction, float Value) { return std::max(Reduction, Value); } @@ -91,7 +91,7 @@ struct MLAS_MAXIMUM_POOLING return MlasReduceMaximumFloat32x4(Reduction); } - static float AveragePool(float Reduction, float Size) + static constexpr float AveragePool(float Reduction, float Size) { MLAS_UNREFERENCED_PARAMETER(Size); @@ -147,7 +147,7 @@ struct MLAS_AVERAGE_POOLING return MlasZeroFloat32x4(); } - static float Reduce(float Reduction, float Value) + static constexpr float Reduce(float Reduction, float Value) { return Reduction + Value; } @@ -162,7 +162,7 @@ struct MLAS_AVERAGE_POOLING return MlasReduceAddFloat32x4(Reduction); } - static float AveragePool(float Reduction, float Size) + static constexpr float AveragePool(float Reduction, float Size) { return Reduction / Size; } diff --git a/onnxruntime/core/mlas/lib/qgemm.cpp b/onnxruntime/core/mlas/lib/qgemm.cpp index c53a468ce0..1a4c1c3f62 100644 --- a/onnxruntime/core/mlas/lib/qgemm.cpp +++ b/onnxruntime/core/mlas/lib/qgemm.cpp @@ -139,7 +139,11 @@ Return Value: { MlasGemmBatch(Shape, &DataParams, 1, ThreadPool); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +// VC++ suggests we can attempt to make 'MlasBitsOfFp32' constexpr, but it is not valid. +#pragma warning(disable : 26451) +#endif void MLASCALL MlasGemmBatch( @@ -216,7 +220,9 @@ MlasGemmBatch( MlasGemmQuantThreaded(&WorkBlock, &Shape, &DataParams[gemm_i], blk_i); }); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif size_t MLASCALL diff --git a/onnxruntime/core/mlas/lib/qgemm.h b/onnxruntime/core/mlas/lib/qgemm.h index 13781bcff7..c4d3532d2a 100644 --- a/onnxruntime/core/mlas/lib/qgemm.h +++ b/onnxruntime/core/mlas/lib/qgemm.h @@ -73,7 +73,7 @@ MlasGemmQuantTryGemvKernel( } template -MLAS_FORCEINLINE +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointA( int32_t ZeroPointA, @@ -84,7 +84,7 @@ MlasGemmQuantFixupZeroPointA( } template -int32_t +int32_t constexpr MlasGemmQuantFixupZeroPointB( int32_t ZeroPointB, bool BIsSigned diff --git a/onnxruntime/core/mlas/lib/qgemm_kernel_avx2.cpp b/onnxruntime/core/mlas/lib/qgemm_kernel_avx2.cpp index bbb64a683b..d9451b878d 100644 --- a/onnxruntime/core/mlas/lib/qgemm_kernel_avx2.cpp +++ b/onnxruntime/core/mlas/lib/qgemm_kernel_avx2.cpp @@ -115,7 +115,7 @@ MlasGemmQuantTryGemvKernel( } template<> -MLAS_FORCEINLINE +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointB( int32_t ZeroPointB, diff --git a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp index c394ac8661..c968c2aae5 100644 --- a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp +++ b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp @@ -34,7 +34,7 @@ constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::Strides; constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedStrides; template<> -MLAS_FORCEINLINE +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointA( int32_t ZeroPointA, diff --git a/onnxruntime/core/mlas/lib/qgemm_kernel_sse.cpp b/onnxruntime/core/mlas/lib/qgemm_kernel_sse.cpp index b074a4afcc..a2abb4aa7e 100644 --- a/onnxruntime/core/mlas/lib/qgemm_kernel_sse.cpp +++ b/onnxruntime/core/mlas/lib/qgemm_kernel_sse.cpp @@ -32,7 +32,7 @@ constexpr size_t MLAS_GEMM_U8X8_KERNEL_SSE::PackedK; constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_U8X8_KERNEL_SSE::Strides; template<> -MLAS_FORCEINLINE +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointB( int32_t ZeroPointB, diff --git a/onnxruntime/core/mlas/lib/qlgavgpool.cpp b/onnxruntime/core/mlas/lib/qlgavgpool.cpp index 860f4e1692..d1c15d315a 100644 --- a/onnxruntime/core/mlas/lib/qlgavgpool.cpp +++ b/onnxruntime/core/mlas/lib/qlgavgpool.cpp @@ -624,28 +624,37 @@ MlasQLinearGlobalAveragePoolNhwcSingleBatch( #if defined(MLAS_TARGET_IX86) switch (ImageSize) { case 1: - i1 = ZeroBuffer; /* fall through */ + i1 = ZeroBuffer; + [[fallthrough]]; case 2: - i2 = ZeroBuffer; /* fall through */ + i2 = ZeroBuffer; + [[fallthrough]]; case 3: - i3 = ZeroBuffer; /* fall through */ + i3 = ZeroBuffer; + [[fallthrough]]; default: break; } #else switch (ImageSize) { case 1: - i1 = ZeroBuffer; /* fall through */ + i1 = ZeroBuffer; + [[fallthrough]]; case 2: - i2 = ZeroBuffer; /* fall through */ + i2 = ZeroBuffer; + [[fallthrough]]; case 3: - i3 = ZeroBuffer; /* fall through */ + i3 = ZeroBuffer; + [[fallthrough]]; case 4: - i4 = ZeroBuffer; /* fall through */ + i4 = ZeroBuffer; + [[fallthrough]]; case 5: - i5 = ZeroBuffer; /* fall through */ + i5 = ZeroBuffer; + [[fallthrough]]; case 6: - i6 = ZeroBuffer; /* fall through */ + i6 = ZeroBuffer; + [[fallthrough]]; default: break; } diff --git a/onnxruntime/core/mlas/lib/sgemm.cpp b/onnxruntime/core/mlas/lib/sgemm.cpp index c3bbc9e48d..0360127ca0 100644 --- a/onnxruntime/core/mlas/lib/sgemm.cpp +++ b/onnxruntime/core/mlas/lib/sgemm.cpp @@ -1552,7 +1552,10 @@ Return Value: DataParams->alpha, A, lda, B, ldb, DataParams->beta, C, ldc); } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif void MLASCALL MlasGemmBatch( @@ -1631,6 +1634,9 @@ MlasGemmBatch( TransA, TransB, M, N, K, &(Data[GemmIdx]), ThreadIdx); }); } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif size_t MLASCALL From 9d9ebd3b8536cc93fe8ac32acdffcd490c16c70c Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Tue, 14 Dec 2021 14:41:42 -0800 Subject: [PATCH 043/113] Fix some static analysis warnings in the core framework (#10033) --- .../core/framework/kernel_def_builder.h | 2 +- .../platform/EigenNonBlockingThreadPool.h | 6 +- .../onnxruntime/core/platform/threadpool.h | 6 +- .../cpu/attnlstm/attention_wrapper.cc | 5 +- .../cpu/attnlstm/bahdanau_attention.cc | 5 +- .../cpu/attnlstm/deep_cpu_attn_lstm.cc | 7 +- .../cpu/attnlstm/uni_dir_attn_lstm.cc | 7 +- onnxruntime/contrib_ops/cpu/bert/attention.cc | 2 +- .../contrib_ops/cpu/bert/attention_cpu_base.h | 9 ++- onnxruntime/contrib_ops/cpu/bert/bias_gelu.cc | 2 +- .../contrib_ops/cpu/crop_and_resize.cc | 5 +- .../cpu/math/sparse_dense_matmul.cc | 2 +- onnxruntime/contrib_ops/cpu/murmur_hash3.cc | 14 ++-- .../cpu/quantization/attention_quant.cc | 2 +- .../cpu/quantization/dynamic_quantize_lstm.cc | 4 +- onnxruntime/contrib_ops/cpu/tokenizer.cc | 12 +-- .../contrib_ops/cuda/math/complex_mul_impl.cu | 6 +- onnxruntime/core/common/cpuid_info.cc | 4 +- onnxruntime/core/common/logging/capture.cc | 2 +- onnxruntime/core/common/path.cc | 2 +- onnxruntime/core/common/threadpool.cc | 6 +- onnxruntime/core/framework/allocatormgr.h | 2 +- onnxruntime/core/framework/bfc_arena.cc | 2 +- .../core/framework/fallback_cpu_capability.cc | 2 +- .../core/framework/kernel_def_builder.cc | 2 +- onnxruntime/core/framework/kernel_registry.cc | 2 +- onnxruntime/core/framework/murmurhash3.cc | 77 +++++++++++-------- onnxruntime/core/framework/node_index_info.cc | 2 +- .../core/framework/onnxruntime_typeinfo.cc | 2 +- .../core/framework/tensor_type_and_shape.cc | 4 +- .../core/framework/tensor_type_and_shape.h | 2 +- .../graph/contrib_ops/onnx_function_util.cc | 12 ++- onnxruntime/core/graph/graph_utils.cc | 2 +- .../core/optimizer/attention_fusion.cc | 2 +- .../core/optimizer/attention_fusion_helper.h | 16 ++-- .../core/optimizer/fast_gelu_fusion.cc | 4 +- onnxruntime/core/optimizer/gemm_sum_fusion.cc | 2 +- .../core/optimizer/layer_norm_fusion.cc | 2 +- .../core/optimizer/matmul_scale_fusion.cc | 4 +- .../core/optimizer/matmul_transpose_fusion.cc | 2 +- .../core/optimizer/nchwc_transformer.cc | 2 +- .../optimizer/selectors_actions/helpers.cc | 18 ++--- .../optimizer/selectors_actions/helpers.h | 8 +- onnxruntime/core/optimizer/utils.cc | 6 +- onnxruntime/core/platform/path_lib.h | 2 +- onnxruntime/core/platform/windows/env.cc | 16 ++-- onnxruntime/core/session/inference_session.cc | 10 ++- onnxruntime/core/session/onnxruntime_c_api.cc | 12 ++- onnxruntime/core/util/math.h | 10 ++- onnxruntime/core/util/qmath.h | 4 +- 50 files changed, 201 insertions(+), 140 deletions(-) diff --git a/include/onnxruntime/core/framework/kernel_def_builder.h b/include/onnxruntime/core/framework/kernel_def_builder.h index d02f19c591..07377f7c2f 100644 --- a/include/onnxruntime/core/framework/kernel_def_builder.h +++ b/include/onnxruntime/core/framework/kernel_def_builder.h @@ -23,7 +23,7 @@ typedef std::map MemTypeMap; class KernelDef { private: // note that input/output might be on CPU implicitly when the node is from CPU execution provider - static inline bool MemTypeOnCpuExplicitly(OrtMemType mem_type) { + constexpr static inline bool MemTypeOnCpuExplicitly(OrtMemType mem_type) { return mem_type == OrtMemTypeCPUInput || mem_type == OrtMemTypeCPUOutput; } diff --git a/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h b/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h index a5af15317d..0842400c2c 100644 --- a/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h +++ b/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h @@ -332,11 +332,11 @@ class ThreadPoolParallelSection { // Number of tasks revoked (i.e., removed from the queues prior to // execution). We count this at various points, and omit waiting // for them at the end of a loop. - unsigned tasks_revoked; + unsigned tasks_revoked{0}; // Current degree of parallelism, including work in the main thread // and in the dispatcher. - unsigned current_dop; + unsigned current_dop{0}; // State shared between the main thread and worker threads // ------------------------------------------------------- @@ -1447,7 +1447,7 @@ int CurrentThreadId() const final { assert(td.GetStatus() == WorkerData::ThreadStatus::Spinning); - const int log2_spin = 20; + constexpr int log2_spin = 20; const int spin_count = allow_spinning_ ? (1ull< using onnxruntime::rnn::detail::Allocate; - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc b/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc index c94a3b40c7..fed268ed9c 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc @@ -8,7 +8,10 @@ #include using onnxruntime::rnn::detail::Allocate; - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc b/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc index f105856445..0a13083d9a 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc @@ -10,7 +10,10 @@ #include "core/common/logging/logging.h" #include "core/platform/threadpool.h" #include "core/framework/allocator.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { @@ -96,7 +99,7 @@ Status DeepCpuAttnLstmOp::ComputeImpl(OpKernelContext& context) const { int input_size = gsl::narrow(X_shape[2]); // Processing attention wrapper - const int first_attn_input = 8; + constexpr int first_attn_input = 8; const Tensor& am_query_layer_weights = *context.Input(first_attn_input + 0); // [num_directions, query_depth(hidden_size of lstm), am_attn_size] const Tensor& am_memory_layer_weights = *context.Input(first_attn_input + 1); // [num_directions, memory_depth, am_attn_size] const Tensor& am_v_weights = *context.Input(first_attn_input + 2); // [num_directions, am_attn_size] diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc b/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc index c52aacdf8b..9c0246347a 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc @@ -14,7 +14,10 @@ #ifdef _MSC_VER #pragma warning(pop) #endif - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif using namespace onnxruntime::rnn::detail; namespace onnxruntime { @@ -91,7 +94,7 @@ UniDirectionalAttnLstm::UniDirectionalAttnLstm(AllocatorPtr allocator, template void UniDirectionalAttnLstm::AllocateBuffers() { // allocate and fill with 0's. - const bool fill = true; + constexpr bool fill = true; hidden0_ = Allocate(allocator_, hidden_size_, hidden0_ptr_, fill); internal_memory_prev_ = Allocate(allocator_, hidden_size_, internal_memory_prev_ptr_, fill); internal_memory_cur_ = Allocate(allocator_, hidden_size_, internal_memory_cur_ptr_, fill); diff --git a/onnxruntime/contrib_ops/cpu/bert/attention.cc b/onnxruntime/contrib_ops/cpu/bert/attention.cc index 8f27b8a866..739360353e 100644 --- a/onnxruntime/contrib_ops/cpu/bert/attention.cc +++ b/onnxruntime/contrib_ops/cpu/bert/attention.cc @@ -196,7 +196,7 @@ Status AttentionBase::CheckInputs(const TensorShape& input_shape, return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Inputs 'mask_index' with 3D data shall have shape batch_size x sequence_length x (past_sequence_length + sequence_length)"); } } else if (mask_dims.size() == 4) { - if (static_cast(mask_dims[0]) != batch_size || mask_dims[1] != 1 || mask_dims[2] != mask_dims[3] || mask_dims[2] < past_sequence_length + sequence_length) { + if (static_cast(mask_dims[0]) != batch_size || mask_dims[1] != 1 || mask_dims[2] != mask_dims[3] || mask_dims[2] < static_cast(past_sequence_length) + sequence_length) { return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Inputs 'mask_index' with 4D data shall have shape batch_size x 1 x max_sequence_length x max_sequence_length)"); } if (is_unidirectional_ == true) { diff --git a/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h b/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h index dff54d5f3b..5ebb515575 100644 --- a/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h +++ b/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h @@ -9,7 +9,11 @@ #include "core/common/common.h" #include "core/common/safeint.h" #include "core/framework/op_kernel.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { @@ -242,3 +246,6 @@ class AttentionCPUBase : public AttentionBase { } // namespace contrib } // namespace onnxruntime +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/bert/bias_gelu.cc b/onnxruntime/contrib_ops/cpu/bert/bias_gelu.cc index 1a3aa6d3cf..2a29db7cb0 100644 --- a/onnxruntime/contrib_ops/cpu/bert/bias_gelu.cc +++ b/onnxruntime/contrib_ops/cpu/bert/bias_gelu.cc @@ -45,7 +45,7 @@ Status BiasGelu::Compute(OpKernelContext* context) const { // N = 4096 is selected based on performance test results on input shape 1x128x768. ORT_ENFORCE(use_approximation); if (use_approximation) { - static const int64_t length_per_task = 4096; + static constexpr int64_t length_per_task = 4096; int64_t task_count = (elem_count + length_per_task - 1) / length_per_task; concurrency::ThreadPool::TryBatchParallelFor( context->GetOperatorThreadPool(), static_cast(task_count), diff --git a/onnxruntime/contrib_ops/cpu/crop_and_resize.cc b/onnxruntime/contrib_ops/cpu/crop_and_resize.cc index 413eaf130b..f0548f66de 100644 --- a/onnxruntime/contrib_ops/cpu/crop_and_resize.cc +++ b/onnxruntime/contrib_ops/cpu/crop_and_resize.cc @@ -22,7 +22,10 @@ limitations under the License. #include "core/framework/tensor.h" #include "core/platform/threadpool.h" #include "core/providers/cpu/object_detection/roialign.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif using namespace onnxruntime::concurrency; namespace onnxruntime { diff --git a/onnxruntime/contrib_ops/cpu/math/sparse_dense_matmul.cc b/onnxruntime/contrib_ops/cpu/math/sparse_dense_matmul.cc index 8f99364ba5..85fde5d3e6 100644 --- a/onnxruntime/contrib_ops/cpu/math/sparse_dense_matmul.cc +++ b/onnxruntime/contrib_ops/cpu/math/sparse_dense_matmul.cc @@ -104,7 +104,7 @@ T Mul(T a_value, float, T b_value) { } template <> inline -float Mul(float a_value, float alpha, float b_value) { +constexpr float Mul(float a_value, float alpha, float b_value) { return a_value * alpha * b_value; } diff --git a/onnxruntime/contrib_ops/cpu/murmur_hash3.cc b/onnxruntime/contrib_ops/cpu/murmur_hash3.cc index d23b112547..3eb519c68b 100644 --- a/onnxruntime/contrib_ops/cpu/murmur_hash3.cc +++ b/onnxruntime/contrib_ops/cpu/murmur_hash3.cc @@ -70,7 +70,7 @@ FORCE_INLINE uint64_t getblock(const uint64_t* p, int i) { //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche -FORCE_INLINE uint32_t fmix(uint32_t h) { +FORCE_INLINE constexpr uint32_t fmix(uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; @@ -82,7 +82,7 @@ FORCE_INLINE uint32_t fmix(uint32_t h) { //---------- -FORCE_INLINE uint64_t fmix(uint64_t k) { +FORCE_INLINE constexpr uint64_t fmix(uint64_t k) { k ^= k >> 33; k *= BIG_CONSTANT(0xff51afd7ed558ccd); k ^= k >> 33; @@ -116,8 +116,8 @@ void MurmurHash3::MurmurHash3_x86_32(const void* key, int len, uint32_t seed, vo const uint8_t* data = reinterpret_cast(key); const int nblocks = len / 4; uint32_t h1 = seed; - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; + constexpr uint32_t c1 = 0xcc9e2d51; + constexpr uint32_t c2 = 0x1b873593; //---------- // body @@ -143,9 +143,11 @@ void MurmurHash3::MurmurHash3_x86_32(const void* key, int len, uint32_t seed, vo switch (len & 3) { case 3: - k1 ^= tail[2] << 16; // Fallthrough. + k1 ^= tail[2] << 16; + [[fallthrough]]; case 2: - k1 ^= tail[1] << 8; // Fallthrough. + k1 ^= tail[1] << 8; + [[fallthrough]]; case 1: k1 ^= tail[0]; k1 *= c1; diff --git a/onnxruntime/contrib_ops/cpu/quantization/attention_quant.cc b/onnxruntime/contrib_ops/cpu/quantization/attention_quant.cc index 50a03d6fca..18bed37532 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/attention_quant.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/attention_quant.cc @@ -87,7 +87,7 @@ Status QAttention::PrePack(const Tensor& weights, int input_idx, AllocatorPtr return Status::OK(); } - const size_t loop_len = 3 * num_heads_; + const size_t loop_len = 3 * static_cast(num_heads_); size_t packed_weights_data_size = packed_weights_size_ * loop_len; auto* packed_weights_data = static_cast(alloc->Alloc(packed_weights_data_size)); diff --git a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_lstm.cc b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_lstm.cc index c7dbd2dec0..302b2f1e0e 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_lstm.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_lstm.cc @@ -48,7 +48,7 @@ Status DynamicQuantizeLSTM::TryPackWeights(const Tensor& weights, PackedWeights& const size_t K = static_cast(shape[1]); const size_t N = static_cast(shape[2]); - if ((shape[0] != num_directions_) || (N != static_cast(hidden_size_ * 4))) { + if ((shape[0] != num_directions_) || (N != static_cast(hidden_size_) * 4)) { return Status::OK(); } @@ -131,7 +131,7 @@ Status DynamicQuantizeLSTM::UseSharedPrePackedBuffers(std::vector(hidden_size_) * 4) || \ weight_shape[0] != num_directions_) { \ return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, \ "Input ", #weight_name, " must have shape {", num_directions_, "} for per-tensor/layer quantization or shape {", \ diff --git a/onnxruntime/contrib_ops/cpu/tokenizer.cc b/onnxruntime/contrib_ops/cpu/tokenizer.cc index ac0cede673..d972692950 100644 --- a/onnxruntime/contrib_ops/cpu/tokenizer.cc +++ b/onnxruntime/contrib_ops/cpu/tokenizer.cc @@ -49,8 +49,8 @@ ONNX_CPU_OPERATOR_TYPED_MS_KERNEL( contrib::Tokenizer); namespace tokenizer_details { -const char start_text = 0x2; -const char end_text = 0x3; +constexpr char start_text = 0x2; +constexpr char end_text = 0x3; } // namespace tokenizer_details using namespace tokenizer_details; @@ -180,8 +180,8 @@ Status Tokenizer::CharTokenize(OpKernelContext* ctx, size_t N, size_t C, ++output_index; } // Padding strings - assert(tokens + (mark_ * 2) <= max_tokens); - const size_t pads = max_tokens - (mark_ * 2) - tokens; + assert(tokens + (static_cast(mark_) * 2) <= max_tokens); + const size_t pads = max_tokens - (static_cast(mark_) * 2) - tokens; for (size_t p = 0; p < pads; ++p) { *(output_data + output_index) = pad_value_; ++output_index; @@ -318,7 +318,7 @@ Status Tokenizer::SeparatorExpressionTokenizer(OpKernelContext* ctx, (output_data + output_index)->assign(&end_text, 1); ++output_index; } - const size_t pads = max_tokens - (mark_ * 2) - row.size(); + const size_t pads = max_tokens - (static_cast(mark_) * 2) - row.size(); for (size_t p = 0; p < pads; ++p) { *(output_data + output_index) = pad_value_; ++output_index; @@ -443,7 +443,7 @@ Status Tokenizer::TokenExpression(OpKernelContext* ctx, (output_data + output_index)->assign(&end_text, 1); ++output_index; } - const size_t pads = max_tokens - (mark_ * 2) - row.size(); + const size_t pads = max_tokens - (static_cast(mark_) * 2) - row.size(); for (size_t p = 0; p < pads; ++p) { *(output_data + output_index) = pad_value_; ++output_index; diff --git a/onnxruntime/contrib_ops/cuda/math/complex_mul_impl.cu b/onnxruntime/contrib_ops/cuda/math/complex_mul_impl.cu index fdbc986b89..e72a83cb20 100644 --- a/onnxruntime/contrib_ops/cuda/math/complex_mul_impl.cu +++ b/onnxruntime/contrib_ops/cuda/math/complex_mul_impl.cu @@ -110,7 +110,9 @@ void ComplexMul_Impl( int blocksPerGrid = static_cast(CeilDiv(count, GridDim::maxThreadsPerBlock * GridDim::maxElementsPerThread)); CUDA_LONG N = static_cast(count); - if (lhs_padded_strides && rhs_padded_strides && lhs_padded_strides->Size() && rhs_padded_strides->Size()) + if (!lhs_padded_strides || !rhs_padded_strides || !fdm_output_strides) return; + + if (lhs_padded_strides->Size() && rhs_padded_strides->Size()) _ElementWiseWithStrideTwo<<>>( output_rank_or_simple_broadcast, *lhs_padded_strides, @@ -123,7 +125,7 @@ void ComplexMul_Impl( lhs_size, rhs_size, is_conj); - else if (lhs_padded_strides && lhs_padded_strides->Size()) + else if (lhs_padded_strides->Size()) _ElementWiseWithStrideTwo<<>>( output_rank_or_simple_broadcast, *lhs_padded_strides, diff --git a/onnxruntime/core/common/cpuid_info.cc b/onnxruntime/core/common/cpuid_info.cc index fbc8fb03a5..57c5327c93 100644 --- a/onnxruntime/core/common/cpuid_info.cc +++ b/onnxruntime/core/common/cpuid_info.cc @@ -71,8 +71,8 @@ CPUIDInfo::CPUIDInfo() { if (num_IDs >= 1) { GetCPUID(1, data); if (data[2] & (1 << 27)) { - const int AVX_MASK = 0x6; - const int AVX512_MASK = 0xE6; + constexpr int AVX_MASK = 0x6; + constexpr int AVX512_MASK = 0xE6; int value = XGETBV(); bool has_sse2 = (data[3] & (1 << 26)); has_sse3_ = (data[2] & 0x1); diff --git a/onnxruntime/core/common/logging/capture.cc b/onnxruntime/core/common/logging/capture.cc index 67d92c1022..cdc8ff7ec1 100644 --- a/onnxruntime/core/common/logging/capture.cc +++ b/onnxruntime/core/common/logging/capture.cc @@ -22,7 +22,7 @@ void Capture::CapturePrintf(msvc_printf_check const char* format, ...) { // Modifications Copyright (c) Microsoft. void Capture::ProcessPrintf(msvc_printf_check const char* format, va_list args) { static constexpr auto kTruncatedWarningText = "[...truncated...]"; - static const int kMaxMessageSize = 2048; + static constexpr int kMaxMessageSize = 2048; char message_buffer[kMaxMessageSize]; const auto message = gsl::make_span(message_buffer); diff --git a/onnxruntime/core/common/path.cc b/onnxruntime/core/common/path.cc index 1050f096a4..e3e1bd6a02 100644 --- a/onnxruntime/core/common/path.cc +++ b/onnxruntime/core/common/path.cc @@ -22,7 +22,7 @@ constexpr PathChar k_preferred_path_separator = ORT_TSTR('/'); constexpr std::array k_valid_path_separators{ ORT_TSTR('/'), ORT_TSTR('\\')}; -bool IsPreferredPathSeparator(PathChar c) { +constexpr bool IsPreferredPathSeparator(PathChar c) { return c == k_preferred_path_separator; } diff --git a/onnxruntime/core/common/threadpool.cc b/onnxruntime/core/common/threadpool.cc index 18b8167dac..85bd859e57 100644 --- a/onnxruntime/core/common/threadpool.cc +++ b/onnxruntime/core/common/threadpool.cc @@ -337,10 +337,10 @@ class alignas(CACHE_LINE_BYTES) LoopCounter { // - The number of shards is <= the number of threads (d_of_p). // Hence, at low thread counts, each of N threads will get its own // shard representing 1/N of the work. - static unsigned GetNumShards(uint64_t num_iterations, + constexpr static unsigned GetNumShards(uint64_t num_iterations, uint64_t d_of_p, uint64_t block_size) { - unsigned num_shards; + unsigned num_shards = 0; auto num_blocks = num_iterations / block_size; if (num_blocks == 0) { num_shards = 1; @@ -531,7 +531,7 @@ using CostModel = Eigen::TensorCostModel; static ptrdiff_t CalculateParallelForBlock(const ptrdiff_t n, const Eigen::TensorOpCost& cost, std::function block_align, int num_threads) { const double block_size_f = 1.0 / CostModel::taskSize(1, cost); - const ptrdiff_t max_oversharding_factor = 4; + constexpr ptrdiff_t max_oversharding_factor = 4; ptrdiff_t block_size = Eigen::numext::mini( n, Eigen::numext::maxi(Eigen::divup(n, max_oversharding_factor * num_threads), static_cast(block_size_f))); diff --git a/onnxruntime/core/framework/allocatormgr.h b/onnxruntime/core/framework/allocatormgr.h index 14ae1b62f6..f8b7403c52 100644 --- a/onnxruntime/core/framework/allocatormgr.h +++ b/onnxruntime/core/framework/allocatormgr.h @@ -16,7 +16,7 @@ using AllocatorMap = std::unordered_map; // TODO: update OrtMemoryInfo, use unordered_set instead using MemoryInfoSet = std::set; -const int DEFAULT_CPU_ALLOCATOR_DEVICE_ID = 0; +constexpr int DEFAULT_CPU_ALLOCATOR_DEVICE_ID = 0; struct AllocatorCreationInfo { AllocatorCreationInfo(AllocatorFactory device_alloc_factory, diff --git a/onnxruntime/core/framework/bfc_arena.cc b/onnxruntime/core/framework/bfc_arena.cc index 57e4fea00b..4b41222474 100644 --- a/onnxruntime/core/framework/bfc_arena.cc +++ b/onnxruntime/core/framework/bfc_arena.cc @@ -164,7 +164,7 @@ Status BFCArena::Extend(size_t rounded_bytes) { static constexpr float kBackpedalFactor = 0.9f; // Try allocating less memory. while (mem_addr == nullptr) { - bytes = RoundedBytes(static_cast(bytes * kBackpedalFactor)); + bytes = RoundedBytes(static_cast(bytes) * static_cast(kBackpedalFactor)); // give up if we can't satisfy the requested size, or we're attempting an allocation of less than 8K. // diff --git a/onnxruntime/core/framework/fallback_cpu_capability.cc b/onnxruntime/core/framework/fallback_cpu_capability.cc index 28e309f26d..ddbafd6fdf 100644 --- a/onnxruntime/core/framework/fallback_cpu_capability.cc +++ b/onnxruntime/core/framework/fallback_cpu_capability.cc @@ -14,7 +14,7 @@ using namespace ONNX_NAMESPACE::Utils; namespace onnxruntime { namespace { -const int64_t kSmallInitializerThreshold = 100; +constexpr int64_t kSmallInitializerThreshold = 100; static bool IsSmallInitializer(const onnxruntime::GraphViewer& graph, const NodeArg* arg) { // 'true' in the function call is to let the searching for the initializer diff --git a/onnxruntime/core/framework/kernel_def_builder.cc b/onnxruntime/core/framework/kernel_def_builder.cc index a1162fd520..35cfecb7bb 100644 --- a/onnxruntime/core/framework/kernel_def_builder.cc +++ b/onnxruntime/core/framework/kernel_def_builder.cc @@ -15,7 +15,7 @@ namespace onnxruntime { namespace { //assume start1 <= end1, start2 <= end2 -inline bool AreIntervalsOverlap(int start1, int end1, int start2, int end2) { +constexpr inline bool AreIntervalsOverlap(int start1, int end1, int start2, int end2) { return start1 <= end2 && start2 <= end1; } diff --git a/onnxruntime/core/framework/kernel_registry.cc b/onnxruntime/core/framework/kernel_registry.cc index a1f91463a0..2e4f86e7c6 100644 --- a/onnxruntime/core/framework/kernel_registry.cc +++ b/onnxruntime/core/framework/kernel_registry.cc @@ -41,7 +41,7 @@ void TraverseFormalParametersWithTypeProto(const Node& node, if (param_filter_fn(param)) { // get type of any corresponding actual parameter, if present for (int i = 0, end = node.InputArgCount()[formal_index]; i < end; ++i) { - const NodeArg* arg = node.InputDefs()[actual_index + i]; + const NodeArg* arg = node.InputDefs()[static_cast(actual_index) + i]; if (!arg->Exists()) continue; // a missing optional argument if (!traverse_fn(param, arg->TypeAsProto())) return; } diff --git a/onnxruntime/core/framework/murmurhash3.cc b/onnxruntime/core/framework/murmurhash3.cc index 2b3ff6510e..767f10e90d 100644 --- a/onnxruntime/core/framework/murmurhash3.cc +++ b/onnxruntime/core/framework/murmurhash3.cc @@ -51,7 +51,7 @@ inline uint64_t rotl64(uint64_t x, int8_t r) { #define BIG_CONSTANT(x) (x##LLU) #endif // !defined(_MSC_VER) - +#include //----------------------------------------------------------------------------- // Block read - if your platform needs to do endian-swapping or can only // handle aligned reads, do the conversion here @@ -67,7 +67,7 @@ FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) { //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche -FORCE_INLINE uint32_t fmix32(uint32_t h) { +FORCE_INLINE constexpr uint32_t fmix32(uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; @@ -79,7 +79,7 @@ FORCE_INLINE uint32_t fmix32(uint32_t h) { //---------- -FORCE_INLINE uint64_t fmix64(uint64_t k) { +FORCE_INLINE constexpr uint64_t fmix64(uint64_t k) { k ^= k >> 33; k *= BIG_CONSTANT(0xff51afd7ed558ccd); k ^= k >> 33; @@ -99,13 +99,13 @@ void MurmurHash3::x86_32(const void* key, int len, uint32_t h1 = seed; - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; + constexpr uint32_t c1 = 0xcc9e2d51; + constexpr uint32_t c2 = 0x1b873593; //---------- // body - const uint32_t* blocks = (const uint32_t*)(data + nblocks * 4); + const uint32_t* blocks = (const uint32_t*)(data + static_cast(nblocks) * 4); for (int i = -nblocks; i; i++) { uint32_t k1 = getblock32(blocks, i); @@ -122,15 +122,17 @@ void MurmurHash3::x86_32(const void* key, int len, //---------- // tail - const uint8_t* tail = (const uint8_t*)(data + nblocks * 4); + const uint8_t* tail = (const uint8_t*)(data + static_cast(nblocks) * 4); uint32_t k1 = 0; switch (len & 3) { case 3: - k1 ^= tail[2] << 16; // Fallthrough. + k1 ^= tail[2] << 16; + [[fallthrough]]; case 2: - k1 ^= tail[1] << 8; // Fallthrough. + k1 ^= tail[1] << 8; + [[fallthrough]]; case 1: k1 ^= tail[0]; k1 *= c1; @@ -160,15 +162,15 @@ void MurmurHash3::x86_128(const void* key, int len, uint32_t seed, void* out) { uint32_t h3 = seed; uint32_t h4 = seed; - const uint32_t c1 = 0x239b961b; - const uint32_t c2 = 0xab0e9789; - const uint32_t c3 = 0x38b34ae5; - const uint32_t c4 = 0xa1e38b93; + constexpr uint32_t c1 = 0x239b961b; + constexpr uint32_t c2 = 0xab0e9789; + constexpr uint32_t c3 = 0x38b34ae5; + constexpr uint32_t c4 = 0xa1e38b93; //---------- // body - const uint32_t* blocks = (const uint32_t*)(data + nblocks * 16); + const uint32_t* blocks = (const uint32_t*)(data + static_cast(nblocks) * 16); for (int i = -nblocks; i; i++) { uint32_t k1 = getblock32(blocks, i * 4 + 0); @@ -216,7 +218,7 @@ void MurmurHash3::x86_128(const void* key, int len, uint32_t seed, void* out) { //---------- // tail - const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + const uint8_t* tail = (const uint8_t*)(data + static_cast(nblocks) * 16); uint32_t k1 = 0; uint32_t k2 = 0; @@ -225,48 +227,59 @@ void MurmurHash3::x86_128(const void* key, int len, uint32_t seed, void* out) { switch (len & 15) { case 15: - k4 ^= tail[14] << 16; // Fallthrough. + k4 ^= tail[14] << 16; + [[fallthrough]]; case 14: - k4 ^= tail[13] << 8; // Fallthrough. + k4 ^= tail[13] << 8; + [[fallthrough]]; case 13: k4 ^= tail[12] << 0; k4 *= c4; k4 = ROTL32(k4, 18); k4 *= c1; - h4 ^= k4; // Fallthrough. - + h4 ^= k4; + [[fallthrough]]; case 12: - k3 ^= tail[11] << 24; // Fallthrough. + k3 ^= tail[11] << 24; + [[fallthrough]]; case 11: - k3 ^= tail[10] << 16; // Fallthrough. + k3 ^= tail[10] << 16; + [[fallthrough]]; case 10: - k3 ^= tail[9] << 8; // Fallthrough. + k3 ^= tail[9] << 8; + [[fallthrough]]; case 9: k3 ^= tail[8] << 0; k3 *= c3; k3 = ROTL32(k3, 17); k3 *= c4; - h3 ^= k3; // Fallthrough. - + h3 ^= k3; + [[fallthrough]]; case 8: - k2 ^= tail[7] << 24; // Fallthrough. + k2 ^= tail[7] << 24; + [[fallthrough]]; case 7: - k2 ^= tail[6] << 16; // Fallthrough. + k2 ^= tail[6] << 16; + [[fallthrough]]; case 6: - k2 ^= tail[5] << 8; // Fallthrough. + k2 ^= tail[5] << 8; + [[fallthrough]]; case 5: k2 ^= tail[4] << 0; k2 *= c2; k2 = ROTL32(k2, 16); k2 *= c3; - h2 ^= k2; // Fallthrough. - + h2 ^= k2; + [[fallthrough]]; case 4: - k1 ^= tail[3] << 24; // Fallthrough. + k1 ^= tail[3] << 24; + [[fallthrough]]; case 3: - k1 ^= tail[2] << 16; // Fallthrough. + k1 ^= tail[2] << 16; + [[fallthrough]]; case 2: - k1 ^= tail[1] << 8; // Fallthrough. + k1 ^= tail[1] << 8; + [[fallthrough]]; case 1: k1 ^= tail[0] << 0; k1 *= c1; diff --git a/onnxruntime/core/framework/node_index_info.cc b/onnxruntime/core/framework/node_index_info.cc index 502568f41c..80c600fd2d 100644 --- a/onnxruntime/core/framework/node_index_info.cc +++ b/onnxruntime/core/framework/node_index_info.cc @@ -53,7 +53,7 @@ void NodeIndexInfo::Init(const TValidNodes& nodes, NodeIndex max_node_index, } std::size_t total_def_count{}; - const bool include_missing_optional_defs = true; + constexpr bool include_missing_optional_defs = true; if (max_node_index == 0) { FindMinAndMaxNodeIndex(nodes, min_node_index_, max_node_index); diff --git a/onnxruntime/core/framework/onnxruntime_typeinfo.cc b/onnxruntime/core/framework/onnxruntime_typeinfo.cc index 1079f5cac9..5a26fe2066 100644 --- a/onnxruntime/core/framework/onnxruntime_typeinfo.cc +++ b/onnxruntime/core/framework/onnxruntime_typeinfo.cc @@ -265,7 +265,7 @@ OrtStatus* OrtTypeInfo::FromTypeProto(const ONNX_NAMESPACE::TypeProto* input, Or break; case on::TensorShapeProto::Dimension::kDimParam: dim_params[i] = t.dim_param(); - // fall through + [[fallthrough]]; case on::TensorShapeProto::Dimension::VALUE_NOT_SET: shape_data[i] = -1; break; diff --git a/onnxruntime/core/framework/tensor_type_and_shape.cc b/onnxruntime/core/framework/tensor_type_and_shape.cc index b4ec9cea18..e1dafc2f83 100644 --- a/onnxruntime/core/framework/tensor_type_and_shape.cc +++ b/onnxruntime/core/framework/tensor_type_and_shape.cc @@ -84,10 +84,10 @@ ORT_API_STATUS_IMPL(OrtApis::GetTensorShapeElementCount, _In_ const OrtTensorTyp struct OrtValue; -ONNXTensorElementDataType TensorDataTypeToOnnxRuntimeTensorElementDataType( +constexpr ONNXTensorElementDataType TensorDataTypeToOnnxRuntimeTensorElementDataType( int32_t dtype) { namespace o = ONNX_NAMESPACE; - ONNXTensorElementDataType type; + ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; switch (dtype) { case o::TensorProto_DataType_FLOAT: type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT; diff --git a/onnxruntime/core/framework/tensor_type_and_shape.h b/onnxruntime/core/framework/tensor_type_and_shape.h index c31af84304..affc3c98a5 100644 --- a/onnxruntime/core/framework/tensor_type_and_shape.h +++ b/onnxruntime/core/framework/tensor_type_and_shape.h @@ -23,4 +23,4 @@ struct OrtTensorTypeAndShapeInfo { OrtStatus* Clone(OrtTensorTypeAndShapeInfo** out); }; -ONNXTensorElementDataType TensorDataTypeToOnnxRuntimeTensorElementDataType(int32_t dtype); +constexpr ONNXTensorElementDataType TensorDataTypeToOnnxRuntimeTensorElementDataType(int32_t dtype); diff --git a/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc b/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc index 929fde218a..8feaa9dd9d 100644 --- a/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc +++ b/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc @@ -7,6 +7,10 @@ namespace ONNX_NAMESPACE { #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#elif defined(_MSC_VER) && !defined(__clang__) +// VC++ suggests we can attempt to make 'onnx::float_to_bits' constexpr, but it is not valid. +#pragma warning(disable : 26497) +#pragma warning(disable : 26450) #endif static uint32_t float_to_bits(float f) { return *reinterpret_cast(&f); } @@ -20,10 +24,10 @@ static float bits_to_float(uint32_t bits) { return *reinterpret_cast(&bi static uint16_t floatToHalf(float ff) { uint32_t floatbits = float_to_bits(ff); - const uint32_t f32infty = {255 << 23}; - const uint32_t f16max = {(127 + 16) << 23}; - const uint32_t denorm_magic = {((127 - 15) + (23 - 10) + 1) << 23}; - const uint32_t sign_mask = 0x80000000u; + constexpr uint32_t f32infty = {255 << 23}; + constexpr uint32_t f16max = {(127 + 16) << 23}; + constexpr uint32_t denorm_magic = {((127 - 15) + (23 - 10) + 1) << 23}; + constexpr uint32_t sign_mask = 0x80000000u; uint16_t result = static_cast(0x0u); diff --git a/onnxruntime/core/graph/graph_utils.cc b/onnxruntime/core/graph/graph_utils.cc index 98c0bdf533..ad79b371f5 100644 --- a/onnxruntime/core/graph/graph_utils.cc +++ b/onnxruntime/core/graph/graph_utils.cc @@ -260,7 +260,7 @@ const ONNX_NAMESPACE::AttributeProto* GetNodeAttribute(const Node& node, const s /** Checks for nodes with >= 1 outputs, if only one of the outputs is input to downstream Operators. Returns the name of the single used output in output_name. */ static bool IsOnlyOneOutputUsed(const Graph& graph, const Node& node, const std::string*& output_name) { - const int unassigned = -1; + constexpr int unassigned = -1; int first_output = unassigned; // check that there are only edges for one output, and set the output_name diff --git a/onnxruntime/core/optimizer/attention_fusion.cc b/onnxruntime/core/optimizer/attention_fusion.cc index 4046c65933..d68cb11b3b 100644 --- a/onnxruntime/core/optimizer/attention_fusion.cc +++ b/onnxruntime/core/optimizer/attention_fusion.cc @@ -242,7 +242,7 @@ Status AttentionFusion::ApplyImpl(Graph& graph, bool& modified, int graph_level, fused_count++; modified = true; } - } else if (reshape_count == 1 && (shape_count == 1 || shape_count == 3) && (reshape_count + shape_count) == node.GetOutputEdgesCount()) { // GPT + } else if (reshape_count == 1 && (shape_count == 1 || shape_count == 3) && (static_cast(reshape_count) + shape_count) == node.GetOutputEdgesCount()) { // GPT if (AttentionFusionHelper::FuseGptAttention(node, graph, hidden_size, mask_int32_map, shape_count == 1, logger)) { fused_count++; modified = true; diff --git a/onnxruntime/core/optimizer/attention_fusion_helper.h b/onnxruntime/core/optimizer/attention_fusion_helper.h index df7bb4e11a..5cd11d193f 100644 --- a/onnxruntime/core/optimizer/attention_fusion_helper.h +++ b/onnxruntime/core/optimizer/attention_fusion_helper.h @@ -16,9 +16,9 @@ namespace onnxruntime { namespace AttentionFusionHelper { struct MatchGemmResult { - const Node* gemm; // the Gemm node. - const Node* input_node; // one node in the subgraph that accept the input. - const Node* output_node; // the node that have output of the subgraph. + const Node* gemm = nullptr; // the Gemm node. + const Node* input_node = nullptr; // one node in the subgraph that accept the input. + const Node* output_node = nullptr; // the node that have output of the subgraph. std::vector node_indices; // id of all nodes. }; @@ -264,8 +264,8 @@ bool ValidateGemmInitializer(const Graph& graph, const Node& gemm, int64_t hidde } struct MatchUnidirMaskResult { - const Node* div_node; // the root node (Div) of the subgraph - bool is_unidirectional; // whether the mask is unidirectional. + const Node* div_node = nullptr; // the root node (Div) of the subgraph + bool is_unidirectional = false; // whether the mask is unidirectional. std::vector node_indices; // id of all nodes in the subgraph for removing later. }; @@ -394,7 +394,7 @@ bool MatchUnidirMaskSubgraph(const Graph& graph, const Node& add_node, MatchUnid const Node& where_node = edges[0]->GetNode(); const Node& div_node = edges[1]->GetNode(); - const float expected_value = -10000.0f; + constexpr float expected_value = -10000.0f; if (!optimizer_utils::IsInitializerWithExpectedValue(graph, *(where_node.InputDefs()[2]), expected_value, true)) { return false; } @@ -877,8 +877,8 @@ bool MatchInputMaskSubgraph(const Graph& graph, const Node& layer_norm, const No } struct MatchPastResult { - NodeArg* past; - NodeArg* present; + NodeArg* past = nullptr; + NodeArg* present = nullptr; std::vector node_indices; }; diff --git a/onnxruntime/core/optimizer/fast_gelu_fusion.cc b/onnxruntime/core/optimizer/fast_gelu_fusion.cc index c2f3ac45d2..5030ae3f69 100644 --- a/onnxruntime/core/optimizer/fast_gelu_fusion.cc +++ b/onnxruntime/core/optimizer/fast_gelu_fusion.cc @@ -45,7 +45,7 @@ MatchResult FastGeluFusion::CheckFirstFormula(Graph& graph, Node& mul1_node, } int32_t input_index = -1; - const float mul_val = 0.044715f; + constexpr float mul_val = 0.044715f; for (auto i = 0; i < 2; i++) { if (optimizer_utils::IsInitializerWithExpectedValue(graph, *(mul1_node.InputDefs()[i]), mul_val, true)) { input_index = i; @@ -89,7 +89,7 @@ MatchResult FastGeluFusion::CheckFirstFormula(Graph& graph, Node& mul1_node, } input_index = -1; - const float mul4_val = 0.7978845834732056f; + constexpr float mul4_val = 0.7978845834732056f; for (auto i = 0; i < 2; i++) { if (optimizer_utils::IsInitializerWithExpectedValue(graph, *(mul4_node.InputDefs()[i]), mul4_val, true)) { input_index = i; diff --git a/onnxruntime/core/optimizer/gemm_sum_fusion.cc b/onnxruntime/core/optimizer/gemm_sum_fusion.cc index c3010b5d54..3f2c1ac046 100644 --- a/onnxruntime/core/optimizer/gemm_sum_fusion.cc +++ b/onnxruntime/core/optimizer/gemm_sum_fusion.cc @@ -16,7 +16,7 @@ Status GemmSumFusion::Apply(Graph& graph, Node& gemm_node, RewriteRuleEffect& mo const bool transA = static_cast(gemm_node.GetAttributes().at("transA").i()); const bool transB = static_cast(gemm_node.GetAttributes().at("transB").i()); const float alpha = gemm_node.GetAttributes().at("alpha").f(); - const float beta = 1.0f; + constexpr float beta = 1.0f; Node& sum_node = *graph.GetNode(gemm_node.OutputEdgesBegin()->GetNode().Index()); diff --git a/onnxruntime/core/optimizer/layer_norm_fusion.cc b/onnxruntime/core/optimizer/layer_norm_fusion.cc index 6ce3fd8971..2218fb072b 100644 --- a/onnxruntime/core/optimizer/layer_norm_fusion.cc +++ b/onnxruntime/core/optimizer/layer_norm_fusion.cc @@ -14,7 +14,7 @@ namespace onnxruntime { // LayerNorm supports limited data types. static std::vector supported_data_types{"tensor(float16)", "tensor(float)", "tensor(double)"}; // Default epsilon -static const float DEFAULT_LAYERNORM_EPSILON = 1e-5f; +static constexpr float DEFAULT_LAYERNORM_EPSILON = 1e-5f; static bool IsSupportedDataType(const Node& node) { for (const auto& input_arg : node.InputDefs()) { diff --git a/onnxruntime/core/optimizer/matmul_scale_fusion.cc b/onnxruntime/core/optimizer/matmul_scale_fusion.cc index 88d6ef615c..68973101fc 100644 --- a/onnxruntime/core/optimizer/matmul_scale_fusion.cc +++ b/onnxruntime/core/optimizer/matmul_scale_fusion.cc @@ -67,7 +67,7 @@ optional> GetScaleFromNode( const auto div_inputs = scale_node.InputDefs(); ORT_ENFORCE(div_inputs.size() == 2); - const int scale_reciprocal_arg_index = 1; + constexpr int scale_reciprocal_arg_index = 1; const NodeArg& scale_reciprocal_node_arg = *div_inputs[scale_reciprocal_arg_index]; if (is_excluded_initializer(scale_reciprocal_node_arg)) return {}; @@ -156,7 +156,7 @@ std::vector GetOutputNodeMerges( if (!scale_and_index.has_value()) continue; ORT_ENFORCE(output_node.OutputDefs().size() == 1); - const int scaled_index = 0; + constexpr int scaled_index = 0; output_node_merges.push_back( {output_edge, diff --git a/onnxruntime/core/optimizer/matmul_transpose_fusion.cc b/onnxruntime/core/optimizer/matmul_transpose_fusion.cc index f46d5136ba..1f6e546e84 100644 --- a/onnxruntime/core/optimizer/matmul_transpose_fusion.cc +++ b/onnxruntime/core/optimizer/matmul_transpose_fusion.cc @@ -170,7 +170,7 @@ static Node* ReorderCastAndTranspose(Graph& graph, Node* cast, } // Check whether the element_type is an allowed FusedMatMul data type or not. -static bool IsAllowedFusedMatMulDataType(ONNX_NAMESPACE::TensorProto_DataType element_type) { +constexpr static bool IsAllowedFusedMatMulDataType(ONNX_NAMESPACE::TensorProto_DataType element_type) { return element_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT || element_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT16 || element_type == ONNX_NAMESPACE::TensorProto_DataType_DOUBLE || diff --git a/onnxruntime/core/optimizer/nchwc_transformer.cc b/onnxruntime/core/optimizer/nchwc_transformer.cc index f264121104..944822f49f 100644 --- a/onnxruntime/core/optimizer/nchwc_transformer.cc +++ b/onnxruntime/core/optimizer/nchwc_transformer.cc @@ -244,7 +244,7 @@ void NchwcTransformerImpl::ConvPoolShapeInference(const Node& node, NchwcArgument::Shape& output_shape, const ONNX_NAMESPACE::TensorProto* filter_shape) { // Skip the leading batch and channel counts. - const int kernel_size = kNchwcSpatialDims; + constexpr int kernel_size = kNchwcSpatialDims; // Maintain the batch count dimension from the NCHWc input. output_shape.dims_[0] = input_shape.dims_[0]; diff --git a/onnxruntime/core/optimizer/selectors_actions/helpers.cc b/onnxruntime/core/optimizer/selectors_actions/helpers.cc index 00c000dfe9..c83f30f3fc 100644 --- a/onnxruntime/core/optimizer/selectors_actions/helpers.cc +++ b/onnxruntime/core/optimizer/selectors_actions/helpers.cc @@ -12,9 +12,9 @@ namespace { // if the last input/output in num_io is for the variadic input/output, // the variadic input/output could have zero or more values // so we need to special case the zero and count that as one. -int NumIOEntries(bool variadic_io, int num_io, int num_variadic_io) { +constexpr size_t NumIOEntries(bool variadic_io, size_t num_io, size_t num_variadic_io) { return variadic_io - ? num_io + std::max(1, num_variadic_io) - 1 + ? num_io + std::max(1, num_variadic_io) - 1 : num_io; } @@ -152,8 +152,8 @@ bool GetNodesByNodeIndex(Graph& graph, const std::vector& indices, st static NodesToOptimizeIndices GetNodesToOptimizeIndices( const std::vector& input_nodes, NodeIndex target_node, const std::vector& output_nodes, int num_input_defs, int num_output_defs) { - int num_inputs = num_input_defs == -1 ? gsl::narrow_cast(input_nodes.size()) : num_input_defs; - int num_outputs = num_output_defs == -1 ? gsl::narrow_cast(output_nodes.size()) : num_output_defs; + size_t num_inputs = num_input_defs == -1 ? input_nodes.size() : static_cast(num_input_defs); + size_t num_outputs = num_output_defs == -1 ? output_nodes.size() : static_cast(num_output_defs); bool variadic_input = false; bool variadic_output = false; int num_variadic_inputs = 0; @@ -181,7 +181,7 @@ static NodesToOptimizeIndices GetNodesToOptimizeIndices( "Node index value is too large to save to ORT format model: ", node_idx); }); - return NodesToOptimizeIndices{std::move(node_indices), num_inputs, num_outputs, + return NodesToOptimizeIndices{std::move(node_indices), static_cast(num_inputs), static_cast(num_outputs), variadic_input, variadic_output, num_variadic_inputs, num_variadic_outputs}; } @@ -249,7 +249,7 @@ std::vector NodesToOptimize::Inputs(const std::vector& indices, bool for (auto idx : indices) { if (idx == num_inputs - 1 && HasVariadicInput()) { for (int i = 0, end = NumVariadicInputs(); i < end; ++i) { - results.push_back(GetNode(idx + i, required)); + results.push_back(GetNode(static_cast(idx) + i, required)); } } else { results.push_back(GetNode(idx, required)); @@ -264,7 +264,7 @@ std::vector NodesToOptimize::Outputs(const std::vector& indices, boo results.reserve(NumOutputEntries()); // offset by all the inputs and the target node - const int offset = NumInputEntries() + 1; + const size_t offset = NumInputEntries() + 1; for (auto idx : indices) { if (idx == num_outputs - 1 && HasVariadicOutput()) { @@ -288,11 +288,11 @@ std::vector NodesToOptimize::GetNodesAtLocation(const NodeLocation& locat return {&Target()}; }; -int NodesToOptimize::NumInputEntries() const { +size_t NodesToOptimize::NumInputEntries() const { return NumIOEntries(variadic_input_, num_inputs, num_variadic_inputs_); } -int NodesToOptimize::NumOutputEntries() const { +size_t NodesToOptimize::NumOutputEntries() const { return NumIOEntries(variadic_output_, num_outputs, num_variadic_outputs_); } diff --git a/onnxruntime/core/optimizer/selectors_actions/helpers.h b/onnxruntime/core/optimizer/selectors_actions/helpers.h index b1bee3567d..c70fee9e9e 100644 --- a/onnxruntime/core/optimizer/selectors_actions/helpers.h +++ b/onnxruntime/core/optimizer/selectors_actions/helpers.h @@ -101,16 +101,16 @@ class NodesToOptimize { ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(NodesToOptimize); private: - Node* GetNode(int index, bool required) const { + Node* GetNode(size_t index, bool required) const { Node* node = nullptr; - ORT_ENFORCE(static_cast(index) < nodes_.size() && + ORT_ENFORCE(index < nodes_.size() && ((node = nodes_[index]) != nullptr || !required)); return node; } - int NumInputEntries() const; - int NumOutputEntries() const; + size_t NumInputEntries() const; + size_t NumOutputEntries() const; bool variadic_input_{false}; // is last input variadic bool variadic_output_{false}; diff --git a/onnxruntime/core/optimizer/utils.cc b/onnxruntime/core/optimizer/utils.cc index d5b7e999de..b3852a7e83 100644 --- a/onnxruntime/core/optimizer/utils.cc +++ b/onnxruntime/core/optimizer/utils.cc @@ -42,8 +42,8 @@ bool IsInitializerWithExpectedValue(const Graph& graph, const NodeArg& input_arg return false; } - const float atol = 1e-8f; - const float rtol = 1e-5f; + constexpr float atol = 1e-8f; + constexpr float rtol = 1e-5f; const ONNX_NAMESPACE::TensorProto* tensor_proto = nullptr; if (is_constant) { tensor_proto = graph_utils::GetConstantInitializer(graph, input_arg.Name()); @@ -76,7 +76,7 @@ bool IsInitializerWithExpectedValue(const Graph& graph, const NodeArg& input_arg const double expected_val = static_cast(expected_value); double diff = std::abs(val[0] - expected_val); - if (diff > (atol + rtol * std::abs(expected_value))) { + if (diff > (atol + static_cast(rtol) * std::abs(expected_value))) { return false; } } else if (data_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT16) { diff --git a/onnxruntime/core/platform/path_lib.h b/onnxruntime/core/platform/path_lib.h index e24e698cd3..7c6e1bf222 100644 --- a/onnxruntime/core/platform/path_lib.h +++ b/onnxruntime/core/platform/path_lib.h @@ -178,7 +178,7 @@ inline OrtFileType DTToFileType(DWORD dwFileAttributes) { return OrtFileType::TYPE_REG; } inline std::string FormatErrorCode(DWORD dw) { - static const DWORD bufferLength = 64 * 1024; + static constexpr DWORD bufferLength = 64 * 1024; std::string s(bufferLength, '\0'); FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)s.data(), bufferLength / sizeof(TCHAR), NULL); diff --git a/onnxruntime/core/platform/windows/env.cc b/onnxruntime/core/platform/windows/env.cc index cb7d733ae2..01ad7b1521 100644 --- a/onnxruntime/core/platform/windows/env.cc +++ b/onnxruntime/core/platform/windows/env.cc @@ -574,15 +574,19 @@ class WindowsEnv : public Env { constexpr DWORD kBufferSize = 32767; // Create buffer to hold the result - char buffer[kBufferSize]; + std::string buffer(kBufferSize, '\0'); - auto char_count = GetEnvironmentVariableA(var_name.c_str(), buffer, kBufferSize); - - // Will be > 0 if the API call was successful - if (char_count) { - return std::string(buffer, buffer + char_count); + //The last argument is the size of the buffer pointed to by the lpBuffer parameter, including the null-terminating character, in characters. + //If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer, not including the terminating null character. + //Therefore, If the function succeeds, kBufferSize should be larger than char_count. + auto char_count = GetEnvironmentVariableA(var_name.c_str(), buffer.data(), kBufferSize); + + if (kBufferSize > char_count) { + buffer.resize(char_count); + return buffer; } + // Else either the call was failed, or the buffer wasn't large enough. // TODO: Understand the reason for failure by calling GetLastError(). // If it is due to the specified environment variable being found in the environment block, // GetLastError() returns ERROR_ENVVAR_NOT_FOUND. diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 99d99ae0e4..3b33d2475c 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -1216,7 +1216,11 @@ static void ResolveMemoryPatternFlags(SessionState& session_state) { } } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +//VC++ reports: "Releasing unheld lock 'l' in function 'onnxruntime::InferenceSession::Initialize'". But I don't see anything wrong. +#pragma warning(disable : 26117) +#endif common::Status InferenceSession::Initialize() { Status status = Status::OK(); TimePoint tp; @@ -1468,7 +1472,9 @@ common::Status InferenceSession::Initialize() { return status; } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif // This method should be called from within Initialize() only and before the creation of the session state. // This ensures all providers have been registered in the session and the session state is consistent with the providers. void InferenceSession::UpdateProvidersWithSharedAllocators() { diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index 7894eb602b..832b8990a8 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -53,7 +53,11 @@ const OrtDmlApi* GetOrtDmlApi(_In_ uint32_t version) NO_EXCEPTION; #ifdef ENABLE_EXTENSION_CUSTOM_OPS #include "onnxruntime_extensions.h" #endif - +#if defined(_MSC_VER) && !defined(__clang__) +//The warning is: "Do not assign the result of an allocation or a function call with an owner return value to a raw pointer, use owner instead(i .11)." +//But this file is for C API. It can't use unique_ptr/shared_ptr in function signature. +#pragma warning(disable : 26400) +#endif using namespace onnxruntime::logging; using onnxruntime::BFloat16; using onnxruntime::DataTypeImpl; @@ -745,7 +749,7 @@ ORT_API_STATUS_IMPL(OrtApis::Run, _Inout_ OrtSession* sess, _In_opt_ const OrtRu _Inout_updates_all_(output_names_len) OrtValue** output) { API_IMPL_BEGIN auto session = reinterpret_cast<::onnxruntime::InferenceSession*>(sess); - const int queue_id = 0; + constexpr int queue_id = 0; std::vector feed_names(input_len); std::vector feeds(input_len); @@ -1455,7 +1459,7 @@ ORT_STATUS_PTR OrtGetNumSequenceElements(const OrtValue* p_ml_value, size_t* out } #if !defined(DISABLE_ML_OPS) -static const int NUM_MAP_INDICES = 2; +static constexpr int NUM_MAP_INDICES = 2; #endif static ORT_STATUS_PTR OrtGetValueCountImpl(const OrtValue* value, size_t* out) { @@ -1963,7 +1967,7 @@ ORT_API_STATUS_IMPL(OrtApis::GetAvailableProviders, _Outptr_ char*** out_ptr, // TODO: there is no need to manually malloc/free these memory, it is insecure // and inefficient. Instead, the implementation could scan the array twice, // and use a single string object to hold all the names. - const size_t MAX_LEN = 30; + constexpr size_t MAX_LEN = 30; const auto& available_providers = GetAvailableExecutionProviderNames(); const int available_count = gsl::narrow(available_providers.size()); char** const out = new char*[available_count]; diff --git a/onnxruntime/core/util/math.h b/onnxruntime/core/util/math.h index 9b5543a667..393340ffc0 100644 --- a/onnxruntime/core/util/math.h +++ b/onnxruntime/core/util/math.h @@ -308,12 +308,16 @@ void CopyMatrix( int ldb, TypedCopy copy) { { + assert(M >= 0); + assert(N >= 0); + assert(lda >= 0); + assert(ldb >= 0); if (lda == N && ldb == N) { - copy(A, B, static_cast(N * M)); + copy(A, B, static_cast(N) * static_cast(M)); return; } - for (int i = 0; i < M; ++i) { + for (size_t i = 0; i < static_cast(M); ++i) { copy(A + lda * i, B + ldb * i, static_cast(N)); } } @@ -330,7 +334,7 @@ void CopyVector(int N, const T* A, T* B, Provider* provider); // negative value of a parameter converts it to value higher than // 0x800... // The casting allows to use one condition instead of two. -inline bool is_a_ge_zero_and_a_lt_b(int64_t a, int64_t b) { +constexpr inline bool is_a_ge_zero_and_a_lt_b(int64_t a, int64_t b) { return static_cast(a) < static_cast(b); } diff --git a/onnxruntime/core/util/qmath.h b/onnxruntime/core/util/qmath.h index 8f1acfc377..9c272cde54 100644 --- a/onnxruntime/core/util/qmath.h +++ b/onnxruntime/core/util/qmath.h @@ -47,7 +47,7 @@ void GetQuantizationParameter(const float* data, int64_t num_of_elements, float& // Min max operation granularity: AVX512 can potentially handle 64 ~ 128 floats // per iteration. - const int granularity = 128; + constexpr int granularity = 128; std::ptrdiff_t block_size; std::ptrdiff_t num_blocks; if (concurrency::ThreadPool::ShouldParallelize(thread_pool) && num_of_elements > granularity) { @@ -114,7 +114,7 @@ void ParQuantizeLinear(const float* Input, float Scale, OutputType ZeroPoint, concurrency::ThreadPool* thread_pool) { - const std::ptrdiff_t block_size = 128; + constexpr std::ptrdiff_t block_size = 128; const std::ptrdiff_t num_blocks = (N + block_size - 1) / block_size; const TensorOpCost unit_cost{static_cast(block_size * sizeof(float)), static_cast(block_size * sizeof(uint8_t)), static_cast(block_size) * 2.0}; concurrency::ThreadPool::TryParallelFor(thread_pool, num_blocks, unit_cost, [&](std::ptrdiff_t begin, std::ptrdiff_t end) { From 91096781c34a5278c496bbd94fd0da4445a3e005 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Tue, 14 Dec 2021 21:21:07 -0800 Subject: [PATCH 044/113] A small fix to allocators (#10042) --- onnxruntime/core/framework/session_state_utils.cc | 2 +- onnxruntime/core/framework/tensor.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxruntime/core/framework/session_state_utils.cc b/onnxruntime/core/framework/session_state_utils.cc index bf35b82beb..3791919438 100644 --- a/onnxruntime/core/framework/session_state_utils.cc +++ b/onnxruntime/core/framework/session_state_utils.cc @@ -44,7 +44,7 @@ static common::Status AllocateBufferUsingDeviceAllocatorFromShapeAndType(const T if (shape_size > 0) { SafeInt mem_size = 0; - if (!alloc->CalcMemSizeForArray(SafeInt(shape_size), type->Size(), &mem_size)) { + if (!IAllocator::CalcMemSizeForArray(SafeInt(shape_size), type->Size(), &mem_size)) { return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed memory size calculation"); } diff --git a/onnxruntime/core/framework/tensor.cc b/onnxruntime/core/framework/tensor.cc index 01ca218ba8..81c9db9163 100644 --- a/onnxruntime/core/framework/tensor.cc +++ b/onnxruntime/core/framework/tensor.cc @@ -29,7 +29,7 @@ Tensor::Tensor(MLDataType p_type, const TensorShape& shape, std::shared_ptr 0) { SafeInt len = 0; - if (!allocator->CalcMemSizeForArray(SafeInt(shape_size), p_type->Size(), &len)) + if (!IAllocator::CalcMemSizeForArray(SafeInt(shape_size), p_type->Size(), &len)) ORT_THROW("tensor failed memory size calculation"); p_data = allocator->Alloc(len); From 8043a9facc311ad11d39f2e614103c82eeb25809 Mon Sep 17 00:00:00 2001 From: jingyanwangms <47403504+jingyanwangms@users.noreply.github.com> Date: Tue, 14 Dec 2021 23:32:06 -0800 Subject: [PATCH 045/113] Bump master version to 1.11 (#9957) * Bump master version to 1.11 * Update Windows AI version * update version in onnxruntime_c_api.cc --- VERSION_NUMBER | 2 +- docs/Versioning.md | 1 + docs/python/README.rst | 7 +- js/common/package-lock.json | 2494 ++-- js/common/package.json | 48 +- js/node/package-lock.json | 5140 ++++---- js/node/package.json | 102 +- js/react_native/package.json | 146 +- js/web/package-lock.json | 10574 ++++++++-------- js/web/package.json | 158 +- onnxruntime/__init__.py | 2 +- onnxruntime/core/session/onnxruntime_c_api.cc | 6 +- package/rpm/onnxruntime.spec | 2 +- 13 files changed, 9345 insertions(+), 9337 deletions(-) diff --git a/VERSION_NUMBER b/VERSION_NUMBER index 81c871de46..1cac385c6c 100644 --- a/VERSION_NUMBER +++ b/VERSION_NUMBER @@ -1 +1 @@ -1.10.0 +1.11.0 diff --git a/docs/Versioning.md b/docs/Versioning.md index 6d8169e29b..bd1348659c 100644 --- a/docs/Versioning.md +++ b/docs/Versioning.md @@ -26,6 +26,7 @@ For more details on ONNX Release versions, see [this page](https://github.com/on | ONNX Runtime release version | ONNX release version | ONNX opset version | ONNX ML opset version | Supported ONNX IR version | [Windows ML Availability](https://docs.microsoft.com/en-us/windows/ai/windows-ml/release-notes/)| |------------------------------|--------------------|--------------------|----------------------|------------------|------------------| +| 1.11.0 | **1.10** down to 1.2 | 15 | 2 | 7 | Windows AI 1.11+ | | 1.10.0 | **1.10** down to 1.2 | 15 | 2 | 7 | Windows AI 1.10+ | | 1.9.0 | **1.10** down to 1.2 | 15 | 2 | 7 | Windows AI 1.9+ | | 1.8.2 | **1.9** down to 1.2 | 14 | 2 | 7 | Windows AI 1.8+ | diff --git a/docs/python/README.rst b/docs/python/README.rst index 3757842b7f..5510d7fb6f 100644 --- a/docs/python/README.rst +++ b/docs/python/README.rst @@ -8,11 +8,16 @@ For more information on ONNX Runtime, please see `aka.ms/onnxruntime =0.3.0 <0.4" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "cmake-js": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.2.1.tgz", - "integrity": "sha512-wEpg0Z8SY6ihXTe+xosadh4PbASdWSM/locbLacWRYJCZfAjWLyOrd4RoVIeirLkfPxmG8GdNQA9tW/Rz5SfJA==", - "dev": true, - "requires": { - "axios": "^0.21.1", - "debug": "^4", - "fs-extra": "^5.0.0", - "is-iojs": "^1.0.1", - "lodash": "^4", - "memory-stream": "0", - "npmlog": "^1.2.0", - "rc": "^1.2.7", - "semver": "^5.0.3", - "splitargs": "0", - "tar": "^4", - "unzipper": "^0.8.13", - "url-join": "0", - "which": "^1.0.9", - "yargs": "^3.6.0" - }, - "dependencies": { - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", - "dev": true, - "requires": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, + }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "requires": { "is-glob": "^4.0.1" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + }, + "version": "5.1.2", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-iojs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", - "integrity": "sha1-TBEDO11dlNbqs3dd7cm+fQCDJfE=", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "jsonc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz", - "integrity": "sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==", - "dev": true, - "requires": { - "fast-safe-stringify": "^2.0.6", - "graceful-fs": "^4.1.15", - "mkdirp": "^0.5.1", - "parse-json": "^4.0.0", - "strip-bom": "^4.0.0", - "strip-json-comments": "^3.0.1" - }, + }, + "duplexer2": { + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "version": "0.1.4", "dependencies": { - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "requires": { + "safe-buffer": "~5.1.0" + }, + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "requires": { + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "core-util-is": "~1.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "process-nextick-args": "~2.0.0", + "util-deprecate": "~1.0.1" + }, + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true } - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, + }, "requires": { - "graceful-fs": "^4.1.6" + "readable-stream": "^2.0.2" } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + }, + "y18n": { + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "version": "3.2.2", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true - }, + }, + "error-ex": { + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "requires": { + "is-arrayish": "^0.2.1" + }, + "version": "1.3.2", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true + }, + "json-parse-better-errors": { + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "path-exists": { + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "@protobufjs/aspromise": { + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", + "dev": true + }, "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "requires": { "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + }, + "version": "6.0.0", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true - }, - "lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", - "dev": true - }, - "lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", - "dev": true - }, - "lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", - "dev": true - }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, + }, + "gauge": { + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", "requires": { - "chalk": "^4.0.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "lodash.padend": "^4.1.0", + "ansi": "^0.3.0", + "lodash.pad": "^4.1.0", + "has-unicode": "^2.0.0", + "lodash.padstart": "^4.1.0" + }, + "version": "1.2.7", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", "dev": true - }, + }, + "@types/fs-extra": { + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz", + "requires": { + "@types/node": "*" + }, + "version": "9.0.11", + "integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==", + "dev": true + }, + "@types/long": { + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "version": "4.0.1", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", + "dev": true + }, + "to-regex-range": { + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "requires": { + "is-number": "^7.0.0" + }, + "version": "5.0.1", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true + }, + "has-unicode": { + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "color-convert": { + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "requires": { + "color-name": "~1.1.4" + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true + }, + "axios": { + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "requires": { + "follow-redirects": "^1.14.0" + }, + "version": "0.21.4", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true + }, + "strip-bom": { + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "util-deprecate": { + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "ansi-colors": { + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "version": "4.1.1", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "unzipper": { + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "dev": true, + "version": "0.8.14", + "dependencies": { + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "version": "1.0.7", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "requires": { + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "core-util-is": "~1.0.0", + "string_decoder": "~0.10.x", + "process-nextick-args": "~1.0.6", + "util-deprecate": "~1.0.1", + "buffer-shims": "^1.0.0" + }, + "version": "2.1.5", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "dev": true + } + }, + "requires": { + "listenercount": "~1.0.1", + "binary": "~0.3.0", + "duplexer2": "~0.1.4", + "big-integer": "^1.6.17", + "fstream": "~1.0.10", + "setimmediate": "~1.0.4", + "readable-stream": "~2.1.5", + "buffer-indexof-polyfill": "~1.0.0", + "bluebird": "~3.4.1" + } + }, + "url-join": { + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g=", + "dev": true + }, + "fs.realpath": { + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "cliui": { + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "requires": { + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0", + "string-width": "^1.0.1" + }, + "version": "3.2.0", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true + }, + "is-extglob": { + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "are-we-there-yet": { + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha1-otKMkxAqpsyWJFomy5VN4G7FPww=", + "dev": true, + "version": "1.0.6", + "dependencies": { + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "requires": { + "safe-buffer": "~5.1.0" + }, + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "requires": { + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "core-util-is": "~1.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "process-nextick-args": "~2.0.0", + "util-deprecate": "~1.0.1" + }, + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true + } + }, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "typescript": { + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "version": "4.2.4", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "which": { + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "requires": { + "isexe": "^2.0.0" + }, + "version": "1.3.1", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true + }, + "npmlog": { + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "requires": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + }, + "version": "1.2.1", + "integrity": "sha1-KOe+YZYJtT960d0wChDWTXFiaLY=", + "dev": true + }, + "graceful-fs": { + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "version": "4.2.6", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "rc": { + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "requires": { + "strip-json-comments": "~2.0.1", + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0" + }, + "version": "1.2.8", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true + }, + "process-nextick-args": { + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "randombytes": { + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "requires": { + "safe-buffer": "^5.1.0" + }, + "version": "2.1.0", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true + }, + "@protobufjs/base64": { + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true + }, + "chainsaw": { + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "requires": { + "traverse": ">=0.3.0 <0.4" + }, + "version": "0.1.0", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true + }, + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "code-point-at": { + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "@protobufjs/pool": { + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", + "dev": true + }, + "workerpool": { + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "version": "6.1.0", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "fs-extra": { + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "version": "9.1.0", + "dependencies": { + "jsonfile": { + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "version": "6.1.0", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true + }, + "universalify": { + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + }, + "requires": { + "jsonfile": "^6.0.1", + "graceful-fs": "^4.2.0", + "at-least-node": "^1.0.0", + "universalify": "^2.0.0" + } + }, + "is-number": { + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "version": "7.0.0", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "lcid": { + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "requires": { + "invert-kv": "^1.0.0" + }, + "version": "1.0.0", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true + }, + "@protobufjs/path": { + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", + "dev": true + }, + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "requires": { + "ms": "2.1.2" + }, + "version": "4.3.1", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "requires": { + "number-is-nan": "^1.0.0" + }, + "version": "1.0.0", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true + }, + "window-size": { + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "version": "0.1.4", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "dev": true + }, "memory-stream": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", - "integrity": "sha1-6+jdHDuLw4wOeUHp3dWuvmtN6D8=", - "dev": true, + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", "requires": { "readable-stream": "~1.0.26-2" - } - }, + }, + "version": "0.0.3", + "integrity": "sha1-6+jdHDuLw4wOeUHp3dWuvmtN6D8=", + "dev": true + }, + "anymatch": { + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "requires": { + "picomatch": "^2.0.4", + "normalize-path": "^3.0.0" + }, + "version": "3.1.2", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true + }, + "semver": { + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "core-util-is": { + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "version": "1.0.3", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "require-directory": { + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "browser-stdout": { + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "version": "1.3.1", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "invert-kv": { + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fast-safe-stringify": { + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "version": "2.0.7", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", + "dev": true + }, + "@protobufjs/fetch": { + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "requires": { + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/aspromise": "^1.1.1" + }, + "version": "1.1.0", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "dev": true + }, + "buffers": { + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "version": "0.1.1", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "requires": { "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + }, + "version": "3.0.4", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, + }, + "find-up": { + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "version": "5.0.0", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true + }, + "os-locale": { + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, + "lcid": "^1.0.0" + }, + "version": "1.4.0", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true + }, + "at-least-node": { + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "wide-align": { + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "requires": { - "minimist": "^1.2.5" + "string-width": "^1.0.2 || 2" + }, + "version": "1.1.3", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true + }, + "wrappy": { + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yargs-unparser": { + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "version": "2.0.0", + "dependencies": { + "decamelize": { + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "camelcase": { + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "version": "6.2.0", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + } + }, + "requires": { + "flat": "^5.0.2", + "decamelize": "^4.0.0", + "is-plain-obj": "^2.1.0", + "camelcase": "^6.0.0" } - }, + }, + "buffer-shims": { + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "delegates": { + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "isexe": { + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "@types/mocha": { + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "version": "8.2.2", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "requires": { + "color-convert": "^2.0.1" + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true + }, + "normalize-path": { + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-binary-path": { + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "requires": { + "binary-extensions": "^2.0.0" + }, + "version": "2.1.0", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true + }, + "chownr": { + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "strip-json-comments": { + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "yocto-queue": { + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "version": "0.1.0", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "splitargs": { + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "version": "0.0.7", + "integrity": "sha1-/p965lc3GzOxDLgNoUPPgknPazs=", + "dev": true + }, + "fstream": { + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "requires": { + "inherits": "~2.0.0", + "graceful-fs": "^4.1.2", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "version": "1.0.12", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true + }, + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "requires": { + "ansi-regex": "^2.0.0" + }, + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "get-caller-file": { + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "version": "2.0.5", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "p-limit": { + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "requires": { + "yocto-queue": "^0.1.0" + }, + "version": "3.1.0", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true + }, + "number-is-nan": { + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "traverse": { + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "version": "0.3.9", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, "mocha": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", - "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "version": "8.3.2", "dependencies": { "ansi-regex": { - "version": "5.0.0", - "resolved": "", + "resolved": "", + "version": "5.0.0", "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, + }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "requires": { "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + }, + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true - }, + }, + "y18n": { + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "version": "5.0.8", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "wrap-ansi": { + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0" + }, + "version": "7.0.0", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true + }, + "strip-json-comments": { + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "is-fullwidth-code-point": "^3.0.0", + "emoji-regex": "^8.0.0" + }, + "version": "4.2.2", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "version": "2.1.3", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "requires": { + "ansi-regex": "^5.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true + }, + "cliui": { + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0", + "string-width": "^4.2.0" + }, + "version": "7.0.4", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", + "y18n": "^5.0.5", + "string-width": "^4.2.0", + "require-directory": "^2.1.1", + "escalade": "^3.1.1", + "cliui": "^7.0.2", + "get-caller-file": "^2.0.5", "yargs-parser": "^20.2.2" - } + }, + "version": "16.2.0", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", - "dev": true - }, - "node-addon-api": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", - "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", - "integrity": "sha1-KOe+YZYJtT960d0wChDWTXFiaLY=", - "dev": true, + }, "requires": { - "ansi": "~0.3.0", - "are-we-there-yet": "~1.0.0", - "gauge": "~1.2.0" + "browser-stdout": "1.3.1", + "nanoid": "3.1.20", + "chokidar": "3.5.1", + "diff": "5.0.0", + "yargs-unparser": "2.0.0", + "yargs": "16.2.0", + "minimatch": "3.0.4", + "find-up": "5.0.0", + "wide-align": "1.1.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "which": "2.0.2", + "log-symbols": "4.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "serialize-javascript": "5.0.1", + "js-yaml": "4.0.0", + "yargs-parser": "20.2.4", + "he": "1.2.0", + "workerpool": "6.1.0", + "supports-color": "8.1.1", + "strip-json-comments": "3.1.1", + "escape-string-regexp": "4.0.0", + "ms": "2.1.3", + "debug": "4.3.1" } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "requires": { - "wrappy": "1" - } - }, - "onnx-proto": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", - "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", - "dev": true, - "requires": { - "protobufjs": "^6.8.8" - } - }, + "strip-ansi": "^3.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0" + }, + "version": "1.0.2", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true + }, + "is-arrayish": { + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "version": "0.2.1", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "escalade": { + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "diff": { + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "version": "5.0.0", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "@protobufjs/float": { + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", + "dev": true + }, + "picomatch": { + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "version": "2.2.3", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true + }, "onnxruntime-common": { - "version": "file:../common", + "version": "file:../common", "dependencies": { - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" - }, - "@types/eslint": { - "version": "7.2.9", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.9.tgz", - "integrity": "sha512-SdAAXZNvWfhtf3X3y1cbbCZhP3xyPh7mfTvzV6CgfWc/ZhiHpyr9bVroe2/RCHIf7gczaNcprhaBLsx0CCJHQA==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.46", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", - "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@types/node": { - "version": "14.14.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", - "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==" - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" - }, - "@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", + "escalade": "^3.1.1", + "electron-to-chromium": "^1.3.712", + "colorette": "^1.2.2", + "caniuse-lite": "^1.0.30001208", "node-releases": "^1.1.71" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "caniuse-lite": { - "version": "1.0.30001208", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz", - "integrity": "sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==" - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + }, + "version": "4.16.4", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==" + }, + "npm-run-path": { + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, + "path-key": "^3.0.0" + }, + "version": "4.0.1", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==" + }, + "@discoveryjs/json-ext": { + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", + "version": "0.5.2", + "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" + }, + "graceful-fs": { + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "version": "4.2.6", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "json-parse-better-errors": { + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "shebang-regex": { + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "locate-path": { + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "requires": { + "p-locate": "^4.1.0" + }, + "version": "5.0.0", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==" + }, "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "version": "1.0.3", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + }, + "@webassemblyjs/helper-wasm-bytecode": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" + }, + "punycode": { + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "to-regex-range": { + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, + "is-number": "^7.0.0" + }, + "version": "5.0.1", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + }, + "mimic-fn": { + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "requires": { "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + }, + "memory-fs": { + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "electron-to-chromium": { - "version": "1.3.712", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.712.tgz", - "integrity": "sha512-3kRVibBeCM4vsgoHHGKHmPocLqtFAGTrebXxxtgKs87hNUzXrX2NuS3jnBys7IozCnw7viQlozxKkmty2KNfrw==" - }, + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "version": "0.5.0", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==" + }, + "util-deprecate": { + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "@types/eslint-scope": { + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + }, + "version": "3.7.0", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==" + }, + "@webassemblyjs/wasm-parser": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "requires": { + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/utf8": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==" + }, + "has": { + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "requires": { + "function-bind": "^1.1.1" + }, + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + }, + "json-schema-traverse": { + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "resolve": { + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "requires": { + "path-parse": "^1.0.6", + "is-core-module": "^2.2.0" + }, + "version": "1.20.0", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==" + }, + "which": { + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "requires": { + "isexe": "^2.0.0" + }, + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + }, + "resolve-from": { + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "version": "5.0.0", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "process-nextick-args": { + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "p-try": { + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "randombytes": { + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "requires": { + "safe-buffer": "^5.1.0" + }, + "version": "2.1.0", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + }, + "get-stream": { + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "version": "6.0.0", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==" + }, + "webpack-merge": { + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "version": "5.7.3", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==" + }, + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "is-core-module": { + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "requires": { + "has": "^1.0.3" + }, + "version": "2.2.0", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==" + }, "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "version": "3.0.0", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + }, + "resolve-cwd": { + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "resolve-from": "^5.0.0" + }, + "version": "3.0.0", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==" + }, + "@webassemblyjs/wast-printer": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", "requires": { - "ansi-colors": "^4.1.1" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "@xtuc/long": "4.2.2", + "@webassemblyjs/ast": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==" + }, + "execa": { + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", "requires": { - "prr": "~1.0.1" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "onetime": "^5.1.2", + "npm-run-path": "^4.0.1", + "human-signals": "^2.1.0", + "merge-stream": "^2.0.0", + "strip-final-newline": "^2.0.0", + "signal-exit": "^3.0.3", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "cross-spawn": "^7.0.3" + }, + "version": "5.0.0", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==" + }, + "shallow-clone": { + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, + "kind-of": "^6.0.2" + }, + "version": "3.0.1", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==" + }, + "is-number": { + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "version": "7.0.0", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "@webpack-cli/serve": { + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", + "version": "1.3.1", + "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" + }, + "loader-utils": { + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "requires": { + "json5": "^2.1.2", + "big.js": "^5.2.2", + "emojis-list": "^3.0.0" + }, + "version": "2.0.0", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==" + }, + "isobject": { + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "version": "3.0.1", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "requires": { "estraverse": "^5.2.0" - }, + }, + "version": "4.3.0", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "version": "5.2.0", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" } } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + }, + "clone-deep": { + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "shallow-clone": "^3.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2" + }, + "version": "4.0.1", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==" + }, + "enhanced-resolve": { + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", - "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==" - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "requires": { - "resolve": "^1.9.0" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, + "tapable": "^1.0.0", + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0" + }, + "version": "4.5.0", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==" + }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "requires": { "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + }, + "version": "7.3.5", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==" + }, + "core-util-is": { + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "@types/eslint": { + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.9.tgz", "requires": { - "randombytes": "^2.1.0" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "@types/json-schema": "*", + "@types/estree": "*" + }, + "version": "7.2.9", + "integrity": "sha512-SdAAXZNvWfhtf3X3y1cbbCZhP3xyPh7mfTvzV6CgfWc/ZhiHpyr9bVroe2/RCHIf7gczaNcprhaBLsx0CCJHQA==" + }, + "merge-stream": { + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "@webassemblyjs/leb128": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", "requires": { - "kind-of": "^6.0.2" - } - }, + "@xtuc/long": "4.2.2" + }, + "version": "1.11.0", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==" + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "mime-types": { + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "requires": { + "mime-db": "1.47.0" + }, + "version": "2.1.30", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==" + }, + "es-module-lexer": { + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" + }, + "tapable": { + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "version": "1.1.3", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + }, + "find-up": { + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "version": "4.1.0", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==" + }, + "source-map-support": { + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "requires": { + "source-map": "^0.6.0", + "buffer-from": "^1.0.0" + }, + "version": "0.5.19", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==" + }, + "@webassemblyjs/helper-wasm-section": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==" + }, + "buffer-from": { + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "ajv": { + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "requires": { + "uri-js": "^4.2.2", + "json-schema-traverse": "^0.4.1", + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0" + }, + "version": "6.12.6", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" + }, "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "requires": { "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - }, - "terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", - "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - } - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.32.0.tgz", - "integrity": "sha512-jB9PrNMFnPRiZGnm/j3qfNqJmP3ViRzkuQMIf8za0dgOYvSLi/cgA+UEEGvik9EQHX1KYyGng5PgBTTzGrH9xg==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.46", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.7.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - }, - "dependencies": { - "enhanced-resolve": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", - "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - } - } - }, + }, + "version": "2.0.0", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" + }, "webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, + "enquirer": "^2.3.6", + "import-local": "^3.0.2", + "@discoveryjs/json-ext": "^0.5.0", + "colorette": "^1.2.1", + "v8-compile-cache": "^2.2.0", + "execa": "^5.0.0", + "@webpack-cli/info": "^1.2.3", + "commander": "^7.0.0", + "fastest-levenshtein": "^1.0.12", + "@webpack-cli/configtest": "^1.0.2", + "@webpack-cli/serve": "^1.3.1", + "webpack-merge": "^5.7.3", + "rechoir": "^0.7.0", + "interpret": "^2.2.0" + }, + "version": "4.6.0", + "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", "dependencies": { "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "version": "7.2.0", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" } } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + }, + "fast-deep-equal": { + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "version": "3.1.3", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "@webassemblyjs/ieee754": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, + "@xtuc/ieee754": "^1.2.0" + }, + "version": "1.11.0", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==" + }, + "estraverse": { + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "version": "4.3.0", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "isexe": { + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "@webpack-cli/configtest": { + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" + }, + "onetime": { + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "requires": { + "mimic-fn": "^2.1.0" + }, + "version": "5.1.2", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==" + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "requires": { + "color-convert": "^2.0.1" + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + }, + "acorn": { + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "version": "8.1.1", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" + }, + "@webassemblyjs/helper-buffer": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" + }, + "interpret": { + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" + }, + "@types/estree": { + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", + "version": "0.0.46", + "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==" + }, + "uri-js": { + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "requires": { + "punycode": "^2.1.0" + }, + "version": "4.4.1", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==" + }, "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "source-map": "^0.6.1", + "source-list-map": "^2.0.1" + }, + "version": "2.2.0", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==" + }, + "@xtuc/long": { + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "version": "4.2.2", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node-releases": { + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "version": "1.1.71", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" + }, + "cross-spawn": { + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "requires": { - "isexe": "^2.0.0" + "shebang-command": "^2.0.0", + "which": "^2.0.1", + "path-key": "^3.1.0" + }, + "version": "7.0.3", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + }, + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "requires": { + "safe-buffer": "~5.1.0" + }, + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" + }, + "schema-utils": { + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "requires": { + "ajv-keywords": "^3.5.2", + "ajv": "^6.12.5", + "@types/json-schema": "^7.0.6" + }, + "version": "3.0.0", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==" + }, + "@webpack-cli/info": { + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", + "requires": { + "envinfo": "^7.7.3" + }, + "version": "1.2.3", + "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==" + }, + "json5": { + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "requires": { + "minimist": "^1.2.5" + }, + "version": "2.2.0", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==" + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "escalade": { + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "picomatch": { + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "version": "2.2.3", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "@webassemblyjs/wasm-gen": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "requires": { + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/utf8": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==" + }, + "braces": { + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "requires": { + "fill-range": "^7.0.1" + }, + "version": "3.0.2", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + }, + "@webassemblyjs/helper-api-error": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" + }, + "terser": { + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", + "requires": { + "source-map": "~0.7.2", + "source-map-support": "~0.5.19", + "commander": "^2.20.0" + }, + "version": "5.6.1", + "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", + "dependencies": { + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "version": "0.7.3", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, + }, + "import-local": { + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "requires": { + "resolve-cwd": "^3.0.0", + "pkg-dir": "^4.2.0" + }, + "version": "3.0.2", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==" + }, + "minimist": { + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "version": "1.2.5", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "ansi-colors": { + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "version": "4.1.1", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + }, + "terser-webpack-plugin": { + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", + "requires": { + "source-map": "^0.6.1", + "p-limit": "^3.1.0", + "jest-worker": "^26.6.2", + "schema-utils": "^3.0.0", + "terser": "^5.5.1", + "serialize-javascript": "^5.0.1" + }, + "version": "5.1.1", + "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==" + }, + "errno": { + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "requires": { + "prr": "~1.0.1" + }, + "version": "0.1.8", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==" + }, + "webpack": { + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.32.0.tgz", + "requires": { + "enhanced-resolve": "^5.7.0", + "browserslist": "^4.14.5", + "schema-utils": "^3.0.0", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "chrome-trace-event": "^1.0.2", + "mime-types": "^2.1.27", + "es-module-lexer": "^0.4.0", + "tapable": "^2.1.1", + "webpack-sources": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "@types/eslint-scope": "^3.7.0", + "eslint-scope": "^5.1.1", + "@webassemblyjs/wasm-edit": "1.11.0", + "events": "^3.2.0", + "neo-async": "^2.6.2", + "@webassemblyjs/ast": "1.11.0", + "acorn": "^8.0.4", + "glob-to-regexp": "^0.4.1", + "@types/estree": "^0.0.46", + "@webassemblyjs/wasm-parser": "1.11.0", + "watchpack": "^2.0.0", + "loader-runner": "^4.2.0" + }, + "version": "5.32.0", + "integrity": "sha512-jB9PrNMFnPRiZGnm/j3qfNqJmP3ViRzkuQMIf8za0dgOYvSLi/cgA+UEEGvik9EQHX1KYyGng5PgBTTzGrH9xg==", + "dependencies": { + "tapable": { + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "enhanced-resolve": { + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", + "requires": { + "tapable": "^2.2.0", + "graceful-fs": "^4.2.4" + }, + "version": "5.7.0", + "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==" + } + } + }, + "source-list-map": { + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "function-bind": { + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "kind-of": { + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "version": "6.0.3", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "mime-db": { + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "version": "1.47.0", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "version": "0.6.1", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "p-limit": { + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "requires": { + "yocto-queue": "^0.1.0" + }, + "version": "3.1.0", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==" + }, + "jest-worker": { + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "requires": { + "supports-color": "^7.0.0", + "@types/node": "*", + "merge-stream": "^2.0.0" + }, + "version": "26.6.2", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==" + }, + "pkg-dir": { + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "requires": { + "find-up": "^4.0.0" + }, + "version": "4.2.0", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==" + }, + "safe-buffer": { + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "@webassemblyjs/ast": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-numbers": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==" + }, + "path-exists": { + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "big.js": { + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "version": "5.2.2", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "ts-loader": { + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^4.0.0", + "semver": "^7.3.4", + "micromatch": "^4.0.0", + "loader-utils": "^2.0.0" + }, + "version": "8.1.0", + "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==" + }, + "@webassemblyjs/helper-numbers": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "requires": { + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2", + "@webassemblyjs/floating-point-hex-parser": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==" + }, + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + }, + "micromatch": { + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "requires": { + "picomatch": "^2.2.3", + "braces": "^3.0.1" + }, + "version": "4.0.4", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==" + }, + "envinfo": { + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "version": "7.8.1", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "requires": { + "supports-color": "^7.1.0", + "ansi-styles": "^4.1.0" + }, + "version": "4.1.0", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==" + }, + "p-locate": { + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "requires": { + "p-limit": "^2.2.0" + }, + "version": "4.1.0", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": { + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "requires": { + "p-try": "^2.0.0" + }, + "version": "2.3.0", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==" + } + } + }, + "is-plain-object": { + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "requires": { + "isobject": "^3.0.1" + }, + "version": "2.0.4", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==" + }, + "loader-runner": { + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "version": "4.2.0", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "version": "0.1.0", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "lru-cache": { + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "requires": { + "yallist": "^4.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + }, + "inherits": { + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "yallist": { + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "caniuse-lite": { + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz", + "version": "1.0.30001208", + "integrity": "sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==" + }, + "human-signals": { + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "path-parse": { + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "version": "1.0.6", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "colorette": { + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "version": "1.2.2", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "version": "2.20.3", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "signal-exit": { + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "version": "3.0.3", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "typescript": { + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "version": "4.2.4", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" + }, + "@types/json-schema": { + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "version": "7.0.7", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, + "prr": { + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "is-stream": { + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "enquirer": { + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "requires": { + "ansi-colors": "^4.1.1" + }, + "version": "2.3.6", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==" + }, + "@webassemblyjs/utf8": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" + }, + "@webassemblyjs/wasm-opt": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==" + }, + "rechoir": { + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "requires": { + "resolve": "^1.9.0" + }, + "version": "0.7.0", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==" + }, + "strip-final-newline": { + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "eslint-scope": { + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "requires": { + "estraverse": "^4.1.1", + "esrecurse": "^4.3.0" + }, + "version": "5.1.1", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==" + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "requires": { + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "core-util-is": "~1.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "process-nextick-args": "~2.0.0", + "util-deprecate": "~1.0.1" + }, + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" + }, + "@webassemblyjs/wasm-edit": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==" + }, + "path-key": { + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "events": { + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "version": "3.3.0", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "neo-async": { + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "version": "2.6.2", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "v8-compile-cache": { + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "version": "2.3.0", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "electron-to-chromium": { + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.712.tgz", + "version": "1.3.712", + "integrity": "sha512-3kRVibBeCM4vsgoHHGKHmPocLqtFAGTrebXxxtgKs87hNUzXrX2NuS3jnBys7IozCnw7viQlozxKkmty2KNfrw==" + }, + "fastest-levenshtein": { + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "version": "1.0.12", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "ajv-keywords": { + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "version": "3.5.2", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "serialize-javascript": { + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "requires": { + "randombytes": "^2.1.0" + }, + "version": "5.0.1", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==" + }, + "@types/node": { + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "version": "14.14.37", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==" + }, + "@xtuc/ieee754": { + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "fast-json-stable-stringify": { + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fill-range": { + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "requires": { + "to-regex-range": "^5.0.1" + }, + "version": "7.0.1", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + }, + "watchpack": { + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "requires": { + "graceful-fs": "^4.1.2", + "glob-to-regexp": "^0.4.1" + }, + "version": "2.1.1", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==" + }, + "@webassemblyjs/floating-point-hex-parser": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" + }, + "wildcard": { + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + }, + "glob-to-regexp": { + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" } } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, + }, + "braces": { + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "fill-range": "^7.0.1" + }, + "version": "3.0.2", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true - }, + }, + "yargs": { + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "requires": { + "os-locale": "^1.4.0", + "camelcase": "^2.0.1", + "y18n": "^3.2.0", + "window-size": "^0.1.4", + "string-width": "^1.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1" + }, + "version": "3.32.0", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "dev": true + }, + "decamelize": { + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "minimist": { + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "version": "1.2.5", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "camelcase": { + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "@ungap/promise-all-settled": { + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "long": { + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + }, + "inflight": { + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "requires": { + "wrappy": "1", + "once": "^1.3.0" + }, + "version": "1.0.6", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "@protobufjs/inquire": { + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", + "dev": true + }, + "fs-minipass": { + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "requires": { + "minipass": "^2.6.0" + }, + "version": "1.2.7", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true + }, + "yargs-parser": { + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "version": "20.2.4", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "binary-extensions": { + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "node-addon-api": { + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", + "version": "3.1.0", + "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==", + "dev": true + }, "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + }, + "flat": { + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "version": "5.0.2", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": "^13.7.0", - "long": "^4.0.0" - }, + }, + "jsonc": { + "resolved": "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz", + "integrity": "sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==", + "dev": true, + "version": "2.0.0", "dependencies": { - "@types/node": { - "version": "13.13.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", - "integrity": "sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ==", + "strip-json-comments": { + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, + }, "requires": { - "safe-buffer": "^5.1.0" + "strip-bom": "^4.0.0", + "parse-json": "^4.0.0", + "strip-json-comments": "^3.0.1", + "graceful-fs": "^4.1.15", + "mkdirp": "^0.5.1", + "fast-safe-stringify": "^2.0.6" } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, + }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + }, + "big-integer": { + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "version": "1.6.51", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, + }, + "follow-redirects": { + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", + "version": "1.14.5", + "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", + "dev": true + }, + "is-glob": { + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "requires": { - "randombytes": "^2.1.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "is-extglob": "^2.1.1" + }, + "version": "4.0.1", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true - }, - "splitargs": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", - "integrity": "sha1-/p965lc3GzOxDLgNoUPPgknPazs=", + }, + "emoji-regex": { + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "version": "8.0.0", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, + }, + "is-iojs": { + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-TBEDO11dlNbqs3dd7cm+fQCDJfE=", + "dev": true + }, + "jsonfile": { + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "graceful-fs": "^4.1.6" + }, + "version": "4.0.0", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + }, + "deep-extend": { + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "version": "0.6.0", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "balanced-match": { + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "he": { + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "cmake-js": { + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.2.1.tgz", + "integrity": "sha512-wEpg0Z8SY6ihXTe+xosadh4PbASdWSM/locbLacWRYJCZfAjWLyOrd4RoVIeirLkfPxmG8GdNQA9tW/Rz5SfJA==", + "dev": true, + "version": "6.2.1", + "dependencies": { + "fs-extra": { + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "requires": { + "jsonfile": "^4.0.0", + "graceful-fs": "^4.1.2", + "universalify": "^0.1.0" + }, + "version": "5.0.0", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dev": true + } + }, "requires": { - "ansi-regex": "^2.0.0" + "npmlog": "^1.2.0", + "semver": "^5.0.3", + "axios": "^0.21.1", + "lodash": "^4", + "tar": "^4", + "fs-extra": "^5.0.0", + "unzipper": "^0.8.13", + "which": "^1.0.9", + "is-iojs": "^1.0.1", + "url-join": "0", + "splitargs": "0", + "rc": "^1.2.7", + "debug": "^4", + "memory-stream": "0", + "yargs": "^3.6.0" } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + }, + "lodash": { + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "version": "4.17.21", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, + }, "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "requires": { "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, + }, + "version": "8.1.1", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true + }, + "parse-json": { + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "version": "4.0.0", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true + }, + "universalify": { + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "version": "0.1.2", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "version": "4.1.0", + "dependencies": { + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true + } + }, + "requires": { + "supports-color": "^7.1.0", + "ansi-styles": "^4.1.0" + } + }, + "p-locate": { + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "requires": { + "p-limit": "^3.0.2" + }, + "version": "5.0.0", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true + }, + "brace-expansion": { + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true + }, + "buffer-indexof-polyfill": { + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true + }, + "@types/minimist": { + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "version": "1.2.1", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "@protobufjs/codegen": { + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true + }, + "inherits": { + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "yallist": { + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "tar": { + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "version": "4.4.19", "dependencies": { "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + }, "requires": { - "is-number": "^7.0.0" + "yallist": "^3.1.1", + "safe-buffer": "^5.2.1", + "mkdirp": "^0.5.5", + "minipass": "^2.9.0", + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minizlib": "^1.3.3" } - }, - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + }, + "is-plain-obj": { + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + }, + "nanoid": { + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "version": "3.1.20", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unzipper": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", - "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", - "dev": true, + }, + "chokidar": { + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "~1.0.10", - "listenercount": "~1.0.1", - "readable-stream": "~2.1.5", - "setimmediate": "~1.0.4" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "readable-stream": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", - "dev": true, - "requires": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - } - } - }, - "url-join": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g=", + "anymatch": "~3.1.1", + "readdirp": "~3.5.0", + "glob-parent": "~5.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "is-binary-path": "~2.1.0", + "fsevents": "~2.3.1", + "braces": "~3.0.2" + }, + "version": "3.5.1", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + }, + "ini": { + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "version": "1.3.8", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", - "dev": true - }, + }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "strip-ansi": "^3.0.1", + "string-width": "^1.0.1" + }, + "version": "2.1.0", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + }, + "lodash.padend": { + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "version": "4.6.1", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, + }, + "binary": { + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "chainsaw": "~0.1.0", + "buffers": "~0.1.1" + }, + "version": "0.3.0", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, + }, + "growl": { + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "version": "1.10.5", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "readdirp": { + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, + "picomatch": "^2.2.1" + }, + "version": "3.5.0", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true + }, + "@protobufjs/eventemitter": { + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "requires": { + "inherits": "~2.0.1", + "isarray": "0.0.1", + "core-util-is": "~1.0.0", + "string_decoder": "~0.10.x" + }, + "version": "1.0.34", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true + }, + "log-symbols": { + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "requires": { + "chalk": "^4.0.0" + }, + "version": "4.0.0", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true + }, + "setimmediate": { + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "version": "1.0.5", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "lodash.pad": { + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "version": "4.5.1", + "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", + "dev": true + }, + "lodash.padstart": { + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "version": "4.6.1", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", + "dev": true + }, + "glob": { + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "requires": { + "inherits": "2", + "minimatch": "^3.0.4", + "inflight": "^1.0.4", + "fs.realpath": "^1.0.0", + "path-is-absolute": "^1.0.0", + "once": "^1.3.0" + }, + "version": "7.1.6", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true + }, + "mkdirp": { + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "requires": { + "minimist": "^1.2.5" + }, + "version": "0.5.5", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true + }, + "minipass": { + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "requires": { + "yallist": "^3.0.0", + "safe-buffer": "^5.1.2" + }, + "version": "2.9.0", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true + }, + "ansi": { + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "version": "0.3.1", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", + "dev": true + }, + "rimraf": { + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "requires": { + "glob": "^7.1.3" + }, + "version": "2.7.1", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true + }, + "serialize-javascript": { + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "requires": { + "randombytes": "^2.1.0" + }, + "version": "5.0.1", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true + }, + "js-yaml": { + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "requires": { + "argparse": "^2.0.1" + }, + "version": "4.0.0", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true + }, + "fsevents": { + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "optional": true, + "version": "2.3.2", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true + }, + "concat-map": { + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "bluebird": { + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "version": "3.4.7", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "protobufjs": { + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "dev": true, + "version": "6.10.2", "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "@types/node": { + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", + "version": "13.13.48", + "integrity": "sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ==", "dev": true } + }, + "requires": { + "@protobufjs/pool": "^1.1.0", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "long": "^4.0.0", + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/codegen": "^2.0.4" } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + }, + "argparse": { + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "onnx-proto": { + "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", + "requires": { + "protobufjs": "^6.8.8" + }, + "version": "4.0.4", + "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", + "dev": true + }, + "fill-range": { + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "requires": { + "to-regex-range": "^5.0.1" + }, + "version": "7.0.1", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true + }, + "@protobufjs/utf8": { + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "dev": true + }, + "escape-string-regexp": { + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "@types/node": { + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "version": "14.14.37", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", + "dev": true + }, + "minizlib": { + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "requires": { + "minipass": "^2.9.0" + }, + "version": "1.3.3", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true + }, + "once": { + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "requires": { + "wrappy": "1" + }, + "version": "1.4.0", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true } - } -} + }, + "version": "1.11.0", + "requires": true, + "name": "onnxruntime-node", + "lockfileVersion": 1 +} \ No newline at end of file diff --git a/js/node/package.json b/js/node/package.json index e05abd6abe..b90c11d985 100644 --- a/js/node/package.json +++ b/js/node/package.json @@ -1,58 +1,58 @@ { - "license": "MIT", - "name": "onnxruntime-node", - "description": "ONNXRuntime Node.js binding", + "license": "MIT", + "name": "onnxruntime-node", "repository": { - "url": "https://github.com/Microsoft/onnxruntime.git", + "url": "https://github.com/Microsoft/onnxruntime.git", "type": "git" - }, - "author": "fs-eire", - "version": "1.10.0", - "keywords": [ - "ONNX", - "ONNXRuntime", - "ONNX Runtime" - ], - "scripts": { - "build": "tsc && node ./script/build", - "buildd": "tsc && node ./script/build --config=Debug", - "buildr": "tsc && node ./script/build --config=RelWithDebInfo", - "rebuild": "tsc && node ./script/build --rebuild", - "rebuildd": "tsc && node ./script/build --rebuild --config=Debug", - "rebuildr": "tsc && node ./script/build --rebuild --config=RelWithDebInfo", - "prepare": "tsc --build script && tsc", - "test": "tsc --build test && mocha ./test/test-main", - "prepack": "node ./script/prepack" - }, - "dependencies": { - "onnxruntime-common": "file:../common" - }, - "devDependencies": { - "@types/fs-extra": "^9.0.6", - "@types/minimist": "1.2.1", - "@types/mocha": "^8.2.2", - "@types/node": "^14.14.37", - "cmake-js": "^6.2.1", - "fs-extra": "^9.1.0", - "jsonc": "^2.0.0", - "minimist": "^1.2.5", - "mocha": "^8.2.1", - "node-addon-api": "^3.1.0", - "onnx-proto": "^4.0.4", - "typescript": "^4.2.4" - }, - "main": "dist/index.js", - "types": "dist/index.d.ts", - "os": [ - "win32", - "darwin", - "linux" - ], + }, + "author": "fs-eire", "binary": { - "module_path": "./bin", - "host": "https://onnxruntimetestdata.blob.core.windows.net/onnxruntime-node-prebuild/", + "module_path": "./bin", + "host": "https://onnxruntimetestdata.blob.core.windows.net/onnxruntime-node-prebuild/", "napi_versions": [ 3 ] - } -} + }, + "version": "1.11.0", + "dependencies": { + "onnxruntime-common": "file:../common" + }, + "scripts": { + "buildr": "tsc && node ./script/build --config=RelWithDebInfo", + "prepare": "tsc --build script && tsc", + "rebuild": "tsc && node ./script/build --rebuild", + "rebuildd": "tsc && node ./script/build --rebuild --config=Debug", + "buildd": "tsc && node ./script/build --config=Debug", + "build": "tsc && node ./script/build", + "test": "tsc --build test && mocha ./test/test-main", + "prepack": "node ./script/prepack", + "rebuildr": "tsc && node ./script/build --rebuild --config=RelWithDebInfo" + }, + "keywords": [ + "ONNX", + "ONNXRuntime", + "ONNX Runtime" + ], + "devDependencies": { + "fs-extra": "^9.1.0", + "cmake-js": "^6.2.1", + "jsonc": "^2.0.0", + "onnx-proto": "^4.0.4", + "minimist": "^1.2.5", + "mocha": "^8.2.1", + "@types/mocha": "^8.2.2", + "typescript": "^4.2.4", + "@types/fs-extra": "^9.0.6", + "node-addon-api": "^3.1.0", + "@types/node": "^14.14.37", + "@types/minimist": "1.2.1" + }, + "main": "dist/index.js", + "os": [ + "win32", + "darwin", + "linux" + ], + "types": "dist/index.d.ts", + "description": "ONNXRuntime Node.js binding" +} \ No newline at end of file diff --git a/js/react_native/package.json b/js/react_native/package.json index a11fb88e0f..280693f36a 100644 --- a/js/react_native/package.json +++ b/js/react_native/package.json @@ -1,53 +1,21 @@ { - "name": "onnxruntime-react-native", - "version": "1.10.0", - "description": "Onnxruntime bridge for react native", - "main": "dist/commonjs/index", - "module": "dist/module/index", - "types": "dist/typescript/index.d.ts", - "react-native": "lib/index", - "source": "lib/index", - "files": [ - "lib", - "dist", - "android", - "ios/*.h", - "ios/*.mm", - "onnxruntime-react-native.podspec", - "!dist/commonjs/*.js.map", - "!dist/module/*.js.map", - "!android/.gitignore", - "!android/.idea", - "!android/build" - ], - "scripts": { - "test": "jest", - "typescript": "tsc --noEmit", - "prepare": "bob build", - "release": "release-it", - "example": "yarn --cwd example", - "pods": "cd example && pod-install --quiet", - "bootstrap": "yarn example && yarn && yarn pods", - "prepack": "tsc --build ./tsconfig.scripts.json && node ./scripts/prepack" - }, + "react-native": "lib/index", + "module": "dist/module/index", + "jest": { + "modulePathIgnorePatterns": [ + "/example/node_modules", + "/dist/" + ], + "preset": "react-native" + }, "keywords": [ - "react-native", - "ios", - "android", - "ONNX", - "ONNXRuntime", + "react-native", + "ios", + "android", + "ONNX", + "ONNXRuntime", "ONNX Runtime" - ], - "repository": "https://github.com/Microsoft/onnxruntime.git", - "author": "ONNX Runtime", - "license": "MIT", - "bugs": { - "url": "https://github.com/Microsoft/onnxruntime/issues" - }, - "homepage": "https://github.com/Microsoft/onnxruntime/js/react_native#readme", - "publishConfig": { - "registry": "https://registry.npmjs.org/" - }, + ], "devDependencies": { "@release-it/conventional-changelog": "^3.3.0", "@types/fs-extra": "^9.0.11", @@ -64,49 +32,81 @@ "typescript": "^4.1.3" }, "peerDependencies": { - "react": "*", + "react": "*", "react-native": "*" - }, - "jest": { - "preset": "react-native", - "modulePathIgnorePatterns": [ - "/example/node_modules", - "/dist/" - ] - }, + }, + "author": "ONNX Runtime", + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "source": "lib/index", + "version": "1.11.0", "release-it": { - "git": { - "commitMessage": "chore: release ${version}", - "tagName": "v${version}" - }, "npm": { "publish": true - }, - "github": { - "release": true - }, + }, + "git": { + "commitMessage": "chore: release ${version}", + "tagName": "v${version}" + }, "plugins": { "@release-it/conventional-changelog": { "preset": "angular" } + }, + "github": { + "release": true } - }, + }, + "main": "dist/commonjs/index", + "homepage": "https://github.com/Microsoft/onnxruntime/js/react_native#readme", + "files": [ + "lib", + "dist", + "android", + "ios/*.h", + "ios/*.mm", + "onnxruntime-react-native.podspec", + "!dist/commonjs/*.js.map", + "!dist/module/*.js.map", + "!android/.gitignore", + "!android/.idea", + "!android/build" + ], + "description": "Onnxruntime bridge for react native", + "repository": "https://github.com/Microsoft/onnxruntime.git", "react-native-builder-bob": { - "source": "lib", - "output": "dist", + "source": "lib", "targets": [ - "commonjs", - "module", + "commonjs", + "module", [ - "typescript", + "typescript", { "project": "tsconfig.build.json" } ] - ] - }, + ], + "output": "dist" + }, "dependencies": { - "buffer": "^6.0.3", + "buffer": "^6.0.3", "onnxruntime-common": "file:../common" + }, + "scripts": { + "typescript": "tsc --noEmit", + "prepare": "bob build", + "bootstrap": "yarn example && yarn && yarn pods", + "release": "release-it", + "test": "jest", + "prepack": "tsc --build ./tsconfig.scripts.json && node ./scripts/prepack", + "pods": "cd example && pod-install --quiet", + "example": "yarn --cwd example" + }, + "types": "dist/typescript/index.d.ts", + "name": "onnxruntime-react-native", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/onnxruntime/issues" } } diff --git a/js/web/package-lock.json b/js/web/package-lock.json index 85fdecc33c..841696e7ae 100644 --- a/js/web/package-lock.json +++ b/js/web/package-lock.json @@ -1,5432 +1,5432 @@ { - "name": "onnxruntime-web", - "version": "1.10.0", - "lockfileVersion": 1, - "requires": true, "dependencies": { - "@chiragrupani/karma-chromium-edge-launcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chiragrupani/karma-chromium-edge-launcher/-/karma-chromium-edge-launcher-2.1.0.tgz", - "integrity": "sha512-POHDni57WeEzA/liw8Ksdzj9FLDoX0KPtvBG+jhXEBcPPARKdRCiP5ntBQLWIHZbp61g5G2g1sD5ZuGuLYyhPA==", - "dev": true - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", - "dev": true - }, - "@electron/get": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.1.tgz", - "integrity": "sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1", - "got": "^9.6.0", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/chai": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", - "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==", - "dev": true - }, - "@types/component-emitter": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", - "dev": true - }, - "@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", - "dev": true - }, - "@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", - "dev": true - }, - "@types/emscripten": { - "version": "1.39.4", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz", - "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==", - "dev": true - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", - "dev": true - }, - "@types/flatbuffers": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", - "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", - "dev": true - }, - "@types/fs-extra": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.10.tgz", - "integrity": "sha512-O9T2LLkRDiTlalOBdjEkcnT0MRdT2+wglCl7pJUJ3mkWkR8hX4K+5bg2raQNJcLv4V8zGuTXe7Ud3wSqkTyuyQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "@types/karma": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/karma/-/karma-6.1.0.tgz", - "integrity": "sha512-JLrEceom1osyv6pUKDCT1Z2WGcecj5UKb99xvEXashYha1B6ntNBNBLTqcVxD2G5PiL5zcpaQodHatnhk3YG+Q==", - "dev": true, - "requires": { - "@types/node": "*", - "log4js": "^6.2.1" - } - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", - "dev": true - }, - "@types/minimist": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", - "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", - "dev": true - }, - "@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", - "dev": true - }, - "@types/node": { - "version": "14.14.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", - "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", - "dev": true - }, - "@types/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA==", - "dev": true - }, - "@types/platform": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.3.tgz", - "integrity": "sha512-1fuOulBHWIxAPLBtLms+UtbeRDt6rL7gP5R+Yugfzdg+poCLxXqXTE8i+FpYeiytGRLUEtnFkjsY/j+usbQBqw==", - "dev": true - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz", - "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==", - "dev": true - }, - "@webpack-cli/info": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz", - "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz", - "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "async": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/async/-/async-3.0.1.tgz", - "integrity": "sha512-ZswD8vwPtmBZzbn9xyi8XBQWXH3AvOQ43Za1KWYq7JeycrZuUYzx01KvHcVbXltjqH4y0MWrQ33008uLTqXuDw==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "dev": true, - "requires": { - "array-filter": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "boolean": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", - "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", + "escalade": "^3.1.1", + "electron-to-chromium": "^1.3.723", + "colorette": "^1.2.2", + "caniuse-lite": "^1.0.30001219", "node-releases": "^1.1.71" - } - }, - "browserstack": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", - "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1" - } - }, - "browserstack-local": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.8.tgz", - "integrity": "sha512-s+mc3gTOJwELdLWi4qFVKtGwMbb5JWsR+JxKlMaJkRJxoZ0gg3WREgPxAN0bm6iU5+S4Bi0sz0oxBRZT8BiNsQ==", - "dev": true, - "requires": { - "https-proxy-agent": "^4.0.0", - "is-running": "^2.1.0", - "ps-tree": "=1.2.0", - "temp-fs": "^0.9.9" - }, - "dependencies": { - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true - }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dev": true, - "requires": { - "agent-base": "5", - "debug": "4" - } - } - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", - "dev": true - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - }, - "dependencies": { - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "optional": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.2.0.tgz", - "integrity": "sha1-RMCMJQbxD7PKb9iI1aNETPjWpmk=", - "dev": true - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "date-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", - "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "domain-browser": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.19.0.tgz", - "integrity": "sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==", - "dev": true - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "edge-launcher": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/edge-launcher/-/edge-launcher-1.2.2.tgz", - "integrity": "sha1-60Cq+9Bnpup27/+rBke81VCbN7I=", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-12.2.3.tgz", - "integrity": "sha512-B27c7eqx1bC5kea6An8oVhk1pShNC4VGqWarHMhD47MDtmg54KepHO5AbAvmKKZK/jWN7NTC7wyCYTDElJNtQA==", - "dev": true, - "requires": { - "@electron/get": "^1.0.1", - "@types/node": "^14.6.2", - "extract-zip": "^1.0.3" - } - }, - "electron-to-chromium": { - "version": "1.3.727", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", - "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", - "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", - "ws": "~7.4.2" - } - }, - "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", - "dev": true, - "requires": { - "base64-arraybuffer": "0.1.4" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", - "dev": true - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", - "dev": true - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, - "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "dev": true - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flatbuffers": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", - "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - } - }, - "globalthis": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", - "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", - "dev": true, - "optional": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "guid-typescript": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", - "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==" - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "requires": { - "duplexer": "^0.1.2" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "optional": true - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { - "source-map": "~0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, + }, + "version": "4.16.6", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true + }, + "shebang-regex": { + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "p-finally": { + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "type-is": { + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "version": "1.6.18", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true + }, + "array-filter": { + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", + "dev": true + }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true - }, - "is-docker": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.0.tgz", - "integrity": "sha512-K4GwB4i/HzhAzwP/XSlspzRdFTI9N8OxJOyOU7Y5Rz+p+WBokXWVWblaJeBkggthmoSV0OoGTH5thJNvplpkvQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, + }, + "@types/eslint-scope": { + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", + "@types/eslint": "*", + "@types/estree": "*" + }, + "version": "3.7.0", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-running": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isbinaryfile": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", - "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, + }, + "elliptic": { + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "version": "6.5.4", "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } - } - }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", - "dev": true - }, - "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dev": true, + }, "requires": { - "argparse": "^2.0.1" + "inherits": "^2.0.4", + "brorand": "^1.1.0", + "bn.js": "^4.11.9", + "minimalistic-assert": "^1.0.1", + "hash.js": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1", + "hmac-drbg": "^1.0.1" } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + }, + "ripemd160": { + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "requires": { + "inherits": "^2.0.1", + "hash-base": "^3.0.0" + }, + "version": "2.0.2", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + }, + "utils-merge": { + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true - }, + }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "optional": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, + }, + "cipher-base": { + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jszip": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", - "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", - "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, - "karma": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", - "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", - "dev": true, - "requires": { - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.4.2", - "colors": "^1.4.0", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.6", - "graceful-fs": "^4.2.4", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.6", - "lodash": "^4.17.19", - "log4js": "^6.2.1", - "mime": "^2.4.5", - "minimatch": "^3.0.4", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^3.1.0", - "source-map": "^0.6.1", - "tmp": "0.2.1", - "ua-parser-js": "^0.7.23", - "yargs": "^16.1.1" - } - }, - "karma-browserstack-launcher": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz", - "integrity": "sha512-Y/UWPdHZkHIVH2To4GWHCTzmrsB6H7PBWy6pw+TWz5sr4HW2mcE+Uj6qWgoVNxvQU1Pfn5LQQzI6EQ65p8QbiQ==", - "dev": true, - "requires": { - "browserstack": "~1.5.1", - "browserstack-local": "^1.3.7", - "q": "~1.5.0" - } - }, - "karma-chai": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", - "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "version": "1.0.4", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true - }, - "karma-chrome-launcher": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", - "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", - "dev": true, + }, + "path-browserify": { + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "strip-eof": { + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "resolve-from": { + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "version": "5.0.0", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "process-nextick-args": { + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "@protobufjs/base64": { + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "electron": { + "resolved": "https://registry.npmjs.org/electron/-/electron-12.2.3.tgz", "requires": { - "which": "^1.2.1" - } - }, - "karma-edge-launcher": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz", - "integrity": "sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw==", - "dev": true, - "requires": { - "edge-launcher": "1.2.2" - } - }, - "karma-electron": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/karma-electron/-/karma-electron-7.0.0.tgz", - "integrity": "sha512-AMwpMCWbYVhqaw9gzUIzmsCftB1ttiNJE4lm+BKPgxmxszdNfIG3gNpxH2rUxwP4aKWucFPo1vAJ4nMQfNBZ3Q==", - "dev": true, - "requires": { - "async": "~3.0.1", - "combine-source-map": "~0.8.0", - "commander": "~2.9.0", - "convert-source-map": "~1.2.0", - "js-string-escape": "~1.0.0", - "minstache": "~1.2.0", - "xtend": "~4.0.1" - } - }, - "karma-firefox-launcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.0.tgz", - "integrity": "sha512-dkiyqN2R6fCWt78rciOXJLFDWcQ7QEQi++HgebPJlw1y0ycDjGNDHuSrhdh48QG02fzZKK20WHFWVyBZ6CPngg==", - "dev": true, - "requires": { - "is-wsl": "^2.2.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", - "dev": true, - "requires": { - "minimist": "^1.2.3" - } - }, - "karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - } - }, + "@types/node": "^14.6.2", + "@electron/get": "^1.0.1", + "extract-zip": "^1.0.3" + }, + "version": "12.2.3", + "integrity": "sha512-B27c7eqx1bC5kea6An8oVhk1pShNC4VGqWarHMhD47MDtmg54KepHO5AbAvmKKZK/jWN7NTC7wyCYTDElJNtQA==", + "dev": true + }, "karma-safari-applescript-launcher": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-safari-applescript-launcher/-/karma-safari-applescript-launcher-0.1.0.tgz", - "integrity": "sha512-BAg8Q+VFgb8G9IajAYWvFSmvCYBr/RwqwZBRs6jbyaoIrHdi5boPgjz92c+y95zcKtsOqg8hncelsuuU6pA4hw==", - "dev": true, + "resolved": "https://registry.npmjs.org/karma-safari-applescript-launcher/-/karma-safari-applescript-launcher-0.1.0.tgz", "requires": { "run-applescript": "^3.2.0" - } - }, - "karma-sourcemap-loader": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz", - "integrity": "sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "keypress": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", - "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=", + }, + "version": "0.1.0", + "integrity": "sha512-BAg8Q+VFgb8G9IajAYWvFSmvCYBr/RwqwZBRs6jbyaoIrHdi5boPgjz92c+y95zcKtsOqg8hncelsuuU6pA4hw==", "dev": true - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "requires": { - "immediate": "~3.0.5" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "log4js": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", - "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", - "dev": true, - "requires": { - "date-format": "^3.0.0", - "debug": "^4.1.1", - "flatted": "^2.0.1", - "rfdc": "^1.1.4", - "streamroller": "^2.2.4" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - }, + }, + "webpack-bundle-analyzer": { + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", + "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", + "dev": true, + "version": "4.5.0", "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "optional": true - } - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", - "dev": true - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "dev": true, - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minstache": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minstache/-/minstache-1.2.0.tgz", - "integrity": "sha1-/xzEA6woRPaNvxjGYhKb5+sO/EE=", - "dev": true, - "requires": { - "commander": "1.0.4" - }, - "dependencies": { - "commander": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.4.tgz", - "integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=", - "dev": true, - "requires": { - "keypress": "0.1.x" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", - "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "requires": { "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, + }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true - }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "requires": { - "chalk": "^4.0.0" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, + }, "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "requires": { "has-flag": "^4.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-polyfill-webpack-plugin": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.0.tgz", - "integrity": "sha512-6eKoqK2BpKqUFN1oI1TRoF9TgpsUC1Y8JaT+UUNuUiODhZIm3vcSoNrsqGAoHAhpZxKF0+9MU9VxOWJR/YjpIA==", - "dev": true, - "requires": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.19.0", - "events": "^3.3.0", - "filter-obj": "^2.0.1", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.1.1", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.3", - "vm-browserify": "^1.1.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + }, + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "version": "7.2.0", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "requires": { - "safe-buffer": "~5.2.0" - } + "supports-color": "^7.1.0", + "ansi-styles": "^4.1.0" + }, + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "requires": { + "color-convert": "^2.0.1" + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "optional": true, + }, "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" + "lodash": "^4.17.20", + "gzip-size": "^6.0.0", + "commander": "^7.2.0", + "chalk": "^4.1.0", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "acorn": "^8.0.4", + "ws": "^7.3.1", + "acorn-walk": "^8.0.0" } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, + }, + "code-point-at": { + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "is-core-module": { + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", "requires": { - "path-key": "^2.0.0" + "has": "^1.0.3" + }, + "version": "2.3.0", + "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "dev": true + }, + "public-encrypt": { + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "version": "4.0.3", + "dependencies": { + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + }, + "requires": { + "safe-buffer": "^5.1.2", + "randombytes": "^2.0.1", + "bn.js": "^4.1.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "browserify-rsa": "^4.0.0" } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, + }, + "socket.io-adapter": { + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", + "dev": true + }, + "resolve-cwd": { + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "resolve-from": "^5.0.0" + }, + "version": "3.0.0", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true + }, + "@webassemblyjs/wast-printer": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "requires": { + "@xtuc/long": "4.2.2", + "@webassemblyjs/ast": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "dev": true + }, + "shallow-clone": { + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "requires": { + "kind-of": "^6.0.2" + }, + "version": "3.0.1", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true + }, + "@webpack-cli/serve": { + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz", + "version": "1.4.0", + "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==", + "dev": true + }, + "browserify-sign": { + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "version": "4.2.1", + "dependencies": { + "safe-buffer": { + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true + } + }, + "requires": { + "inherits": "^2.0.4", + "browserify-rsa": "^4.0.1", + "readable-stream": "^3.6.0", + "bn.js": "^5.1.1", + "create-hash": "^1.2.0", + "elliptic": "^6.5.3", + "parse-asn1": "^5.1.5", + "safe-buffer": "^5.2.0", + "create-hmac": "^1.1.7" } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + }, + "isobject": { + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "version": "3.0.1", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true - }, - "numpy-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/numpy-parser/-/numpy-parser-1.2.3.tgz", - "integrity": "sha512-hdb0XHWTMk9lOyWxHWbwwstD2MQxpecIbqURtyrAxEf8OUbUjEbdjTu/PimTycX99/l7pSMbtw7ueANMcfQzcA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, + }, + "worker-loader": { + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", "requires": { - "call-bind": "^1.0.2", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "version": "3.0.8", + "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", + "dev": true + }, + "anymatch": { + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "requires": { + "picomatch": "^2.0.4", + "normalize-path": "^3.0.0" + }, + "version": "3.1.2", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "wrap-ansi": { + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "version": "7.0.0", + "dependencies": { + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "color-convert": { + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "requires": { + "color-name": "~1.1.4" + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "requires": { + "color-convert": "^2.0.1" + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "is-fullwidth-code-point": "^3.0.0", + "emoji-regex": "^8.0.0" + }, + "version": "4.2.2", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "requires": { + "ansi-regex": "^5.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + }, + "requires": { + "strip-ansi": "^6.0.0", + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0" + } + }, + "set-blocking": { + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "negotiator": { + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "version": "0.6.2", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "dev": true + }, + "buffer-crc32": { + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "version": "0.2.13", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "minstache": { + "resolved": "https://registry.npmjs.org/minstache/-/minstache-1.2.0.tgz", + "integrity": "sha1-/xzEA6woRPaNvxjGYhKb5+sO/EE=", + "dev": true, + "version": "1.2.0", + "dependencies": { + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.4.tgz", + "requires": { + "keypress": "0.1.x" + }, + "version": "1.0.4", + "integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=", + "dev": true + } + }, + "requires": { + "commander": "1.0.4" + } + }, + "find-up": { + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "version": "5.0.0", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true + }, + "is-arguments": { + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "requires": { + "call-bind": "^1.0.0" + }, + "version": "1.1.0", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true + }, + "is-symbol": { + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "requires": { + "has-symbols": "^1.0.1" + }, + "version": "1.0.3", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true + }, + "source-map-support": { + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "requires": { + "source-map": "^0.6.0", + "buffer-from": "^1.0.0" + }, + "version": "0.5.21", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true + }, + "@types/npmlog": { + "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.2.tgz", + "version": "4.1.2", + "integrity": "sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA==", + "dev": true + }, + "aproba": { + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "browserify-rsa": { + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "requires": { + "randombytes": "^2.0.1", + "bn.js": "^5.0.0" + }, + "version": "4.1.0", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true + }, + "gzip-size": { + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "requires": { + "duplexer": "^0.1.2" + }, + "version": "6.0.0", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true + }, + "isexe": { + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "flatbuffers": { + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "version": "1.12.0", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, + "agent-base": { + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "requires": { + "es6-promisify": "^5.0.0" + }, + "version": "4.3.0", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true + }, + "string.prototype.trimend": { + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + }, + "version": "1.0.4", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, + }, + "normalize-path": { + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "lodash.memoize": { + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "version": "3.0.4", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "dev": true + }, + "interpret": { + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "normalize-url": { + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "version": "4.5.1", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "isbinaryfile": { + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "version": "4.0.6", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, + "base64id": { + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true + }, + "sprintf-js": { + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "optional": true, + "version": "1.1.2", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "mime": { + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "version": "2.5.2", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "console-control-strings": { + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "cross-spawn": { + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "version": "6.0.5", + "dependencies": { + "semver": { + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + }, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "shebang-command": "^1.2.0", + "semver": "^5.5.0", + "path-key": "^2.0.1", + "which": "^1.2.9", + "nice-try": "^1.0.4" } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, + }, + "@types/karma": { + "resolved": "https://registry.npmjs.org/@types/karma/-/karma-6.1.0.tgz", "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, + "@types/node": "*", + "log4js": "^6.2.1" + }, + "version": "6.1.0", + "integrity": "sha512-JLrEceom1osyv6pUKDCT1Z2WGcecj5UKb99xvEXashYha1B6ntNBNBLTqcVxD2G5PiL5zcpaQodHatnhk3YG+Q==", + "dev": true + }, + "json5": { + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "onnx-proto": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", - "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", - "requires": { - "protobufjs": "^6.8.8" - } - }, + "minimist": "^1.2.5" + }, + "version": "2.2.0", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true + }, + "boolean": { + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", + "optional": true, + "version": "3.1.4", + "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==", + "dev": true + }, + "is-docker": { + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-K4GwB4i/HzhAzwP/XSlspzRdFTI9N8OxJOyOU7Y5Rz+p+WBokXWVWblaJeBkggthmoSV0OoGTH5thJNvplpkvQ==", + "dev": true + }, + "array-union": { + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "env-paths": { + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "version": "2.2.1", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, "onnxruntime-common": { "version": "file:../common" - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + }, + "iconv-lite": { + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "requires": { - "yocto-queue": "^0.1.0" + "safer-buffer": ">= 2.1.2 < 3" + }, + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true + }, + "parse-asn1": { + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "requires": { + "asn1.js": "^5.2.0", + "evp_bytestokey": "^1.0.0", + "safe-buffer": "^5.1.1", + "browserify-aes": "^1.0.0", + "pbkdf2": "^3.0.3" + }, + "version": "5.1.6", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true + }, + "from": { + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "version": "0.1.7", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "type-fest": { + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "optional": true, + "version": "0.13.1", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "es-to-primitive": { + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "requires": { + "is-callable": "^1.1.4", + "is-symbol": "^1.0.2", + "is-date-object": "^1.0.1" + }, + "version": "1.2.1", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true + }, + "terser-webpack-plugin": { + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", + "requires": { + "source-map": "^0.6.1", + "p-limit": "^3.1.0", + "jest-worker": "^26.6.2", + "schema-utils": "^3.0.0", + "terser": "^5.5.1", + "serialize-javascript": "^5.0.1" + }, + "version": "5.1.1", + "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", + "dev": true + }, + "@ungap/promise-all-settled": { + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "get-intrinsic": { + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "requires": { + "has": "^1.0.3", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1" + }, + "version": "1.1.1", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true + }, + "es6-object-assign": { + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", + "dev": true + }, + "source-list-map": { + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "set-immediate-shim": { + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "flat": { + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "version": "5.0.2", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "emoji-regex": { + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "version": "8.0.0", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "randomfill": { + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + }, + "version": "1.0.4", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true + }, + "streamroller": { + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "dev": true, + "version": "2.2.4", + "dependencies": { + "fs-extra": { + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "requires": { + "jsonfile": "^4.0.0", + "graceful-fs": "^4.2.0", + "universalify": "^0.1.0" + }, + "version": "8.1.0", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true + }, + "universalify": { + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "version": "0.1.2", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "jsonfile": { + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "requires": { + "graceful-fs": "^4.1.6" + }, + "version": "4.0.0", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true + }, + "date-format": { + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + } + }, + "requires": { + "debug": "^4.1.1", + "fs-extra": "^8.1.0", + "date-format": "^2.1.0" } - }, + }, + "void-elements": { + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "path-key": { + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "check-error": { + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "ts-loader": { + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.1.2.tgz", + "integrity": "sha512-ryMgATvLLl+z8zQvdlm6Pep0slmwxFWIEnq/5VdiLVjqQXnFJgO+qNLGIIP+d2N2jsFZ9MibZCVDb2bSp7OmEA==", + "dev": true, + "version": "9.1.2", + "dependencies": { + "color-convert": { + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "requires": { + "color-name": "~1.1.4" + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true + }, + "semver": { + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "requires": { + "lru-cache": "^6.0.0" + }, + "version": "7.3.5", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "requires": { + "supports-color": "^7.1.0", + "ansi-styles": "^4.1.0" + }, + "version": "4.1.1", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "requires": { + "color-convert": "^2.0.1" + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + }, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "semver": "^7.3.4", + "micromatch": "^4.0.0" + } + }, + "@webassemblyjs/helper-numbers": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "requires": { + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2", + "@webassemblyjs/floating-point-hex-parser": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "dev": true + }, + "browserify-des": { + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "requires": { + "inherits": "^2.0.1", + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "safe-buffer": "^5.1.2" + }, + "version": "1.0.2", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true + }, + "tunnel": { + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "optional": true, + "version": "0.0.6", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true + }, + "micromatch": { + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "requires": { + "picomatch": "^2.0.5", + "braces": "^3.0.1" + }, + "version": "4.0.2", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true + }, + "karma-chrome-launcher": { + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "requires": { + "which": "^1.2.1" + }, + "version": "3.1.0", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "dev": true + }, "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "requires": { "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + }, + "version": "5.0.0", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, + }, + "loader-runner": { + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "version": "4.2.0", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "@sindresorhus/is": { + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "version": "0.14.0", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "lru-cache": { + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "yallist": "^4.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, + }, + "global-tunnel-ng": { + "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", + "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, + "encodeurl": "^1.0.2", + "tunnel": "^0.0.6", + "lodash": "^4.17.10", + "npm-conf": "^1.1.3" + }, + "dev": true, + "version": "2.7.1", "optional": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, + }, + "is-plain-obj": { + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "es6-promisify": { + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "requires": { - "find-up": "^4.0.0" - }, + "es6-promise": "^4.0.3" + }, + "version": "5.0.0", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true + }, + "chokidar": { + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "requires": { + "anymatch": "~3.1.1", + "readdirp": "~3.5.0", + "glob-parent": "~5.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "is-binary-path": "~2.1.0", + "fsevents": "~2.3.1", + "braces": "~3.0.2" + }, + "version": "3.5.1", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true + }, + "crypto-browserify": { + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "requires": { + "inherits": "^2.0.1", + "public-encrypt": "^4.0.0", + "browserify-cipher": "^1.0.0", + "pbkdf2": "^3.0.3", + "randombytes": "^2.0.0", + "create-ecdh": "^4.0.0", + "randomfill": "^1.0.3", + "create-hash": "^1.1.0", + "browserify-sign": "^4.0.0", + "diffie-hellman": "^5.0.0", + "create-hmac": "^1.1.0" + }, + "version": "3.12.0", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true + }, + "@types/json-schema": { + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "version": "7.0.7", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@protobufjs/eventemitter": { + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "rechoir": { + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "requires": { + "resolve": "^1.9.0" + }, + "version": "0.7.0", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "dev": true + }, + "acorn": { + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", + "version": "8.2.4", + "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "dev": true + }, + "karma-chai": { + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "version": "0.1.0", + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", + "dev": true + }, + "foreach": { + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "version": "2.0.5", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "totalist": { + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true + }, + "electron-to-chromium": { + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", + "version": "1.3.727", + "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "dev": true + }, + "jszip": { + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", + "requires": { + "set-immediate-shim": "~1.0.1", + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6" + }, + "version": "3.7.1", + "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", + "dev": true + }, + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "requires": { + "ansi-regex": "^3.0.0" + }, + "version": "4.0.0", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true + }, + "karma-mocha": { + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", + "requires": { + "minimist": "^1.2.3" + }, + "version": "2.0.1", + "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", + "dev": true + }, + "serialize-javascript": { + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "requires": { + "randombytes": "^2.1.0" + }, + "version": "5.0.1", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true + }, + "@xtuc/ieee754": { + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "pkg-dir": { + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "version": "4.2.0", "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "requires": { "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + }, + "version": "5.0.0", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true + }, + "find-up": { + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "requires": { - "p-try": "^2.0.0" - } - }, + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "version": "4.1.0", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true + }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "requires": { "p-limit": "^2.2.0" - } + }, + "version": "4.1.0", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true + }, + "p-limit": { + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "requires": { + "p-try": "^2.0.0" + }, + "version": "2.3.0", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true } - } - }, - "platform": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true, - "optional": true - }, - "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + }, "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": "^13.7.0", - "long": "^4.0.0" - }, + "find-up": "^4.0.0" + } + }, + "decamelize": { + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "domain-browser": { + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.19.0.tgz", + "version": "4.19.0", + "integrity": "sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==", + "dev": true + }, + "yargs-parser": { + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "version": "20.2.4", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "argparse": { + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globby": { + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "requires": { + "array-union": "^2.1.0", + "merge2": "^1.3.0", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "dir-glob": "^3.0.1", + "slash": "^3.0.0" + }, + "version": "11.0.3", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "dev": true + }, + "browserstack": { + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", + "requires": { + "https-proxy-agent": "^2.2.1" + }, + "version": "1.5.3", + "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", + "dev": true + }, + "q": { + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "version": "1.5.1", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "concat-stream": { + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "requires": { + "inherits": "^2.0.3", + "typedarray": "^0.0.6", + "buffer-from": "^1.0.0", + "readable-stream": "^2.2.2" + }, + "version": "1.6.2", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true + }, + "brorand": { + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "@types/node": { + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "version": "14.14.37", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", + "dev": true + }, + "media-typer": { + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "version": "0.3.0", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "is-number-object": { + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "version": "1.0.4", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, + "chrome-trace-event": { + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "version": "1.0.3", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "vary": { + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "json-parse-better-errors": { + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "webpack-merge": { + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "version": "5.7.3", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "dev": true + }, + "fastest-levenshtein": { + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "version": "1.0.12", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "through": { + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "version": "2.3.8", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "@types/fs-extra": { + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.10.tgz", + "requires": { + "@types/node": "*" + }, + "version": "9.0.10", + "integrity": "sha512-O9T2LLkRDiTlalOBdjEkcnT0MRdT2+wglCl7pJUJ3mkWkR8hX4K+5bg2raQNJcLv4V8zGuTXe7Ud3wSqkTyuyQ==", + "dev": true + }, + "path-parse": { + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "version": "1.0.7", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "mimic-fn": { + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "has-unicode": { + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "which-boxed-primitive": { + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "requires": { + "is-bigint": "^1.0.1", + "is-number-object": "^1.0.4", + "is-symbol": "^1.0.3", + "is-boolean-object": "^1.1.0", + "is-string": "^1.0.5" + }, + "version": "1.0.2", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true + }, + "object-inspect": { + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "version": "1.10.2", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", + "dev": true + }, + "ent": { + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "defer-to-connect": { + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "version": "1.1.3", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "ansi-colors": { + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "version": "4.1.1", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "pend": { + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "globalthis": { + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "requires": { + "define-properties": "^1.1.3" + }, + "dev": true, + "version": "1.0.2", + "optional": true + }, + "cliui": { + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "version": "7.0.4", + "dependencies": { + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "requires": { + "ansi-regex": "^5.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true + }, + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "is-fullwidth-code-point": "^3.0.0", + "emoji-regex": "^8.0.0" + }, + "version": "4.2.2", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true + } + }, + "requires": { + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0", + "string-width": "^4.2.0" + } + }, + "rfdc": { + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "version": "1.3.0", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "typescript": { + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "version": "4.2.4", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "npmlog": { + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "requires": { + "console-control-strings": "~1.1.0", + "set-blocking": "~2.0.0", + "are-we-there-yet": "~1.1.2", + "gauge": "~2.7.3" + }, + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true + }, + "karma-electron": { + "resolved": "https://registry.npmjs.org/karma-electron/-/karma-electron-7.0.0.tgz", + "requires": { + "minstache": "~1.2.0", + "combine-source-map": "~0.8.0", + "xtend": "~4.0.1", + "commander": "~2.9.0", + "js-string-escape": "~1.0.0", + "convert-source-map": "~1.2.0", + "async": "~3.0.1" + }, + "version": "7.0.0", + "integrity": "sha512-AMwpMCWbYVhqaw9gzUIzmsCftB1ttiNJE4lm+BKPgxmxszdNfIG3gNpxH2rUxwP4aKWucFPo1vAJ4nMQfNBZ3Q==", + "dev": true + }, + "p-try": { + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "es6-error": { + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "optional": true, + "version": "4.1.1", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "querystring-es3": { + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "version": "0.2.1", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "http-proxy": { + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "requires": { + "eventemitter3": "^4.0.0", + "requires-port": "^1.0.0", + "follow-redirects": "^1.0.0" + }, + "version": "1.18.1", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true + }, + "is-generator-function": { + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "version": "1.0.8", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", + "dev": true + }, + "run-applescript": { + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz", + "requires": { + "execa": "^0.10.0" + }, + "version": "3.2.0", + "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==", + "dev": true + }, + "execa": { + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "version": "0.10.0", + "dependencies": { + "get-stream": { + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + }, + "requires": { + "cross-spawn": "^6.0.0", + "signal-exit": "^3.0.0", + "p-finally": "^1.0.0", + "strip-eof": "^1.0.0", + "is-stream": "^1.1.0", + "get-stream": "^3.0.0", + "npm-run-path": "^2.0.0" + } + }, + "@types/flatbuffers": { + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "version": "1.10.0", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", + "dev": true + }, + "is-number": { + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "version": "7.0.0", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "date-format": { + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", + "dev": true + }, + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "requires": { + "ms": "2.1.2" + }, + "version": "4.3.1", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true + }, + "loader-utils": { + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "requires": { + "json5": "^2.1.2", + "big.js": "^5.2.2", + "emojis-list": "^3.0.0" + }, + "version": "2.0.0", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true + }, + "esrecurse": { + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "version": "4.3.0", + "dependencies": { + "estraverse": { + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "version": "5.2.0", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + }, + "requires": { + "estraverse": "^5.2.0" + } + }, + "@nodelib/fs.stat": { + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "dev": true + }, + "nice-try": { + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "version": "1.0.5", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "querystring": { + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "version": "0.2.0", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "inline-source-map": { + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "version": "0.6.2", + "dependencies": { + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + }, + "requires": { + "source-map": "~0.5.3" + } + }, + "dir-glob": { + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "requires": { + "path-type": "^4.0.0" + }, + "version": "3.0.1", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true + }, + "connect": { + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "version": "3.7.0", + "dependencies": { + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "requires": { + "ms": "2.0.0" + }, + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + }, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "utils-merge": "1.0.1", + "parseurl": "~1.3.3" + } + }, + "numpy-parser": { + "resolved": "https://registry.npmjs.org/numpy-parser/-/numpy-parser-1.2.3.tgz", + "version": "1.2.3", + "integrity": "sha512-hdb0XHWTMk9lOyWxHWbwwstD2MQxpecIbqURtyrAxEf8OUbUjEbdjTu/PimTycX99/l7pSMbtw7ueANMcfQzcA==", + "dev": true + }, + "@protobufjs/fetch": { + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "requires": { + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/aspromise": "^1.1.1" + }, + "version": "1.1.0", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=" + }, + "minimatch": { + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "requires": { + "brace-expansion": "^1.1.7" + }, + "version": "3.0.4", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true + }, + "v8-compile-cache": { + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "version": "2.3.0", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "buffer-from": { + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "ajv": { + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "requires": { + "uri-js": "^4.2.2", + "json-schema-traverse": "^0.4.1", + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0" + }, + "version": "6.12.6", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true + }, + "yargs-unparser": { + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "requires": { + "flat": "^5.0.2", + "decamelize": "^4.0.0", + "is-plain-obj": "^2.1.0", + "camelcase": "^6.0.0" + }, + "version": "2.0.0", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true + }, + "opener": { + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "version": "1.5.2", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "got": { + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "requires": { + "mimic-response": "^1.0.1", + "duplexer3": "^0.1.4", + "url-parse-lax": "^3.0.0", + "cacheable-request": "^6.0.0", + "@szmarczak/http-timer": "^1.1.2", + "to-readable-stream": "^1.0.0", + "decompress-response": "^3.3.0", + "get-stream": "^4.1.0", + "p-cancelable": "^1.0.0", + "@sindresorhus/is": "^0.14.0", + "lowercase-keys": "^1.0.1" + }, + "version": "9.6.0", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true + }, + "webpack-cli": { + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz", + "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==", + "dev": true, + "version": "4.7.0", + "dependencies": { + "cross-spawn": { + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "requires": { + "shebang-command": "^2.0.0", + "which": "^2.0.1", + "path-key": "^3.1.0" + }, + "version": "7.0.3", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true + }, + "shebang-regex": { + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shebang-command": { + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "requires": { + "shebang-regex": "^3.0.0" + }, + "version": "2.0.0", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true + }, + "execa": { + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "requires": { + "onetime": "^5.1.2", + "npm-run-path": "^4.0.1", + "human-signals": "^2.1.0", + "merge-stream": "^2.0.0", + "strip-final-newline": "^2.0.0", + "signal-exit": "^3.0.3", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "cross-spawn": "^7.0.3" + }, + "version": "5.0.0", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "dev": true + }, + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "version": "7.2.0", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "get-stream": { + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "version": "6.0.1", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "which": { + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "requires": { + "isexe": "^2.0.0" + }, + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true + }, + "path-key": { + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "is-stream": { + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "requires": { + "path-key": "^3.0.0" + }, + "version": "4.0.1", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true + } + }, + "requires": { + "import-local": "^3.0.2", + "@discoveryjs/json-ext": "^0.5.0", + "colorette": "^1.2.1", + "v8-compile-cache": "^2.2.0", + "execa": "^5.0.0", + "@webpack-cli/info": "^1.2.4", + "commander": "^7.0.0", + "fastest-levenshtein": "^1.0.12", + "@webpack-cli/configtest": "^1.0.3", + "@webpack-cli/serve": "^1.4.0", + "webpack-merge": "^5.7.3", + "rechoir": "^0.7.0", + "interpret": "^2.2.0" + } + }, + "@webassemblyjs/ieee754": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "requires": { + "@xtuc/ieee754": "^1.2.0" + }, + "version": "1.11.0", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "dev": true + }, + "to-readable-stream": { + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "delegates": { + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "detect-node": { + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "optional": true, + "version": "2.1.0", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "decompress-response": { + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "requires": { + "mimic-response": "^1.0.0" + }, + "version": "3.3.0", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true + }, + "ansi-styles": { + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "requires": { + "color-convert": "^1.9.0" + }, + "version": "3.2.1", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true + }, + "cookie": { + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true + }, + "assertion-error": { + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "is-bigint": { + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", + "dev": true + }, + "is-callable": { + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "version": "1.2.3", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "jsonfile": { + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "version": "6.1.0", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true + }, + "sirv": { + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.18.tgz", + "requires": { + "totalist": "^1.0.0", + "mime": "^2.3.1", + "@polka/url": "^1.0.0-next.20" + }, + "version": "1.0.18", + "integrity": "sha512-f2AOPogZmXgJ9Ma2M22ZEhc1dNtRIzcEkiflMFeVTRq+OViOZMvH1IPMVOwrKaxpSaHioBJiDR0SluRqGa7atA==", + "dev": true + }, + "stream-http": { + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "version": "3.2.0", + "dependencies": { + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true + } + }, + "requires": { + "inherits": "^2.0.4", + "builtin-status-codes": "^3.0.0", + "xtend": "^4.0.2", + "readable-stream": "^3.6.0" + } + }, + "universalify": { + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "uri-js": { + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "requires": { + "punycode": "^2.1.0" + }, + "version": "4.4.1", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true + }, + "event-stream": { + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "requires": { + "pause-stream": "0.0.11", + "from": "~0", + "stream-combiner": "~0.0.4", + "through": "~2.3.1", + "split": "0.3", + "duplexer": "~0.1.1", + "map-stream": "~0.1.0" + }, + "version": "3.3.4", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true + }, + "is-string": { + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "version": "1.0.5", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "dir-compare": { + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "requires": { + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" + }, + "version": "3.3.0", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", + "dev": true + }, + "body-parser": { + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "version": "1.19.0", + "dependencies": { + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "requires": { + "ms": "2.0.0" + }, + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + }, + "requires": { + "depd": "~1.1.2", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17", + "bytes": "3.1.0", + "http-errors": "1.7.2", + "on-finished": "~2.3.0", + "debug": "2.6.9", + "content-type": "~1.0.4", + "iconv-lite": "0.4.24" + } + }, + "safer-buffer": { + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "@nodelib/fs.scandir": { + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "requires": { + "run-parallel": "^1.1.9", + "@nodelib/fs.stat": "2.0.4" + }, + "version": "2.1.4", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dev": true + }, + "util": { + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2", + "safe-buffer": "^5.1.2" + }, + "version": "0.12.3", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "dev": true + }, + "lowercase-keys": { + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "karma-edge-launcher": { + "resolved": "https://registry.npmjs.org/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz", + "requires": { + "edge-launcher": "1.2.2" + }, + "version": "0.4.2", + "integrity": "sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw==", + "dev": true + }, + "define-properties": { + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "requires": { + "object-keys": "^1.0.12" + }, + "version": "1.1.3", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "version": "1.0.2", + "dependencies": { + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "requires": { + "ansi-regex": "^2.0.0" + }, + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + }, + "requires": { + "strip-ansi": "^3.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0" + } + }, + "miller-rabin": { + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "version": "4.0.1", + "dependencies": { + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + }, + "requires": { + "brorand": "^1.0.1", + "bn.js": "^4.0.0" + } + }, + "@webassemblyjs/wasm-gen": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "requires": { + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/utf8": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "dev": true + }, + "which-typed-array": { + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "requires": { + "es-abstract": "^1.18.0-next.1", + "is-typed-array": "^1.1.3", + "call-bind": "^1.0.0", + "has-symbols": "^1.0.1", + "foreach": "^2.0.5", + "available-typed-arrays": "^1.0.2", + "function-bind": "^1.1.1" + }, + "version": "1.1.4", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "dev": true + }, + "braces": { + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "requires": { + "fill-range": "^7.0.1" + }, + "version": "3.0.2", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true + }, + "parseurl": { + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "version": "1.3.3", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "node-polyfill-webpack-plugin": { + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.0.tgz", + "integrity": "sha512-6eKoqK2BpKqUFN1oI1TRoF9TgpsUC1Y8JaT+UUNuUiODhZIm3vcSoNrsqGAoHAhpZxKF0+9MU9VxOWJR/YjpIA==", + "dev": true, + "version": "1.1.0", + "dependencies": { + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "requires": { + "safe-buffer": "~5.2.0" + }, + "version": "1.3.0", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true + }, + "safe-buffer": { + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true + } + }, + "requires": { + "process": "^0.11.10", + "filter-obj": "^2.0.1", + "tty-browserify": "^0.0.1", + "timers-browserify": "^2.0.12", + "crypto-browserify": "^3.12.0", + "os-browserify": "^0.3.0", + "punycode": "^2.1.1", + "vm-browserify": "^1.1.2", + "stream-browserify": "^3.0.0", + "https-browserify": "^1.0.0", + "string_decoder": "^1.3.0", + "readable-stream": "^3.6.0", + "constants-browserify": "^1.0.0", + "events": "^3.3.0", + "path-browserify": "^1.0.1", + "buffer": "^6.0.3", + "assert": "^2.0.0", + "domain-browser": "^4.19.0", + "querystring-es3": "^0.2.1", + "util": "^0.12.3", + "stream-http": "^3.1.1", + "url": "^0.11.0", + "console-browserify": "^1.2.0", + "browserify-zlib": "^0.2.0" + } + }, + "camelcase": { + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "version": "6.2.0", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "ieee754": { + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "version": "1.2.1", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "inflight": { + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "requires": { + "wrappy": "1", + "once": "^1.3.0" + }, + "version": "1.0.6", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "@nodelib/fs.walk": { + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "version": "1.2.6", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dev": true + }, + "binary-extensions": { + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "dom-serialize": { + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "requires": { + "void-elements": "^2.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "custom-event": "~1.0.0" + }, + "version": "2.2.1", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true + }, + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "version": "0.6.1", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "p-limit": { + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "requires": { + "yocto-queue": "^0.1.0" + }, + "version": "3.1.0", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true + }, + "setprototypeof": { + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "follow-redirects": { + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "version": "1.13.3", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", + "dev": true + }, + "is-glob": { + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "requires": { + "is-extglob": "^2.1.1" + }, + "version": "4.0.1", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true + }, + "karma-browserstack-launcher": { + "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz", + "requires": { + "browserstack-local": "^1.3.7", + "q": "~1.5.0", + "browserstack": "~1.5.1" + }, + "version": "1.6.0", + "integrity": "sha512-Y/UWPdHZkHIVH2To4GWHCTzmrsB6H7PBWy6pw+TWz5sr4HW2mcE+Uj6qWgoVNxvQU1Pfn5LQQzI6EQ65p8QbiQ==", + "dev": true + }, + "immediate": { + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "version": "3.0.6", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "concat-map": { + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "@webassemblyjs/ast": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-numbers": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "dev": true + }, + "minimalistic-crypto-utils": { + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "path-exists": { + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "big.js": { + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "version": "5.2.2", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "karma-mocha-reporter": { + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "version": "2.2.5", + "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", + "dev": true + }, + "raw-body": { + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "requires": { + "unpipe": "1.0.0", + "bytes": "3.1.0", + "iconv-lite": "0.4.24", + "http-errors": "1.7.2" + }, + "version": "2.4.0", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true + }, + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "requires": { + "has-flag": "^3.0.0" + }, + "version": "5.5.0", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true + }, + "sha.js": { + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "version": "2.4.11", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true + }, + "is-plain-object": { + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "requires": { + "isobject": "^3.0.1" + }, + "version": "2.0.4", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true + }, + "url-parse-lax": { + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "requires": { + "prepend-http": "^2.0.0" + }, + "version": "3.0.0", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true + }, + "object-keys": { + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "yallist": { + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "caniuse-lite": { + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", + "version": "1.0.30001223", + "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", + "dev": true + }, + "p-cancelable": { + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "fastq": { + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "requires": { + "reusify": "^1.0.4" + }, + "version": "1.11.0", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "dev": true + }, + "nanoid": { + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "version": "3.1.20", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "signal-exit": { + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "version": "3.0.3", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "path-type": { + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "hash.js": { + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + }, + "version": "1.1.7", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true + }, + "pify": { + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "optional": true, + "version": "3.0.0", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "lie": { + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "requires": { + "immediate": "~3.0.5" + }, + "version": "3.3.0", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true + }, + "combine-source-map": { + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "version": "0.8.0", + "dependencies": { + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "convert-source-map": { + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "version": "1.1.3", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + } + }, + "requires": { + "source-map": "~0.5.3", + "inline-source-map": "~0.6.0", + "convert-source-map": "~1.1.0", + "lodash.memoize": "~3.0.3" + } + }, + "stream-browserify": { + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "version": "3.0.0", + "dependencies": { + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true + } + }, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "extract-zip": { + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dev": true, + "version": "1.7.0", + "dependencies": { + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "requires": { + "ms": "2.0.0" + }, + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + }, + "requires": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + } + }, + "global-agent": { + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "requires": { + "semver": "^7.3.2", + "matcher": "^3.0.0", + "boolean": "^3.0.1", + "serialize-error": "^7.0.1", + "roarr": "^2.15.3", + "es6-error": "^4.1.1" + }, + "dev": true, + "version": "3.0.0", + "dependencies": { + "semver": { + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dev": true, + "version": "7.3.5", + "optional": true + } + }, + "optional": true + }, + "which": { + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "requires": { + "isexe": "^2.0.0" + }, + "version": "1.3.1", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true + }, + "unbox-primitive": { + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "requires": { + "has-bigints": "^1.0.1", + "function-bind": "^1.1.1", + "which-boxed-primitive": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "version": "1.0.1", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true + }, + "is-negative-zero": { + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "version": "2.0.1", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "neo-async": { + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "version": "2.6.2", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "log-symbols": { + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "requires": { + "chalk": "^2.0.1" + }, + "version": "2.2.0", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true + }, + "setimmediate": { + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "version": "1.0.5", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "buffer": { + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "requires": { + "ieee754": "^1.2.1", + "base64-js": "^1.3.1" + }, + "version": "6.0.3", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true + }, + "glob": { + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "requires": { + "inherits": "2", + "minimatch": "^3.0.4", + "inflight": "^1.0.4", + "fs.realpath": "^1.0.0", + "path-is-absolute": "^1.0.0", + "once": "^1.3.0" + }, + "version": "7.1.6", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true + }, + "create-ecdh": { + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "version": "4.0.4", + "dependencies": { + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + }, + "requires": { + "elliptic": "^6.5.3", + "bn.js": "^4.1.0" + } + }, + "engine.io-parser": { + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "requires": { + "base64-arraybuffer": "0.1.4" + }, + "version": "4.0.2", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "dev": true + }, + "minimalistic-assert": { + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "ps-tree": { + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "requires": { + "event-stream": "=3.3.4" + }, + "version": "1.2.0", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true + }, + "@chiragrupani/karma-chromium-edge-launcher": { + "resolved": "https://registry.npmjs.org/@chiragrupani/karma-chromium-edge-launcher/-/karma-chromium-edge-launcher-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-POHDni57WeEzA/liw8Ksdzj9FLDoX0KPtvBG+jhXEBcPPARKdRCiP5ntBQLWIHZbp61g5G2g1sD5ZuGuLYyhPA==", + "dev": true + }, + "url": { + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "version": "0.11.0", + "dependencies": { + "punycode": { + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "version": "1.3.2", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + }, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "queue-microtask": { + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "version": "1.2.3", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "wide-align": { + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "requires": { + "string-width": "^1.0.2 || 2" + }, + "version": "1.1.3", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true + }, + "wildcard": { + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "console-browserify": { + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "is-boolean-object": { + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "requires": { + "call-bind": "^1.0.0" + }, + "version": "1.1.0", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true + }, + "content-type": { + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "version": "1.0.4", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "is-nan": { + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "version": "1.3.2", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true + }, + "sumchecker": { + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "requires": { + "debug": "^4.1.0" + }, + "version": "3.0.1", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true + }, + "socket.io-parser": { + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "requires": { + "debug": "~4.3.1", + "component-emitter": "~1.3.0", + "@types/component-emitter": "^1.2.10" + }, + "version": "4.0.4", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "dev": true + }, + "npm-run-path": { + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "requires": { + "path-key": "^2.0.0" + }, + "version": "2.0.2", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true + }, + "custom-event": { + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "@discoveryjs/json-ext": { + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", + "version": "0.5.2", + "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", + "dev": true + }, + "y18n": { + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "version": "5.0.8", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "randombytes": { + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "requires": { + "safe-buffer": "^5.1.0" + }, + "version": "2.1.0", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true + }, + "@protobufjs/aspromise": { + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "locate-path": { + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "requires": { + "p-locate": "^5.0.0" + }, + "version": "6.0.0", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true + }, + "colors": { + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "version": "1.4.0", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "terser": { + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "version": "5.10.0", + "dependencies": { + "source-map": { + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "version": "0.7.3", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "version": "2.20.3", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + }, + "requires": { + "source-map": "~0.7.2", + "source-map-support": "~0.5.20", + "commander": "^2.20.0" + } + }, + "gauge": { + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "version": "2.7.4", + "dependencies": { + "strip-ansi": { + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "requires": { + "ansi-regex": "^2.0.0" + }, + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + }, + "requires": { + "object-assign": "^4.1.0", + "console-control-strings": "^1.0.0", + "wide-align": "^1.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "has-unicode": "^2.0.0", + "aproba": "^1.0.3" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "dev": true + }, + "hmac-drbg": { + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "requires": { + "minimalistic-assert": "^1.0.0", + "hash.js": "^1.0.3", + "minimalistic-crypto-utils": "^1.0.1" + }, + "version": "1.0.1", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true + }, + "punycode": { + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "vm-browserify": { + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "https-browserify": { + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "pathval": { + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "util-deprecate": { + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "mimic-response": { + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "fs.realpath": { + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "is-extglob": { + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "are-we-there-yet": { + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "version": "1.1.5", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true + }, + "end-of-stream": { + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "requires": { + "once": "^1.4.0" + }, + "version": "1.4.4", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true + }, + "di": { + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "ua-parser-js": { + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.27.tgz", + "version": "0.7.27", + "integrity": "sha512-eXMaRYK2skomGocoX0x9sBXzx5A1ZVQgXfrW4mTc8dT0zS7olEcyfudAzRC5tIIRgLxQ69B6jut3DI+n5hslPA==", + "dev": true + }, + "range-parser": { + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "version": "1.2.1", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "requires-port": { + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "isarray": { + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "qs": { + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "version": "6.7.0", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "resolve": { + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "requires": { + "path-parse": "^1.0.6", + "is-core-module": "^2.2.0" + }, + "version": "1.20.0", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true + }, + "merge2": { + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "version": "1.4.1", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "bytes": { + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "version": "3.1.0", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "run-parallel": { + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "requires": { + "queue-microtask": "^1.2.2" + }, + "version": "1.2.0", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true + }, + "type-detect": { + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "version": "4.0.8", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "proto-list": { + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "optional": true, + "version": "1.2.4", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "serialize-error": { + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "requires": { + "type-fest": "^0.13.1" + }, + "dev": true, + "version": "7.0.1", + "optional": true + }, + "clone-deep": { + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "requires": { + "shallow-clone": "^3.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2" + }, + "version": "4.0.1", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true + }, + "@types/cookie": { + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", + "version": "0.4.0", + "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", + "dev": true + }, + "buffer-equal": { + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "filter-obj": { + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", + "version": "2.0.2", + "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "dev": true + }, + "des.js": { + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + }, + "version": "1.0.1", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true + }, + "browser-stdout": { + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "version": "1.3.1", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "socket.io": { + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", + "requires": { + "socket.io-parser": "~4.0.3", + "@types/cors": "^2.8.8", + "@types/cookie": "^0.4.0", + "base64id": "~2.0.0", + "socket.io-adapter": "~2.1.0", + "accepts": "~1.3.4", + "engine.io": "~4.1.0", + "debug": "~4.3.1", + "@types/node": ">=10.0.0" + }, + "version": "3.1.2", + "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "dev": true + }, + "@webassemblyjs/leb128": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "requires": { + "@xtuc/long": "4.2.2" + }, + "version": "1.11.0", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "dev": true + }, + "color-name": { + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "version": "1.1.3", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "timers-browserify": { + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "requires": { + "setimmediate": "^1.0.4" + }, + "version": "2.0.12", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true + }, + "browserify-aes": { + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "requires": { + "buffer-xor": "^1.0.3", + "inherits": "^2.0.1", + "cipher-base": "^1.0.0", + "evp_bytestokey": "^1.0.3", + "safe-buffer": "^5.0.1", + "create-hash": "^1.1.0" + }, + "version": "1.2.0", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true + }, + "es-module-lexer": { + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "dev": true + }, + "tapable": { + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "version": "2.2.0", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "dev": true + }, + "keypress": { + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", + "version": "0.1.0", + "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=", + "dev": true + }, + "pump": { + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + }, + "version": "3.0.0", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true + }, + "js-string-escape": { + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, + "convert-source-map": { + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha1-RMCMJQbxD7PKb9iI1aNETPjWpmk=", + "dev": true + }, + "progress": { + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "version": "2.0.3", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "constants-browserify": { + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "extend": { + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "version": "3.0.2", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "prepend-http": { + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "@webpack-cli/configtest": { + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz", + "version": "1.0.3", + "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==", + "dev": true + }, + "@types/mocha": { + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "version": "8.2.2", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "ws": { + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "version": "7.4.6", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true + }, + "guid-typescript": { + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "version": "1.0.9", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==" + }, + "http-errors": { + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "version": "1.7.2", + "dependencies": { + "inherits": { + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "version": "2.0.3", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + }, + "requires": { + "inherits": "2.0.3", + "depd": "~1.1.2", + "toidentifier": "1.0.0", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2" + } + }, + "ansi-regex": { + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "evp_bytestokey": { + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + }, + "version": "1.0.3", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true + }, + "acorn-walk": { + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "version": "8.2.0", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "deep-eql": { + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "requires": { + "type-detect": "^4.0.0" + }, + "version": "3.0.1", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true + }, + "ee-first": { + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node-releases": { + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "version": "1.1.71", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "get-func-name": { + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "schema-utils": { + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "requires": { + "ajv-keywords": "^3.5.2", + "ajv": "^6.12.5", + "@types/json-schema": "^7.0.6" + }, + "version": "3.0.0", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true + }, + "@electron/get": { + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.1.tgz", + "integrity": "sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA==", + "dev": true, + "version": "1.13.1", + "dependencies": { + "fs-extra": { + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "requires": { + "jsonfile": "^4.0.0", + "graceful-fs": "^4.2.0", + "universalify": "^0.1.0" + }, + "version": "8.1.0", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true + }, + "jsonfile": { + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "requires": { + "graceful-fs": "^4.1.6" + }, + "version": "4.0.0", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true + }, + "universalify": { + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "version": "0.1.2", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + }, + "requires": { + "sumchecker": "^3.0.1", + "semver": "^6.2.0", + "global-tunnel-ng": "^2.7.1", + "fs-extra": "^8.1.0", + "global-agent": "^3.0.0", + "env-paths": "^2.2.0", + "debug": "^4.1.1", + "got": "^9.6.0", + "progress": "^2.0.3" + } + }, + "wrappy": { + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "platform": { + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "version": "1.3.6", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" + }, + "xtend": { + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "version": "4.0.2", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "escalade": { + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "map-stream": { + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "version": "0.1.0", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "@protobufjs/float": { + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "picomatch": { + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "version": "2.2.2", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "dev": true + }, + "string.prototype.trimstart": { + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "version": "1.0.4", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true + }, + "minimist": { + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "version": "1.2.5", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "hash-base": { + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "version": "3.1.0", + "dependencies": { + "safe-buffer": { + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true + } + }, + "requires": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.0", + "readable-stream": "^3.6.0" + } + }, + "base64-arraybuffer": { + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "version": "0.1.4", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", + "dev": true + }, + "https-proxy-agent": { + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "version": "2.2.4", + "dependencies": { + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "requires": { + "ms": "^2.1.1" + }, + "version": "3.2.7", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true + } + }, + "requires": { + "debug": "^3.1.0", + "agent-base": "^4.3.0" + } + }, + "unpipe": { + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "karma-sourcemap-loader": { + "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz", + "requires": { + "graceful-fs": "^4.1.2" + }, + "version": "0.3.8", + "integrity": "sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g==", + "dev": true + }, + "encodeurl": { + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "mime-db": { + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "version": "1.47.0", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true + }, + "jest-worker": { + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "version": "26.6.2", + "dependencies": { + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + }, + "requires": { + "supports-color": "^7.0.0", + "@types/node": "*", + "merge-stream": "^2.0.0" + } + }, + "es6-promise": { + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "version": "4.2.8", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "onetime": { + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "requires": { + "mimic-fn": "^2.1.0" + }, + "version": "5.1.2", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true + }, + "assert": { + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "requires": { + "util": "^0.12.0", + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1" + }, + "version": "2.0.0", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "dev": true + }, + "npm-conf": { + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "dev": true, + "version": "1.1.3", + "optional": true + }, + "balanced-match": { + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "object-is": { + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "version": "1.1.5", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true + }, + "depd": { + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "@types/minimatch": { + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "version": "3.0.4", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "@types/platform": { + "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.3.tgz", + "version": "1.3.3", + "integrity": "sha512-1fuOulBHWIxAPLBtLms+UtbeRDt6rL7gP5R+Yugfzdg+poCLxXqXTE8i+FpYeiytGRLUEtnFkjsY/j+usbQBqw==", + "dev": true + }, + "lodash": { + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "version": "4.17.21", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "json-stringify-safe": { + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "optional": true, + "version": "5.0.1", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "envinfo": { + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "version": "7.8.1", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "requires": { + "supports-color": "^5.3.0", + "escape-string-regexp": "^1.0.5", + "ansi-styles": "^3.2.1" + }, + "version": "2.4.2", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true + }, + "shebang-command": { + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "requires": { + "shebang-regex": "^1.0.0" + }, + "version": "1.2.0", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true + }, + "duplexer": { + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "version": "0.1.2", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "reusify": { + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "version": "1.0.4", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "karma-firefox-launcher": { + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.0.tgz", + "integrity": "sha512-dkiyqN2R6fCWt78rciOXJLFDWcQ7QEQi++HgebPJlw1y0ycDjGNDHuSrhdh48QG02fzZKK20WHFWVyBZ6CPngg==", + "dev": true, + "version": "2.1.0", + "dependencies": { + "which": { + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "requires": { + "isexe": "^2.0.0" + }, + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true + } + }, + "requires": { + "is-wsl": "^2.2.0", + "which": "^2.0.1" + } + }, + "@protobufjs/codegen": { + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "inherits": { + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "base64-js": { + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "version": "1.5.1", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "colorette": { + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "version": "1.2.2", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "is-wsl": { + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "requires": { + "is-docker": "^2.0.0" + }, + "version": "2.2.0", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true + }, + "commander": { + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "requires": { + "graceful-readlink": ">= 1.0.0" + }, + "version": "2.9.0", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true + }, + "fsevents": { + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "optional": true, + "version": "2.3.2", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true + }, + "object.assign": { + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "object-keys": "^1.1.1", + "has-symbols": "^1.0.1" + }, + "version": "4.1.2", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true + }, + "is-stream": { + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "growl": { + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "version": "1.10.5", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "@webassemblyjs/utf8": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "dev": true + }, + "number-is-nan": { + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "eslint-scope": { + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "requires": { + "estraverse": "^4.1.1", + "esrecurse": "^4.3.0" + }, + "version": "5.1.1", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true + }, + "split": { + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "requires": { + "through": "2" + }, + "version": "0.3.3", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true + }, + "readable-stream": { + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "requires": { + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "core-util-is": "~1.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "process-nextick-args": "~2.0.0", + "util-deprecate": "~1.0.1" + }, + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true + }, + "matcher": { + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "requires": { + "escape-string-regexp": "^4.0.0" + }, + "dev": true, + "version": "3.0.0", + "dependencies": { + "escape-string-regexp": { + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "optional": true, + "version": "4.0.0", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + } + }, + "optional": true + }, + "events": { + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "version": "3.3.0", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "es-abstract": { + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "requires": { + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "has-symbols": "^1.0.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "call-bind": "^1.0.2", + "is-regex": "^1.1.2", + "get-intrinsic": "^1.1.1", + "es-to-primitive": "^1.2.1", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "function-bind": "^1.1.1", + "unbox-primitive": "^1.0.0", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object-keys": "^1.1.1" + }, + "version": "1.18.0", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true + }, + "browserify-cipher": { + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "requires": { + "evp_bytestokey": "^1.0.0", + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0" + }, + "version": "1.0.1", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true + }, + "keyv": { + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "requires": { + "json-buffer": "3.0.0" + }, + "version": "3.1.0", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true + }, + "stream-combiner": { + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "requires": { + "duplexer": "~0.1.1" + }, + "version": "0.0.4", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true + }, + "ajv-keywords": { + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "version": "3.5.2", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "js-yaml": { + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "requires": { + "argparse": "^2.0.1" + }, + "version": "4.0.0", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true + }, + "toidentifier": { + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "protobufjs": { + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "requires": { + "@protobufjs/pool": "^1.1.0", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "long": "^4.0.0", + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/codegen": "^2.0.4" + }, + "version": "6.10.2", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", "dependencies": { "@types/node": { - "version": "13.13.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", + "version": "13.13.48", "integrity": "sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ==" } } - }, - "ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, + }, + "onnx-proto": { + "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", "requires": { - "event-stream": "=3.3.4" - } - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, + "protobufjs": "^6.8.8" + }, + "version": "4.0.4", + "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==" + }, + "http-cache-semantics": { + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "version": "4.1.0", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "eventemitter3": { + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "version": "4.0.7", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "create-hmac": { + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, + "inherits": "^2.0.1", + "cipher-base": "^1.0.3", + "safe-buffer": "^5.0.1", + "create-hash": "^1.1.0", + "sha.js": "^2.4.8", + "ripemd160": "^2.0.0" + }, + "version": "1.1.7", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true + }, + "browserstack-local": { + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.8.tgz", + "integrity": "sha512-s+mc3gTOJwELdLWi4qFVKtGwMbb5JWsR+JxKlMaJkRJxoZ0gg3WREgPxAN0bm6iU5+S4Bi0sz0oxBRZT8BiNsQ==", + "dev": true, + "version": "1.4.8", "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "agent-base": { + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "version": "5.1.1", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, + "https-proxy-agent": { + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "requires": { + "debug": "4", + "agent-base": "5" + }, + "version": "4.0.0", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", "dev": true } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, + }, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "is-running": "^2.1.0", + "https-proxy-agent": "^4.0.0", + "ps-tree": "=1.2.0", + "temp-fs": "^0.9.9" } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + }, + "glob-parent": { + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "requires": { + "is-glob": "^4.0.1" + }, + "version": "5.1.2", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + }, + "is-typed-array": { + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "requires": { + "es-abstract": "^1.18.0-next.2", + "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + }, + "version": "1.1.5", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", "dev": true - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + }, + "duplexer3": { + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "version": "0.1.4", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + }, + "graceful-fs": { + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "version": "4.2.6", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + }, + "tty-browserify": { + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "version": "0.0.1", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + }, + "on-finished": { + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "requires": { + "ee-first": "1.1.1" + }, + "version": "2.3.0", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - } - }, - "run-applescript": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz", - "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==", - "dev": true, - "requires": { - "execa": "^0.10.0" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true, - "optional": true - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "sirv": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.18.tgz", - "integrity": "sha512-f2AOPogZmXgJ9Ma2M22ZEhc1dNtRIzcEkiflMFeVTRq+OViOZMvH1IPMVOwrKaxpSaHioBJiDR0SluRqGa7atA==", - "dev": true, - "requires": { - "@polka/url": "^1.0.0-next.20", - "mime": "^2.3.1", - "totalist": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "socket.io": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", - "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", - "dev": true, - "requires": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~4.1.0", - "socket.io-adapter": "~2.1.0", - "socket.io-parser": "~4.0.3" - } - }, - "socket.io-adapter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", - "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", - "dev": true - }, - "socket.io-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", - "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", - "dev": true, - "requires": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", - "debug": "~4.3.1" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "requires": { - "through": "2" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "optional": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "streamroller": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", - "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", - "dev": true, - "requires": { - "date-format": "^2.1.0", - "debug": "^4.1.1", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "date-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", - "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true - }, - "temp-fs": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", - "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", - "dev": true, - "requires": { - "rimraf": "~2.5.2" - }, - "dependencies": { - "rimraf": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - } - } - }, - "terser": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", - "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "dev": true, - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, + }, + "@types/long": { + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "version": "4.0.1", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "requires": { "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + }, + "version": "5.0.1", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true - }, - "totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", - "dev": true - }, - "ts-loader": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.1.2.tgz", - "integrity": "sha512-ryMgATvLLl+z8zQvdlm6Pep0slmwxFWIEnq/5VdiLVjqQXnFJgO+qNLGIIP+d2N2jsFZ9MibZCVDb2bSp7OmEA==", - "dev": true, + }, + "color-convert": { + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, + "color-name": "1.1.3" + }, + "version": "1.9.3", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true + }, + "has-bigints": { + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "md5.js": { + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2", + "hash-base": "^3.0.0" + }, + "version": "1.3.5", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true + }, + "has": { + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "requires": { + "function-bind": "^1.1.1" + }, + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true + }, + "@types/emscripten": { + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz", + "version": "1.39.4", + "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==", + "dev": true + }, + "graceful-readlink": { + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "get-stream": { + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "requires": { + "pump": "^3.0.0" + }, + "version": "4.1.0", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true + }, + "edge-launcher": { + "resolved": "https://registry.npmjs.org/edge-launcher/-/edge-launcher-1.2.2.tgz", + "version": "1.2.2", + "integrity": "sha1-60Cq+9Bnpup27/+rBke81VCbN7I=", + "dev": true + }, + "@polka/url": { + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "version": "1.0.0-next.21", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "@protobufjs/pool": { + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@webassemblyjs/wasm-parser": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "requires": { + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/utf8": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "dev": true + }, + "emojis-list": { + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "workerpool": { + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "version": "6.1.0", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "fs-extra": { + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "requires": { + "jsonfile": "^6.0.1", + "graceful-fs": "^4.2.0", + "at-least-node": "^1.0.0", + "universalify": "^2.0.0" + }, + "version": "9.1.0", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true + }, + "@protobufjs/path": { + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "version": "1.1.2", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "async": { + "resolved": "https://registry.npmjs.org/async/-/async-3.0.1.tgz", + "version": "3.0.1", + "integrity": "sha512-ZswD8vwPtmBZzbn9xyi8XBQWXH3AvOQ43Za1KWYq7JeycrZuUYzx01KvHcVbXltjqH4y0MWrQ33008uLTqXuDw==", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "requires": { + "number-is-nan": "^1.0.0" + }, + "version": "1.0.0", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true + }, + "browserify-zlib": { + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "requires": { + "pako": "~1.0.5" + }, + "version": "0.2.0", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true + }, + "qjobs": { + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "asn1.js": { + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "version": "5.4.1", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "optional": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.27", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.27.tgz", - "integrity": "sha512-eXMaRYK2skomGocoX0x9sBXzx5A1ZVQgXfrW4mTc8dT0zS7olEcyfudAzRC5tIIRgLxQ69B6jut3DI+n5hslPA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, + }, "requires": { - "prepend-http": "^2.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0", + "bn.js": "^4.0.0" } - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "dev": true, + }, + "semver": { + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "@types/eslint": { + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "@types/json-schema": "*", + "@types/estree": "*" + }, + "version": "7.2.10", + "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + }, + "merge-stream": { + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + }, + "escape-html": { + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "version": "1.0.3", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "dev": true, + }, + "yauzl": { + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.36.2.tgz", - "integrity": "sha512-XJumVnnGoH2dV+Pk1VwgY4YT6AiMKpVoudUFCNOXMIVrEKPUgEwdIfWPjIuGLESAiS8EdIHX5+TiJz/5JccmRg==", - "dev": true, + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + }, + "version": "2.10.0", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true + }, + "@types/component-emitter": { + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "version": "1.2.10", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", + "dev": true + }, + "diff": { + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "version": "5.0.0", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "os-browserify": { + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "version": "0.3.0", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "flatted": { + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "version": "2.0.2", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "tmp": { + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.2.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - } - }, - "webpack-bundle-analyzer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", - "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", - "dev": true, + "rimraf": "^3.0.0" + }, + "version": "0.2.1", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true + }, + "ignore": { + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "version": "5.1.8", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "@types/cors": { + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", + "version": "2.8.10", + "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", + "dev": true + }, + "at-least-node": { + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "version": "1.0.0", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "mkdirp": { + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "requires": { - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", - "commander": "^7.2.0", - "gzip-size": "^6.0.0", - "lodash": "^4.17.20", - "opener": "^1.5.2", - "sirv": "^1.0.7", - "ws": "^7.3.1" - }, + "minimist": "^1.2.5" + }, + "version": "0.5.5", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true + }, + "cacheable-request": { + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "version": "6.1.0", "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "webpack-cli": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz", - "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.3", - "@webpack-cli/info": "^1.2.4", - "@webpack-cli/serve": "^1.4.0", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "requires": { - "path-key": "^3.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "pump": "^3.0.0" + }, + "version": "5.2.0", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + }, + "lowercase-keys": { + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + }, + "requires": { + "normalize-url": "^4.1.0", + "keyv": "^3.0.0", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "responselike": "^1.0.2", + "clone-response": "^1.0.2", + "lowercase-keys": "^2.0.0" + } + }, + "slash": { + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "fast-deep-equal": { + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "version": "3.1.3", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "buffer-xor": { + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "version": "1.0.3", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "process": { + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "version": "0.11.10", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "require-directory": { + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "version": "2.1.1", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "estraverse": { + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "version": "4.3.0", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "create-hash": { + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "requires": { + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "cipher-base": "^1.0.1", + "sha.js": "^2.4.0", + "ripemd160": "^2.0.1" + }, + "version": "1.2.0", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true + }, + "cors": { + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "requires": { + "object-assign": "^4", + "vary": "^1" + }, + "version": "2.8.5", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true + }, + "@types/estree": { + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "version": "0.0.47", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", + "dev": true + }, + "pause-stream": { + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "requires": { + "through": "~2.3" + }, + "version": "0.0.11", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true + }, + "is-binary-path": { + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "requires": { + "binary-extensions": "^2.0.0" + }, + "version": "2.1.0", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true + }, + "strip-json-comments": { + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "version": "3.1.1", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "accepts": { + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "requires": { + "negotiator": "0.6.2", + "mime-types": "~2.1.24" + }, + "version": "1.3.7", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true + }, + "engine.io": { + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", + "requires": { + "base64id": "2.0.0", + "accepts": "~1.3.4", + "engine.io-parser": "~4.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "ws": "~7.4.2" + }, + "version": "4.1.1", + "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", + "dev": true + }, + "fd-slicer": { + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "requires": { + "pend": "~1.2.0" + }, + "version": "1.1.0", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true + }, + "@xtuc/long": { + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "version": "4.2.2", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "path-is-absolute": { + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "version": "1.0.1", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "get-caller-file": { + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "version": "2.0.5", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "enhanced-resolve": { + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", + "requires": { + "tapable": "^2.2.0", + "graceful-fs": "^4.2.4" + }, + "version": "5.8.0", + "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", + "dev": true + }, + "string_decoder": { + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "requires": { + "safe-buffer": "~5.1.0" + }, + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true + }, + "fast-glob": { + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "requires": { + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "@nodelib/fs.stat": "^2.0.2", + "micromatch": "^4.0.2", + "@nodelib/fs.walk": "^1.2.3", + "picomatch": "^2.2.1" + }, + "version": "3.2.5", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true + }, + "@webpack-cli/info": { + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz", + "requires": { + "envinfo": "^7.7.3" + }, + "version": "1.2.4", + "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==", + "dev": true + }, + "mocha": { + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "version": "8.3.2", + "dependencies": { + "log-symbols": { + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "chalk": "^4.0.0" + }, + "version": "4.0.0", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true - }, + }, + "color-convert": { + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "requires": { + "color-name": "~1.1.4" + }, + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true + }, + "has-flag": { + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "requires": { "isexe": "^2.0.0" - } - } - } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "worker-loader": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", - "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - } - }, - "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + }, + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true - }, + }, + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "8.1.1", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true + }, + "chalk": { + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "version": "4.1.0", + "dependencies": { + "supports-color": { + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "requires": { + "has-flag": "^4.0.0" + }, + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true + } + }, + "requires": { + "supports-color": "^7.1.0", + "ansi-styles": "^4.1.0" + } + }, + "escape-string-regexp": { + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "requires": { "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, + }, + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true + }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "version": "2.1.3", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } + }, + "requires": { + "browser-stdout": "1.3.1", + "nanoid": "3.1.20", + "chokidar": "3.5.1", + "diff": "5.0.0", + "yargs-unparser": "2.0.0", + "yargs": "16.2.0", + "minimatch": "3.0.4", + "find-up": "5.0.0", + "wide-align": "1.1.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "which": "2.0.2", + "log-symbols": "4.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "serialize-javascript": "5.0.1", + "js-yaml": "4.0.0", + "yargs-parser": "20.2.4", + "he": "1.2.0", + "workerpool": "6.1.0", + "supports-color": "8.1.1", + "strip-json-comments": "3.1.1", + "escape-string-regexp": "4.0.0", + "ms": "2.1.3", + "debug": "4.3.1" } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + }, + "core-util-is": { + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true - }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + }, + "component-emitter": { + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "version": "1.3.0", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, + }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "version": "16.2.0", "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "requires": { "ansi-regex": "^5.0.0" - } + }, + "version": "6.0.0", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true + }, + "ansi-regex": { + "resolved": "", + "version": "5.0.0", + "dev": true + }, + "is-fullwidth-code-point": { + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "requires": { + "strip-ansi": "^6.0.0", + "is-fullwidth-code-point": "^3.0.0", + "emoji-regex": "^8.0.0" + }, + "version": "4.2.2", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true } + }, + "requires": { + "y18n": "^5.0.5", + "string-width": "^4.2.0", + "require-directory": "^2.1.1", + "escalade": "^3.1.1", + "cliui": "^7.0.2", + "get-caller-file": "^2.0.5", + "yargs-parser": "^20.2.2" } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + }, + "import-local": { + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "requires": { + "resolve-cwd": "^3.0.0", + "pkg-dir": "^4.2.0" + }, + "version": "3.0.2", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, + }, + "@protobufjs/inquire": { + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "webpack": { + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.36.2.tgz", "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, + "enhanced-resolve": "^5.8.0", + "browserslist": "^4.14.5", + "schema-utils": "^3.0.0", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "chrome-trace-event": "^1.0.2", + "mime-types": "^2.1.27", + "es-module-lexer": "^0.4.0", + "tapable": "^2.1.1", + "webpack-sources": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "@types/eslint-scope": "^3.7.0", + "eslint-scope": "^5.1.1", + "@webassemblyjs/wasm-edit": "1.11.0", + "events": "^3.2.0", + "neo-async": "^2.6.2", + "@webassemblyjs/ast": "1.11.0", + "acorn": "^8.2.1", + "glob-to-regexp": "^0.4.1", + "@types/estree": "^0.0.47", + "@webassemblyjs/wasm-parser": "1.11.0", + "watchpack": "^2.0.0", + "loader-runner": "^4.2.0" + }, + "version": "5.36.2", + "integrity": "sha512-XJumVnnGoH2dV+Pk1VwgY4YT6AiMKpVoudUFCNOXMIVrEKPUgEwdIfWPjIuGLESAiS8EdIHX5+TiJz/5JccmRg==", + "dev": true + }, + "long": { + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "version": "4.0.0", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "diffie-hellman": { + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "version": "5.0.3", + "dependencies": { + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "version": "4.12.0", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + }, "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "miller-rabin": "^4.0.0", + "bn.js": "^4.1.0", + "randombytes": "^2.0.0" } - }, + }, + "function-bind": { + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "kind-of": { + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "version": "6.0.3", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "available-typed-arrays": { + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "requires": { + "array-filter": "^1.0.0" + }, + "version": "1.0.2", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "dev": true + }, + "pako": { + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "version": "1.0.11", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "safe-buffer": { + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "webpack-sources": { + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "requires": { + "source-map": "^0.6.1", + "source-list-map": "^2.0.1" + }, + "version": "2.2.0", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "dev": true + }, + "glob-to-regexp": { + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "version": "0.4.1", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "log4js": { + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "requires": { + "debug": "^4.1.1", + "rfdc": "^1.1.4", + "flatted": "^2.0.1", + "streamroller": "^2.2.4", + "date-format": "^3.0.0" + }, + "version": "6.3.0", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "dev": true + }, + "he": { + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "version": "1.2.0", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "object-assign": { + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "call-bind": { + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "version": "1.0.2", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true + }, + "@szmarczak/http-timer": { + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "requires": { + "defer-to-connect": "^1.0.1" + }, + "version": "1.1.2", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true + }, + "brace-expansion": { + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true + }, + "pbkdf2": { + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "requires": { + "create-hash": "^1.1.2", + "sha.js": "^2.4.8", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "create-hmac": "^1.1.4" + }, + "version": "3.1.2", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true + }, + "@types/minimist": { + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "version": "1.2.1", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "version": "0.1.0", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "is-regex": { + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + }, + "version": "1.1.2", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true + }, + "human-signals": { + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "chai": { + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "requires": { + "get-func-name": "^2.0.0", + "deep-eql": "^3.0.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5", + "assertion-error": "^1.1.0", + "check-error": "^1.0.2" + }, + "version": "4.3.4", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true + }, + "has-symbols": { + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "version": "1.0.2", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "ini": { + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "optional": true, + "version": "1.3.8", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "mime-types": { + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "requires": { + "mime-db": "1.47.0" + }, + "version": "2.1.30", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true + }, + "statuses": { + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "version": "1.5.0", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "temp-fs": { + "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", + "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", + "dev": true, + "version": "0.9.9", + "dependencies": { + "rimraf": { + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "requires": { + "glob": "^7.0.5" + }, + "version": "2.5.4", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "dev": true + } + }, + "requires": { + "rimraf": "~2.5.2" + } + }, + "config-chain": { + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + }, + "dev": true, + "version": "1.1.13", + "optional": true + }, + "readdirp": { + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "requires": { + "picomatch": "^2.2.1" + }, + "version": "3.5.0", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true + }, + "@webassemblyjs/wasm-opt": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "requires": { + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0" + }, + "version": "1.11.0", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "dev": true + }, + "is-running": { + "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", + "dev": true + }, + "strip-final-newline": { + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "roarr": { + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "requires": { + "semver-compare": "^1.0.0", + "json-stringify-safe": "^5.0.1", + "detect-node": "^2.0.4", + "sprintf-js": "^1.1.2", + "boolean": "^3.0.1", + "globalthis": "^1.0.1" + }, + "dev": true, + "version": "2.15.4", + "optional": true + }, + "@types/chai": { + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", + "version": "4.2.16", + "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==", + "dev": true + }, + "responselike": { + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "requires": { + "lowercase-keys": "^1.0.0" + }, + "version": "1.0.2", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true + }, + "rimraf": { + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "requires": { + "glob": "^7.1.3" + }, + "version": "3.0.2", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true + }, + "typedarray": { + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "version": "0.0.6", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "json-buffer": { + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "clone-response": { + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "requires": { + "mimic-response": "^1.0.0" + }, + "version": "1.0.2", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true + }, + "fast-json-stable-stringify": { + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "version": "2.1.0", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "finalhandler": { + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "version": "1.1.2", + "dependencies": { + "debug": { + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "requires": { + "ms": "2.0.0" + }, + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true + }, + "ms": { + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + }, + "requires": { + "parseurl": "~1.3.3", + "escape-html": "~1.0.3", + "encodeurl": "~1.0.2", + "unpipe": "~1.0.0", + "on-finished": "~2.3.0", + "debug": "2.6.9", + "statuses": "~1.5.0" + } + }, + "semver-compare": { + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "optional": true, + "version": "1.0.0", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "fill-range": { + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "requires": { + "to-regex-range": "^5.0.1" + }, + "version": "7.0.1", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true + }, + "@protobufjs/utf8": { + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "version": "1.1.0", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "watchpack": { + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "requires": { + "graceful-fs": "^4.1.2", + "glob-to-regexp": "^0.4.1" + }, + "version": "2.1.1", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "dev": true + }, + "bn.js": { + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "version": "5.2.0", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "@webassemblyjs/floating-point-hex-parser": { + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "version": "1.11.0", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "dev": true + }, + "escape-string-regexp": { + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "version": "1.0.5", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "karma": { + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", + "requires": { + "graceful-fs": "^4.2.4", + "chokidar": "^3.4.2", + "socket.io": "^3.1.0", + "connect": "^3.7.0", + "braces": "^3.0.2", + "yargs": "^16.1.1", + "tmp": "0.2.1", + "minimatch": "^3.0.4", + "dom-serialize": "^2.2.1", + "range-parser": "^1.2.1", + "source-map": "^0.6.1", + "di": "^0.0.1", + "glob": "^7.1.6", + "ua-parser-js": "^0.7.23", + "mime": "^2.4.5", + "rimraf": "^3.0.2", + "log4js": "^6.2.1", + "lodash": "^4.17.19", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.6", + "colors": "^1.4.0", + "body-parser": "^1.19.0", + "qjobs": "^1.2.0" + }, + "version": "6.3.2", + "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", + "dev": true + }, + "builtin-status-codes": { + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "version": "3.0.0", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "once": { + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "requires": { + "wrappy": "1" + }, + "version": "1.4.0", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true } - } -} + }, + "version": "1.11.0", + "requires": true, + "name": "onnxruntime-web", + "lockfileVersion": 1 +} \ No newline at end of file diff --git a/js/web/package.json b/js/web/package.json index 32f95d118f..9f8c1e33bd 100644 --- a/js/web/package.json +++ b/js/web/package.json @@ -1,85 +1,85 @@ { - "license": "MIT", - "name": "onnxruntime-web", - "description": "A Javascript library for running ONNX models on browsers", + "license": "MIT", + "browser": "dist/ort-web.min.js", + "unpkg": "dist/ort.min.js", + "name": "onnxruntime-web", "repository": { - "url": "https://github.com/Microsoft/onnxruntime.git", + "url": "https://github.com/Microsoft/onnxruntime.git", "type": "git" - }, - "author": "fs-eire", - "version": "1.10.0", - "keywords": [ - "ONNX", - "ONNXRuntime", - "ONNX Runtime" - ], - "scripts": { - "prepare": "tsc", - "build": "node ./script/build", - "build:doc": "node ./script/generate-operator-md", - "pull:wasm": "node ./script/pull-prebuilt-wasm-artifacts", - "test": "node ./script/prepare-test-data && node ./script/test-runner-cli", - "test:e2e": "node ./test/e2e/run", - "prepack": "node ./script/build && node ./script/prepack" - }, + }, + "author": "fs-eire", + "module": "./lib/index.js", + "version": "1.11.0", + "jsdelivr": "dist/ort.min.js", "dependencies": { - "flatbuffers": "^1.12.0", - "guid-typescript": "^1.0.9", - "long": "^4.0.0", - "onnx-proto": "^4.0.4", - "onnxruntime-common": "file:../common", - "platform": "^1.3.6" - }, + "onnx-proto": "^4.0.4", + "flatbuffers": "^1.12.0", + "long": "^4.0.0", + "platform": "^1.3.6", + "guid-typescript": "^1.0.9", + "onnxruntime-common": "file:../common" + }, + "scripts": { + "prepare": "tsc", + "build:doc": "node ./script/generate-operator-md", + "pull:wasm": "node ./script/pull-prebuilt-wasm-artifacts", + "test:e2e": "node ./test/e2e/run", + "build": "node ./script/build", + "test": "node ./script/prepare-test-data && node ./script/test-runner-cli", + "prepack": "node ./script/build && node ./script/prepack" + }, + "keywords": [ + "ONNX", + "ONNXRuntime", + "ONNX Runtime" + ], "devDependencies": { - "@chiragrupani/karma-chromium-edge-launcher": "^2.1.0", - "@types/chai": "^4.2.16", - "@types/emscripten": "^1.39.4", - "@types/flatbuffers": "^1.10.0", - "@types/fs-extra": "^9.0.10", - "@types/karma": "^6.1.0", - "@types/long": "^4.0.1", - "@types/minimatch": "^3.0.4", - "@types/minimist": "^1.2.1", - "@types/mocha": "^8.2.2", - "@types/npmlog": "^4.1.2", - "@types/platform": "^1.3.3", - "base64-js": "^1.5.1", - "chai": "^4.3.4", - "dir-compare": "^3.3.0", - "electron": "^12.2.3", - "fs-extra": "^9.1.0", - "globby": "^11.0.3", - "jszip": "^3.7.1", - "karma": "^6.3.2", - "karma-browserstack-launcher": "^1.6.0", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^3.1.0", - "karma-edge-launcher": "^0.4.2", - "karma-electron": "^7.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-safari-applescript-launcher": "^0.1.0", - "karma-sourcemap-loader": "^0.3.8", - "minimatch": "^3.0.4", - "minimist": "^1.2.5", - "mocha": "^8.3.2", - "node-polyfill-webpack-plugin": "^1.1.0", - "npmlog": "^4.1.2", - "numpy-parser": "^1.2.3", - "strip-json-comments": "^3.1.1", - "terser": "^5.10.0", - "ts-loader": "^9.1.2", - "typescript": "^4.2.4", - "webpack": "^5.36.2", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-cli": "^4.7.0", + "karma-edge-launcher": "^0.4.2", + "base64-js": "^1.5.1", + "chai": "^4.3.4", + "@types/karma": "^6.1.0", + "mocha": "^8.3.2", + "terser": "^5.10.0", + "@types/fs-extra": "^9.0.10", + "@types/long": "^4.0.1", + "numpy-parser": "^1.2.3", + "minimatch": "^3.0.4", + "minimist": "^1.2.5", + "webpack": "^5.36.2", + "@types/npmlog": "^4.1.2", + "karma-sourcemap-loader": "^0.3.8", + "karma-chai": "^0.1.0", + "@types/chai": "^4.2.16", + "webpack-cli": "^4.7.0", + "@types/emscripten": "^1.39.4", + "ts-loader": "^9.1.2", + "typescript": "^4.2.4", + "npmlog": "^4.1.2", + "karma-electron": "^7.0.0", + "karma-browserstack-launcher": "^1.6.0", + "jszip": "^3.7.1", + "@types/mocha": "^8.2.2", + "electron": "^12.2.3", + "karma-safari-applescript-launcher": "^0.1.0", + "webpack-bundle-analyzer": "^4.5.0", + "@chiragrupani/karma-chromium-edge-launcher": "^2.1.0", + "karma-mocha-reporter": "^2.2.5", + "@types/minimatch": "^3.0.4", + "karma-firefox-launcher": "^2.1.0", + "@types/platform": "^1.3.3", + "node-polyfill-webpack-plugin": "^1.1.0", + "globby": "^11.0.3", + "strip-json-comments": "^3.1.1", + "dir-compare": "^3.3.0", + "karma-mocha": "^2.0.1", + "fs-extra": "^9.1.0", + "karma-chrome-launcher": "^3.1.0", + "@types/flatbuffers": "^1.10.0", + "karma": "^6.3.2", + "@types/minimist": "^1.2.1", "worker-loader": "^3.0.8" - }, - "main": "dist/ort-web.node.js", - "types": "./types/lib/index.d.ts", - "jsdelivr": "dist/ort.min.js", - "unpkg": "dist/ort.min.js", - "module": "./lib/index.js", - "browser": "dist/ort-web.min.js" -} + }, + "main": "dist/ort-web.node.js", + "types": "./types/lib/index.d.ts", + "description": "A Javascript library for running ONNX models on browsers" +} \ No newline at end of file diff --git a/onnxruntime/__init__.py b/onnxruntime/__init__.py index 01a8f0fff1..25d761da6f 100644 --- a/onnxruntime/__init__.py +++ b/onnxruntime/__init__.py @@ -7,7 +7,7 @@ ONNX Runtime is a performance-focused scoring engine for Open Neural Network Exc For more information on ONNX Runtime, please see `aka.ms/onnxruntime `_ or the `Github project `_. """ -__version__ = "1.10.0" +__version__ = "1.11.0" __author__ = "Microsoft" # we need to do device version validation (for example to check Cuda version for an onnxruntime-training package). diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index 832b8990a8..74880c7ba3 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -2498,7 +2498,6 @@ static constexpr OrtApi ort_api_1_to_10 = { &OrtApis::GetSparseTensorIndices, // End of Version 9 - DO NOT MODIFY ABOVE (see above text for more information) - // Version 10 - In development, feel free to add/remove/rearrange here &OrtApis::HasValue, &OrtApis::KernelContext_GetGPUComputeStream, &OrtApis::GetTensorMemoryInfo, @@ -2511,6 +2510,9 @@ static constexpr OrtApi ort_api_1_to_10 = { &OrtApis::SetGlobalCustomJoinThreadFn, &OrtApis::SynchronizeBoundInputs, &OrtApis::SynchronizeBoundOutputs + // End of Version 10 - DO NOT MODIFY ABOVE (see above text for more information) + + // Version 11 - In development, feel free to add/remove/rearrange here }; // Asserts to do a some checks to ensure older Versions of the OrtApi never change (will detect an addition or deletion but not if they cancel out each other) @@ -2525,7 +2527,7 @@ static_assert(offsetof(OrtApi, GetCurrentGpuDeviceId) / sizeof(void*) == 161, "S static_assert(offsetof(OrtApi, CreateSessionFromArrayWithPrepackedWeightsContainer) / sizeof(void*) == 169, "Size of version 8 API cannot change"); // So that nobody forgets to finish an API version, this check will serve as a reminder: -static_assert(std::string_view(ORT_VERSION) == "1.10.0", "ORT_Version change detected, please follow below steps to ensure OrtApi is updated properly"); +static_assert(std::string_view(ORT_VERSION) == "1.11.0", "ORT_Version change detected, please follow below steps to ensure OrtApi is updated properly"); // 1. Update the hardcoded version string in above static_assert to silence it // 2. If there were any APIs added to ort_api_1_to_10 above: // a. Add the 'End of version #' markers (pattern above should be obvious) diff --git a/package/rpm/onnxruntime.spec b/package/rpm/onnxruntime.spec index e3a40ab977..f3f2e1eef2 100644 --- a/package/rpm/onnxruntime.spec +++ b/package/rpm/onnxruntime.spec @@ -1,5 +1,5 @@ Name: onnxruntime -Version: 1.10.0 +Version: 1.11.0 Release: 1%{?dist} Summary: onnxruntime From 20f8a06f1f111ab4915c55c53338e67122f8c5b8 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Wed, 15 Dec 2021 00:58:42 -0800 Subject: [PATCH 046/113] Remove OpenMP code (#10032) --- cmake/CMakeLists.txt | 25 +- cmake/onnxruntime_common.cmake | 3 - cmake/onnxruntime_unittests.cmake | 3 - include/onnxruntime/core/common/denormal.h | 5 - .../onnxruntime/core/platform/threadpool.h | 19 -- .../contrib_ops/cpu/maxpool_with_mask.h | 14 - onnxruntime/core/common/denormal.cc | 26 -- onnxruntime/core/common/threadpool.cc | 59 ---- onnxruntime/core/mlas/lib/mlasi.h | 9 - onnxruntime/core/mlas/lib/pooling.cpp | 11 - onnxruntime/core/mlas/lib/threading.cpp | 7 - .../core/providers/cpu/nn/pool_functors.h | 18 -- .../providers/dnnl/dnnl_provider_factory.cc | 2 +- .../nuphar/common/nuphar_settings.cc | 7 - .../core/session/abi_session_options.cc | 11 - onnxruntime/core/session/inference_session.cc | 3 - onnxruntime/core/util/thread_utils.cc | 10 - .../python/onnxruntime_pybind_state_common.h | 6 - .../test_apis_without_env.cc | 4 - onnxruntime/test/common/denormal_test.cc | 38 --- .../test/framework/inference_session_test.cc | 18 -- .../test/global_thread_pools/test_main.cc | 6 - onnxruntime/test/providers/cpu/model_tests.cc | 10 +- onnxruntime/test/shared_lib/test_inference.cc | 3 +- tools/ci_build/build.py | 2 +- .../azure-pipelines/templates/c-api-cpu.yml | 2 +- .../azure-pipelines/templates/win-cpu-ci.yml | 7 +- .../azure-pipelines/templates/win-gpu-ci.yml | 257 ++++++++++++++++++ .../azure-pipelines/win-ci-pipeline.yml | 30 +- tools/ci_build/github/linux/run_build.sh | 2 +- 30 files changed, 287 insertions(+), 330 deletions(-) create mode 100644 tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7a43d53c3e..fa7d3c59d4 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -67,7 +67,6 @@ option(onnxruntime_USE_AVX "Use AVX instructions" OFF) option(onnxruntime_USE_AVX2 "Use AVX2 instructions" OFF) option(onnxruntime_USE_AVX512 "Use AVX512 instructions" OFF) -option(onnxruntime_USE_OPENMP "Build with OpenMP support" OFF) option(onnxruntime_BUILD_SHARED_LIB "Build a shared library" OFF) option(onnxruntime_BUILD_APPLE_FRAMEWORK "Build a macOS/iOS framework" OFF) option(onnxruntime_ENABLE_MICROSOFT_INTERNAL "Use this option to enable/disable microsoft internal only code" OFF) @@ -292,18 +291,6 @@ if (NOT WIN32) endif() endif() -if (onnxruntime_USE_OPENMP) - find_package(OpenMP) - if (OPENMP_FOUND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - include_directories(${OpenMP_CXX_INCLUDE_DIR}) - else() - message(WARNING "Flag --use_openmp is specified, but OpenMP is not found in current build environment. Setting it to OFF.") - set(onnxruntime_USE_OPENMP OFF) - endif() -endif() - # 'extended' implies minimal. if (onnxruntime_EXTENDED_MINIMAL_BUILD AND NOT onnxruntime_MINIMAL_BUILD) set(onnxruntime_MINIMAL_BUILD ON) @@ -509,7 +496,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin|iOS") endforeach() endif() -#must after OpenMP settings find_package(Threads) macro(check_nvcc_compiler_flag _FLAG _RESULT) @@ -970,9 +956,6 @@ if (WIN32) else() list(APPEND ORT_WARNING_FLAGS "/w34800") endif() - if (onnxruntime_USE_OPENMP) - list(APPEND ORT_WARNING_FLAGS "/wd6993") # Code analysis ignores OpenMP constructs - endif() # operator 'operator-name': deprecated between enumerations of different types list(APPEND ORT_WARNING_FLAGS "/wd5054") # Enable warning: data member 'member' will be initialized after data member 'member2' / base class 'base_class' @@ -1142,6 +1125,7 @@ if (onnxruntime_USE_COREML) list(APPEND ONNXRUNTIME_PROVIDER_NAMES coreml) endif() function(onnxruntime_set_compile_flags target_name) + target_compile_definitions(${target_name} PUBLIC EIGEN_USE_THREADS) if (MSVC) target_compile_definitions(${target_name} PUBLIC -DPLATFORM_WINDOWS -DNOGDI -DNOMINMAX -D_USE_MATH_DEFINES -D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) if (onnxruntime_ENABLE_MEMLEAK_CHECKER) @@ -1337,9 +1321,6 @@ if (onnxruntime_USE_TVM) set(USE_LLVM ON) add_definitions(-DUSE_TVM_WITH_LLVM) endif() - if (onnxruntime_USE_OPENMP) - set(USE_OPENMP "gnu") - endif() add_subdirectory(${PROJECT_SOURCE_DIR}/external/tvm EXCLUDE_FROM_ALL) set_target_properties(tvm PROPERTIES FOLDER "External/tvm") @@ -1825,10 +1806,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Android") list(APPEND onnxruntime_EXTERNAL_LIBRARIES log) endif() -if (onnxruntime_USE_OPENMP) - list(APPEND onnxruntime_EXTERNAL_LIBRARIES OpenMP::OpenMP_CXX) -endif() - if (WIN32) list(APPEND onnxruntime_EXTERNAL_LIBRARIES ${SYS_PATH_LIB} Shlwapi) list(APPEND onnxruntime_EXTERNAL_LIBRARIES debug Dbghelp) diff --git a/cmake/onnxruntime_common.cmake b/cmake/onnxruntime_common.cmake index 4065e4e4ee..3ee4a14e4c 100644 --- a/cmake/onnxruntime_common.cmake +++ b/cmake/onnxruntime_common.cmake @@ -121,9 +121,6 @@ if(NOT WIN32) target_include_directories(onnxruntime_common PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/external/nsync/public") endif() -if(NOT onnxruntime_USE_OPENMP) - target_compile_definitions(onnxruntime_common PUBLIC EIGEN_USE_THREADS) -endif() add_dependencies(onnxruntime_common ${onnxruntime_EXTERNAL_DEPENDENCIES}) install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/common DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/core) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 6bdb2d03c9..1f1f037d97 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -1105,9 +1105,6 @@ if (NOT onnxruntime_ENABLE_TRAINING_TORCH_INTEROP) if (CMAKE_SYSTEM_NAME STREQUAL "Android") list(APPEND onnxruntime_mlas_test_libs ${android_shared_libs}) endif() - if (onnxruntime_USE_OPENMP) - list(APPEND onnxruntime_mlas_test_libs OpenMP::OpenMP_CXX) - endif() list(APPEND onnxruntime_mlas_test_libs Threads::Threads) target_link_libraries(onnxruntime_mlas_test PRIVATE ${onnxruntime_mlas_test_libs}) if(WIN32) diff --git a/include/onnxruntime/core/common/denormal.h b/include/onnxruntime/core/common/denormal.h index baac1093ef..ca94411781 100644 --- a/include/onnxruntime/core/common/denormal.h +++ b/include/onnxruntime/core/common/denormal.h @@ -9,9 +9,4 @@ namespace onnxruntime { // Return true if SSE3 instruction is supported, otherwise return false. bool SetDenormalAsZero(bool on); -#ifdef _OPENMP -// Set flush-to-zero and denormal-as-zero on OpenMP threads when on is true. -void InitializeWithDenormalAsZero(bool on); -#endif - } // namespace onnxruntime diff --git a/include/onnxruntime/core/platform/threadpool.h b/include/onnxruntime/core/platform/threadpool.h index 39110eb10c..4fed0c3bed 100644 --- a/include/onnxruntime/core/platform/threadpool.h +++ b/include/onnxruntime/core/platform/threadpool.h @@ -210,9 +210,7 @@ class ThreadPool { // point to avoid a dependence on the Eigen headers. std::unique_ptr ps_{nullptr, [](ThreadPoolParallelSection*){}}; -#ifndef _OPENMP ThreadPool *tp_; -#endif ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(ParallelSection); // Non-owning reference to the current thread's paralel section @@ -260,13 +258,6 @@ class ThreadPool { inline static void TrySimpleParallelFor(ThreadPool* tp, std::ptrdiff_t total, const std::function& fn) { -#ifdef _OPENMP - ORT_UNUSED_PARAMETER(tp); -#pragma omp parallel for - for (std::ptrdiff_t i = 0; i < total; ++i) { - fn(i); - } -#else if (tp != nullptr) { tp->SimpleParallelFor(total, fn); } else { @@ -275,7 +266,6 @@ class ThreadPool { fn(i); } } -#endif } /** @@ -290,14 +280,6 @@ class ThreadPool { **/ template inline static void TryBatchParallelFor(ThreadPool* tp, std::ptrdiff_t total, F&& fn, std::ptrdiff_t num_batches) { -#ifdef _OPENMP - ORT_UNUSED_PARAMETER(tp); - ORT_UNUSED_PARAMETER(num_batches); -#pragma omp parallel for - for (std::ptrdiff_t i = 0; i < total; ++i) { - fn(i); - } -#else if (tp == nullptr) { for (std::ptrdiff_t i = 0; i < total; ++i) { // In many cases, fn can be inlined here. @@ -330,7 +312,6 @@ class ThreadPool { fn(i); } }); -#endif } struct WorkInfo { diff --git a/onnxruntime/contrib_ops/cpu/maxpool_with_mask.h b/onnxruntime/contrib_ops/cpu/maxpool_with_mask.h index acd8b9f3fc..0d3ae02b1f 100644 --- a/onnxruntime/contrib_ops/cpu/maxpool_with_mask.h +++ b/onnxruntime/contrib_ops/cpu/maxpool_with_mask.h @@ -34,9 +34,6 @@ struct MaxpoolWithMask1DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -84,9 +81,6 @@ struct MaxpoolWithMask2DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -147,9 +141,6 @@ struct MaxpoolWithMask3DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -193,12 +184,7 @@ struct MaxpoolWithMask3DTask final { }; template inline static void RunMaxpoolLoop(concurrency::ThreadPool* tp, std::ptrdiff_t total_channels, T&& task) { -#ifdef _OPENMP - ORT_UNUSED_PARAMETER(tp); - task(0, total_channels); -#else concurrency::ThreadPool::TryParallelFor(tp, total_channels, task.Cost(), task); -#endif } class MaxpoolWithMask : public OpKernel, public PoolBase { public: diff --git a/onnxruntime/core/common/denormal.cc b/onnxruntime/core/common/denormal.cc index 7f1c40957f..d1998fc960 100644 --- a/onnxruntime/core/common/denormal.cc +++ b/onnxruntime/core/common/denormal.cc @@ -42,31 +42,5 @@ bool SetDenormalAsZero(bool on) { return false; } -#ifdef _OPENMP -// To execute an initialization for each openmp thread, use a property of the firstprivate clause: -// "the initialization or construction of the given variable happens as if it were done once per thread, -// prior to the thread's execution of the construct". -class DenormalAsZeroInitializer { - public: - explicit DenormalAsZeroInitializer(bool on) : on_(on) {} - - // Working as initializer per each openmp thread. - DenormalAsZeroInitializer(const DenormalAsZeroInitializer& init) : on_(init.on_) { - SetDenormalAsZero(on_); - } - - private: - bool on_; -}; - -void InitializeWithDenormalAsZero(bool on) { - DenormalAsZeroInitializer init(on); -// Each openmp thread calls DenormalAsZeroInitializer's copy constructor by firstprivate. -// Even if loop count is less than the maximum number of openmp threads, all openmp threads are initialized here. -#pragma omp parallel for firstprivate(init) - for (auto i = 0; i < 1; ++i) { - } -} -#endif } // namespace onnxruntime diff --git a/onnxruntime/core/common/threadpool.cc b/onnxruntime/core/common/threadpool.cc index 85bd859e57..eb709dcadc 100644 --- a/onnxruntime/core/common/threadpool.cc +++ b/onnxruntime/core/common/threadpool.cc @@ -250,9 +250,7 @@ std::string ThreadPoolProfiler::DumpChildThreadStat() { static constexpr int CACHE_LINE_BYTES = 64; static constexpr unsigned MAX_SHARDS = 8; -#ifndef _OPENMP static constexpr int TaskGranularityFactor = 4; -#endif struct alignas(CACHE_LINE_BYTES) LoopCounterShard { ::std::atomic _next{0}; @@ -460,10 +458,6 @@ std::string ThreadPool::StopProfiling() { thread_local ThreadPool::ParallelSection* ThreadPool::ParallelSection::current_parallel_section{nullptr}; ThreadPool::ParallelSection::ParallelSection(ThreadPool* tp) { -#ifdef _OPENMP - // Nothing - ORT_UNUSED_PARAMETER(tp); -#else ORT_ENFORCE(!current_parallel_section, "Nested parallelism not supported"); ORT_ENFORCE(!ps_.get()); tp_ = tp; @@ -472,19 +466,14 @@ ThreadPool::ParallelSection::ParallelSection(ThreadPool* tp) { tp_->underlying_threadpool_->StartParallelSection(*ps_.get()); current_parallel_section = this; } -#endif } ThreadPool::ParallelSection::~ParallelSection() { -#ifdef _OPENMP - // Nothing -#else if (current_parallel_section) { tp_->underlying_threadpool_->EndParallelSection(*ps_.get()); ps_.reset(); current_parallel_section = nullptr; } -#endif } void ThreadPool::RunInParallel(std::function fn, unsigned n, std::ptrdiff_t block_size) { @@ -608,14 +597,6 @@ bool ThreadPool::ShouldParallelize(const concurrency::ThreadPool* tp) { } int ThreadPool::DegreeOfParallelism(const concurrency::ThreadPool* tp) { -#ifdef _OPENMP - // When using OpenMP, omp_get_num_threads() returns the number of threads in the - // current parallel region. Hence if this is 1 then we aim to parallelise - // across the number of threads configured. Otherwise, given that we do not - // use nested parallelism, we do not parallelise further. - ORT_UNUSED_PARAMETER(tp); - return (omp_get_num_threads() == 1) ? omp_get_max_threads() : 1; -#else // When not using OpenMP, we parallelise over the N threads created by the pool // tp, plus 1 for the thread entering a loop. if (tp) { @@ -627,7 +608,6 @@ int ThreadPool::DegreeOfParallelism(const concurrency::ThreadPool* tp) { } else { return 1; } -#endif } void ThreadPool::StartProfiling(concurrency::ThreadPool* tp) { @@ -665,50 +645,11 @@ int ThreadPool::CurrentThreadId() const { void ThreadPool::TryParallelFor(concurrency::ThreadPool* tp, std::ptrdiff_t total, const TensorOpCost& cost_per_unit, const std::function& fn) { -#ifdef _OPENMP - ORT_ENFORCE(total >= 0); - if (total == 0) { - return; - } - - if (total == 1) { - fn(0, 1); - return; - } - - Eigen::TensorOpCost cost{cost_per_unit.bytes_loaded, cost_per_unit.bytes_stored, cost_per_unit.compute_cycles}; - auto d_of_p = DegreeOfParallelism(tp); - std::ptrdiff_t num_threads = CostModel::numThreads(static_cast(total), cost, d_of_p); - - if (total < num_threads) { - num_threads = total; - } - - if (num_threads == 1) { - fn(0, total); - return; - } - - ptrdiff_t block_size = CalculateParallelForBlock(total, cost, nullptr, d_of_p); - ptrdiff_t block_count = Eigen::divup(total, block_size); - - if (block_count == 1) { - fn(0, total); - return; - } - -#pragma omp parallel for schedule(dynamic, 1) - for (std::ptrdiff_t i = 0; i < block_count; i++) { - const auto start = i * block_size; - fn(start, std::min(start + block_size, total)); - } -#else //!_OPENMP if (tp == nullptr) { fn(0, total); return; } tp->ParallelFor(total, cost_per_unit, fn); -#endif } } // namespace concurrency diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h index e3f224503c..50ad470710 100644 --- a/onnxruntime/core/mlas/lib/mlasi.h +++ b/onnxruntime/core/mlas/lib/mlasi.h @@ -137,10 +137,6 @@ using MLAS_CPUIDINFO = MLASCPUIDInfo; #endif // BUILD_MLAS_NO_ONNXRUNTIME -#if defined(_OPENMP) -#include -#endif - // // Define the maximum number of threads supported by this implementation. // @@ -888,12 +884,7 @@ MlasGetMaximumThreadCount( { #if defined(BUILD_MLAS_NO_ONNXRUNTIME) MLAS_UNREFERENCED_PARAMETER(ThreadPool); - -#if defined(_OPENMP) - return (omp_get_num_threads() == 1) ? omp_get_max_threads() : 1; -#else return 1; -#endif #else return onnxruntime::concurrency::ThreadPool::DegreeOfParallelism(ThreadPool); #endif diff --git a/onnxruntime/core/mlas/lib/pooling.cpp b/onnxruntime/core/mlas/lib/pooling.cpp index 5abe594685..5655435581 100644 --- a/onnxruntime/core/mlas/lib/pooling.cpp +++ b/onnxruntime/core/mlas/lib/pooling.cpp @@ -1280,19 +1280,8 @@ Return Value: // Execute the pooling kernel routine. // -#if defined(_OPENMP) - -#pragma omp parallel for - for (int64_t c = 0; c < int64_t(TotalChannelCount); c++) { - PoolKernelRoutine(&WorkBlock, 1, Input + c * InputSize, Output + c * OutputSize); - } - -#else - MLAS_UNREFERENCED_PARAMETER(OutputSize); PoolKernelRoutine(&WorkBlock, TotalChannelCount, Input, Output); - -#endif #else // // Use an external thread pool if one is provided. diff --git a/onnxruntime/core/mlas/lib/threading.cpp b/onnxruntime/core/mlas/lib/threading.cpp index 317101d8c0..ecdc5250eb 100644 --- a/onnxruntime/core/mlas/lib/threading.cpp +++ b/onnxruntime/core/mlas/lib/threading.cpp @@ -43,9 +43,6 @@ MlasExecuteThreaded( // // Execute the routine for the specified number of iterations. // -#ifdef _OPENMP -#pragma omp parallel for -#endif for (ptrdiff_t tid = 0; tid < Iterations; tid++) { ThreadedRoutine(Context, tid); } @@ -85,10 +82,6 @@ MlasTrySimpleParallel( // // Execute the routine for the specified number of iterations. // -#ifdef _OPENMP -#pragma omp parallel for -#endif - for (ptrdiff_t tid = 0; tid < Iterations; tid++) { Work(tid); } diff --git a/onnxruntime/core/providers/cpu/nn/pool_functors.h b/onnxruntime/core/providers/cpu/nn/pool_functors.h index a02189ad0d..16d3da07a1 100644 --- a/onnxruntime/core/providers/cpu/nn/pool_functors.h +++ b/onnxruntime/core/providers/cpu/nn/pool_functors.h @@ -25,9 +25,6 @@ struct Pool1DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -77,9 +74,6 @@ struct Pool2DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -143,9 +137,6 @@ struct Pool3DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -208,9 +199,6 @@ struct MaxPool1DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -264,9 +252,6 @@ struct MaxPool2DTask final { } void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } @@ -333,9 +318,6 @@ struct MaxPool3DTask { int64_t storage_order; void operator()(std::ptrdiff_t begin, std::ptrdiff_t end) const { -#ifdef _OPENMP -#pragma omp parallel for -#endif for (int64_t c = begin; c < end; ++c) { operator()(c); } diff --git a/onnxruntime/core/providers/dnnl/dnnl_provider_factory.cc b/onnxruntime/core/providers/dnnl/dnnl_provider_factory.cc index 0cf1f56f50..a56c49b01f 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_provider_factory.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_provider_factory.cc @@ -29,7 +29,7 @@ std::unique_ptr DnnlProviderFactory::CreateProvider() { struct Dnnl_Provider : Provider { std::shared_ptr CreateExecutionProviderFactory(int use_arena) override { -#if defined(_WIN32) && !defined(_OPENMP) +#if defined(_WIN32) { // We crash when unloading DNNL on Windows when OpenMP also unloads (As there are threads // still running code inside the openmp runtime DLL if OMP_WAIT_POLICY is set to ACTIVE). diff --git a/onnxruntime/core/providers/nuphar/common/nuphar_settings.cc b/onnxruntime/core/providers/nuphar/common/nuphar_settings.cc index 672875bddb..af5812df8c 100644 --- a/onnxruntime/core/providers/nuphar/common/nuphar_settings.cc +++ b/onnxruntime/core/providers/nuphar/common/nuphar_settings.cc @@ -58,17 +58,10 @@ void SetDefaultOptions(std::map& options) { options.insert(std::make_pair(cache_so_name_opt, cache_so_name_default)); std::string parallel_min_workloads_opt(kNupharParallelMinWorkloads); -#if defined(_OPENMP) - // a rough estimate of workloads based on static dimensions for each thread, when using parallel schedule - // user may change it to 0 to turn it off, - // or use OMP_NUM_THREADS to control TVM thread pool similar to control MKL - unsigned int parallel_min_workloads_default = 64; -#else // turn off parallel schedule by default to avoid TVM thread pool confliction with others // this is to ensure performance when user runs multiple inference threads, with each runs as single thread // if needed, user can override it with settings, and use TVM_NUM_THREADS to control the thread pool unsigned int parallel_min_workloads_default = 0; -#endif options.insert(std::make_pair(parallel_min_workloads_opt, std::to_string(parallel_min_workloads_default))); } diff --git a/onnxruntime/core/session/abi_session_options.cc b/onnxruntime/core/session/abi_session_options.cc index 678bfb67e0..e5cb9fa176 100644 --- a/onnxruntime/core/session/abi_session_options.cc +++ b/onnxruntime/core/session/abi_session_options.cc @@ -141,18 +141,7 @@ ORT_API_STATUS_IMPL(OrtApis::SetSessionGraphOptimizationLevel, _In_ OrtSessionOp } ORT_API_STATUS_IMPL(OrtApis::SetIntraOpNumThreads, _Inout_ OrtSessionOptions* options, int intra_op_num_threads) { -#ifdef _OPENMP - ORT_UNUSED_PARAMETER(options); - ORT_UNUSED_PARAMETER(intra_op_num_threads); - // Can't use the default logger here since it's possible that the default logger has not been created - // at this point. The default logger gets created when the env is created and these APIs don't require - // the env to be created first. - std::cout << "WARNING: Since openmp is enabled in this build, this API cannot be used to configure" - " intra op num threads. Please use the openmp environment variables to control" - " the number of threads.\n"; -#else options->value.intra_op_param.thread_pool_size = intra_op_num_threads; -#endif return nullptr; } diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 3b33d2475c..1c899c626f 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -265,9 +265,6 @@ void InferenceSession::ConstructorCommon(const SessionOptions& session_options, static std::once_flag once; std::call_once(once, [&] { -#ifdef _OPENMP - InitializeWithDenormalAsZero(set_denormal_as_zero); -#endif SetDenormalAsZero(set_denormal_as_zero); LOGS(*session_logger_, INFO) << "Flush-to-zero and denormal-as-zero are " << ((set_denormal_as_zero) ? "on" : "off"); diff --git a/onnxruntime/core/util/thread_utils.cc b/onnxruntime/core/util/thread_utils.cc index ab87422cd6..4446c2f7a4 100644 --- a/onnxruntime/core/util/thread_utils.cc +++ b/onnxruntime/core/util/thread_utils.cc @@ -45,18 +45,8 @@ CreateThreadPool(Env* env, OrtThreadPoolParams options, ThreadPoolType tpool_typ // If openmp is enabled we don't want to create any additional threadpools for sequential execution. // However, parallel execution relies on the existence of a separate threadpool. Hence we allow eigen threadpools // to be created for parallel execution. -#ifdef _OPENMP - ORT_UNUSED_PARAMETER(env); - ORT_UNUSED_PARAMETER(options); - if (tpool_type != ThreadPoolType::INTER_OP) { - return nullptr; - } else { - return CreateThreadPoolHelper(env, options); - } -#else ORT_UNUSED_PARAMETER(tpool_type); return CreateThreadPoolHelper(env, options); -#endif } } // namespace concurrency diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index fb286e2ad2..f5f4a3c75f 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -35,12 +35,6 @@ struct OrtStatus { #define BACKEND_PROC "CPU" #endif -#if _OPENMP -#define BACKEND_OPENMP "-OPENMP" -#else -#define BACKEND_OPENMP "" -#endif - #if USE_DNNL #define BACKEND_DNNL "-DNNL" #else diff --git a/onnxruntime/test/api_tests_without_env/test_apis_without_env.cc b/onnxruntime/test/api_tests_without_env/test_apis_without_env.cc index 5a32bed79a..fc0cf08767 100644 --- a/onnxruntime/test/api_tests_without_env/test_apis_without_env.cc +++ b/onnxruntime/test/api_tests_without_env/test_apis_without_env.cc @@ -21,11 +21,7 @@ TEST(TestSessionOptions, SetIntraOpNumThreadsWithoutEnv) { Ort::SessionOptions session_options; session_options.SetIntraOpNumThreads(48); const auto* ort_session_options = (const OrtSessionOptions*)session_options; -#ifdef _OPENMP - ASSERT_EQ(ort_session_options->value.intra_op_param.thread_pool_size, 0); -#else ASSERT_EQ(ort_session_options->value.intra_op_param.thread_pool_size, 48); -#endif } int main(int argc, char** argv) { diff --git a/onnxruntime/test/common/denormal_test.cc b/onnxruntime/test/common/denormal_test.cc index 40730eb15c..dfc6933656 100644 --- a/onnxruntime/test/common/denormal_test.cc +++ b/onnxruntime/test/common/denormal_test.cc @@ -35,43 +35,5 @@ TEST(DenormalTest, DenormalAsZeroTest) { test_denormal(false); } -#ifdef _OPENMP -TEST(DenormalTest, OpenMPDenormalAsZeroTest) { - auto test_denormal = [&](bool set_denormal_as_zero) { - const float denormal_float = 1e-38f; - const double denormal_double = 1e-308; - const int test_size = 4; - - std::array input_float; - std::array input_double; - - // When it returns false, disabling denormal as zero isn't supported, - // so validation will be skipped - bool set = SetDenormalAsZero(set_denormal_as_zero); - if (set || !set_denormal_as_zero) { - input_float.fill(denormal_float); - input_double.fill(denormal_double); - - InitializeWithDenormalAsZero(set_denormal_as_zero); -#pragma omp parallel for - for (auto i = 0; i < test_size; ++i) { - input_float[i] *= 2; - input_double[i] *= 2; - } - - std::for_each(input_float.begin(), input_float.end(), [&](float f) { - EXPECT_EQ(f, (set_denormal_as_zero) ? 0.0f : denormal_float * 2); - }); - std::for_each(input_double.begin(), input_double.end(), [&](double d) { - EXPECT_EQ(d, (set_denormal_as_zero) ? 0.0 : denormal_double * 2); - }); - } - }; - - test_denormal(true); - test_denormal(false); -} -#endif - } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/framework/inference_session_test.cc b/onnxruntime/test/framework/inference_session_test.cc index 4f1e831020..7a12cdb9ce 100644 --- a/onnxruntime/test/framework/inference_session_test.cc +++ b/onnxruntime/test/framework/inference_session_test.cc @@ -2792,9 +2792,6 @@ TEST(InferenceSessionTests, GlobalThreadPoolWithDenormalAsZero) { // Since only the first session option for flush-to-zero and denormal-as-zero are effective, // set them manually here for a test. -#ifdef _OPENMP - InitializeWithDenormalAsZero(true); -#endif SetDenormalAsZero(true); InferenceSessionTestGlobalThreadPools session{so, *env}; @@ -2806,15 +2803,10 @@ TEST(InferenceSessionTests, GlobalThreadPoolWithDenormalAsZero) { run_options.run_log_severity_level = static_cast(Severity::kVERBOSE); RunModelWithDenormalAsZero(session, run_options, true); -#ifndef _OPENMP VerifyThreadPoolWithDenormalAsZero(env->GetIntraOpThreadPool(), true); -#endif VerifyThreadPoolWithDenormalAsZero(env->GetInterOpThreadPool(), true); // Set back to default. -#ifdef _OPENMP - InitializeWithDenormalAsZero(false); -#endif SetDenormalAsZero(false); } @@ -2842,9 +2834,6 @@ TEST(InferenceSessionTests, InterThreadPoolWithDenormalAsZero) { // Since only the first session option for flush-to-zero and denormal-as-zero are effective, // set them manually here for a test. -#ifdef _OPENMP - InitializeWithDenormalAsZero(true); -#endif SetDenormalAsZero(true); InferenceSessionTestGlobalThreadPools session1{so, *env}; @@ -2856,9 +2845,7 @@ TEST(InferenceSessionTests, InterThreadPoolWithDenormalAsZero) { run_options.run_log_severity_level = static_cast(Severity::kVERBOSE); RunModelWithDenormalAsZero(session1, run_options, true); -#ifndef _OPENMP VerifyThreadPoolWithDenormalAsZero(session1.GetIntraOpThreadPoolToUse(), true); -#endif VerifyThreadPoolWithDenormalAsZero(session1.GetInterOpThreadPoolToUse(), true); // inference session without denormal as zero. @@ -2866,9 +2853,6 @@ TEST(InferenceSessionTests, InterThreadPoolWithDenormalAsZero) { // Since only the first session option for flush-to-zero and denormal-as-zero are effective, // set them manually here for a test. -#ifdef _OPENMP - InitializeWithDenormalAsZero(false); -#endif SetDenormalAsZero(false); InferenceSessionTestGlobalThreadPools session2{so, *env}; @@ -2878,9 +2862,7 @@ TEST(InferenceSessionTests, InterThreadPoolWithDenormalAsZero) { // Since it's parallel, it runs on threads. RunModelWithDenormalAsZero(session2, run_options, false); -#ifndef _OPENMP VerifyThreadPoolWithDenormalAsZero(session2.GetIntraOpThreadPoolToUse(), false); -#endif VerifyThreadPoolWithDenormalAsZero(session2.GetInterOpThreadPoolToUse(), false); } diff --git a/onnxruntime/test/global_thread_pools/test_main.cc b/onnxruntime/test/global_thread_pools/test_main.cc index 6b39abfa55..82677e99b0 100644 --- a/onnxruntime/test/global_thread_pools/test_main.cc +++ b/onnxruntime/test/global_thread_pools/test_main.cc @@ -101,12 +101,6 @@ int main(int argc, char** argv) { //TODO: Fix the C API issue ort_env.reset(); //If we don't do this, it will crash -#ifndef _OPENMP - const int expexted_custom_calls = (thread_pool_size - 1) << 1; - ORT_ENFORCE(custom_creation_hook_called == expexted_custom_calls, "custom thread creation function was not called as expected"); - ORT_ENFORCE(custom_join_hook_called == expexted_custom_calls, "custom thread join function was not called as expected"); -#endif - #ifndef USE_ONNXRUNTIME_DLL //make memory leak checker happy ::google::protobuf::ShutdownProtobufLibrary(); diff --git a/onnxruntime/test/providers/cpu/model_tests.cc b/onnxruntime/test/providers/cpu/model_tests.cc index 85a5a9275c..fbdb421e5f 100644 --- a/onnxruntime/test/providers/cpu/model_tests.cc +++ b/onnxruntime/test/providers/cpu/model_tests.cc @@ -558,26 +558,22 @@ TEST_P(ModelTest, Run) { if (provider_name == "cpu" && !is_single_node) execution_modes.push_back(ExecutionMode::ORT_PARALLEL); -#ifndef _OPENMP std::vector use_single_thread{false}; // Test the model with intra op threadpool disabled if (provider_name == "cpu" && is_single_node) use_single_thread.push_back(true); -#endif + std::unique_ptr l = CreateOnnxTestCase(ToMBString(test_case_name), std::move(model_info), per_sample_tolerance, relative_per_sample_tolerance); -#ifndef _OPENMP + for (bool is_single_thread : use_single_thread) { -#endif for (ExecutionMode execution_mode : execution_modes) { SessionOptions so; -#ifndef _OPENMP if (!is_single_thread) so.use_per_session_threads = false; else so.intra_op_param.thread_pool_size = 1; // Disable intra op thread pool -#endif so.execution_mode = execution_mode; so.session_logid = ToMBString(test_case_name); so.session_log_severity_level = (int)logging::Severity::kERROR; @@ -708,9 +704,7 @@ TEST_P(ModelTest, Run) { } } } -#ifndef _OPENMP } -#endif } // TODO: all providers diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index f5167e1089..70878c53d3 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -1844,7 +1844,6 @@ TEST(CApiTest, TestConfigureTensorRTProviderOptions) { } #endif -#ifndef _OPENMP namespace TestPerSessionCustomThreadHooks { std::vector threads; @@ -1926,4 +1925,4 @@ TEST(CApiTest, crop_and_resize) { #endif } // namespace TestPerSessionCustomThreadHooks -#endif + diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 8ef9038e19..0c84ef93d9 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -1691,7 +1691,7 @@ def nuphar_run_python_tests(build_dir, configs): def run_nodejs_tests(nodejs_binding_dir): - args = ['npm', 'test', '--', '--timeout=10000'] + args = ['npm', 'test', '--', '--timeout=30000'] if is_windows(): args = ['cmd', '/c'] + args run_subprocess(args, cwd=nodejs_binding_dir) diff --git a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml index 32a0552932..84002ad381 100644 --- a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml +++ b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml @@ -41,7 +41,7 @@ parameters: - name: BuildVariant type: string - default: 'openmp' + default: 'default' jobs: - job: Linux_C_API_Packaging_CPU_x64 diff --git a/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml b/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml index 3e952d1fd6..8189eda2cc 100644 --- a/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml @@ -2,9 +2,6 @@ parameters: - name: BuildConfig type: string -- name: UseOmp - type: string - - name: EnvSetupScript type: string @@ -121,7 +118,7 @@ jobs: displayName: 'Generate cmake config' inputs: scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' - arguments: '--config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) ${{ parameters.UseOmp }} --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }}' + arguments: '--config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }}' workingDirectory: '$(Build.BinariesDirectory)' - task: VSBuild@1 @@ -183,7 +180,7 @@ jobs: - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: - powershell: | - python $(Build.SourcesDirectory)\tools\ci_build\build.py --config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) ${{ parameters.UseOmp }} --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} + python $(Build.SourcesDirectory)\tools\ci_build\build.py --config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' displayName: 'Run tests' diff --git a/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml b/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml new file mode 100644 index 0000000000..e919400234 --- /dev/null +++ b/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml @@ -0,0 +1,257 @@ +parameters: +- name: BuildConfig + type: string + +- name: EnvSetupScript + type: string + +- name: job_name_suffix + type: string + +- name: buildArch + type: string + +- name: additionalBuildFlags + type: string + +- name: msbuildPlatform + type: string + +- name: isX86 + type: boolean + default: false + +- name: EnablePython + type: boolean + default: true + +- name: RunOnnxRuntimeTests + displayName: Run Tests? + type: boolean + default: true + +- name: RunStaticCodeAnalysis + displayName: Run Static Code Analysis + type: boolean + default: true + +- name: ORT_EP_NAME + type: string + +- name: DocUpdateNeeded + displayName: Run Tests? + type: boolean + default: false + +jobs: +- job: build_${{ parameters.job_name_suffix }} + variables: + OrtPackageId: 'Microsoft.ML.OnnxRuntime' + OnnxRuntimeBuildDirectory: '$(Build.BinariesDirectory)' + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + setVcvars: true + ALLOW_RELEASED_ONNX_OPSET_ONLY: '0' + DocUpdateNeeded: ${{ parameters.DocUpdateNeeded }} + workspace: + clean: all + pool: 'Win-GPU-2019' + timeoutInMinutes: 300 + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.7' + addToPath: true + architecture: ${{ parameters.buildArch }} + + - task: NodeTool@0 + inputs: + versionSpec: '12.x' + force32bit: ${{ parameters.isX86 }} + + # Our build machine doesn't have java x86 + - ${{ if eq(parameters.buildArch, 'x64') }}: + - task: JavaToolInstaller@0 + inputs: + versionSpec: '11' + jdkArchitectureOption: ${{ parameters.buildArch }} + jdkSourceOption: 'PreInstalled' + + - task: BatchScript@1 + displayName: 'setup env' + inputs: + filename: '$(Build.SourcesDirectory)\tools\ci_build\github\windows\${{ parameters.EnvSetupScript }}' + modifyEnvironment: true + workingFolder: '$(Build.BinariesDirectory)' + + - script: | + set ORT_DOXY_SRC=$(Build.SourcesDirectory) + set ORT_DOXY_OUT=$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }} + mkdir %ORT_DOXY_SRC% + mkdir %ORT_DOXY_OUT% + "C:\Program Files\doxygen\bin\doxygen.exe" $(Build.SourcesDirectory)\tools\ci_build\github\Doxyfile_csharp.cfg + + workingDirectory: '$(Build.SourcesDirectory)' + displayName: 'API Documentation Check and generate' + + - script: | + python -m pip install -q setuptools wheel numpy + workingDirectory: '$(Build.BinariesDirectory)' + displayName: 'Install python modules' + + - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: + - powershell: | + $Env:USE_MSVC_STATIC_RUNTIME=1 + $Env:ONNX_ML=1 + $Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{ parameters.buildArch }}-windows-static" + python setup.py bdist_wheel + python -m pip uninstall -y onnx -qq + Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} + workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx' + displayName: 'Install ONNX' + + - task: NuGetToolInstaller@0 + displayName: Use Nuget 5.7.0 + inputs: + versionSpec: 5.7.0 + + - task: NuGetCommand@2 + displayName: 'NuGet restore' + inputs: + command: 'restore' + feedsToUse: 'config' + restoreSolution: '$(Build.SourcesDirectory)\packages.config' + nugetConfigPath: '$(Build.SourcesDirectory)\NuGet.config' + restoreDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}' + + - task: PythonScript@0 + displayName: 'Generate cmake config' + inputs: + scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' + arguments: '--config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }}' + workingDirectory: '$(Build.BinariesDirectory)' + + - task: VSBuild@1 + displayName: 'Build' + inputs: + solution: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\onnxruntime.sln' + platform: ${{ parameters.msbuildPlatform }} + configuration: ${{ parameters.BuildConfig }} + msbuildArgs: -maxcpucount + msbuildArchitecture: ${{ parameters.buildArch }} + maximumCpuCount: true + logProjectEvents: false + workingFolder: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}' + createLogFile: true + + - ${{ if eq(parameters.EnablePython, true) }}: + - task: PythonScript@0 + displayName: 'Build wheel' + inputs: + scriptPath: '$(Build.SourcesDirectory)\setup.py' + arguments: 'bdist_wheel' + workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' + + - task: MSBuild@1 + displayName: 'Restore NuGet Packages' + inputs: + solution: '$(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.sln' + platform: 'Any CPU' + configuration: '${{ parameters.BuildConfig }}' + msbuildArguments: '-t:restore -p:OrtPackageId=$(OrtPackageId)' + workingDirectory: '$(Build.SourcesDirectory)\csharp' + + - task: MSBuild@1 + displayName: 'Build C#' + inputs: + solution: '$(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.sln' + configuration: '${{ parameters.BuildConfig }}' + platform: 'Any CPU' + msbuildArguments: '-p:OnnxRuntimeBuildDirectory="$(Build.BinariesDirectory)" -p:OrtPackageId=$(OrtPackageId) -p:DefineConstants=USE_${{ parameters.ORT_EP_NAME }}' + workingDirectory: '$(Build.SourcesDirectory)\csharp' + + + - ${{ if and(eq(parameters.BuildConfig, 'RelWithDebInfo'), eq(parameters.RunOnnxRuntimeTests, true)) }}: + - task: DotNetCoreCLI@2 + displayName: 'Test C#' + inputs: + command: test + projects: '$(Build.SourcesDirectory)\csharp\test\Microsoft.ML.OnnxRuntime.Tests.NetCoreApp\Microsoft.ML.OnnxRuntime.Tests.NetCoreApp.csproj' + configuration: '${{ parameters.BuildConfig }}' + arguments: '--configuration ${{ parameters.BuildConfig }} -p:Platform="Any CPU" -p:OnnxRuntimeBuildDirectory="$(Build.BinariesDirectory)" -p:OrtPackageId=$(OrtPackageId) -p:DefineConstants=USE_${{ parameters.ORT_EP_NAME }} --blame' + workingDirectory: '$(Build.SourcesDirectory)\csharp' + + - ${{ if eq(parameters.EnablePython, true) }}: + - powershell: | + Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} + + workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' + displayName: 'Install onnxruntime wheel' + + - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: + - powershell: | + python $(Build.SourcesDirectory)\tools\ci_build\build.py --config ${{ parameters.BuildConfig }} --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} + + workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' + displayName: 'Run tests' + + + - ${{ if eq(parameters.RunStaticCodeAnalysis, true) }}: + - task: DeleteFiles@1 + displayName: 'Delete binaries files from $(Build.BinariesDirectory)\RelWithDebInfo' + inputs: + SourceFolder: '$(Build.BinariesDirectory)\RelWithDebInfo' + Contents: | + **/*.obj + **/*.pdb + **/*.dll + + - task: PythonScript@0 + displayName: 'Generate cmake config' + inputs: + scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' + arguments: '--config Debug --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} onnxruntime_ENABLE_STATIC_ANALYSIS=ON' + workingDirectory: '$(Build.BinariesDirectory)' + + + - task: VSBuild@1 + displayName: 'Build' + inputs: + solution: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\onnxruntime.sln' + platform: ${{ parameters.msbuildPlatform }} + configuration: ${{ parameters.BuildConfig }} + msbuildArgs: /m /p:CAExcludePath="$(Build.BinariesDirectory);$(Build.SourcesDirectory)\cmake;C:\program files (x86)" /p:PreferredToolArchitecture=x64 + msbuildArchitecture: ${{ parameters.buildArch }} + maximumCpuCount: true + logProjectEvents: false + workingFolder: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}' + createLogFile: true + + + - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: + - task: PublishTestResults@2 + displayName: 'Publish unit test results' + inputs: + testResultsFiles: '**/*.results.xml' + searchFolder: '$(Build.BinariesDirectory)/${{ parameters.BuildConfig }}' + testRunTitle: 'Unit Test Run' + condition: succeededOrFailed() + + # if the validation from --gen_doc failed it sets a variable so we can publish the latest version of the docs + # as an artifact, allowing a developer to download this and replace the current version instead of having to build + # and generate the docs locally themselves. handle each of the two md files separately - simpler than copying + # them to another location and publishing from there in a single task. + - task: PublishBuildArtifacts@1 + condition: and(failed(), eq(variables['DocUpdateNeeded'], 'true')) + inputs: + pathtoPublish: '$(Build.SourcesDirectory)/docs/OperatorKernels.md' + artifactName: 'OperatorKernels.md' + + - task: PublishBuildArtifacts@1 + condition: and(failed(), eq(variables['DocUpdateNeeded'], 'true')) + inputs: + pathtoPublish: '$(Build.SourcesDirectory)/docs/ContribOperators.md' + artifactName: 'ContribOperators.md' + + - template: component-governance-component-detection-steps.yml + parameters : + condition : 'succeeded' diff --git a/tools/ci_build/github/azure-pipelines/win-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/win-ci-pipeline.yml index d4995bd406..ecfe9f16bb 100644 --- a/tools/ci_build/github/azure-pipelines/win-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/win-ci-pipeline.yml @@ -11,10 +11,9 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'Debug' - UseOmp: '--use_openmp' EnvSetupScript: setup_env.bat buildArch: x64 - additionalBuildFlags: --use_dnnl --build_java --build_nodejs --build_wheel + additionalBuildFlags: --build_java --build_nodejs --build_wheel msbuildPlatform: x64 isX86: false job_name_suffix: x64_debug @@ -27,17 +26,32 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'RelWithDebInfo' - UseOmp: '' EnvSetupScript: setup_env.bat buildArch: x64 - # Compare to our Nuget packaging pipeline, this job has "--build_wheel --use_dnnl" but doesn't have "--enable_lto --disable_rtti --use_telemetry --enable_wcos" - # Python bindings use typeid so I can't disable RTTI here. So we may need to split it to two pipelines - additionalBuildFlags: --build_wheel --use_dnnl --build_java --build_nodejs + # Compare to our Nuget packaging pipeline, this job has "--build_wheel" but doesn't have "--enable_lto --disable_rtti --use_telemetry --enable_wcos" + # Python bindings use typeid so I can't disable RTTI here. If it causes a problem, we will need to split this job to two jobs. + additionalBuildFlags: --build_wheel --build_java --build_nodejs msbuildPlatform: x64 isX86: false job_name_suffix: x64_release RunOnnxRuntimeTests: ${{ parameters.RunOnnxRuntimeTests }} RunStaticCodeAnalysis: true + +- stage: x64_release_dnnl + dependsOn: [] + jobs: + - template: templates/win-cpu-ci.yml + parameters: + BuildConfig: 'RelWithDebInfo' + EnvSetupScript: setup_env.bat + buildArch: x64 + additionalBuildFlags: --build_wheel --use_dnnl --build_java + msbuildPlatform: x64 + isX86: false + job_name_suffix: x64_release + RunOnnxRuntimeTests: ${{ parameters.RunOnnxRuntimeTests }} + RunStaticCodeAnalysis: false + - stage: x64_release_winml dependsOn: [] @@ -45,7 +59,6 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'RelWithDebInfo' - UseOmp: '' EnvSetupScript: setup_env.bat buildArch: x64 additionalBuildFlags: --use_winml --enable_wcos --disable_rtti @@ -63,7 +76,6 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'RelWithDebInfo' - UseOmp: '' EnvSetupScript: setup_env_x86.bat buildArch: x86 additionalBuildFlags: --build_wheel @@ -79,7 +91,6 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'Debug' - UseOmp: '' EnvSetupScript: setup_env.bat buildArch: x64 additionalBuildFlags: --enable_training --build_wheel @@ -95,7 +106,6 @@ stages: - template: templates/win-cpu-ci.yml parameters: BuildConfig: 'RelWithDebInfo' - UseOmp: '' EnvSetupScript: setup_env.bat buildArch: x64 additionalBuildFlags: --enable_training --build_wheel diff --git a/tools/ci_build/github/linux/run_build.sh b/tools/ci_build/github/linux/run_build.sh index 52bcc6db88..599da9fece 100755 --- a/tools/ci_build/github/linux/run_build.sh +++ b/tools/ci_build/github/linux/run_build.sh @@ -35,7 +35,7 @@ if [ $BUILD_OS = "yocto" ]; then cd build . /opt/fsl-imx-xwayland/$YOCTO_FOLDER/environment-setup-aarch64-poky-linux alias cmake="/usr/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$OECORE_NATIVE_SYSROOT/usr/share/cmake/OEToolchainConfig.cmake" - cmake ../cmake -Donnxruntime_RUN_ONNX_TESTS=OFF -Donnxruntime_GENERATE_TEST_REPORTS=ON -Donnxruntime_DEV_MODE=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -Donnxruntime_USE_CUDA=OFF -Donnxruntime_USE_NSYNC=OFF -Donnxruntime_CUDNN_HOME= -Donnxruntime_USE_JEMALLOC=OFF -Donnxruntime_ENABLE_PYTHON=OFF -Donnxruntime_BUILD_CSHARP=OFF -Donnxruntime_USE_EIGEN_FOR_BLAS=ON -Donnxruntime_USE_OPENBLAS=OFF -Donnxruntime_USE_ACL=ON -Donnxruntime_USE_MKLDNN=OFF -Donnxruntime_USE_MKLML=OFF -Donnxruntime_USE_OPENMP=ON -Donnxruntime_USE_TVM=OFF -Donnxruntime_USE_LLVM=OFF -Donnxruntime_ENABLE_MICROSOFT_INTERNAL=OFF -Donnxruntime_USE_NUPHAR=OFF -Donnxruntime_USE_EIGEN_THREADPOOL=OFF -Donnxruntime_BUILD_UNIT_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/opt/fsl-imx-xwayland/$YOCTO_FOLDER/sysroots/aarch64-poky-linux/usr/include -DCMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/opt/fsl-imx-xwayland/$YOCTO_FOLDER/sysroots/aarch64-poky-linux/usr/include -DONNX_CUSTOM_PROTOC_EXECUTABLE=/usr/bin/protoc + cmake ../cmake -Donnxruntime_RUN_ONNX_TESTS=OFF -Donnxruntime_GENERATE_TEST_REPORTS=ON -Donnxruntime_DEV_MODE=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -Donnxruntime_USE_CUDA=OFF -Donnxruntime_USE_NSYNC=OFF -Donnxruntime_CUDNN_HOME= -Donnxruntime_USE_JEMALLOC=OFF -Donnxruntime_ENABLE_PYTHON=OFF -Donnxruntime_BUILD_CSHARP=OFF -Donnxruntime_USE_EIGEN_FOR_BLAS=ON -Donnxruntime_USE_OPENBLAS=OFF -Donnxruntime_USE_ACL=ON -Donnxruntime_USE_MKLDNN=OFF -Donnxruntime_USE_MKLML=OFF -Donnxruntime_USE_TVM=OFF -Donnxruntime_USE_LLVM=OFF -Donnxruntime_ENABLE_MICROSOFT_INTERNAL=OFF -Donnxruntime_USE_NUPHAR=OFF -Donnxruntime_USE_EIGEN_THREADPOOL=OFF -Donnxruntime_BUILD_UNIT_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/opt/fsl-imx-xwayland/$YOCTO_FOLDER/sysroots/aarch64-poky-linux/usr/include -DCMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/opt/fsl-imx-xwayland/$YOCTO_FOLDER/sysroots/aarch64-poky-linux/usr/include -DONNX_CUSTOM_PROTOC_EXECUTABLE=/usr/bin/protoc make -j$(nproc) else From 6cdab0625523d3c800ee60e583ed01818fc989dc Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Wed, 15 Dec 2021 08:22:15 -0800 Subject: [PATCH 047/113] Enable argument files in build.py. (#10040) --- tools/ci_build/build.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 0c84ef93d9..36aaa5da58 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -125,9 +125,14 @@ def _openvino_verify_device_type(device_read): def parse_arguments(): - parser = argparse.ArgumentParser( + class Parser(argparse.ArgumentParser): + # override argument file line parsing behavior - allow multiple arguments per line and handle quotes + def convert_arg_line_to_args(self, arg_line): + return shlex.split(arg_line) + + parser = Parser( description="ONNXRuntime CI build driver.", - usage=""" # noqa + usage=""" Default behavior is --update --build --test for native architecture builds. Default behavior is --update --build for cross-compiled builds. @@ -136,7 +141,10 @@ def parse_arguments(): The Test phase will run all unit tests, and optionally the ONNX tests. Use the individual flags to only run the specified stages. - """) + """, + # files containing arguments can be specified on the command line with "@" and the arguments within + # will be included at that point + fromfile_prefix_chars="@") # Main arguments parser.add_argument( "--build_dir", required=True, help="Path to the build directory.") From ee975de77b547554c99788e30a1779ebc03d6c8c Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Wed, 15 Dec 2021 15:45:04 -0800 Subject: [PATCH 048/113] reorganize quantization files (#10023) * reorganize quantization files --- .../contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc | 2 +- .../contrib_ops/cpu/{ => quantization}/matmul_integer16.cc | 2 +- .../contrib_ops/cpu/{ => quantization}/matmul_integer16.h | 0 .../cpu/{bert => quantization}/qembed_layer_norm.cc | 2 +- .../cpu/{bert => quantization}/qembed_layer_norm.h | 2 +- .../contrib_ops/cpu/{ => quantization}/qlinear_activations.cc | 2 +- .../contrib_ops/cpu/{ => quantization}/qlinear_activations.h | 0 .../contrib_ops/cpu/{ => quantization}/qlinear_binary_op.cc | 0 .../contrib_ops/cpu/{ => quantization}/qlinear_binary_op.h | 0 .../contrib_ops/cpu/{ => quantization}/qlinear_concat.cc | 3 ++- .../contrib_ops/cpu/{ => quantization}/qlinear_concat.h | 0 .../cpu/{ => quantization}/qlinear_global_average_pool.cc | 0 .../cpu/{ => quantization}/qlinear_global_average_pool.h | 0 .../cpu/{ => quantization}/qlinear_lookup_table.cc | 0 .../contrib_ops/cpu/{ => quantization}/qlinear_lookup_table.h | 0 .../contrib_ops/cpu/{ => quantization}/qlinear_pool.cc | 4 ++-- onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_pool.h | 0 onnxruntime/contrib_ops/cpu/quantization/quant_gemm.cc | 2 +- onnxruntime/contrib_ops/cpu/quantization/quantize_ops.cc | 2 +- .../core/providers/cpu/{nn => quantization}/conv_integer.cc | 0 .../cpu/{tensor => quantization}/dynamicquantizelinear.cc | 0 .../cpu/{tensor => quantization}/dynamicquantizelinear.h | 0 .../providers/cpu/{math => quantization}/matmul_integer.cc | 0 .../cpu/{math => quantization}/matmul_integer_base.h | 0 .../core/providers/cpu/{nn => quantization}/qlinearconv.cc | 0 .../providers/cpu/{tensor => quantization}/quantize_linear.cc | 2 +- .../providers/cpu/{tensor => quantization}/quantize_linear.h | 0 .../cpu/{math => quantization}/quantize_linear_matmul.cc | 0 .../cpu/{math => quantization}/quantize_linear_matmul.h | 0 .../test/providers/cpu/math/quantize_linear_matmul_test.cc | 2 +- 30 files changed, 13 insertions(+), 12 deletions(-) rename onnxruntime/contrib_ops/cpu/{ => quantization}/matmul_integer16.cc (97%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/matmul_integer16.h (100%) rename onnxruntime/contrib_ops/cpu/{bert => quantization}/qembed_layer_norm.cc (99%) rename onnxruntime/contrib_ops/cpu/{bert => quantization}/qembed_layer_norm.h (91%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_activations.cc (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_activations.h (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_binary_op.cc (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_binary_op.h (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_concat.cc (99%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_concat.h (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_global_average_pool.cc (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_global_average_pool.h (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_lookup_table.cc (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_lookup_table.h (100%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_pool.cc (99%) rename onnxruntime/contrib_ops/cpu/{ => quantization}/qlinear_pool.h (100%) rename onnxruntime/core/providers/cpu/{nn => quantization}/conv_integer.cc (100%) rename onnxruntime/core/providers/cpu/{tensor => quantization}/dynamicquantizelinear.cc (100%) rename onnxruntime/core/providers/cpu/{tensor => quantization}/dynamicquantizelinear.h (100%) rename onnxruntime/core/providers/cpu/{math => quantization}/matmul_integer.cc (100%) rename onnxruntime/core/providers/cpu/{math => quantization}/matmul_integer_base.h (100%) rename onnxruntime/core/providers/cpu/{nn => quantization}/qlinearconv.cc (100%) rename onnxruntime/core/providers/cpu/{tensor => quantization}/quantize_linear.cc (99%) rename onnxruntime/core/providers/cpu/{tensor => quantization}/quantize_linear.h (100%) rename onnxruntime/core/providers/cpu/{math => quantization}/quantize_linear_matmul.cc (100%) rename onnxruntime/core/providers/cpu/{math => quantization}/quantize_linear_matmul.h (100%) diff --git a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc index a9d817b5e8..b0d1c3aec8 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/dynamic_quantize_matmul.cc @@ -5,7 +5,7 @@ #include "core/mlas/inc/mlas.h" #include "core/providers/cpu/math/element_wise_ops.h" #include "core/providers/cpu/math/matmul_helper.h" -#include "core/providers/cpu/math/matmul_integer_base.h" +#include "core/providers/cpu/quantization/matmul_integer_base.h" #include "core/util/math_cpuonly.h" #include "core/util/qmath.h" diff --git a/onnxruntime/contrib_ops/cpu/matmul_integer16.cc b/onnxruntime/contrib_ops/cpu/quantization/matmul_integer16.cc similarity index 97% rename from onnxruntime/contrib_ops/cpu/matmul_integer16.cc rename to onnxruntime/contrib_ops/cpu/quantization/matmul_integer16.cc index d94914cf41..64a307530b 100644 --- a/onnxruntime/contrib_ops/cpu/matmul_integer16.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/matmul_integer16.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "contrib_ops/cpu/matmul_integer16.h" +#include "matmul_integer16.h" #include "core/providers/cpu/math/matmul_helper.h" namespace onnxruntime { diff --git a/onnxruntime/contrib_ops/cpu/matmul_integer16.h b/onnxruntime/contrib_ops/cpu/quantization/matmul_integer16.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/matmul_integer16.h rename to onnxruntime/contrib_ops/cpu/quantization/matmul_integer16.h diff --git a/onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.cc b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc similarity index 99% rename from onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.cc rename to onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc index fee4d5a169..2f684362e1 100644 --- a/onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc @@ -5,7 +5,7 @@ #include -#include "embed_layer_norm_helper.h" +#include "contrib_ops/cpu/bert/embed_layer_norm_helper.h" #include "core/framework/op_kernel.h" #include "core/providers/common.h" #include "core/quantization/quantization.h" diff --git a/onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.h b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.h similarity index 91% rename from onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.h rename to onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.h index 1788c2e2c6..baab2cac7c 100644 --- a/onnxruntime/contrib_ops/cpu/bert/qembed_layer_norm.h +++ b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.h @@ -3,7 +3,7 @@ #pragma once -#include "embed_layer_norm.h" +#include "contrib_ops/cpu/bert/embed_layer_norm.h" #include "core/common/common.h" #include "core/framework/op_kernel.h" diff --git a/onnxruntime/contrib_ops/cpu/qlinear_activations.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_activations.cc similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_activations.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_activations.cc index b1e9778373..3bb663c77f 100644 --- a/onnxruntime/contrib_ops/cpu/qlinear_activations.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qlinear_activations.cc @@ -2,8 +2,8 @@ // Licensed under the MIT License. #include "qlinear_activations.h" - #include "qlinear_lookup_table.h" + #include "core/mlas/inc/mlas.h" #include "core/platform/threadpool.h" diff --git a/onnxruntime/contrib_ops/cpu/qlinear_activations.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_activations.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_activations.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_activations.h diff --git a/onnxruntime/contrib_ops/cpu/qlinear_binary_op.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_binary_op.cc similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_binary_op.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_binary_op.cc diff --git a/onnxruntime/contrib_ops/cpu/qlinear_binary_op.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_binary_op.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_binary_op.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_binary_op.h diff --git a/onnxruntime/contrib_ops/cpu/qlinear_concat.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_concat.cc similarity index 99% rename from onnxruntime/contrib_ops/cpu/qlinear_concat.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_concat.cc index 2adeb4d697..76288daa8f 100644 --- a/onnxruntime/contrib_ops/cpu/qlinear_concat.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qlinear_concat.cc @@ -2,7 +2,8 @@ // Licensed under the MIT License. #include "qlinear_concat.h" -#include "contrib_ops/cpu/qlinear_lookup_table.h" +#include "qlinear_lookup_table.h" + #include "core/providers/common.h" #include "core/mlas/inc/mlas.h" #include "core/platform/threadpool.h" diff --git a/onnxruntime/contrib_ops/cpu/qlinear_concat.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_concat.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_concat.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_concat.h diff --git a/onnxruntime/contrib_ops/cpu/qlinear_global_average_pool.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_global_average_pool.cc similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_global_average_pool.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_global_average_pool.cc diff --git a/onnxruntime/contrib_ops/cpu/qlinear_global_average_pool.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_global_average_pool.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_global_average_pool.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_global_average_pool.h diff --git a/onnxruntime/contrib_ops/cpu/qlinear_lookup_table.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_lookup_table.cc similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_lookup_table.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_lookup_table.cc diff --git a/onnxruntime/contrib_ops/cpu/qlinear_lookup_table.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_lookup_table.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_lookup_table.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_lookup_table.h diff --git a/onnxruntime/contrib_ops/cpu/qlinear_pool.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc similarity index 99% rename from onnxruntime/contrib_ops/cpu/qlinear_pool.cc rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc index 6953206a70..e97b654994 100644 --- a/onnxruntime/contrib_ops/cpu/qlinear_pool.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include "qlinear_global_average_pool.h" +#include "qlinear_lookup_table.h" #include "qlinear_pool.h" -#include "contrib_ops/cpu/qlinear_lookup_table.h" -#include "contrib_ops/cpu/qlinear_global_average_pool.h" #include "core/common/safeint.h" #include "core/util/math_cpuonly.h" #include "core/providers/common.h" diff --git a/onnxruntime/contrib_ops/cpu/qlinear_pool.h b/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.h similarity index 100% rename from onnxruntime/contrib_ops/cpu/qlinear_pool.h rename to onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.h diff --git a/onnxruntime/contrib_ops/cpu/quantization/quant_gemm.cc b/onnxruntime/contrib_ops/cpu/quantization/quant_gemm.cc index 523d80f441..9bc7b8e769 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/quant_gemm.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/quant_gemm.cc @@ -4,7 +4,7 @@ #include "core/common/safeint.h" #include "core/providers/cpu/math/gemm_base.h" #include "core/providers/cpu/math/gemm_helper.h" -#include "core/providers/cpu/math/matmul_integer_base.h" +#include "core/providers/cpu/quantization/matmul_integer_base.h" #include "core/quantization/quantization.h" #include "core/util/math_cpuonly.h" diff --git a/onnxruntime/contrib_ops/cpu/quantization/quantize_ops.cc b/onnxruntime/contrib_ops/cpu/quantization/quantize_ops.cc index 46587733c4..9d2931e9c9 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/quantize_ops.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/quantize_ops.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "core/providers/cpu/tensor/quantize_linear.h" +#include "core/providers/cpu/quantization/quantize_linear.h" #include "core/providers/common.h" namespace onnxruntime { diff --git a/onnxruntime/core/providers/cpu/nn/conv_integer.cc b/onnxruntime/core/providers/cpu/quantization/conv_integer.cc similarity index 100% rename from onnxruntime/core/providers/cpu/nn/conv_integer.cc rename to onnxruntime/core/providers/cpu/quantization/conv_integer.cc diff --git a/onnxruntime/core/providers/cpu/tensor/dynamicquantizelinear.cc b/onnxruntime/core/providers/cpu/quantization/dynamicquantizelinear.cc similarity index 100% rename from onnxruntime/core/providers/cpu/tensor/dynamicquantizelinear.cc rename to onnxruntime/core/providers/cpu/quantization/dynamicquantizelinear.cc diff --git a/onnxruntime/core/providers/cpu/tensor/dynamicquantizelinear.h b/onnxruntime/core/providers/cpu/quantization/dynamicquantizelinear.h similarity index 100% rename from onnxruntime/core/providers/cpu/tensor/dynamicquantizelinear.h rename to onnxruntime/core/providers/cpu/quantization/dynamicquantizelinear.h diff --git a/onnxruntime/core/providers/cpu/math/matmul_integer.cc b/onnxruntime/core/providers/cpu/quantization/matmul_integer.cc similarity index 100% rename from onnxruntime/core/providers/cpu/math/matmul_integer.cc rename to onnxruntime/core/providers/cpu/quantization/matmul_integer.cc diff --git a/onnxruntime/core/providers/cpu/math/matmul_integer_base.h b/onnxruntime/core/providers/cpu/quantization/matmul_integer_base.h similarity index 100% rename from onnxruntime/core/providers/cpu/math/matmul_integer_base.h rename to onnxruntime/core/providers/cpu/quantization/matmul_integer_base.h diff --git a/onnxruntime/core/providers/cpu/nn/qlinearconv.cc b/onnxruntime/core/providers/cpu/quantization/qlinearconv.cc similarity index 100% rename from onnxruntime/core/providers/cpu/nn/qlinearconv.cc rename to onnxruntime/core/providers/cpu/quantization/qlinearconv.cc diff --git a/onnxruntime/core/providers/cpu/tensor/quantize_linear.cc b/onnxruntime/core/providers/cpu/quantization/quantize_linear.cc similarity index 99% rename from onnxruntime/core/providers/cpu/tensor/quantize_linear.cc rename to onnxruntime/core/providers/cpu/quantization/quantize_linear.cc index 76b61cb772..595b424973 100644 --- a/onnxruntime/core/providers/cpu/tensor/quantize_linear.cc +++ b/onnxruntime/core/providers/cpu/quantization/quantize_linear.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "core/providers/cpu/tensor/quantize_linear.h" +#include "core/providers/cpu/quantization/quantize_linear.h" #include "core/providers/common.h" #include "core/mlas/inc/mlas.h" #include "core/util/qmath.h" diff --git a/onnxruntime/core/providers/cpu/tensor/quantize_linear.h b/onnxruntime/core/providers/cpu/quantization/quantize_linear.h similarity index 100% rename from onnxruntime/core/providers/cpu/tensor/quantize_linear.h rename to onnxruntime/core/providers/cpu/quantization/quantize_linear.h diff --git a/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc b/onnxruntime/core/providers/cpu/quantization/quantize_linear_matmul.cc similarity index 100% rename from onnxruntime/core/providers/cpu/math/quantize_linear_matmul.cc rename to onnxruntime/core/providers/cpu/quantization/quantize_linear_matmul.cc diff --git a/onnxruntime/core/providers/cpu/math/quantize_linear_matmul.h b/onnxruntime/core/providers/cpu/quantization/quantize_linear_matmul.h similarity index 100% rename from onnxruntime/core/providers/cpu/math/quantize_linear_matmul.h rename to onnxruntime/core/providers/cpu/quantization/quantize_linear_matmul.h diff --git a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc index 090feb09ae..aa5e103874 100644 --- a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc +++ b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "core/providers/cpu/math/quantize_linear_matmul.h" +#include "core/providers/cpu/quantization/quantize_linear_matmul.h" #include "core/mlas/inc/mlas.h" #include "gtest/gtest.h" From 16274beb6fb01b054c7729859c63e7c93574b747 Mon Sep 17 00:00:00 2001 From: George Wu Date: Wed, 15 Dec 2021 15:59:31 -0800 Subject: [PATCH 049/113] update TensorRT EP to use TensorRT 8.2 (#9981) * update base image from 11.4.0 to 11.4.2 * update Linux TRT GPU pipeline to TRT 8.2 * update onnx-tensorrt to 8.2-GA * disable failing TensorRT 8.2 tests. * update pad test. * fix * update win trt ci pipeline to trt 8.2 * test run with cuda 11.4 and cudnn 8.2 * increase timeout * revert * revert * update packaging pipelines to use trt 8.2 * fix typo * update trt gpu perf pipeline to trt 8.2 * increase timeout * delete deprecated ci-perf-pipeline.yml * bump timeout * adjust timeout packaging --- cmake/external/onnx-tensorrt | 2 +- .../providers/cpu/tensor/gather_nd_op_test.cc | 18 +- .../test/providers/cpu/tensor/pad_test.cc | 48 +++-- .../cpu/tensor/scatter_nd_op_test.cc | 2 +- .../providers/cpu/tensor/scatter_op_test.cc | 4 +- .../c-api-noopenmp-packaging-pipelines.yml | 2 +- .../linux-gpu-tensorrt-ci-perf-pipeline.yml | 186 ---------------- .../linux-gpu-tensorrt-ci-pipeline.yml | 8 +- .../linux-gpu-tensorrt-packaging-pipeline.yml | 8 +- .../templates/py-packaging-stage.yml | 20 +- .../win-gpu-tensorrt-ci-pipeline.yml | 6 +- .../docker/Dockerfile.manylinux2014_cuda11 | 2 +- ...kerfile.manylinux2014_cuda11_4_tensorrt8_2 | 201 ++++++++++++++++++ .../ci_build/github/windows/setup_env_gpu.bat | 2 +- 14 files changed, 271 insertions(+), 238 deletions(-) delete mode 100644 tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-perf-pipeline.yml create mode 100644 tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 diff --git a/cmake/external/onnx-tensorrt b/cmake/external/onnx-tensorrt index 1f416bb462..e9456d5760 160000 --- a/cmake/external/onnx-tensorrt +++ b/cmake/external/onnx-tensorrt @@ -1 +1 @@ -Subproject commit 1f416bb462689f3ef9e3f1057a113d9c6aba6972 +Subproject commit e9456d57605c883cdf985e634ab483e2c1500bb1 diff --git a/onnxruntime/test/providers/cpu/tensor/gather_nd_op_test.cc b/onnxruntime/test/providers/cpu/tensor/gather_nd_op_test.cc index f498db7637..8efe0a52cf 100644 --- a/onnxruntime/test/providers/cpu/tensor/gather_nd_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/gather_nd_op_test.cc @@ -18,14 +18,22 @@ static void RunTest(const std::vector& input_dims, const std::initializ test1.AddInput("data", input_dims, input); test1.AddInput("indices", indices_dims, indices); test1.AddOutput("output", output_dims, output); - test1.Run(); + if (std::is_same::value) { + test1.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); + } else { + test1.Run(); + } // ONNX domain opset-12 OpTester test2("GatherND", 12); test2.AddInput("data", input_dims, input); test2.AddInput("indices", indices_dims, indices); test2.AddOutput("output", output_dims, output); - test2.Run(); + if (std::is_same::value) { + test2.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); + } else { + test2.Run(); + } #ifndef DISABLE_CONTRIB_OPS @@ -34,7 +42,11 @@ static void RunTest(const std::vector& input_dims, const std::initializ test3.AddInput("data", input_dims, input); test3.AddInput("indices", indices_dims, indices); test3.AddOutput("output", output_dims, output); - test3.Run(); + if (std::is_same::value) { + test3.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); + } else { + test3.Run(); + } #endif } diff --git a/onnxruntime/test/providers/cpu/tensor/pad_test.cc b/onnxruntime/test/providers/cpu/tensor/pad_test.cc index daef965b9d..cbeb35e44e 100644 --- a/onnxruntime/test/providers/cpu/tensor/pad_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/pad_test.cc @@ -17,7 +17,8 @@ static void RunOnnxOpsetTypedTest( const std::vector& output, std::string mode = "constant", OpTester::ExpectResult expect = OpTester::ExpectResult::kExpectSuccess, - const std::string& error_msg = "") { + const std::string& error_msg = "", + const std::unordered_set& excluded_provider_types = {}) { // ONNX domain opset OpTester test("Pad", opset); if (mode != "constant") @@ -31,15 +32,16 @@ static void RunOnnxOpsetTypedTest( test.AddAttribute("value", static_cast(value)); } test.AddOutput("output", output_dims, output); + std::unordered_set provider_types(excluded_provider_types.begin(), excluded_provider_types.end()); + if (std::is_same::value) + provider_types.insert(kTensorrtExecutionProvider); if constexpr (opset >= 11) { - // TensorRT do not yet support opset-11 and builds break on this test, hence exclude the EP - test.Run(expect, error_msg, {kTensorrtExecutionProvider}); + test.Run(expect, error_msg, provider_types); } else { #if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M) - test.Run(expect, error_msg, {kOpenVINOExecutionProvider}); -#else - test.Run(expect, error_msg); + provider_types.insert(kOpenVINOExecutionProvider); #endif + test.Run(expect, error_msg, provider_types); } } @@ -53,7 +55,8 @@ static void RunAllOpsetAllDomainPadTests( const std::vector& output, std::string mode = "constant", OpTester::ExpectResult expect = OpTester::ExpectResult::kExpectSuccess, - const std::string& error_msg = "") { + const std::string& error_msg = "", + const std::unordered_set& excluded_provider_types = {}) { // Test opset-11 and opset-13 kernels of Pad RunOnnxOpsetTypedTest(input_dims, input, @@ -61,7 +64,7 @@ static void RunAllOpsetAllDomainPadTests( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); RunOnnxOpsetTypedTest(input_dims, input, @@ -69,8 +72,9 @@ static void RunAllOpsetAllDomainPadTests( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); } + template <> void RunAllOpsetAllDomainPadTests<>( const std::vector& input_dims, @@ -81,7 +85,8 @@ void RunAllOpsetAllDomainPadTests<>( const std::vector& output, std::string mode, OpTester::ExpectResult expect, - const std::string& error_msg) { + const std::string& error_msg, + const std::unordered_set& excluded_provider_types) { // Test opset-10, opset-11 and opset-13 kernels of Pad (for double type) RunOnnxOpsetTypedTest(input_dims, input, @@ -89,7 +94,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); RunOnnxOpsetTypedTest(input_dims, input, @@ -97,7 +102,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); RunOnnxOpsetTypedTest(input_dims, input, @@ -105,7 +110,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); } // There is only support for float type for MSDomain kernel in ORT @@ -119,7 +124,8 @@ void RunAllOpsetAllDomainPadTests<>( const std::vector& output, std::string mode, OpTester::ExpectResult expect, - const std::string& error_msg) { + const std::string& error_msg, + const std::unordered_set& excluded_provider_types) { // Test opset-10, opset-11 and opset-13 kernels of Pad (for float type) RunOnnxOpsetTypedTest(input_dims, input, @@ -127,7 +133,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); RunOnnxOpsetTypedTest(input_dims, input, @@ -135,7 +141,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); RunOnnxOpsetTypedTest(input_dims, input, @@ -143,7 +149,7 @@ void RunAllOpsetAllDomainPadTests<>( value, output_dims, output, - mode, expect, error_msg); + mode, expect, error_msg, excluded_provider_types); #ifndef DISABLE_CONTRIB_OPS @@ -731,7 +737,7 @@ TYPED_TEST(PadOpTest, Pad_Edge_DimWithZeroInput) { {}, "edge", OpTester::ExpectResult::kExpectFailure, - "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{0}"); + "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{0}", {kTensorrtExecutionProvider}); RunAllOpsetAllDomainPadTests({2, 0}, // 2D {}, @@ -741,7 +747,7 @@ TYPED_TEST(PadOpTest, Pad_Edge_DimWithZeroInput) { {}, "edge", OpTester::ExpectResult::kExpectFailure, - "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{2,0}"); + "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{2,0}", {kTensorrtExecutionProvider}); RunAllOpsetAllDomainPadTests({2, 0}, // 2D {}, @@ -759,7 +765,7 @@ TYPED_TEST(PadOpTest, Pad_Edge_DimWithZeroInput) { {}, "edge", OpTester::ExpectResult::kExpectFailure, - "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{2,2,0}"); + "Cannot use 'edge' mode to pad dimension with a value of 0. Input shape:{2,2,0}", {kTensorrtExecutionProvider}); RunAllOpsetAllDomainPadTests({2, 2, 0}, // 3D {}, @@ -788,7 +794,7 @@ TYPED_TEST(PadOpTest, Pad_Reflect_DimWithZeroInput) { {}, "reflect", OpTester::ExpectResult::kExpectFailure, - "Cannot use 'reflect' mode to pad dimension with a value of 0. Input shape:{0,2,1}"); + "Cannot use 'reflect' mode to pad dimension with a value of 0. Input shape:{0,2,1}", {kTensorrtExecutionProvider}); } TEST(PadOpTest, BoolType) { diff --git a/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc b/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc index a3d943ea78..0326f53717 100644 --- a/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc @@ -111,7 +111,7 @@ TEST(ScatterNDOpTest, ScatterND_3tensor_int64) { test2.AddInput("indices", {2,3}, {0,0,1,-1,0,-1}); test2.AddInput("updates", {2}, {1,5}); test2.AddOutput("output", {2,2,2}, {0,1,2,3,4,5,6,7}); - test2.Run(); + test2.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); // Exclude TensorRT from INT8 tests OpTester test3("ScatterND", 11); test3.AddInput("data", {2,2,2}, {0,1,2,3,0,1,2,3}); diff --git a/onnxruntime/test/providers/cpu/tensor/scatter_op_test.cc b/onnxruntime/test/providers/cpu/tensor/scatter_op_test.cc index 9b9c32074d..f2bad0dca1 100644 --- a/onnxruntime/test/providers/cpu/tensor/scatter_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/scatter_op_test.cc @@ -174,7 +174,7 @@ static void scatter_indices_updates_dont_match(const char* op_name, int op_versi test.AddInput("indices", {1, 3}, {1, 3, 3}); test.AddInput("updates", {1, 2}, {1.1f, 2.1f}); test.AddOutput("y", {1, 5}, {1.0f, 1.1f, 3.0f, 2.1f, 5.0f}); - test.Run(OpTester::ExpectResult::kExpectFailure, "Indices vs updates dimensions differs at position=1 3 vs 2"); + test.Run(OpTester::ExpectResult::kExpectFailure, "Indices vs updates dimensions differs at position=1 3 vs 2", {kTensorrtExecutionProvider}); } TEST(Scatter, IndicesUpdatesDontMatch) { @@ -208,7 +208,7 @@ static void scatter_invalid_index(const char* op_name, int op_version) { test.AddOutput("y", {4, 2, 1}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f}); test.Run(OpTester::ExpectResult::kExpectFailure, "indices element out of data bounds, idx=4 must be within the inclusive range [-4,3]", - {kCudaExecutionProvider}); + {kCudaExecutionProvider, kTensorrtExecutionProvider}); } TEST(Scatter, InvalidIndex) { diff --git a/tools/ci_build/github/azure-pipelines/c-api-noopenmp-packaging-pipelines.yml b/tools/ci_build/github/azure-pipelines/c-api-noopenmp-packaging-pipelines.yml index 283bb70f67..bf224e3af7 100644 --- a/tools/ci_build/github/azure-pipelines/c-api-noopenmp-packaging-pipelines.yml +++ b/tools/ci_build/github/azure-pipelines/c-api-noopenmp-packaging-pipelines.yml @@ -109,7 +109,7 @@ jobs: buildArch: x64 msbuildPlatform: x64 packageName: x64-tensorrt - buildparameter: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --enable_onnx_tests --enable_wcos --build_java --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;52;60;61;70;75;80" + buildparameter: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --enable_onnx_tests --enable_wcos --build_java --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;52;60;61;70;75;80" runTests: ${{ parameters.RunOnnxRuntimeTests }} buildJava: true java_artifact_id: onnxruntime_gpu diff --git a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-perf-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-perf-pipeline.yml deleted file mode 100644 index b1b2f1f53f..0000000000 --- a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-perf-pipeline.yml +++ /dev/null @@ -1,186 +0,0 @@ -parameters: - -- name: BuildORT - displayName: Build ORT - type: boolean - default: true - -- name: PostToDashboard - displayName: Post to Dashboard - type: boolean - default: true - -- name: RunNvidiaContainer - displayName: Run in Nvidia Container (or set trtContainer Variable) - type: boolean - default: true - -- name: RunDocker - displayName: Run on Docker - type: boolean - default: true - -- name: TrtVersion - displayName: TensorRT Version - type: string - default: 8.0.1.6 - values: - - 8.0.1.6 - - 7.2.3.4 - -- name: ConfigureEPs - displayName: Configure EPs (set epList variable - separate by spaces) - type: boolean - default: false - -- name: PublishWheel - displayName: Publish Wheel - type: boolean - default: false - -- name: ModelGroups - type: object - default: - - "onnx-zoo-models" - - "partner-models" - -- name: MemTest - displayName: Run Memory Test - type: boolean - default: false - -jobs: -- job: Linux_CI_GPU_TENSORRT_PERF - pool: - name: Linux-GPU-TensorRT-Perf - demands: - - Agent.Name -equals K8S-HVZD1T2CL-HVZD1T2 - - variables: - - name: trt_dockerfile - ${{ if eq(parameters.TrtVersion, '8.0.1.6') }}: - value: Dockerfile.ubuntu_cuda11_4_tensorrt8_0 - ${{ if eq(parameters.TrtVersion, '7.2.3.4') }}: - value: Dockerfile.ubuntu_cuda11_4_tensorrt7_2 - - - name: build_args - ${{ if eq(parameters.RunNvidiaContainer, true) }}: - value: Dockerfile.tensorrt-perf -t $(trtContainer) -o $(Build.SourcesDirectory)/dockerfiles/Dockerfile.tensorrt - ${{ if ne(parameters.RunNvidiaContainer, true) }}: - value: Dockerfile.custom-trt-perf -t ${{ parameters.TrtVersion }} -o $(Build.SourcesDirectory)/tools/ci_build/github/linux/docker/$(trt_dockerfile) - - - name: anubis_image - value: ort-master-py38 - - - name: environment - ${{ if eq(parameters.RunDocker, true) }}: - value: docker.sh -d ort-$(branch) -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf - ${{ if ne(parameters.RunDocker, true) }}: - value: machine.sh - - - name: with_arguments - value: $(environment) -e "$(epList)" - timeoutInMinutes: 3000 - - steps: - - - ${{ if eq(parameters.BuildORT, true) }}: - - - ${{ if eq(parameters.RunDocker, true) }}: - - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/$(build_args) -b $(branch) -i ort-$(branch) -c 75' - displayName: 'Build latest ORT Image' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' - - - ${{ if ne(parameters.RunDocker, true) }}: - - script: 'python3 $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/ort_build_latest.py -b $(branch) -c /usr/local/cuda -o ~/repos/onnxruntime/ -t ${{ parameters.TrtVersion }}' - displayName: 'Build latest ORT' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' - - - ${{ if eq(parameters.PublishWheel, true) }}: - - - script: 'docker build --build-arg IMAGE=ort-master -t $(anubis_image) -f $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/Dockerfile.python38 .' - displayName: 'Build Python 3.8 Images' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' - - - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis/copy_wheel.sh -t $(trtContainer) -i $(anubis_image)' - displayName: 'Copy Wheel from Docker' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis' - - - script: 'OUTPUT=$(ls dist) && az storage blob upload --account-name anubiscustomerstorage --account-key $(account-key) --container-name upload --file $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/dist/*.whl --name ort-trt-ep/$(Build.BuildNumber)/$OUTPUT' - displayName: 'Upload Wheel File' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' - - - task: PowerShell@2 - inputs: - filePath: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1' - arguments: '-file_folder $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/dist -account_key $(account-key) -trt_container $(trtContainer)' - displayName: 'Start Anubis Job' - - - ${{ if eq(parameters.MemTest, true) }}: - - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/run_mem_test_docker.sh -d ort-$(branch) -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/ -w /code/ -l false' - displayName: 'Run Memory Test' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/' - - - ${{ each option in parameters.ModelGroups }}: - - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/run_perf_$(with_arguments) -o ${{option}} -m $(${{option}})' - displayName: '${{option}} perf' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' - - - ${{ if eq(parameters.MemTest, true) }}: - - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/run_mem_test_docker.sh -d ort-$(branch) -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/' - displayName: 'Run Memory Test' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/' - - # Prepare and Publish Artifacts - - - script: 'mkdir $(Build.SourcesDirectory)/Artifact' - displayName: 'Prepare Artifacts Directory' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' - condition: always() - - - ${{ if not(eq(length(parameters.ModelGroups), 0)) }}: - - script: 'cp -r $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/result/ $(Build.SourcesDirectory)/Artifact' - displayName: 'Copy Artifacts' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' - - - ${{ if eq(parameters.MemTest, true) }}: - - script: 'cp -r $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/build/result $(Build.SourcesDirectory)/Artifact/result_mem_test' - displayName: 'Copy Artifacts' - workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' - condition: always() - - - template: templates/component-governance-component-detection-steps.yml - parameters : - condition : 'succeeded' - - - task: PublishBuildArtifacts@1 - inputs: - pathtoPublish: '$(Build.SourcesDirectory)/Artifact' - artifactName: 'result-$(Build.BuildNumber)' - - - script: sudo rm -rf $(Agent.BuildDirectory) - displayName: Clean build files (POSIX) - condition: not(eq(variables['Agent.OS'], 'Windows_NT')) # and always() - continueOnError: true # continuing on error for this step, since linux build folder is somehow getting permission issue - -- job: Linux_CI_GPU_TENSORRT_PERF_DASHBOARD - dependsOn: Linux_CI_GPU_TENSORRT_PERF - pool: - name: Linux-GPU-TensorRT-Perf - demands: - - Agent.Name -equals cus-cpu-52wc - - steps: - - ${{ if eq(parameters.PostToDashboard, true) }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: 'result-$(Build.BuildNumber)' - - - script: conda activate clean && python $(Build.SourcesDirectory)\onnxruntime\python\tools\tensorrt\perf\post.py -r $(Pipeline.Workspace)\result -c $(Build.SourceVersion) -u "https://dev.azure.com/onnxruntime/onnxruntime/_build/results?buildId=$(Build.BuildId)" -t ${{ parameters.TrtVersion }} -b $(branch) - displayName: 'Post to Dashboard' - env: - DASHBOARD_MYSQL_ORT_PASSWORD: $(dashboard-mysql-ort-password) - - - script: rd /S /Q $(Agent.BuildDirectory) - displayName: Clean build files (Windows) - condition: eq(variables['Agent.OS'], 'Windows_NT') # and always() diff --git a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-pipeline.yml index 99dc790937..3b89fa63ca 100644 --- a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-ci-pipeline.yml @@ -3,7 +3,7 @@ jobs: pool: onnxruntime-tensorrt-linuxbuild variables: ALLOW_RELEASED_ONNX_OPSET_ONLY: '1' - timeoutInMinutes: 120 + timeoutInMinutes: 180 steps: - checkout: self clean: true @@ -11,10 +11,10 @@ jobs: - template: templates/get-docker-image-steps.yml parameters: - Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_0 + Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 Context: tools/ci_build/github/linux/docker DockerBuildArgs: "--network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-10/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-10/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64 --build-arg BUILD_UID=$( id -u )" - Repository: onnxruntimetensorrt8gpubuild + Repository: onnxruntimetensorrt82gpubuild - task: CmdLine@2 inputs: script: | @@ -28,7 +28,7 @@ jobs: -e ALLOW_RELEASED_ONNX_OPSET_ONLY=0 \ -e NIGHTLY_BUILD \ -e BUILD_BUILDNUMBER \ - onnxruntimetensorrt8gpubuild \ + onnxruntimetensorrt82gpubuild \ /opt/python/cp37-cp37m/bin/python3 /onnxruntime_src/tools/ci_build/build.py \ --build_dir /build --cmake_generator Ninja \ --config Release \ diff --git a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-packaging-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-packaging-pipeline.yml index c97fb7acf0..d83630b741 100644 --- a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-packaging-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-packaging-pipeline.yml @@ -20,7 +20,7 @@ jobs: - job: Linux_C_API_Packaging_GPU_TensorRT_x64 workspace: clean: all - timeoutInMinutes: 120 + timeoutInMinutes: 180 pool: 'Onnxruntime-Linux-GPU' variables: CUDA_VERSION: '11.4' @@ -28,16 +28,16 @@ jobs: - template: templates/set-version-number-variables-step.yml - template: templates/get-docker-image-steps.yml parameters: - Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_0 + Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 Context: tools/ci_build/github/linux/docker DockerBuildArgs: "--network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-10/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-10/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64 --build-arg BUILD_UID=$( id -u )" - Repository: onnxruntimecuda114xtrt80build + Repository: onnxruntimecuda114xtrt82build - task: CmdLine@2 inputs: script: | mkdir -p $HOME/.onnx docker run --gpus all -e CC=/opt/rh/devtoolset-10/root/usr/bin/cc -e CXX=/opt/rh/devtoolset-10/root/usr/bin/c++ -e CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection -fcf-protection -O3 -Wl,--strip-all" -e CXXFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection -fcf-protection -O3 -Wl,--strip-all" -e NVIDIA_VISIBLE_DEVICES=all --rm --volume /data/onnx:/data/onnx:ro --volume $(Build.SourcesDirectory):/onnxruntime_src --volume $(Build.BinariesDirectory):/build \ - --volume /data/models:/build/models:ro --volume $HOME/.onnx:/home/onnxruntimedev/.onnx -e NIGHTLY_BUILD onnxruntimecuda114xtrt80build \ + --volume /data/models:/build/models:ro --volume $HOME/.onnx:/home/onnxruntimedev/.onnx -e NIGHTLY_BUILD onnxruntimecuda114xtrt82build \ /opt/python/cp37-cp37m/bin/python3 /onnxruntime_src/tools/ci_build/build.py --build_dir /build --config Release \ --skip_submodule_sync --parallel --build_shared_lib ${{ parameters.buildJavaOption }} --use_tensorrt --cuda_version=$(CUDA_VERSION) --cuda_home=/usr/local/cuda-$(CUDA_VERSION) --cudnn_home=/usr --tensorrt_home=/usr --cmake_extra_defines CMAKE_CUDA_HOST_COMPILER=/opt/rh/devtoolset-10/root/usr/bin/cc 'CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80' workingDirectory: $(Build.SourcesDirectory) diff --git a/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml b/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml index fc599a42b0..208ffd63a1 100644 --- a/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml +++ b/tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml @@ -187,7 +187,7 @@ stages: - ${{ if eq(parameters.enable_linux_gpu, true) }}: - job: Linux_py_GPU_Wheels - timeoutInMinutes: 120 + timeoutInMinutes: 180 workspace: clean: all pool: Onnxruntime-Linux-GPU @@ -210,10 +210,10 @@ stages: - template: get-docker-image-steps.yml parameters: - Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_0 + Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 Context: tools/ci_build/github/linux/docker DockerBuildArgs: "--network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-10/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-10/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64 --build-arg BUILD_UID=$( id -u )" - Repository: onnxruntimecuda114xtrt80build + Repository: onnxruntimecuda114xtrt82build - task: CmdLine@2 displayName: 'Build Python Wheel' @@ -228,7 +228,7 @@ stages: --volume $HOME/.onnx:/home/onnxruntimedev/.onnx \ -e NIGHTLY_BUILD \ -e BUILD_BUILDNUMBER \ - onnxruntimecuda114xtrt80build \ + onnxruntimecuda114xtrt82build \ $(PythonManylinuxDir)/bin/python3 /onnxruntime_src/tools/ci_build/build.py \ --build_dir /build --cmake_generator Ninja \ --config Release --update --build \ @@ -804,7 +804,7 @@ stages: workspace: clean: all pool: 'onnxruntime-gpu-winbuild' - timeoutInMinutes: 240 + timeoutInMinutes: 300 variables: CUDA_VERSION: '11.4' buildArch: x64 @@ -812,22 +812,22 @@ stages: matrix: Python36_GPU: PythonVersion: '3.6' - EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" + EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" EnvSetupScript: setup_env_gpu.bat EP_NAME: gpu Python37_GPU: PythonVersion: '3.7' - EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" + EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" EnvSetupScript: setup_env_gpu.bat EP_NAME: gpu Python38_GPU: PythonVersion: '3.8' - EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" + EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" EnvSetupScript: setup_env_gpu.bat EP_NAME: gpu Python39_GPU: PythonVersion: '3.9' - EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" + EpBuildFlags: --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=$(CUDA_VERSION) --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$(CUDA_VERSION)" --cudnn_home="C:\local\cudnn-$(CUDA_VERSION)-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=37;50;52;60;61;70;75;80" EnvSetupScript: setup_env_gpu.bat EP_NAME: gpu Python36_dml: @@ -1066,7 +1066,7 @@ stages: - ${{ if eq(parameters.enable_linux_arm, true) }}: - job: Linux_py_Wheels - timeoutInMinutes: 180 + timeoutInMinutes: 240 workspace: clean: all pool: 'Linux-CPU' diff --git a/tools/ci_build/github/azure-pipelines/win-gpu-tensorrt-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/win-gpu-tensorrt-ci-pipeline.yml index 80f7222c4b..ad6a5d2a4d 100644 --- a/tools/ci_build/github/azure-pipelines/win-gpu-tensorrt-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/win-gpu-tensorrt-ci-pipeline.yml @@ -11,7 +11,7 @@ jobs: setVcvars: true BuildConfig: 'RelWithDebInfo' ALLOW_RELEASED_ONNX_OPSET_ONLY: '1' - timeoutInMinutes: 120 + timeoutInMinutes: 150 workspace: clean: all steps: @@ -47,7 +47,7 @@ jobs: displayName: 'Generate cmake config' inputs: scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' - arguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.1.6.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52' + arguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52' workingDirectory: '$(Build.BinariesDirectory)' - task: VSBuild@1 @@ -77,7 +77,7 @@ jobs: del wheel_filename_file python.exe -m pip install -q --upgrade %WHEEL_FILENAME% set PATH=$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig);%PATH% - python $(Build.SourcesDirectory)\tools\ci_build\build.py --config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.0.1.6.Windows10.x86_64.cuda-11.3.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52 + python $(Build.SourcesDirectory)\tools\ci_build\build.py --config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests --use_tensorrt --tensorrt_home="C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2" --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52 workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig)' displayName: 'Run tests' diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11 index 18765d04e2..dc35bf3048 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11 @@ -1,4 +1,4 @@ -ARG BASEIMAGE=nvidia/cuda:11.4.0-cudnn8-devel-centos7 +ARG BASEIMAGE=nvidia/cuda:11.4.2-cudnn8-devel-centos7 ARG POLICY=manylinux2014 ARG PLATFORM=x86_64 ARG DEVTOOLSET_ROOTPATH= diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 new file mode 100644 index 0000000000..92dbd25f56 --- /dev/null +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 @@ -0,0 +1,201 @@ +ARG BASEIMAGE=nvidia/cuda:11.4.2-cudnn8-devel-centos7 +ARG POLICY=manylinux2014 +ARG PLATFORM=x86_64 +ARG DEVTOOLSET_ROOTPATH= +ARG LD_LIBRARY_PATH_ARG= +ARG PREPEND_PATH= + +#We need CUDA, TensorRT and manylinux. But the CUDA Toolkit End User License Agreement says NVIDIA CUDA Driver Libraries(libcuda.so, libnvidia-ptxjitcompiler.so) are only distributable in applications that meet this criteria: +#1. The application was developed starting from a NVIDIA CUDA container obtained from Docker Hub or the NVIDIA GPU Cloud, and +#2. The resulting application is packaged as a Docker container and distributed to users on Docker Hub or the NVIDIA GPU Cloud only. +#So we use CUDA as the base image then add manylinux and TensorRT on top of it. + +#Build manylinux2014 docker image begin +FROM $BASEIMAGE AS runtime_base +ARG POLICY +ARG PLATFORM +ARG DEVTOOLSET_ROOTPATH +ARG LD_LIBRARY_PATH_ARG +ARG PREPEND_PATH +LABEL maintainer="The ManyLinux project" + +ENV AUDITWHEEL_POLICY=${POLICY} AUDITWHEEL_ARCH=${PLATFORM} AUDITWHEEL_PLAT=${POLICY}_${PLATFORM} +ENV LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 +ENV DEVTOOLSET_ROOTPATH=${DEVTOOLSET_ROOTPATH} +ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH_ARG} +ENV PATH=${PREPEND_PATH}${PATH} +ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + +# first copy the fixup mirrors script, keep the script around +COPY build_scripts/fixup-mirrors.sh /usr/local/sbin/fixup-mirrors + +# setup entrypoint, this will wrap commands with `linux32` with i686 images +COPY build_scripts/install-entrypoint.sh \ + build_scripts/update-system-packages.sh \ + build_scripts/build_utils.sh \ + /build_scripts/ + +RUN /build_scripts/install-entrypoint.sh && rm -rf /build_scripts +COPY manylinux-entrypoint /usr/local/bin/manylinux-entrypoint +ENTRYPOINT ["manylinux-entrypoint"] + +COPY build_scripts/install-runtime-packages.sh \ + build_scripts/update-system-packages.sh \ + build_scripts/build_utils.sh \ + /build_scripts/ +RUN manylinux-entrypoint /build_scripts/install-runtime-packages.sh && rm -rf /build_scripts/ + +COPY build_scripts/build_utils.sh /build_scripts/ + +COPY build_scripts/install-autoconf.sh /build_scripts/ +RUN export AUTOCONF_ROOT=autoconf-2.71 && \ + export AUTOCONF_HASH=431075ad0bf529ef13cb41e9042c542381103e80015686222b8a9d4abef42a1c && \ + export AUTOCONF_DOWNLOAD_URL=http://ftp.gnu.org/gnu/autoconf && \ + manylinux-entrypoint /build_scripts/install-autoconf.sh + +COPY build_scripts/install-automake.sh /build_scripts/ +RUN export AUTOMAKE_ROOT=automake-1.16.5 && \ + export AUTOMAKE_HASH=07bd24ad08a64bc17250ce09ec56e921d6343903943e99ccf63bbf0705e34605 && \ + export AUTOMAKE_DOWNLOAD_URL=http://ftp.gnu.org/gnu/automake && \ + manylinux-entrypoint /build_scripts/install-automake.sh + +COPY build_scripts/install-libtool.sh /build_scripts/ +RUN export LIBTOOL_ROOT=libtool-2.4.6 && \ + export LIBTOOL_HASH=e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3 && \ + export LIBTOOL_DOWNLOAD_URL=http://ftp.gnu.org/gnu/libtool && \ + manylinux-entrypoint /build_scripts/install-libtool.sh + +COPY build_scripts/install-patchelf.sh /build_scripts/ +RUN export PATCHELF_VERSION=0.13 && \ + export PATCHELF_HASH=60c6aeadb673de9cc1838b630c81f61e31c501de324ef7f1e8094a2431197d09 && \ + export PATCHELF_DOWNLOAD_URL=https://github.com/NixOS/patchelf/archive && \ + manylinux-entrypoint /build_scripts/install-patchelf.sh + +COPY build_scripts/install-libxcrypt.sh /build_scripts/ +RUN export LIBXCRYPT_VERSION=4.4.26 && \ + export LIBXCRYPT_HASH=e8a544dd19171c1e6191a6044c96cc31496d781ba08b5a00f53310d001d58114 && \ + export LIBXCRYPT_DOWNLOAD_URL=https://github.com/besser82/libxcrypt/archive && \ + export PERL_ROOT=perl-5.34.0 && \ + export PERL_HASH=551efc818b968b05216024fb0b727ef2ad4c100f8cb6b43fab615fa78ae5be9a && \ + export PERL_DOWNLOAD_URL=https://www.cpan.org/src/5.0 && \ + manylinux-entrypoint /build_scripts/install-libxcrypt.sh + +FROM runtime_base AS build_base +COPY build_scripts/install-build-packages.sh /build_scripts/ +RUN manylinux-entrypoint /build_scripts/install-build-packages.sh + + +FROM build_base AS build_git +COPY build_scripts/build-git.sh /build_scripts/ +RUN export GIT_ROOT=git-2.33.1 && \ + export GIT_HASH=02047f8dc8934d57ff5e02aadd8a2fe8e0bcf94a7158da375e48086cc46fce1d && \ + export GIT_DOWNLOAD_URL=https://www.kernel.org/pub/software/scm/git && \ + manylinux-entrypoint /build_scripts/build-git.sh + + +FROM build_base AS build_swig +COPY build_scripts/build-swig.sh /build_scripts/ +RUN export SWIG_ROOT=swig-4.0.2 && \ + export SWIG_HASH=d53be9730d8d58a16bf0cbd1f8ac0c0c3e1090573168bfa151b01eb47fa906fc && \ + export SWIG_DOWNLOAD_URL=https://sourceforge.net/projects/swig/files/swig/${SWIG_ROOT} && \ + export PCRE_ROOT=pcre-8.45 && \ + export PCRE_HASH=4e6ce03e0336e8b4a3d6c2b70b1c5e18590a5673a98186da90d4f33c23defc09 && \ + export PCRE_DOWNLOAD_URL=https://sourceforge.net/projects/pcre/files/pcre/8.45 && \ + manylinux-entrypoint /build_scripts/build-swig.sh + + +FROM build_base AS build_cpython +COPY build_scripts/build-sqlite3.sh /build_scripts/ +RUN export SQLITE_AUTOCONF_ROOT=sqlite-autoconf-3360000 && \ + export SQLITE_AUTOCONF_HASH=bd90c3eb96bee996206b83be7065c9ce19aef38c3f4fb53073ada0d0b69bbce3 && \ + export SQLITE_AUTOCONF_DOWNLOAD_URL=https://www.sqlite.org/2021 && \ + manylinux-entrypoint /build_scripts/build-sqlite3.sh + +COPY build_scripts/build-openssl.sh /build_scripts/ +RUN export OPENSSL_ROOT=openssl-1.1.1l && \ + export OPENSSL_HASH=0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 && \ + export OPENSSL_DOWNLOAD_URL=https://www.openssl.org/source && \ + manylinux-entrypoint /build_scripts/build-openssl.sh + +COPY build_scripts/build-cpython.sh /build_scripts/ + + +FROM build_cpython AS build_cpython36 +COPY build_scripts/cpython-pubkeys.txt /build_scripts/cpython-pubkeys.txt +RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.6.15 + + +FROM build_cpython AS build_cpython37 +COPY build_scripts/cpython-pubkeys.txt /build_scripts/cpython-pubkeys.txt +RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.7.12 + + +FROM build_cpython AS build_cpython38 +COPY build_scripts/ambv-pubkey.txt /build_scripts/cpython-pubkeys.txt +RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.8.12 + + +FROM build_cpython AS build_cpython39 +COPY build_scripts/ambv-pubkey.txt /build_scripts/cpython-pubkeys.txt +RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.9.8 + + +FROM build_cpython AS build_cpython310 +COPY build_scripts/cpython-pubkey-310-311.txt /build_scripts/cpython-pubkeys.txt +RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.10.0 + + +FROM build_cpython AS all_python +COPY build_scripts/install-pypy.sh /build_scripts/install-pypy.sh +COPY build_scripts/pypy.sha256 /build_scripts/pypy.sha256 +RUN manylinux-entrypoint /build_scripts/install-pypy.sh 3.7 7.3.7 +RUN manylinux-entrypoint /build_scripts/install-pypy.sh 3.8 7.3.7 +COPY --from=build_cpython36 /opt/_internal /opt/_internal/ +COPY --from=build_cpython37 /opt/_internal /opt/_internal/ +COPY --from=build_cpython38 /opt/_internal /opt/_internal/ +COPY --from=build_cpython39 /opt/_internal /opt/_internal/ +COPY --from=build_cpython310 /opt/_internal /opt/_internal/ +RUN hardlink -cv /opt/_internal + + +FROM runtime_base +COPY --from=build_git /manylinux-rootfs / +COPY --from=build_swig /manylinux-rootfs / +COPY --from=build_cpython /manylinux-rootfs / +COPY --from=all_python /opt/_internal /opt/_internal/ +COPY build_scripts/finalize.sh \ + build_scripts/update-system-packages.sh \ + build_scripts/python-tag-abi-tag.py \ + build_scripts/requirements3.6.txt \ + build_scripts/requirements3.7.txt \ + build_scripts/requirements3.8.txt \ + build_scripts/requirements3.9.txt \ + build_scripts/requirements3.10.txt \ + build_scripts/requirements-base-tools.txt \ + /build_scripts/ +COPY build_scripts/requirements-tools/* /build_scripts/requirements-tools/ +RUN manylinux-entrypoint /build_scripts/finalize.sh && rm -rf /build_scripts + +ENV SSL_CERT_FILE=/opt/_internal/certs.pem + +CMD ["/bin/bash"] + +#Build manylinux2014 docker image end + +#Install TensorRT 8.2.1.8 +#RUN yum install -y wget +RUN v="8.2.1-1.cuda11.4" &&\ + yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo &&\ + yum -y install libnvinfer8-${v} libnvparsers8-${v} libnvonnxparsers8-${v} libnvinfer-plugin8-${v} \ + libnvinfer-devel-${v} libnvparsers-devel-${v} libnvonnxparsers-devel-${v} libnvinfer-plugin-devel-${v} + +#Add our own dependencies +ADD scripts /tmp/scripts +RUN cd /tmp/scripts && /tmp/scripts/manylinux/install_centos.sh && /tmp/scripts/manylinux/install_deps.sh && rm -rf /tmp/scripts + +ARG BUILD_UID=1001 +ARG BUILD_USER=onnxruntimedev +RUN adduser --uid $BUILD_UID $BUILD_USER +WORKDIR /home/$BUILD_USER +USER $BUILD_USER +ENV PATH /usr/local/gradle/bin:/usr/local/dotnet:$PATH diff --git a/tools/ci_build/github/windows/setup_env_gpu.bat b/tools/ci_build/github/windows/setup_env_gpu.bat index 9e57927e61..ce216eb587 100644 --- a/tools/ci_build/github/windows/setup_env_gpu.bat +++ b/tools/ci_build/github/windows/setup_env_gpu.bat @@ -1,2 +1,2 @@ -set PATH=C:\azcopy;C:\local\TensorRT-8.0.3.4.Windows10.x86_64.cuda-11.3.cudnn8.2\lib;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\extras\CUPTI\lib64;%PATH% +set PATH=C:\azcopy;C:\local\TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2\lib;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\extras\CUPTI\lib64;%PATH% set GRADLE_OPTS=-Dorg.gradle.daemon=false From b327e89efa22c5c8c2c32988dbbe60154df2a39e Mon Sep 17 00:00:00 2001 From: Valery Chernov Date: Thu, 16 Dec 2021 03:59:20 +0300 Subject: [PATCH 050/113] Standalone TVM Executor Provider (#10019) * squashed commit for standalone tvm execution provider * critical fix for correct python build with stvm ep * get tuning log file from ep options. It has priority over AUTOTVM_TUNING_LOG * updates and fixes * update parsing of stvm provider options * add support of external data for onnx model * add conditional dump of subgraphs * remove unused code * get input tensor shapes through provider options. get output shapes for fixed input ones by TVM API * support AUTO_TVM tuning log file inside ORT. Selector for Ansor and Auto_TVM is provider option (tuning_type) * add fp16 * add functionality of conversion of model layout to NHWC if need. Necessary parameter was added to STVM provider options * fix license text in header. fix log format * small fixes * fix issues from flake8 * remove model proto construction from GetCapability * reserve memory for vector of DLTensors * add simple tutorial for STVM EP * STVM docs * jroesch/tvm -> apache/tvm * remove dead code, unneccessary logs and comments * fix in readme * improve tutorial notebook * tvm update * update STVM_EP.md * fix default value * update STVM_EP.md * some TODOs for the future development * shorten long lines * add hyperlink to STVM_EP.md * fix Linux CI error * fix error in csharp test Co-authored-by: Jared Roesch Co-authored-by: Valery Chernov Co-authored-by: KJlaccHoeUM9l --- .gitignore | 1 + .gitmodules | 3 + cmake/CMakeLists.txt | 10 +- cmake/external/tvm_update | 1 + cmake/onnxruntime.cmake | 1 + cmake/onnxruntime_csharp.cmake | 4 + cmake/onnxruntime_java.cmake | 1 - cmake/onnxruntime_providers.cmake | 47 ++ cmake/onnxruntime_python.cmake | 18 + cmake/onnxruntime_unittests.cmake | 22 + .../NativeMethods.shared.cs | 3 + .../SessionOptions.shared.cs | 31 + .../InferenceTest.cs | 4 + docs/STVM_EP.md | 152 +++++ .../notebooks/onnxruntime-stvm-tutorial.ipynb | 517 +++++++++++++++++ include/onnxruntime/core/graph/constants.h | 1 + .../providers/stvm/stvm_provider_factory.h | 16 + ...ai_onnxruntime_OrtSession_SessionOptions.c | 19 + onnxruntime/core/framework/utils.cc | 1 + .../core/providers/get_execution_providers.cc | 8 + .../core/providers/stvm/stvm_allocator.cc | 28 + .../core/providers/stvm/stvm_allocator.h | 42 ++ onnxruntime/core/providers/stvm/stvm_api.cc | 96 ++++ onnxruntime/core/providers/stvm/stvm_api.h | 28 + onnxruntime/core/providers/stvm/stvm_common.h | 11 + .../providers/stvm/stvm_execution_provider.cc | 531 ++++++++++++++++++ .../providers/stvm/stvm_execution_provider.h | 71 +++ .../stvm/stvm_execution_provider_info.cc | 107 ++++ .../stvm/stvm_execution_provider_info.h | 53 ++ .../providers/stvm/stvm_provider_factory.cc | 43 ++ onnxruntime/core/providers/stvm/stvm_utils.h | 53 ++ onnxruntime/core/providers/stvm/symbols.txt | 1 + .../core/providers/stvm/xpu_data_transfer.cc | 83 +++ .../core/providers/stvm/xpu_data_transfer.h | 35 ++ onnxruntime/core/session/provider_stubs.cc | 9 + .../python/onnxruntime_pybind_state.cc | 10 + .../python/onnxruntime_pybind_state_common.h | 15 +- onnxruntime/python/providers/stvm/__init__.py | 10 + onnxruntime/python/providers/stvm/ort.py | 121 ++++ .../test/contrib_ops/fused_conv_test.cc | 3 + .../test/providers/provider_test_utils.cc | 1 + onnxruntime/test/util/default_providers.cc | 8 + .../test/util/include/default_providers.h | 2 + onnxruntime/test/util/include/providers.h | 3 + server/CMakeLists.txt | 1 + server/environment.cc | 10 + setup.py | 6 +- tools/ci_build/build.py | 17 +- 48 files changed, 2251 insertions(+), 7 deletions(-) create mode 160000 cmake/external/tvm_update create mode 100644 docs/STVM_EP.md create mode 100644 docs/python/inference/notebooks/onnxruntime-stvm-tutorial.ipynb create mode 100644 include/onnxruntime/core/providers/stvm/stvm_provider_factory.h create mode 100644 onnxruntime/core/providers/stvm/stvm_allocator.cc create mode 100644 onnxruntime/core/providers/stvm/stvm_allocator.h create mode 100644 onnxruntime/core/providers/stvm/stvm_api.cc create mode 100644 onnxruntime/core/providers/stvm/stvm_api.h create mode 100644 onnxruntime/core/providers/stvm/stvm_common.h create mode 100644 onnxruntime/core/providers/stvm/stvm_execution_provider.cc create mode 100644 onnxruntime/core/providers/stvm/stvm_execution_provider.h create mode 100644 onnxruntime/core/providers/stvm/stvm_execution_provider_info.cc create mode 100644 onnxruntime/core/providers/stvm/stvm_execution_provider_info.h create mode 100644 onnxruntime/core/providers/stvm/stvm_provider_factory.cc create mode 100644 onnxruntime/core/providers/stvm/stvm_utils.h create mode 100644 onnxruntime/core/providers/stvm/symbols.txt create mode 100644 onnxruntime/core/providers/stvm/xpu_data_transfer.cc create mode 100644 onnxruntime/core/providers/stvm/xpu_data_transfer.h create mode 100644 onnxruntime/python/providers/stvm/__init__.py create mode 100644 onnxruntime/python/providers/stvm/ort.py diff --git a/.gitignore b/.gitignore index f212e3fd0a..418e30eed1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ gen *~ .vs .DS_Store +*.DS_Store TestResults/ .idea/ onnxruntime.egg-info diff --git a/.gitmodules b/.gitmodules index 4e09a75462..b8ecf47269 100644 --- a/.gitmodules +++ b/.gitmodules @@ -79,3 +79,6 @@ [submodule "cmake/external/onnx-tensorrt"] path = cmake/external/onnx-tensorrt url = https://github.com/onnx/onnx-tensorrt.git +[submodule "cmake/external/tvm_update"] + path = cmake/external/tvm_update + url = https://github.com/apache/tvm diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index fa7d3c59d4..59a9bb9688 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -59,8 +59,8 @@ option(onnxruntime_BUILD_OBJC "Build Objective-C library" OFF) option(onnxruntime_USE_PREINSTALLED_EIGEN "Use pre-installed EIGEN. Need to provide eigen_SOURCE_PATH if turn this on." OFF) option(onnxruntime_BUILD_BENCHMARKS "Build ONNXRuntime micro-benchmarks" OFF) -option(onnxruntime_USE_TVM "Build tvm for code-gen" OFF) -option(onnxruntime_USE_LLVM "Build tvm with LLVM" OFF) +option(onnxruntime_USE_TVM "Build TVM for code generation." OFF) +option(onnxruntime_USE_LLVM "Build TVM with LLVM" OFF) option(onnxruntime_BUILD_FOR_NATIVE_MACHINE "Enable this option for turning on optimization specific to this machine" OFF) option(onnxruntime_USE_AVX "Use AVX instructions" OFF) @@ -103,6 +103,7 @@ option(onnxruntime_USE_MIMALLOC "Override new/delete and arena allocator with mi #It's default OFF because it's experimental now. option(onnxruntime_PREFER_SYSTEM_LIB "Experimental: Build with the preinstalled libraries in your system" OFF) option(onnxruntime_USE_ROCM "Build with AMD GPU support" OFF) +option(onnxruntime_USE_STVM "Build with standalone TVM support" OFF) # Options related to reducing the binary size produced by the build option(onnxruntime_DISABLE_CONTRIB_OPS "Disable contrib ops" OFF) @@ -1088,6 +1089,11 @@ if (onnxruntime_USE_NUPHAR) list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_NUPHAR=1) list(APPEND ONNXRUNTIME_PROVIDER_NAMES nuphar) endif() +if (onnxruntime_USE_STVM) + list(APPEND ORT_PROVIDER_FLAGS -DUSE_STVM=1) + list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_STVM=1) + list(APPEND ONNXRUNTIME_PROVIDER_NAMES stvm) +endif() if (onnxruntime_USE_WINML) list(APPEND ORT_PROVIDER_FLAGS -DUSE_WINML=1) list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_WINML=1) diff --git a/cmake/external/tvm_update b/cmake/external/tvm_update new file mode 160000 index 0000000000..094a73d4e4 --- /dev/null +++ b/cmake/external/tvm_update @@ -0,0 +1 @@ +Subproject commit 094a73d4e43a25651555bab9b1fd6373262208c3 diff --git a/cmake/onnxruntime.cmake b/cmake/onnxruntime.cmake index bcce2cf706..3ed69a8ad7 100644 --- a/cmake/onnxruntime.cmake +++ b/cmake/onnxruntime.cmake @@ -167,6 +167,7 @@ set(onnxruntime_INTERNAL_LIBRARIES ${PROVIDERS_MIGRAPHX} ${PROVIDERS_NNAPI} ${PROVIDERS_NUPHAR} + ${PROVIDERS_STVM} ${PROVIDERS_RKNPU} ${PROVIDERS_ROCM} ${PROVIDERS_VITISAI} diff --git a/cmake/onnxruntime_csharp.cmake b/cmake/onnxruntime_csharp.cmake index 9db3cff3ef..aad3400997 100644 --- a/cmake/onnxruntime_csharp.cmake +++ b/cmake/onnxruntime_csharp.cmake @@ -34,6 +34,10 @@ if (onnxruntime_USE_NUPHAR) STRING(APPEND CSHARP_PREPROCESSOR_DEFINES "USE_NUPHAR;") endif() +if (onnxruntime_USE_STVM) + STRING(APPEND CSHARP_PREPROCESSOR_DEFINES "USE_STVM,") +endif() + if (onnxruntime_USE_OPENVINO) STRING(APPEND CSHARP_PREPROCESSOR_DEFINES "USE_OPENVINO;") endif() diff --git a/cmake/onnxruntime_java.cmake b/cmake/onnxruntime_java.cmake index 8057fa3ada..722fb09ebf 100644 --- a/cmake/onnxruntime_java.cmake +++ b/cmake/onnxruntime_java.cmake @@ -62,7 +62,6 @@ file(GLOB onnxruntime4j_native_src onnxruntime_add_shared_library_module(onnxruntime4j_jni ${onnxruntime4j_native_src}) set_property(TARGET onnxruntime4j_jni PROPERTY CXX_STANDARD 11) - # depend on java sources. if they change, the JNI should recompile add_dependencies(onnxruntime4j_jni onnxruntime4j) onnxruntime_add_include_to_target(onnxruntime4j_jni onnxruntime_session) diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index d8f1e08a55..396f8b17db 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -97,6 +97,10 @@ endif() if(onnxruntime_USE_ROCM) set(PROVIDERS_ROCM onnxruntime_providers_rocm) endif() +if (onnxruntime_USE_STVM) + set(PROVIDERS_STVM onnxruntime_providers_stvm) +endif() + source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_common_srcs} ${onnxruntime_providers_srcs}) @@ -1168,3 +1172,46 @@ if (onnxruntime_USE_ROCM) RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() + +if (onnxruntime_USE_STVM) + add_definitions(-DUSE_STVM=1) + + file (GLOB_RECURSE onnxruntime_providers_stvm_cc_srcs CONFIGURE_DEPENDS + "${ONNXRUNTIME_ROOT}/core/providers/stvm/*.h" + "${ONNXRUNTIME_ROOT}/core/providers/stvm/*.cc" + ) + source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_stvm_cc_srcs}) + onnxruntime_add_static_library(onnxruntime_providers_stvm ${onnxruntime_providers_stvm_cc_srcs}) + + if ( CMAKE_COMPILER_IS_GNUCC ) + target_compile_options(onnxruntime_providers_stvm PRIVATE -Wno-unused-parameter -Wno-missing-field-initializers) + endif() + + target_include_directories(onnxruntime_providers_stvm PRIVATE + ${onnxruntime_STVM_HOME}/include + ${onnxruntime_STVM_HOME}/3rdparty/dlpack/include + ${onnxruntime_STVM_HOME}/3rdparty/dmlc-core/include + ${PYTHON_INLCUDE_DIRS}) + onnxruntime_add_include_to_target(onnxruntime_providers_stvm onnxruntime_common onnx) + + add_dependencies(onnxruntime_providers_stvm ${onnxruntime_EXTERNAL_DEPENDENCIES}) + + target_link_libraries(onnxruntime_providers_stvm PRIVATE + onnx + onnxruntime_common + onnxruntime_framework + ) + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + target_link_libraries(onnxruntime_providers_stvm PRIVATE ${onnxruntime_STVM_HOME}/build/libtvm.dylib) + else() + target_link_libraries(onnxruntime_providers_stvm PRIVATE ${onnxruntime_STVM_HOME}/build/libtvm.so) + endif() + + set_target_properties(onnxruntime_providers_stvm PROPERTIES FOLDER "ONNXRuntime") + set_target_properties(onnxruntime_providers_stvm PROPERTIES LINKER_LANGUAGE CXX) + + target_compile_options(onnxruntime_providers_stvm PRIVATE -Wno-error=type-limits) + target_compile_definitions(onnxruntime_providers_stvm PUBLIC DMLC_USE_LOGGING_LIBRARY=) + + install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/providers/stvm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/core/providers) +endif() diff --git a/cmake/onnxruntime_python.cmake b/cmake/onnxruntime_python.cmake index 7c894556cf..c47f2b94ee 100644 --- a/cmake/onnxruntime_python.cmake +++ b/cmake/onnxruntime_python.cmake @@ -138,6 +138,7 @@ target_link_libraries(onnxruntime_pybind11_state PRIVATE ${onnxruntime_libs} ${PROVIDERS_MIGRAPHX} ${PROVIDERS_NUPHAR} + ${PROVIDERS_STVM} ${PROVIDERS_VITISAI} ${PROVIDERS_NNAPI} ${PROVIDERS_COREML} @@ -654,6 +655,23 @@ if (onnxruntime_USE_NUPHAR) ) endif() +if (onnxruntime_USE_STVM) + file(GLOB onnxruntime_python_providers_stvm_srcs CONFIGURE_DEPENDS + "${ONNXRUNTIME_ROOT}/python/providers/stvm/*.py" + ) + add_custom_command( + TARGET onnxruntime_pybind11_state POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory $/onnxruntime/providers + COMMAND ${CMAKE_COMMAND} -E make_directory $/onnxruntime/providers/stvm + COMMAND ${CMAKE_COMMAND} -E copy + ${onnxruntime_python_providers_stvm_srcs} + $/onnxruntime/providers/stvm + COMMAND ${CMAKE_COMMAND} -E copy + $ + $/onnxruntime/capi/ + ) +endif() + if (onnxruntime_USE_DML) add_custom_command( TARGET onnxruntime_pybind11_state POST_BUILD diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 1f1f037d97..2a9eeca37e 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -483,6 +483,7 @@ set(ONNXRUNTIME_TEST_LIBS ${PROVIDERS_ACL} ${PROVIDERS_ARMNN} ${PROVIDERS_COREML} + # ${PROVIDERS_STVM} onnxruntime_optimizer onnxruntime_providers onnxruntime_util @@ -537,6 +538,14 @@ if(onnxruntime_USE_COREML) endif() endif() +if (onnxruntime_USE_STVM) + file (GLOB_RECURSE onnxruntime_test_stvm_src CONFIGURE_DEPENDS + "${ONNXRUNTIME_ROOT}/test/stvm/*.h" + "${ONNXRUNTIME_ROOT}/test/stvm/*.cc" + ) + + list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_stvm) +endif() if(WIN32) if (onnxruntime_USE_TVM) @@ -626,6 +635,11 @@ endif() if (onnxruntime_USE_TVM) list(APPEND all_tests ${onnxruntime_test_tvm_src}) endif() + +if (onnxruntime_USE_STVM) + list(APPEND all_tests ${onnxruntime_test_stvm_src}) +endif() + if (onnxruntime_USE_OPENVINO) list(APPEND all_tests ${onnxruntime_test_openvino_src}) endif() @@ -1202,4 +1216,12 @@ if (NOT onnxruntime_MINIMAL_BUILD AND NOT onnxruntime_EXTENDED_MINIMAL_BUILD endif() endif() +if (onnxruntime_USE_STVM) + # find_library(STVM_LIBS NAMES libtvm.so PATHS ${onnxruntime_STVM_HOME}/lib) + # link_directories(onnxruntime_test_all ${STVM_LIBS}) + find_library(PYTHON_LIBS NAMES libpython PATHS /usr/local/lib) + #target_link_libraries(onnxruntime_test_all PRIVATE ${PYTHON_LIBRARIES} -lutil) + # set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-rpath,${STVM_LIBS}") +endif() + include(onnxruntime_fuzz_test.cmake) diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs index 09b3cc48c9..ba774b44e9 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs +++ b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs @@ -792,6 +792,9 @@ namespace Microsoft.ML.OnnxRuntime [DllImport(NativeLib.DllName, CharSet = CharSet.Ansi)] public static extern IntPtr /*(OrtStatus*)*/ OrtSessionOptionsAppendExecutionProvider_Nuphar(IntPtr /*(OrtSessionOptions*) */ options, int allow_unaligned_buffers, IntPtr /*(char char*)*/ settings); + + [DllImport(NativeLib.DllName, CharSet = CharSet.Ansi)] + public static extern IntPtr /*(OrtStatus*)*/ OrtSessionOptionsAppendExecutionProvider_Stvm(IntPtr /*(OrtSessionOptions*) */ options, IntPtr /*(char char*)*/ settings); #endif /// /// Append a TensorRT EP instance (configured based on given provider options) to the native OrtSessionOptions instance diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs index 2dd5344aec..ef7140a3ec 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs +++ b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs @@ -127,6 +127,20 @@ namespace Microsoft.ML.OnnxRuntime return options; } + /// + /// A helper method to construct a SessionOptions object for Stvm execution. + /// Use only if you have the onnxruntime package specific to this Execution Provider. + /// + /// settings string, comprises of comma separated key:value pairs. default is empty + /// A SessionsOptions() object configured for execution with Stvm + public static SessionOptions MakeSessionOptionWithStvmProvider(String settings = "") + { + SessionOptions options = new SessionOptions(); + options.AppendExecutionProvider_Stvm(settings); + + return options; + } + /// /// A helper method to construct a SessionOptions object for ROCM execution. /// Use only if ROCM is installed and you have the onnxruntime package specific to this Execution Provider. @@ -304,6 +318,23 @@ namespace Microsoft.ML.OnnxRuntime { NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionOptionsAppendExecutionProvider_Nuphar(handle, 1, pinnedSettingsName.Pointer)); } +#endif + } + + /// + /// Use only if you have the onnxruntime package specific to this Execution Provider. + /// + /// string with Stvm specific settings + public void AppendExecutionProvider_Stvm(string settings = "") + { +#if __MOBILE__ + throw new NotSupportedException("The Stvm Execution Provider is not supported in this build"); +#else + var settingsPinned = GCHandle.Alloc(NativeOnnxValueHelper.StringToZeroTerminatedUtf8(settings), GCHandleType.Pinned); + using (var pinnedSettingsName = new PinnedGCHandle(settingsPinned)) + { + NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionOptionsAppendExecutionProvider_Stvm(handle, pinnedSettingsName.Pointer)); + } #endif } #endregion //ExecutionProviderAppends diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTest.cs b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTest.cs index b9ed2d4f26..c41be5443c 100644 --- a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTest.cs +++ b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTest.cs @@ -118,6 +118,10 @@ namespace Microsoft.ML.OnnxRuntime.Tests opt.AppendExecutionProvider_Nnapi(0); #endif +#if USE_STVM + opt.AppendExecutionProvider_Stvm("Vulkan -device=amd_apu"); +#endif + #if USE_NUPHAR opt.AppendExecutionProvider_Nuphar(); #endif diff --git a/docs/STVM_EP.md b/docs/STVM_EP.md new file mode 100644 index 0000000000..0175cdfa10 --- /dev/null +++ b/docs/STVM_EP.md @@ -0,0 +1,152 @@ +# Standalone TVM (STVM) Execution Provider + +## Contents + +- [Introduction](#introduction) +- [Build](#build) +- [Configuration options](#configuration-option) +- [Performance Tuning](#performance-tuning) +- [Samples](#samples) +- [Known issues](#known-issues) + + +## Introduction + +STVM is an execution provider for ONNX Runtime that is built on top of Apache TVM. It enables ONNX Runtime users to leverage Apache TVM model optimizations. +STVM EP is currently in "Preview". It's been tested to work on a handful of models on Linux, but not on Windows or MacOS. + +## Build + +To use the STVM EP in ONNX Runtime (ORT), users first need to build Apache TVM and ONNX Runtime. + +Note: some python packages may need to be upgraded/downgraded because both TVM and ORT with the STVM EP use the Python API. Alternatively, use modify PYTHONPATH to solve these conflicts. + +### Build and configure TVM + +Install the minimal pre-requisites on Ubuntu/Debian like linux operating systems: +``` +apt-get install -y python3 python3-dev python3-pip python3-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake libedit-dev libxml2-dev llvm-12 +pip3 install numpy decorator attrs +``` + +Clone this repo using the `--recursive` flag to pull all associated dependencies + + +Build TVM from the tvm_update folder: + +``` +cd onnxruntime/cmake/external/tvm_update/ +mkdir build +cd ./build +cmake -DCMAKE_BUILD_TYPE=Release -DUSE_LLVM=ON -DUSE_OPENMP=gnu -DUSE_MICRO=ON (If your machine is CUDA enabled -DUSE_CUDA=ON) .. +make -j +``` + +Set the environment variable PYTHONPATH to tell python where to find the TVM library: + +``` +export TVM_HOME=/cmake/external/tvm_update +export PYTHONPATH=$TVM_HOME/python:${PYTHONPATH} +``` + +For more details on installing Apache TVM click [here](https://tvm.apache.org/docs/install/from_source.html) + +### Build ONNX Runtime with the STVM Execution Provider + +In order to build ONNXRT you will need to have CMake 3.18 or higher. In Ubuntu 20.04 you can use the following commands to install the latest version of CMake: + +``` +sudo apt-get update +sudo apt-get install gpg wget + +wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null + +echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null +sudo apt-get update + +sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg +sudo apt-get install kitware-archive-keyring + +sudo apt-get install cmake +``` + +Build ONNX Runtime: +``` +./build.sh --config Release --enable_pybind --build_wheel --skip_tests --parallel --use_stvm --skip_onnx_tests +``` + +Build the python API for ONNX Runtime instead of using the standard package: +``` +cd +pip3 uninstall onnxruntime onnxruntime-stvm -y +whl_path=$(find ./build/Linux/Release/dist -name "*.whl") +python3 -m pip install $whl_path +``` +Alternatively, you can set PYTHONPATH to tell python where to find the ONNXRT library: +``` +export ORT_PYTHON_HOME=/build/Linux/Release +export PYTHONPATH=$ORT_PYTHON_HOME:${PYTHONPATH} +``` + +## Configuration options +STVM Executor Provider can be configured with the following provider options: +``` +po = [dict(target=client_target, + target_host=client_target_host, + opt_level=client_opt_level, + freeze_weights=freeze, + tuning_file_path=client_tuning_logfile, + input_names = input_names_str, + input_shapes = input_shapes_str)] +stvm_session = onnxruntime.InferenceSession(model_path, providers=["StvmExecutionProvider"], provider_options=po) +``` +
+ +- `target` and `target_host` are strings like in TVM (e.g. "llvm --mcpu=avx2"). When using accelerators, target may be something like `cuda` while target_host may be `llvm -mtriple=x86_64-linux-gnu` +- `opt_level` is TVM optimization level. It is 3 by default +- `freeze_weights` means that all model weights are kept on compilation stage otherwise they are downloaded each inference. True is recommended value for the best performance. It is true by default. +- `tuning_type` defines the type of TVM tuning logs being used, and can be set to either `AutoTVM` (1st gen auto tuning logs) or `Ansor` (2nd gen auto tuning logs). By default this option is set to `AutoTVM`. +- `tuning_file_path` is path to AutoTVM or Ansor tuning file which gives specifications for given model and target for the best performance. (See below for more details). + +TVM supports models with fixed graph only. If your model has unknown dimensions in input shapes (excluding batch size) you must provide the shape using the `input_names` and `input_shapes` provider options. Below is an example of what must be passed to `provider_options`: +``` +input_names = "input_1 input_2" +input_shapes = "[1 3 224 224] [1 2]" +``` + +## Performance Tuning +TVM optimizes machine learning models through an automated tuning process that produces model variants specific to targeted hardware architectures. This process also generates 'tuning logs' that the STVM EP relies on to maximize model performance. These logs can be acquired for your model by either using TVM as described here: + +AutoTVM: +https://tvm.apache.org/docs/how_to/tune_with_autotvm/index.html + +Ansor (Autoscheduling): +https://tvm.apache.org/docs/how_to/tune_with_autoscheduler/index.html + +or by using logs generated through the OctoML platform (https://onnx.octoml.ai) using instructions [here](https://help.octoml.ai/en/articles/5814452-using-octoml-platform-logs-with-onnx-rt-tvm-ep) + +Using the STVM EP with TVM tuning logs also requires users to turn off ONNX Runtime preprocessing. To do this, the following `SessionOptions()` can be used: +``` +so = onnxruntime.SessionOptions() +so.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_DISABLE_ALL + +stvm_session = onnxruntime.InferenceSession(model_path, sess_options=so, providers=["StvmExecutionProvider"], provider_options=po) +``` + +## Samples +- [Sample notebook for ResNet50 inference with STVM EP](https://github.com/octoml/onnxruntime/blob/STVM_EP_PR/docs/python/inference/notebooks/onnxruntime-stvm-tutorial.ipynb) + +## Known issues +- At this moment, the STVM EP has only been verified on UNIX/Linux systems. +- CUDA/GPU support is still in pre-alpha mode and results are expected to change. It is recommended that only CPU targets are used. +- Some compatibility issues have been found between ONNX and Google protobuf. `AttributeError: module 'google.protobuf.internal.containers' has no attribute 'MutableMapping'`. This usually occurss during `import onnx` in any python scripts for protobuf version >= 3.19.0 and ONNX version <= 1.8.1. To resolve the issue Google protobuf and ONNX can be reinstalled separately or together using: +``` +pip3 uninstall onnx -y +pip3 install onnx==1.10.1 +pip3 uninstall protobuf -y +pip3 install protobuf==3.19.1 +``` + +The following pair of ONNX and protobuf versions have been found to be compatible: +- 3.17.3 and 1.8.0 +- 3.19.1 and 1.10.1 \ No newline at end of file diff --git a/docs/python/inference/notebooks/onnxruntime-stvm-tutorial.ipynb b/docs/python/inference/notebooks/onnxruntime-stvm-tutorial.ipynb new file mode 100644 index 0000000000..cba197ad00 --- /dev/null +++ b/docs/python/inference/notebooks/onnxruntime-stvm-tutorial.ipynb @@ -0,0 +1,517 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "72476497", + "metadata": {}, + "source": [ + "# ONNX Runtime: Tutorial for STVM execution provider\n", + "\n", + "This notebook shows a simple example for model inference with STVM EP.\n", + "\n", + "\n", + "#### Tutorial Roadmap:\n", + "1. Prerequistes\n", + "2. Accuracy check for STVM EP\n", + "3. Configuration options" + ] + }, + { + "cell_type": "markdown", + "id": "9345cbab", + "metadata": {}, + "source": [ + "## 1. Prerequistes\n", + "\n", + "Make sure that you have installed all the necessary dependencies described in the corresponding paragraph of the documentation.\n", + "\n", + "Also, make sure you have the `tvm` and `onnxruntime-stvm` packages in your pip environment. \n", + "\n", + "If you are using `PYTHONPATH` variable expansion, make sure it contains the following paths: `/onnxruntime/cmake/external/tvm_update/python` and `/onnxruntime/build/Linux/Release`." + ] + }, + { + "cell_type": "markdown", + "id": "da4ca21f", + "metadata": {}, + "source": [ + "### Common import\n", + "\n", + "These packages can be delivered from standard `pip`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0f072875", + "metadata": {}, + "outputs": [], + "source": [ + "import onnx\n", + "import numpy as np\n", + "from typing import List, AnyStr\n", + "from onnx import ModelProto, helper, checker, mapping" + ] + }, + { + "cell_type": "markdown", + "id": "118670aa", + "metadata": {}, + "source": [ + "### Specialized import\n", + "\n", + "It is better to collect these packages from source code in order to clearly understand what is available to you right now." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a5502966", + "metadata": {}, + "outputs": [], + "source": [ + "import tvm.testing\n", + "from tvm.contrib.download import download_testdata\n", + "import onnxruntime.providers.stvm # nessesary to register tvm_onnx_import_and_compile and others" + ] + }, + { + "cell_type": "markdown", + "id": "b7313183", + "metadata": {}, + "source": [ + "### Helper functions for working with ONNX ModelProto\n", + "\n", + "This set of helper functions allows you to recognize the meta information of the models. This information is needed for more versatile processing of ONNX models." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "7d0a36e8", + "metadata": {}, + "outputs": [], + "source": [ + "def get_onnx_input_names(model: ModelProto) -> List[AnyStr]:\n", + " inputs = [node.name for node in model.graph.input]\n", + " initializer = [node.name for node in model.graph.initializer]\n", + " inputs = list(set(inputs) - set(initializer))\n", + " return sorted(inputs)\n", + "\n", + "\n", + "def get_onnx_output_names(model: ModelProto) -> List[AnyStr]:\n", + " return [node.name for node in model.graph.output]\n", + "\n", + "\n", + "def get_onnx_input_types(model: ModelProto) -> List[np.dtype]:\n", + " input_names = get_onnx_input_names(model)\n", + " return [\n", + " mapping.TENSOR_TYPE_TO_NP_TYPE[node.type.tensor_type.elem_type]\n", + " for node in sorted(model.graph.input, key=lambda node: node.name) if node.name in input_names\n", + " ]\n", + "\n", + "\n", + "def get_onnx_input_shapes(model: ModelProto) -> List[List[int]]:\n", + " input_names = get_onnx_input_names(model)\n", + " return [\n", + " [dv.dim_value for dv in node.type.tensor_type.shape.dim]\n", + " for node in sorted(model.graph.input, key=lambda node: node.name) if node.name in input_names\n", + " ]\n", + "\n", + "\n", + "def get_random_model_inputs(model: ModelProto) -> List[np.ndarray]:\n", + " input_shapes = get_onnx_input_shapes(model)\n", + " input_types = get_onnx_input_types(model)\n", + " assert len(input_types) == len(input_shapes)\n", + " inputs = [np.random.uniform(size=shape).astype(dtype) for shape, dtype in zip(input_shapes, input_types)]\n", + " return inputs" + ] + }, + { + "cell_type": "markdown", + "id": "f0de1682", + "metadata": {}, + "source": [ + "### Wrapper helper functions for Inference\n", + "\n", + "Wrapper helper functions for running model inference using ONNX Runtime EP." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "258ce9e9", + "metadata": {}, + "outputs": [], + "source": [ + "def get_onnxruntime_output(model: ModelProto, inputs: List, provider_name: AnyStr) -> np.ndarray:\n", + " output_names = get_onnx_output_names(model)\n", + " input_names = get_onnx_input_names(model)\n", + " assert len(input_names) == len(inputs)\n", + " input_dict = {input_name: input_value for input_name, input_value in zip(input_names, inputs)}\n", + "\n", + " inference_session = onnxruntime.InferenceSession(model.SerializeToString(), providers=[provider_name])\n", + " output = inference_session.run(output_names, input_dict)\n", + "\n", + " # Unpack output if there's only a single value.\n", + " if len(output) == 1:\n", + " output = output[0]\n", + " return output\n", + "\n", + "\n", + "def get_cpu_onnxruntime_output(model: ModelProto, inputs: List) -> np.ndarray:\n", + " return get_onnxruntime_output(model, inputs, \"CPUExecutionProvider\")\n", + "\n", + "\n", + "def get_stvm_onnxruntime_output(model: ModelProto, inputs: List) -> np.ndarray:\n", + " return get_onnxruntime_output(model, inputs, \"StvmExecutionProvider\")" + ] + }, + { + "cell_type": "markdown", + "id": "cc17d3b2", + "metadata": {}, + "source": [ + "### Helper function for checking accuracy\n", + "\n", + "This function uses the TVM API to compare two output tensors. The tensor obtained using the `CPUExecutionProvider` is used as a reference.\n", + "\n", + "If a mismatch is found between tensors, an appropriate exception will be thrown." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f33a372b", + "metadata": {}, + "outputs": [], + "source": [ + "def verify_with_ort_with_inputs(\n", + " model,\n", + " inputs,\n", + " out_shape=None,\n", + " opset=None,\n", + " freeze_params=False,\n", + " dtype=\"float32\",\n", + " rtol=1e-5,\n", + " atol=1e-5,\n", + " opt_level=1,\n", + "):\n", + " if opset is not None:\n", + " model.opset_import[0].version = opset\n", + "\n", + " ort_out = get_cpu_onnxruntime_output(model, inputs)\n", + " stvm_out = get_stvm_onnxruntime_output(model, inputs)\n", + " for stvm_val, ort_val in zip(stvm_out, ort_out):\n", + " tvm.testing.assert_allclose(ort_val, stvm_val, rtol=rtol, atol=atol)\n", + " assert ort_val.dtype == stvm_val.dtype" + ] + }, + { + "cell_type": "markdown", + "id": "8c62b01a", + "metadata": {}, + "source": [ + "### Helper functions for download models\n", + "\n", + "These functions use the TVM API to download models from the ONNX Model Zoo." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "324c00e7", + "metadata": {}, + "outputs": [], + "source": [ + "BASE_MODEL_URL = \"https://github.com/onnx/models/raw/master/\"\n", + "MODEL_URL_COLLECTION = {\n", + " \"ResNet50-v1\": \"vision/classification/resnet/model/resnet50-v1-7.onnx\",\n", + " \"ResNet50-v2\": \"vision/classification/resnet/model/resnet50-v2-7.onnx\",\n", + " \"SqueezeNet-v1.1\": \"vision/classification/squeezenet/model/squeezenet1.1-7.onnx\",\n", + " \"SqueezeNet-v1.0\": \"vision/classification/squeezenet/model/squeezenet1.0-7.onnx\",\n", + " \"Inception-v1\": \"vision/classification/inception_and_googlenet/inception_v1/model/inception-v1-7.onnx\",\n", + " \"Inception-v2\": \"vision/classification/inception_and_googlenet/inception_v2/model/inception-v2-7.onnx\",\n", + "}\n", + "\n", + "\n", + "def get_model_url(model_name):\n", + " return BASE_MODEL_URL + MODEL_URL_COLLECTION[model_name]\n", + "\n", + "\n", + "def get_name_from_url(url):\n", + " return url[url.rfind(\"/\") + 1 :].strip()\n", + "\n", + "\n", + "def find_of_download(model_name):\n", + " model_url = get_model_url(model_name)\n", + " model_file_name = get_name_from_url(model_url)\n", + " return download_testdata(model_url, model_file_name, module=\"models\")" + ] + }, + { + "cell_type": "markdown", + "id": "90fb7c5c", + "metadata": {}, + "source": [ + "## 2. Accuracy check for STVM EP \n", + "\n", + "This section will check the accuracy. The check will be to compare the output tensors for `CPUExecutionProvider` and `STVMExecutionProvider`. See the description of `verify_with_ort_with_inputs` function used above.\n", + "\n", + "\n", + "### Check for simple architectures" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c739ed5c", + "metadata": {}, + "outputs": [], + "source": [ + "def get_two_input_model(op_name: AnyStr) -> ModelProto:\n", + " dtype = \"float32\"\n", + " in_shape = [1, 2, 3, 3]\n", + " in_type = mapping.NP_TYPE_TO_TENSOR_TYPE[np.dtype(dtype)]\n", + " out_shape = in_shape\n", + " out_type = in_type\n", + "\n", + " layer = helper.make_node(op_name, [\"in1\", \"in2\"], [\"out\"])\n", + " graph = helper.make_graph(\n", + " [layer],\n", + " \"two_input_test\",\n", + " inputs=[\n", + " helper.make_tensor_value_info(\"in1\", in_type, in_shape),\n", + " helper.make_tensor_value_info(\"in2\", in_type, in_shape),\n", + " ],\n", + " outputs=[\n", + " helper.make_tensor_value_info(\n", + " \"out\", out_type, out_shape\n", + " )\n", + " ],\n", + " )\n", + " model = helper.make_model(graph, producer_name=\"two_input_test\")\n", + " checker.check_model(model, full_check=True)\n", + " return model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7048ee6d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "STVM ep options:\n", + "target: llvm -mcpu=skylake-avx512\n", + "target_host: llvm -mcpu=skylake-avx512\n", + "opt level: 3\n", + "freeze weights: 1\n", + "tuning file path: \n", + "tuning type: Ansor\n", + "convert layout to NHWC: 0\n", + "input tensor names: \n", + "input tensor shapes: \n", + "Build TVM graph executor\n", + "****************** Success! ******************\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/agladyshev/workspace/tvm/python/tvm/relay/build_module.py:414: UserWarning: target_host parameter is going to be deprecated. Please pass in tvm.target.Target(target, host=target_host) instead.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "onnx_model = get_two_input_model(\"Add\")\n", + "inputs = get_random_model_inputs(onnx_model)\n", + "verify_with_ort_with_inputs(onnx_model, inputs)\n", + "print(\"****************** Success! ******************\")" + ] + }, + { + "cell_type": "markdown", + "id": "52c880f4", + "metadata": {}, + "source": [ + "### Check for DNN architectures " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f5d465dc", + "metadata": {}, + "outputs": [], + "source": [ + "def get_onnx_model(model_name):\n", + " model_path = find_of_download(model_name)\n", + " onnx_model = onnx.load(model_path)\n", + " return onnx_model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "68daac7e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "STVM ep options:\n", + "target: llvm -mcpu=skylake-avx512\n", + "target_host: llvm -mcpu=skylake-avx512\n", + "opt level: 3\n", + "freeze weights: 1\n", + "tuning file path: \n", + "tuning type: Ansor\n", + "convert layout to NHWC: 0\n", + "input tensor names: \n", + "input tensor shapes: \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/agladyshev/workspace/tvm/python/tvm/driver/build_module.py:235: UserWarning: Specifying name with IRModule input is useless\n", + " warnings.warn(\"Specifying name with IRModule input is useless\")\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Build TVM graph executor\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "One or more operators have not been tuned. Please tune your model for better performance. Use DEBUG logging level to see more details.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "****************** Success! ******************\n" + ] + } + ], + "source": [ + "model_name = \"ResNet50-v1\"\n", + "\n", + "onnx_model = get_onnx_model(model_name)\n", + "inputs = get_random_model_inputs(onnx_model)\n", + "verify_with_ort_with_inputs(onnx_model, inputs)\n", + "print(\"****************** Success! ******************\")" + ] + }, + { + "cell_type": "markdown", + "id": "e27f64a2", + "metadata": {}, + "source": [ + "## 3. Configuration options\n", + "\n", + "This section shows how you can configure STVM EP using custom options. For more details on the options used, see the corresponding section of the documentation." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a053f59f", + "metadata": {}, + "outputs": [], + "source": [ + "provider_name = \"StvmExecutionProvider\"\n", + "provider_options = dict(target=\"llvm -mtriple=x86_64-linux-gnu\",\n", + " target_host=\"llvm -mtriple=x86_64-linux-gnu\",\n", + " opt_level=3,\n", + " freeze_weights=True,\n", + " tuning_file_path=\"\",\n", + " tuning_type=\"Ansor\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "3f6e6f01", + "metadata": {}, + "outputs": [], + "source": [ + "model_name = \"ResNet50-v1\"\n", + "onnx_model = get_onnx_model(model_name)\n", + "input_dict = {input_name: input_value for input_name, input_value in zip(get_onnx_input_names(onnx_model),\n", + " get_random_model_inputs(onnx_model))}\n", + "output_names = get_onnx_output_names(onnx_model)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "85ab83f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "STVM ep options:\n", + "target: llvm -mtriple=x86_64-linux-gnu\n", + "target_host: llvm -mtriple=x86_64-linux-gnu\n", + "opt level: 3\n", + "freeze weights: 1\n", + "tuning file path: \n", + "tuning type: Ansor\n", + "convert layout to NHWC: 0\n", + "input tensor names: \n", + "input tensor shapes: \n", + "Build TVM graph executor\n", + "****************** Output shape: (1, 1000) ******************\n" + ] + } + ], + "source": [ + "stvm_session = onnxruntime.InferenceSession(onnx_model.SerializeToString(),\n", + " providers=[provider_name],\n", + " provider_options=[provider_options]\n", + " )\n", + "output = stvm_session.run(output_names, input_dict)[0]\n", + "print(f\"****************** Output shape: {output.shape} ******************\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/include/onnxruntime/core/graph/constants.h b/include/onnxruntime/core/graph/constants.h index 49a277e226..09588e5dde 100644 --- a/include/onnxruntime/core/graph/constants.h +++ b/include/onnxruntime/core/graph/constants.h @@ -35,6 +35,7 @@ constexpr const char* kAclExecutionProvider = "ACLExecutionProvider"; constexpr const char* kArmNNExecutionProvider = "ArmNNExecutionProvider"; constexpr const char* kRocmExecutionProvider = "ROCMExecutionProvider"; constexpr const char* kCoreMLExecutionProvider = "CoreMLExecutionProvider"; +constexpr const char* kStvmExecutionProvider = "StvmExecutionProvider"; constexpr const char* kExecutionProviderSharedLibraryPath = "shared_lib_path"; constexpr const char* kExecutionProviderSharedLibraryEntry = "provider_factory_entry_point"; diff --git a/include/onnxruntime/core/providers/stvm/stvm_provider_factory.h b/include/onnxruntime/core/providers/stvm/stvm_provider_factory.h new file mode 100644 index 0000000000..3e0b52aa63 --- /dev/null +++ b/include/onnxruntime/core/providers/stvm/stvm_provider_factory.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "onnxruntime_c_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Stvm, _In_ OrtSessionOptions* options, _In_ const char* settings); + +#ifdef __cplusplus +} +#endif + + diff --git a/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c b/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c index 18c5d59205..5a1b8d004f 100644 --- a/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c +++ b/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c @@ -18,6 +18,7 @@ #include "onnxruntime/core/providers/dnnl/dnnl_provider_factory.h" #include "onnxruntime/core/providers/nnapi/nnapi_provider_factory.h" #include "onnxruntime/core/providers/nuphar/nuphar_provider_factory.h" +#include "onnxruntime/core/providers/stvm/stvm_provider_factory.h" #include "onnxruntime/core/providers/openvino/openvino_provider_factory.h" #include "onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.h" #include "onnxruntime/core/providers/migraphx/migraphx_provider_factory.h" @@ -464,6 +465,24 @@ JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addNup #endif } +/* + * Class:: ai_onnxruntime_OrtSession_SessionOptions + * Method: addStvm + * Signature: (JILjava/lang/String)V + */ +JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addStvm + (JNIEnv * jniEnv, jobject jobj, jlong apiHandle, jlong handle, jstring settingsString) { + (void)jobj; + #ifdef USE_STVM + const char* settings = (*jniEnv)->GetStringUTFChars(jniEnv, settingsString, NULL); + checkOrtStatus(jniEnv,(const OrtApi*)apiHandle,OrtSessionOptionsAppendExecutionProvider_Stvm((OrtSessionOptions*) handle, settings)); + (*jniEnv)->ReleaseStringUTFChars(jniEnv,settingsString,settings); + #else + (void)apiHandle;(void)handle;(void)settingsString; // Parameters used when Stvm is defined. + throwOrtException(jniEnv,convertErrorCode(ORT_INVALID_ARGUMENT),"This binary was not compiled with Stvm support."); + #endif +} + /* * Class: ai_onnxruntime_OrtSession_SessionOptions * Method: addMIGraphX diff --git a/onnxruntime/core/framework/utils.cc b/onnxruntime/core/framework/utils.cc index 83adab1de4..840b0321ac 100644 --- a/onnxruntime/core/framework/utils.cc +++ b/onnxruntime/core/framework/utils.cc @@ -96,6 +96,7 @@ bool ProviderIsCpuBased(const std::string& provider_type) { return provider_type == onnxruntime::kCpuExecutionProvider || provider_type == onnxruntime::kDnnlExecutionProvider || provider_type == onnxruntime::kNupharExecutionProvider || + provider_type == onnxruntime::kStvmExecutionProvider || provider_type == onnxruntime::kVitisAIExecutionProvider || provider_type == onnxruntime::kOpenVINOExecutionProvider || provider_type == onnxruntime::kNnapiExecutionProvider || diff --git a/onnxruntime/core/providers/get_execution_providers.cc b/onnxruntime/core/providers/get_execution_providers.cc index 78239625b4..14030ede10 100644 --- a/onnxruntime/core/providers/get_execution_providers.cc +++ b/onnxruntime/core/providers/get_execution_providers.cc @@ -71,6 +71,14 @@ constexpr ProviderInfo kProvidersInPriorityOrder[] = true, #else false, +#endif + }, + { + kStvmExecutionProvider, +#ifdef USE_STVM + true, +#else + false, #endif }, { diff --git a/onnxruntime/core/providers/stvm/stvm_allocator.cc b/onnxruntime/core/providers/stvm/stvm_allocator.cc new file mode 100644 index 0000000000..3784e49e23 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_allocator.cc @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "stvm_allocator.h" +#include "core/framework/allocatormgr.h" +#include "core/framework/session_state.h" +#include "xpu_data_transfer.h" + + +namespace onnxruntime { + + +void* STVMAllocator::Alloc(size_t size) { + void* p = nullptr; + if (size > 0) { + DLDataType dl_type{kDLInt, 8, 1}; + int err = TVMDeviceAllocDataSpace(ctx, size, 128, dl_type, (void**)&p); + CHECK_EQ(err, 0); + return p; + } + return p; +} + +void STVMAllocator::Free(void* p) { + TVMDeviceFreeDataSpace(ctx, p); +} + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/stvm/stvm_allocator.h b/onnxruntime/core/providers/stvm/stvm_allocator.h new file mode 100644 index 0000000000..4fc5b94120 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_allocator.h @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_ALLOCATOR +#define STVM_ALLOCATOR + +#include "core/framework/allocator.h" +#include "stvm_common.h" + +namespace onnxruntime { + +#define STVM_ALLOC_ALIGN 128 + +class STVMAllocator : public IAllocator { + public: + STVMAllocator() : STVMAllocator(OrtMemoryInfo("TVM", + OrtAllocatorType::OrtDeviceAllocator, + OrtDevice(OrtDevice::CPU, OrtDevice::MemType::DEFAULT, 0), + 0, + OrtMemTypeDefault)) {} + explicit STVMAllocator(const OrtMemoryInfo& info) + : IAllocator(info) { + switch (info.device.Type()) { + case OrtDevice::CPU: + ctx = {kDLCPU, info.device.Id()}; + break; + case OrtDevice::GPU: + ctx = {kDLVulkan, info.device.Id()}; + break; + default: + ORT_NOT_IMPLEMENTED("Unsupported device"); + break; + } + } + + virtual void* Alloc(size_t size) override; + virtual void Free(void* p) override; + DLDevice ctx; +}; + +} // namespace onnxruntime +#endif // STVM_ALLOCATOR diff --git a/onnxruntime/core/providers/stvm/stvm_api.cc b/onnxruntime/core/providers/stvm/stvm_api.cc new file mode 100644 index 0000000000..d0423e839c --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_api.cc @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "stvm_api.h" + +#include +#include + +namespace stvm { + +tvm::runtime::Module TVMCompile(const std::string& onnx_txt, + const std::string& model_path, + const std::string& target, + const std::string& target_host, + int opt_level, + int opset, + bool freeze_params, + const std::vector>& input_shapes, + bool nhwc, + const std::string& tuning_logfile, + const std::string& tuning_type) +{ + tvm::Array> shapes; + for (size_t i = 0; i < input_shapes.size(); ++i) + { + tvm::Array shape; + for (auto& dim : input_shapes[i]) + { + shape.push_back(tvm::Integer(dim)); + } + shapes.push_back(shape); + } + + const tvm::PackedFunc* compile = tvm::runtime::Registry::Get("tvm_onnx_import_and_compile"); + tvm::runtime::Module mod = (*compile)( + TVMByteArray{onnx_txt.data(), onnx_txt.size()}, + model_path, + target, + target_host, + opt_level, + opset, + freeze_params, + shapes, + nhwc, + tuning_logfile, + tuning_type); + return mod; +} + +void TVMSetInputs(tvm::runtime::Module& mod, + std::vector& inds, + std::vector& inputs) +{ + // TODO(vvchernov): set_input_zero_copy is more preferable but it does not satisfy alignment conditions. + //tvm::PackedFunc set_input = mod.GetFunction("set_input_zero_copy", false); + + tvm::PackedFunc set_input = mod.GetFunction("set_input", false); + for (auto& i : inds) + { + set_input(i, &inputs[i]); + } +} + +void TVMGetOutputShapes(tvm::runtime::Module& mod, + size_t num_outputs, + std::vector>& output_shapes) +{ + output_shapes.clear(); + tvm::PackedFunc get_output = mod.GetFunction("get_output", false); + for (size_t i = 0; i < num_outputs; ++i) { + tvm::runtime::NDArray output_array = get_output(i); + tvm::runtime::ShapeTuple shape_tuple = output_array.Shape(); + size_t dims_num = shape_tuple.size(); + std::vector dims; + for (size_t j = 0; j < dims_num; ++j) { + dims.push_back(int64_t(shape_tuple[j])); + } + output_shapes.push_back(dims); + } +} + +void TVMRun(tvm::runtime::Module& mod, + std::vector& outputs, + [[maybe_unused]] tvm::runtime::TVMRetValue *ret) +{ + const tvm::PackedFunc* run = tvm::runtime::Registry::Get("tvm_run"); + (*run)(mod); + + tvm::PackedFunc get_output = mod.GetFunction("get_output", false); + for (size_t i = 0; i < outputs.size(); ++i) + { + get_output(i, &outputs[i]); + } +} + +} // namespace stvm diff --git a/onnxruntime/core/providers/stvm/stvm_api.h b/onnxruntime/core/providers/stvm/stvm_api.h new file mode 100644 index 0000000000..41d4b5f08b --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_api.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_API_H +#define STVM_API_H + +#include "stvm_common.h" + +namespace stvm { + tvm::runtime::Module TVMCompile(const std::string& onnx_txt, + const std::string& model_path, + const std::string& target, + const std::string& target_host, + int opt_level, + int opset, + bool freeze_params, + const std::vector>& input_shapes, + bool nhwc = false, + const std::string& tuning_logfile = "", + const std::string& tuning_type = "AutoTVM"); + void TVMSetInputs(tvm::runtime::Module& mod, std::vector& inds, std::vector& inputs); + void TVMGetOutputShapes(tvm::runtime::Module& mod, + size_t num_outputs, + std::vector>& output_shapes); + void TVMRun(tvm::runtime::Module& mod, std::vector& outputs, tvm::runtime::TVMRetValue *ret); +} // namespace stvm + +#endif // STVM_API_H \ No newline at end of file diff --git a/onnxruntime/core/providers/stvm/stvm_common.h b/onnxruntime/core/providers/stvm/stvm_common.h new file mode 100644 index 0000000000..a926a451cf --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_common.h @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_COMMON_H +#define STVM_COMMON_H + +#include +#include +#include + +#endif // STVM_COMMON_H diff --git a/onnxruntime/core/providers/stvm/stvm_execution_provider.cc b/onnxruntime/core/providers/stvm/stvm_execution_provider.cc new file mode 100644 index 0000000000..4df2132a38 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_execution_provider.cc @@ -0,0 +1,531 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include + +#include "core/framework/execution_provider.h" +#include "core/framework/tensorprotoutils.h" +#include "core/framework/kernel_registry.h" +#include "core/framework/compute_capability.h" +#include "core/platform/env.h" +#include "core/graph/model.h" +#include "core/common/cpuid_info.h" + +#include "stvm_execution_provider.h" +#include "xpu_data_transfer.h" +#include "stvm_allocator.h" +#include "stvm_utils.h" +#include "stvm_api.h" + +using namespace ONNX_NAMESPACE; + +namespace onnxruntime { + +// Information to construct kernel function state. +struct STVMFuncState { + AllocateFunc allocate_func = nullptr; + DestroyFunc release_func = nullptr; + AllocatorHandle allocator = nullptr; + tvm::runtime::Module* module = nullptr; + std::function>& input_shapes)> compiler = nullptr; +}; + +class STVMRunner { + public: + using TVMTensorShape = std::vector; + using TVMTensorShapes = std::vector; + using InputsInfoMap = std::map; + using ORTGraphNodes = std::vector; + + STVMRunner() = delete; + ~STVMRunner() = default; + + STVMRunner(StvmExecutionProvider* ep, + const std::string& name, + const Graph& graph) { + // Extract input shapes + const ORTGraphNodes& all_nodes = graph.GetInputsIncludingInitializers(); + TVMTensorShapes input_shapes; + size_t indx = 0; + if (ep->info_.freeze_weights) { + for (const auto* node : all_nodes) { + const auto& node_name = node->Name(); + if(!graph.IsInitializedTensor(node_name)) { + TVMTensorShape ishape; + if(!ep->info_.input_shapes.empty() && + ep->info_.input_shapes.count(node_name)) { + ishape = ep->info_.input_shapes[node_name]; + inputs_info_[indx] = ishape; + update_output_shapes_ = true; + } else { + getTensorInfo(*node->Shape(), ishape, indx); + } + input_shapes.emplace_back(ishape); + } + ++indx; + } + } else { + for (const auto* node : all_nodes) { + const auto& node_name = node->Name(); + TVMTensorShape ishape; + if(!ep->info_.input_shapes.empty() && + ep->info_.input_shapes.count(node_name)) { + ishape = ep->info_.input_shapes[node_name]; + inputs_info_[indx++] = ishape; + update_output_shapes_ = true; + } else { + getTensorInfo(*node->Shape(), ishape, indx++); + } + if(!graph.IsInitializedTensor(node_name)) { + input_shapes.emplace_back(ishape); + } + } + } + + // Get module from tvm + mod_ = ep->CompileFunc(name, input_shapes); + + // Prepare draft for output tvm tensors + const ORTGraphNodes& ort_outputs_info = graph.GetOutputs(); + size_t num_outputs = ort_outputs_info.size(); + + if (update_output_shapes_) { + stvm::TVMGetOutputShapes(*mod_, num_outputs, output_shapes_); + } else { + for (auto i = 0u; i < num_outputs; i++) { + TensorShape ort_shape = utils::GetTensorShapeFromTensorShapeProto(*ort_outputs_info[i]->Shape()); + int dims = ort_shape.NumDimensions(); + + TVMTensorShape oshape(dims); + for (int j = 0; j < dims; ++j) { + oshape[j] = int64_t(ort_shape[j]); + } + output_shapes_.emplace_back(oshape); + } + } + + for (auto i = 0u; i < num_outputs; i++) { + DLTensor t; + // Data pointer and type are defined during inference + t.strides = nullptr; + t.byte_offset = 0; + t.data = nullptr; + t.ndim = output_shapes_[i].size(); + t.shape = output_shapes_[i].data(); + tensors_outputs_.push_back(t); + } + } + + common::Status operator()(FunctionState state, const OrtCustomOpApi* api, OrtKernelContext* context) { + Ort::CustomOpApi ort{*api}; + + size_t num = inputs_info_.size(); + std::vector inds(num); + std::vector dl_tensors_inputs(num); + size_t counter = 0u; + for (auto& info : inputs_info_) { + // TODO(vvchernov): decomposition declaration only available with -std=c++1z or -std=gnu++1z + auto& i = info.first; + auto& shape = info.second; + const OrtValue* input_tensor = ort.KernelContext_GetInput(context, i); + ORT_ENFORCE(input_tensor->IsTensor()); + const Tensor& tensor = input_tensor->Get(); + const OrtDevice& device = tensor.Location().device; + auto tensor_info = ort.GetTensorTypeAndShape(input_tensor); + auto tensor_type = ort.GetTensorElementType(tensor_info); + if (!update_output_shapes_) { + std::vector ort_shape = ort.GetTensorShape(tensor_info); + ORT_ENFORCE(compare_shapes(shape, ort_shape)); + } + ort.ReleaseTensorTypeAndShapeInfo(tensor_info); + + DLTensor t; + t.device = GetDLDevice(device); + t.dtype = GetDataType(tensor_type); + t.strides = nullptr; + t.byte_offset = 0; + t.data = const_cast(ort.GetTensorData(input_tensor)); + t.ndim = shape.size(); + t.shape = shape.data(); + dl_tensors_inputs[counter] = t; + inds[counter++] = i; + } + stvm::TVMSetInputs(*mod_, inds, dl_tensors_inputs); + + size_t num_outputs = tensors_outputs_.size(); + for (auto i = 0u; i < num_outputs; i++) { + //setup output tensor property + OrtValue* output_tensor = ort.KernelContext_GetOutput(context, + i, + output_shapes_[i].data(), + output_shapes_[i].size()); + ORT_ENFORCE(output_tensor->IsTensor()); + const Tensor& tensor = output_tensor->Get(); + const OrtDevice& device = tensor.Location().device; + auto tensor_info = ort.GetTensorTypeAndShape(output_tensor); + auto tensor_type = ort.GetTensorElementType(tensor_info); + ort.ReleaseTensorTypeAndShapeInfo(tensor_info); + + tensors_outputs_[i].device = GetDLDevice(device); + tensors_outputs_[i].dtype = GetDataType(tensor_type); + tensors_outputs_[i].data = ort.GetTensorMutableData(output_tensor); + } + + tvm::runtime::TVMRetValue rvalue; + stvm::TVMRun(*mod_, tensors_outputs_, &rvalue); + + return Status::OK(); + } + private: + void getTensorInfo(const TensorShapeProto& shape_proto, + TVMTensorShape& ishape, + size_t indx) { + TensorShape ort_shape = utils::GetTensorShapeFromTensorShapeProto(shape_proto); + int dims = ort_shape.NumDimensions(); + + ishape.resize(dims); + for (int j = 0; j < dims; ++j) { + int64_t dim = int64_t(ort_shape[j]); + if (dim > 0) { + ishape[j] = dim; + } else { + LOGS_DEFAULT(WARNING) << "input dimension is not positive value (dim = " << dim << "). " << + "It is replaced by 1. if it needs another value please use provider options to correct it"; + ishape[j] = 1; + update_output_shapes_ = true; + } + } + inputs_info_[indx] = ishape; + } + + bool compare_shapes(const TVMTensorShape& shape1, const TVMTensorShape& shape2) { + size_t size = shape1.size(); + if (shape2.size() == size) { + for (size_t i = 0; i < size; ++i) { + if(shape1[i] != shape2[i]) { + return false; + } + } + } else { + return false; + } + + return true; + } + + private: + tvm::runtime::Module* mod_; + InputsInfoMap inputs_info_{}; + bool update_output_shapes_ = false; + TVMTensorShapes output_shapes_; + std::vector tensors_outputs_; +}; + +StvmExecutionProvider::StvmExecutionProvider(const StvmExecutionProviderInfo& info) + : IExecutionProvider{kStvmExecutionProvider}, + info_{info} { + ProcessInfo(); + + AllocatorCreationInfo default_memory_info = {[](int) { + return std::make_unique(); + }, + 0, false}; + allocator_ = CreateAllocator(default_memory_info); + InsertAllocator(allocator_); + + // Get environment variables + const Env& env_instance = Env::Default(); + + const std::string dump_subgraphs_env = env_instance.GetEnvironmentVar(stvm_env_vars::kDumpSubgraphs); + if (!dump_subgraphs_env.empty()) { + dump_subgraphs_ = std::stoi(dump_subgraphs_env) != 0; + } +} + +StvmExecutionProvider::~StvmExecutionProvider() {} + +AllocatorPtr StvmExecutionProvider::GetAllocator(int id, OrtMemType mem_type) const { + return allocator_; +} + +std::vector> +StvmExecutionProvider::GetCapability(const GraphViewer& graph_viewer, + const std::vector& /*kernel_registries*/) const { + std::vector> result; + if (graph_viewer.IsSubgraph()) { + return result; + } + + const auto& init_tensors = graph_viewer.GetAllInitializedTensors(); + + std::unordered_set required_initializers; + const std::vector& sorted_nodes = graph_viewer.GetNodesInTopologicalOrder(); + std::unique_ptr sub_graph = std::make_unique(); + for (auto& node_idx : sorted_nodes) { + graph_viewer.GetNode(node_idx)->ForEachDef([&required_initializers, &init_tensors] + (const NodeArg& node_arg, bool is_input) { + if(is_input && init_tensors.count(node_arg.Name())) { + required_initializers.insert(node_arg.Name()); + } }, true); + } + + auto meta_def = std::make_unique<::onnxruntime::IndexedSubGraph::MetaDef>(); + meta_def->name = "TVMStandalone"; + meta_def->domain = "StandaloneTest"; + std::vector inputs; + std::vector outputs; + + for (auto& nodeArgPtr : graph_viewer.GetInputs()) { + inputs.push_back(nodeArgPtr->Name()); + } + + for (auto& name : required_initializers) { + inputs.push_back(name); + } + + for (auto& nodeArgPtr : graph_viewer.GetOutputs()) { + outputs.push_back(nodeArgPtr->Name()); + } + meta_def->inputs = inputs; + meta_def->outputs = outputs; + meta_def->since_version = 1; + meta_def->status = ONNX_NAMESPACE::EXPERIMENTAL; + sub_graph->SetMetaDef(std::move(meta_def)); + sub_graph->nodes = sorted_nodes; + result.push_back( + std::make_unique(std::move(sub_graph))); + return result; +} + +common::Status StvmExecutionProvider::Compile(const std::vector& nodes, + std::vector& node_compute_funcs) { + for (auto* fused_node : nodes) { + auto func_body = fused_node->GetFunctionBody(); + if (!func_body) + return common::Status(common::ONNXRUNTIME, common::INVALID_ARGUMENT, "Function body is empty"); + const std::string func_name = fused_node->Name(); + const Graph& node_graph = func_body->Body(); + Model model(node_graph.Name(), true, ModelMetaData(), PathString(), + IOnnxRuntimeOpSchemaRegistryList(), node_graph.DomainToVersionMap(), + std::vector(), *GetLogger()); + ONNX_NAMESPACE::ModelProto model_proto = model.ToProto(); + + *(model_proto.mutable_graph()) = node_graph.ToGraphProto(); + auto opset = model_proto.add_opset_import(); + opset->set_domain(kOnnxDomain); + opset->set_version(node_graph.DomainToVersionMap().at(kOnnxDomain)); + + std::string string_buf; + model_proto.SerializeToString(&string_buf); + buffers_[func_name] = string_buf; + opsets_[func_name] = int(opset->version()); + model_paths_[func_name] = fused_node->ModelPath().ToPathString();; + + if (dump_subgraphs_) { + std::fstream dump("/tmp/" + fused_node->Name() + ".onnx", + std::ios::out | std::ios::trunc | std::ios::binary); + model_proto.SerializeToOstream(&dump); + } + + NodeComputeInfo compute_info; + compute_info.create_state_func = std::bind(&StvmExecutionProvider::CreateStateFunc, + this, + std::placeholders::_1, + std::placeholders::_2); + + compute_info.release_state_func = [](FunctionState state) { + if (state) + delete static_cast(state); + }; + // TODO(vvchernov): implement ops checking and mechanism of gracefully passing the responsibility to other EPs + // if the checking fails due to unsupported op(s) + runners_[func_name] = std::make_shared(this, func_name, node_graph); + compute_info.compute_func = *runners_[func_name].get(); + + node_compute_funcs.push_back(compute_info); + } + return Status::OK(); +} + +std::unique_ptr StvmExecutionProvider::GetDataTransfer() const { + if (GPUTargetCheck()) { + return std::make_unique(); + } else if (info_.target.find("llvm") != std::string::npos) { + return std::make_unique(); + } else { + ORT_NOT_IMPLEMENTED("STVM GetDataTransfer is not implemented for target ", info_.target); + } +} + +bool StvmExecutionProvider::GPUTargetCheck() const { + //TODO(vvchernov): target or target host? + bool check = ( + info_.target.find("cuda") != std::string::npos || + info_.target.find("opencl") != std::string::npos || + info_.target.find("metal") != std::string::npos || + info_.target.find("vulkan") != std::string::npos + ); + return check; +} + +size_t StvmExecutionProvider::split(const std::string &txt, std::vector &strs, char ch) const { + size_t pos = txt.find( ch ); + size_t initialPos = 0; + strs.clear(); + + while( pos != std::string::npos ) { + strs.push_back( txt.substr( initialPos, pos - initialPos ) ); + initialPos = pos + 1; + + pos = txt.find( ch, initialPos ); + } + + strs.push_back( txt.substr( initialPos, std::min( pos, txt.size() ) - initialPos + 1 ) ); + + return strs.size(); +} + +void StvmExecutionProvider::ProcessInfo() { + if(!info_.input_shapes_str.empty()) { + ORT_ENFORCE(!info_.input_names_str.empty(), + "Please insert input tensor names. Input shapes only is invalid case"); + // Parse strings and set to input_shapes map + std::vector tmp_strs; + std::vector names_strs; + + std::string names_str = StvmExecutionProviderInfo::whitespace_trimming(info_.input_names_str); + std::string shapes_str = StvmExecutionProviderInfo::whitespace_trimming(info_.input_shapes_str); + + ORT_ENFORCE(split(names_str, names_strs, ' '), "There is no any input tensor names!"); + size_t inp_tensors_num = names_strs.size(); + + size_t end_pos = shapes_str.find_last_of(']'); + ORT_ENFORCE(end_pos != std::string::npos, "Invalid string for input shapes. Symbol ] is not found"); + ORT_ENFORCE(end_pos == (shapes_str.size() - 1), + "Invalid string for input shapes. Symbol ] should be last after whitespace trimming"); + split(shapes_str, tmp_strs, ']'); + tmp_strs.pop_back(); + ORT_ENFORCE( tmp_strs.size() == inp_tensors_num, + "Number of shapes is not the same as number of input tensor names"); + for (size_t i = 0; i < inp_tensors_num; ++i) { + size_t pos = tmp_strs[i].find('['); + ORT_ENFORCE(pos != std::string::npos, "There is no symbol [ as pair for ]"); + std::string nums_str = tmp_strs[i].substr(pos + 1); + std::vector nums_strs; + ORT_ENFORCE(split(nums_str, nums_strs, ' '), "There is no any numbers between [ and ] symbols"); + std::vector dims; + for(const auto& num_str : nums_strs) { + dims.push_back(std::stoi(num_str)); + } + + info_.input_shapes[names_strs[i]] = dims; + } + } + + if(info_.target == cpu_target_str || + info_.target == llvm_target_str) { + ProcessCPUTarget(); + } else if(info_.target == gpu_target_str) { + ProcessGPUTarget(); + } else if(info_.target.empty()) { + ORT_NOT_IMPLEMENTED("target option is empty!"); + } else { + // TODO(vvchernov): extend mechanism of auto-definition of target + // target is gotten from option set up by client + } + + if((info_.target_host == cpu_target_str || + info_.target_host == llvm_target_str) && + info_.target_host != info_.target) { + info_.target_host = info_.target; + } else if (info_.target_host.empty()) { + info_.target_host = info_.target; + } else { + // TODO(vvchernov): extend mechanism of auto-definition of target host + // target host is gotten from option set up by client + } + + if(info_.opt_level < 1) { + info_.opt_level = default_opt_level; + } + + PrintInfo(); +} + +void StvmExecutionProvider::ProcessCPUTarget() { + const auto& cpu_id_info = CPUIDInfo::GetCPUIDInfo(); + // auto detect from CPU ID + if (cpu_id_info.HasAVX512Skylake()) { + info_.target = stvm_cpu_targets::LLVM_TARGET_SKYLAKE_AVX512; + } else if (cpu_id_info.HasAVX512f()) { + info_.target = stvm_cpu_targets::LLVM_TARGET_AVX512; + } else if (cpu_id_info.HasAVX2()) { + info_.target = stvm_cpu_targets::LLVM_TARGET_AVX2; + } else if (cpu_id_info.HasAVX()) { + info_.target = stvm_cpu_targets::LLVM_TARGET_AVX; + } else { + // TODO(vvchernov): extend mechanism of auto-definition of cpu target + info_.target = llvm_target_str; + } +} + +void StvmExecutionProvider::ProcessGPUTarget() { + ORT_NOT_IMPLEMENTED("GPU target auto-defenition is not implemented now!"); +} + +void StvmExecutionProvider::PrintInfo() const { + LOG(INFO) << "STVM ep options:\n" << + "target: " << info_.target << "\n" << + "target_host: " << info_.target_host << "\n" << + "opt level: " << info_.opt_level << "\n" << + "freeze weights: " << info_.freeze_weights << "\n" << + "tuning file path: " << info_.tuning_file_path << "\n" << + "tuning type: " << info_.tuning_type << "\n" << + "convert layout to NHWC: " << info_.to_nhwc << "\n" << + "input tensor names: " << info_.input_names_str << "\n" << + "input tensor shapes: " << info_.input_shapes_str; +} + +int StvmExecutionProvider::CreateStateFunc(ComputeContext* context, FunctionState* state) { + auto* state_ptr = new STVMFuncState(); + *state_ptr = {context->allocate_func, + context->release_func, + context->allocator_handle, + nullptr, + std::bind(&StvmExecutionProvider::CompileFunc, + this, + std::placeholders::_1, + std::placeholders::_2)}; + *state = state_ptr; + return 0; +} + +tvm::runtime::Module* StvmExecutionProvider::CompileFunc(std::string func_name, + const TVMTensorShapes& input_shapes) { + if (modules_.count(func_name)) { + return modules_[func_name].get(); + } + + tvm::runtime::Module mod_f = stvm::TVMCompile(buffers_[func_name], + model_paths_[func_name], + info_.target, + info_.target_host, + info_.opt_level, + opsets_[func_name], + info_.freeze_weights, + input_shapes, + info_.to_nhwc, + info_.tuning_file_path, + info_.tuning_type); + auto module_ptr = std::make_shared(); + *module_ptr = mod_f; + modules_[func_name] = module_ptr; + // Release memory after module generation + buffers_.erase(func_name); + opsets_.erase(func_name); + return modules_[func_name].get(); +} + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/stvm/stvm_execution_provider.h b/onnxruntime/core/providers/stvm/stvm_execution_provider.h new file mode 100644 index 0000000000..9e1f568edf --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_execution_provider.h @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_EXECUTION_PROVIDER_H +#define STVM_EXECUTION_PROVIDER_H + +#include +#include +#include +#include + +#include "core/common/logging/logging.h" +#include "core/framework/execution_provider.h" +#include "core/providers/stvm/stvm_execution_provider_info.h" +#include "core/platform/ort_mutex.h" + +#include "stvm_common.h" + +namespace onnxruntime { + +namespace stvm_env_vars { + static const std::string kDumpSubgraphs = "ORT_STVM_DUMP_SUBGRAPHS"; +} // namespace stvm_env_vars + +class STVMRunner; + +class StvmExecutionProvider : public IExecutionProvider { + friend STVMRunner; + + using TVMTensorShape = std::vector; + using TVMTensorShapes = std::vector; + using STVMRunners = std::unordered_map>; + using STVMModules = std::unordered_map>; + public: + explicit StvmExecutionProvider(const StvmExecutionProviderInfo& info); + virtual ~StvmExecutionProvider(); + + std::vector> + GetCapability(const onnxruntime::GraphViewer& graph, + const std::vector& /*kernel_registries*/) const override; + + common::Status Compile(const std::vector& fused_nodes, + std::vector& node_compute_funcs) override; + std::unique_ptr GetDataTransfer() const override; + AllocatorPtr GetAllocator(int id, OrtMemType mem_type) const override; + + private: + bool GPUTargetCheck() const; + size_t split(const std::string &txt, std::vector &strs, char ch) const; + void ProcessInfo(); + void ProcessCPUTarget(); + void ProcessGPUTarget(); + void PrintInfo() const; + // Bindings for compute info + int CreateStateFunc(ComputeContext*, FunctionState*); + tvm::runtime::Module* CompileFunc(std::string func_name, const TVMTensorShapes& input_shapes); + private: + STVMRunners runners_; + std::unordered_map buffers_; + std::unordered_map opsets_; + std::unordered_map model_paths_; + bool dump_subgraphs_ = false; + OrtMutex stvm_mu_; + AllocatorPtr allocator_; + StvmExecutionProviderInfo info_; + STVMModules modules_; +}; + +} // namespace onnxruntime + +#endif // STVM_EXECUTION_PROVIDER_H diff --git a/onnxruntime/core/providers/stvm/stvm_execution_provider_info.cc b/onnxruntime/core/providers/stvm/stvm_execution_provider_info.cc new file mode 100644 index 0000000000..079b2742fa --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_execution_provider_info.cc @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include + +#include "core/providers/stvm/stvm_execution_provider_info.h" + +#include "core/common/common.h" +#include "core/framework/provider_options_utils.h" + +namespace onnxruntime { +namespace stvm { +namespace provider_option_names { +constexpr const char* kTarget = "target"; +constexpr const char* kTargetHost = "target_host"; +constexpr const char* kOptLevel = "opt_level"; +constexpr const char* kFreezeWeights = "freeze_weights"; +constexpr const char* kToNHWC = "to_nhwc"; +constexpr const char* kTuningFilePath = "tuning_file_path"; +constexpr const char* kTuningType = "tuning_type"; +constexpr const char* kInputNames = "input_names"; +constexpr const char* kInputShapes = "input_shapes"; + +static const std::unordered_set valid_keys { + std::string{kTarget}, + std::string{kTargetHost}, + std::string{kOptLevel}, + std::string{kFreezeWeights}, + std::string{kToNHWC}, + std::string{kTuningFilePath}, + std::string{kTuningType}, + std::string{kInputNames}, + std::string{kInputShapes} +}; + +} // namespace provider_option_names +} // namespace stvm + +std::string StvmExecutionProviderInfo::whitespace_trimming(const std::string& str) { + const std::string WHITESPACE = " \n\r\t\f\v"; + size_t start = str.find_first_not_of(WHITESPACE); + if (start == std::string::npos) { + return ""; + } else { + size_t end = str.find_last_not_of(WHITESPACE); + ORT_ENFORCE(end != std::string::npos); + return str.substr(start, end + 1); + } +} + +StvmExecutionProviderInfo StvmExecutionProviderInfo::FromProviderOptions(const ProviderOptions& options) { + StvmExecutionProviderInfo info{}; + + ORT_THROW_IF_ERROR( + ProviderOptionsParser{} + .AddAssignmentToReference(stvm::provider_option_names::kTarget, info.target) + .AddAssignmentToReference(stvm::provider_option_names::kTargetHost, info.target_host) + .AddAssignmentToReference(stvm::provider_option_names::kOptLevel, info.opt_level) + .AddAssignmentToReference(stvm::provider_option_names::kFreezeWeights, info.freeze_weights) + .AddAssignmentToReference(stvm::provider_option_names::kToNHWC, info.to_nhwc) + .AddAssignmentToReference(stvm::provider_option_names::kTuningFilePath, info.tuning_file_path) + .AddAssignmentToReference(stvm::provider_option_names::kTuningType, info.tuning_type) + .AddAssignmentToReference(stvm::provider_option_names::kInputNames, info.input_names_str) + .AddAssignmentToReference(stvm::provider_option_names::kInputShapes, info.input_shapes_str) + .Parse(options)); + + return info; +} + +StvmExecutionProviderInfo StvmExecutionProviderInfo::FromOptionsString(const char* opt_str) { + std::string settings{opt_str}; + ProviderOptions options; + if (!settings.empty()) { + const std::string& str = settings; + + // tokenize settings + std::regex reg("\\s*,\\s*"); + std::sregex_token_iterator iter(str.begin(), str.end(), reg, -1); + std::sregex_token_iterator iter_end; + std::vector pairs(iter, iter_end); + + ORT_ENFORCE(pairs.size() > 0); + + for(const auto& pair : pairs) { + auto pos_colon = pair.find(':'); + ORT_ENFORCE(pos_colon != std::string::npos, "Invalid key value pair."); + std::string key = pair.substr(0, pos_colon); + std::string value = pair.substr(pos_colon + 1); + + // trim leading and trailing spaces from key/value + key = whitespace_trimming(key); + value = whitespace_trimming(value); + + // Check keys of obtained options + if (stvm::provider_option_names::valid_keys.count(key) == 0) { + ORT_NOT_IMPLEMENTED("StvmOptions: unknown option (", key, ")"); + } + + options[key] = value; + } + } + + return FromProviderOptions(options); +} + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/stvm/stvm_execution_provider_info.h b/onnxruntime/core/providers/stvm/stvm_execution_provider_info.h new file mode 100644 index 0000000000..d3adc5d3f7 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_execution_provider_info.h @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_EXECUTION_PROVIDER_INFO_H +#define STVM_EXECUTION_PROVIDER_INFO_H + +#include +#include +#include + +#include "core/framework/provider_options.h" + +namespace onnxruntime { + +constexpr const char* default_target_str = "cpu"; +constexpr const char* llvm_target_str = "llvm"; + +constexpr const char* cpu_target_str = "cpu"; +constexpr const char* gpu_target_str = "gpu"; + +namespace stvm_cpu_targets { +// TODO(vvchernov): avx and avx512 need more careful differentiation for target +const std::string LLVM_TARGET_AVX = "llvm -mcpu=corei7-avx"; +const std::string LLVM_TARGET_AVX2 = "llvm -mcpu=core-avx2"; +const std::string LLVM_TARGET_SKYLAKE_AVX512 = "llvm -mcpu=skylake-avx512"; +const std::string LLVM_TARGET_AVX512 = "llvm -mcpu=skylake-avx512"; +} + +constexpr const unsigned int default_opt_level = 3; + +using STVMInputShapes = std::unordered_map>; + +// Information needed to construct an TVM execution provider. +struct StvmExecutionProviderInfo { + std::string target{default_target_str}; + std::string target_host{default_target_str}; + unsigned int opt_level{default_opt_level}; + bool freeze_weights = true; + bool to_nhwc = false; + std::string tuning_file_path{""}; + std::string tuning_type{"AutoTVM"}; + std::string input_names_str{""}; + std::string input_shapes_str{""}; + STVMInputShapes input_shapes{}; + + static std::string whitespace_trimming(const std::string& str); + static StvmExecutionProviderInfo FromProviderOptions(const ProviderOptions& options); + static StvmExecutionProviderInfo FromOptionsString(const char* options); +}; + +} // namespace onnxruntime + +#endif // STVM_EXECUTION_PROVIDER_INFO_H diff --git a/onnxruntime/core/providers/stvm/stvm_provider_factory.cc b/onnxruntime/core/providers/stvm/stvm_provider_factory.cc new file mode 100644 index 0000000000..79c13a08b1 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_provider_factory.cc @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include + +#include "core/providers/stvm/stvm_provider_factory.h" +#include "stvm_execution_provider.h" + +#include "core/session/abi_session_options_impl.h" + +namespace onnxruntime { + +struct StvmProviderFactory : IExecutionProviderFactory { + StvmProviderFactory(const StvmExecutionProviderInfo& info) : info_{info} {} + ~StvmProviderFactory() = default; + + std::unique_ptr CreateProvider() override { + return std::make_unique(info_); + } + + private: + StvmExecutionProviderInfo info_; +}; + +std::shared_ptr CreateExecutionProviderFactory_Stvm(const char* settings) { + StvmExecutionProviderInfo info = StvmExecutionProviderInfo::FromOptionsString(settings); + return std::make_shared(info); +} + +std::shared_ptr CreateExecutionProviderFactory_Stvm(const StvmExecutionProviderInfo& info) +{ + return std::make_shared(info); +} +} // namespace onnxruntime + +ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Stvm, + _In_ OrtSessionOptions* options, + _In_ const char* settings) { + onnxruntime::StvmExecutionProviderInfo info = onnxruntime::StvmExecutionProviderInfo::FromOptionsString(settings); + options->provider_factories.push_back(onnxruntime::CreateExecutionProviderFactory_Stvm(info)); + return nullptr; +} diff --git a/onnxruntime/core/providers/stvm/stvm_utils.h b/onnxruntime/core/providers/stvm/stvm_utils.h new file mode 100644 index 0000000000..95c6a66e21 --- /dev/null +++ b/onnxruntime/core/providers/stvm/stvm_utils.h @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef STVM_UTILS_H +#define STVM_UTILS_H + +#include "stvm_common.h" + +#include "core/session/onnxruntime_cxx_api.h" +#include "core/framework/ortdevice.h" +#include "core/common/common.h" + +namespace onnxruntime { + +inline DLDataType GetDataType(ONNXTensorElementDataType type) { + if (type == ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE) { + return {kDLFloat, 64, 1}; + } else if (type == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16) { + return {kDLFloat, 16, 1}; + } else if (type == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT) { + return {kDLFloat, 32, 1}; + } else if (type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) { + return {kDLInt, 64, 1}; + } else if (type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32) { + return {kDLInt, 32, 1}; + } else { + ORT_NOT_IMPLEMENTED("Unsupported data type"); + } +} + +inline DLDataType GetDataTypeFromProto() { + return {kDLFloat, 32, 1}; +} + +inline DLDevice GetDLDevice(const OrtDevice& device) { + DLDevice context; + switch (device.Type()) { + case OrtDevice::CPU: + context = {kDLCPU, 0}; + break; + case OrtDevice::GPU: + context = {kDLVulkan, 0}; + break; + default: + ORT_NOT_IMPLEMENTED("Unsupported device"); + break; + } + return context; +} + +} // namespace onnxruntime + +#endif // STVM_UTILS_H diff --git a/onnxruntime/core/providers/stvm/symbols.txt b/onnxruntime/core/providers/stvm/symbols.txt new file mode 100644 index 0000000000..0fbccbe287 --- /dev/null +++ b/onnxruntime/core/providers/stvm/symbols.txt @@ -0,0 +1 @@ +OrtSessionOptionsAppendExecutionProvider_Stvm diff --git a/onnxruntime/core/providers/stvm/xpu_data_transfer.cc b/onnxruntime/core/providers/stvm/xpu_data_transfer.cc new file mode 100644 index 0000000000..3bbdcfb5c3 --- /dev/null +++ b/onnxruntime/core/providers/stvm/xpu_data_transfer.cc @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "core/framework/tensor.h" + +#include "xpu_data_transfer.h" +#include "stvm_utils.h" + +namespace onnxruntime { +XPUDataTransfer::XPUDataTransfer() { +} + +XPUDataTransfer::~XPUDataTransfer() { +} + +bool XPUDataTransfer::CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const { + return (src_device.Type() == OrtDevice::CPU && dst_device.Type() == OrtDevice::CPU) || + (src_device.Type() == OrtDevice::GPU || dst_device.Type() == OrtDevice::GPU); +} + +common::Status XPUDataTransfer::CopyTensor(const Tensor& src, Tensor& dst, int _exec_queue_id) const { + _exec_queue_id = _exec_queue_id + 1; + size_t bytes = src.SizeInBytes(); + const void* src_data = src.DataRaw(); + void* dst_data = dst.MutableDataRaw(); + const OrtDevice& src_device = src.Location().device; + const OrtDevice& dst_device = dst.Location().device; + + if ((src_device.Type() == OrtDevice::CPU) && (dst_device.Type() == OrtDevice::CPU)) { + if (src_data == dst_data) { + // no need copying as both pointers are referring to same piece of memory. + return Status::OK(); + } + memcpy(dst_data, src_data, bytes); + } else { + DLTensor tvm_src, tvm_dst; + DLDataType dl_type{kDLInt, 8, 1}; + std::vector shape{int64_t(bytes)}; + // Construct source DLTensor + tvm_src.device = GetDLDevice(src_device); + tvm_src.dtype = dl_type; + tvm_src.strides = nullptr; + tvm_src.byte_offset = 0; + tvm_src.data = const_cast(src_data); + tvm_src.ndim = 1; + tvm_src.shape = shape.data(); + // Construct destination DLTensor + tvm_dst.device = GetDLDevice(dst_device); + tvm_dst.dtype = dl_type; + tvm_dst.strides = nullptr; + tvm_dst.byte_offset = 0; + tvm_dst.data = dst_data; + tvm_dst.ndim = 1; + tvm_dst.shape = shape.data(); + // Copying from src to dst + TVMDeviceCopyDataFromTo(&tvm_src, &tvm_dst, nullptr); + } + return Status::OK(); +} + +DLDevice XPUDataTransfer::get_context(const OrtDevice& device) const +{ + return GetDLDevice(device); +} + +bool StvmCPUDataTransfer::CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const { + return src_device.Type() == OrtDevice::CPU && dst_device.Type() == OrtDevice::CPU; +} + +common::Status StvmCPUDataTransfer::CopyTensor(const Tensor& src, Tensor& dst, int /*exec_queue_id*/) const { + const void* src_data = src.DataRaw(); + void* dst_data = dst.MutableDataRaw(); + if (src_data == dst_data) { + // no need copying as both pointers are referring to same piece of memory. + return Status::OK(); + } + // Copying only happens between two same size tensors. + ORT_ENFORCE(src.SizeInBytes() == dst.SizeInBytes()); + memcpy(dst_data, src_data, src.SizeInBytes()); + return Status::OK(); +} + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/stvm/xpu_data_transfer.h b/onnxruntime/core/providers/stvm/xpu_data_transfer.h new file mode 100644 index 0000000000..1d5d655fa4 --- /dev/null +++ b/onnxruntime/core/providers/stvm/xpu_data_transfer.h @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#ifndef XPU_DATA_TRANSFER +#define XPU_DATA_TRANSFER + +#include "core/framework/data_transfer.h" +#include "stvm_common.h" + +namespace onnxruntime { + +class XPUDataTransfer : public IDataTransfer { + public: + XPUDataTransfer(); + ~XPUDataTransfer(); + + bool CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const override; + + // Dumpen MSVC warning about not fully overriding + using IDataTransfer::CopyTensor; + common::Status CopyTensor(const Tensor& src, Tensor& dst, int exec_queue_id) const override; + DLDevice get_context(const OrtDevice& device) const; +}; + +class StvmCPUDataTransfer : public IDataTransfer { + public: + StvmCPUDataTransfer() = default; + // Dampen MSVC warning about not fully overriding CopyTensor + using IDataTransfer::CopyTensor; + bool CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const override; + common::Status CopyTensor(const Tensor& src, Tensor& dst, int exec_queue_id) const override; +}; + +} // namespace onnxruntime +#endif // XPU_DATA_TRANSFER diff --git a/onnxruntime/core/session/provider_stubs.cc b/onnxruntime/core/session/provider_stubs.cc index b136854a6c..2b3369daa8 100644 --- a/onnxruntime/core/session/provider_stubs.cc +++ b/onnxruntime/core/session/provider_stubs.cc @@ -58,6 +58,15 @@ ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Nuphar, } #endif +#ifndef USE_STVM +ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Stvm, + _In_ OrtSessionOptions* options, _In_ const char* settings) { + ORT_UNUSED_PARAMETER(options); + ORT_UNUSED_PARAMETER(settings); + return CreateNotEnabledStatus("Stvm"); +} +#endif + #ifdef __cplusplus } #endif diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc index 05bed14739..2ed442df75 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.cc +++ b/onnxruntime/python/onnxruntime_pybind_state.cc @@ -636,6 +636,16 @@ std::unique_ptr CreateExecutionProviderInstance( // clear nuphar_settings after use to avoid it being accidentally passed on to next session nuphar_settings.clear(); return p; +#endif + } else if (type == kStvmExecutionProvider) { +#if USE_STVM + onnxruntime::StvmExecutionProviderInfo info{}; + const auto it = provider_options_map.find(type); + if (it != provider_options_map.end()) { + info = onnxruntime::StvmExecutionProviderInfo::FromProviderOptions(it->second); + } + + return onnxruntime::CreateExecutionProviderFactory_Stvm(info)->CreateProvider(); #endif } else if (type == kVitisAIExecutionProvider) { #if USE_VITISAI diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index f5f4a3c75f..0218c2c5f1 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -23,7 +23,7 @@ struct OrtStatus { char msg[1]; // a null-terminated string }; -#define BACKEND_DEVICE BACKEND_PROC BACKEND_DNNL BACKEND_OPENVINO BACKEND_NUPHAR BACKEND_OPENBLAS BACKEND_MIGRAPHX BACKEND_ACL BACKEND_ARMNN BACKEND_DML +#define BACKEND_DEVICE BACKEND_PROC BACKEND_DNNL BACKEND_OPENVINO BACKEND_NUPHAR BACKEND_STVM BACKEND_OPENBLAS BACKEND_MIGRAPHX BACKEND_ACL BACKEND_ARMNN BACKEND_DML #include "core/session/onnxruntime_cxx_api.h" #include "core/providers/providers.h" #include "core/providers/cpu/cpu_execution_provider.h" @@ -85,6 +85,12 @@ struct OrtStatus { #define BACKEND_NUPHAR "" #endif +#ifdef USE_STVM +#define BACKEND_STVM "-STVM" +#else +#define BACKEND_STVM "" +#endif + #if USE_VITISAI #define BACKEND_VITISAI "-VITISAI" #include "core/providers/vitisai/vitisai_execution_provider.h" @@ -149,6 +155,9 @@ extern std::string nuphar_settings; } } // namespace onnxruntime #endif +#ifdef USE_STVM +#include "core/providers/stvm/stvm_execution_provider_info.h" +#endif #ifdef USE_VITISAI #include "core/providers/vitisai/vitisai_provider_factory.h" #endif @@ -464,6 +473,10 @@ std::shared_ptr CreateExecutionProviderFactory_Cuda(c std::shared_ptr CreateExecutionProviderFactory_Dnnl(int use_arena); std::shared_ptr CreateExecutionProviderFactory_OpenVINO(const OrtOpenVINOProviderOptions* params); std::shared_ptr CreateExecutionProviderFactory_Nuphar(bool, const char*); +#ifdef USE_STVM +std::shared_ptr CreateExecutionProviderFactory_Stvm(const StvmExecutionProviderInfo& info); +std::shared_ptr CreateExecutionProviderFactory_Stvm(const char* params); +#endif std::shared_ptr CreateExecutionProviderFactory_VITISAI(const char* backend_type, int device_id, const char* export_runtime_module, const char* load_runtime_module); diff --git a/onnxruntime/python/providers/stvm/__init__.py b/onnxruntime/python/providers/stvm/__init__.py new file mode 100644 index 0000000000..4bafb9be5b --- /dev/null +++ b/onnxruntime/python/providers/stvm/__init__.py @@ -0,0 +1,10 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +""" +JIT interface implementing packed functions that +import and compile frontend models +""" +from .ort import ANSOR_TYPE, AUTO_TVM_TYPE, run_with_benchmark, run_without_benchmark, onnx_compile diff --git a/onnxruntime/python/providers/stvm/ort.py b/onnxruntime/python/providers/stvm/ort.py new file mode 100644 index 0000000000..2cefade4e2 --- /dev/null +++ b/onnxruntime/python/providers/stvm/ort.py @@ -0,0 +1,121 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import os +import timeit +import numpy as np +import collections + +import onnx +import tvm +from tvm import relay, auto_scheduler +from tvm.contrib import graph_executor +from tvm import autotvm + +ANSOR_TYPE = "Ansor" +AUTO_TVM_TYPE = "AutoTVM" + + +@tvm.register_func("tvm_run_with_benchmark") +def run_with_benchmark(mod): + run = mod.get_function('run') + + def benchmark(name): + t = timeit.Timer(lambda: run()).repeat(repeat=5, number=5) + ts = np.array(t) * 1000 + print("{} benchmark results: {:.2f}ms mean, {:.2f}ms median, {:.2f}ms std".format( + name, np.mean(ts), np.median(ts), np.std(ts) + )) + if os.getenv("AUTOTVM_TUNING_LOG"): + benchmark("Tuned") + else: + benchmark("Baseline") + + +@tvm.register_func("tvm_run") +def run_without_benchmark(mod): + run = mod.get_function('run') + run() + + +@tvm.register_func("tvm_onnx_import_and_compile") +def onnx_compile(model_string, + model_path, + target, + target_host, + opt_level, + opset, + freeze_params, + input_shapes, + nhwc=False, + tuning_logfile="", + tuning_type=AUTO_TVM_TYPE): + model = onnx.load_model_from_string(bytes(model_string)) + if model_path: + base_dir = os.path.dirname(os.path.abspath(model_path)) + onnx.load_external_data_for_model(model, base_dir) + + # Collect only feed input names from all input names + all_input_names = [node.name for node in model.graph.input] + all_initializer = [node.name for node in model.graph.initializer] + net_feed_input_names = list(set(all_input_names) - set(all_initializer)) + + # Match names and input shapes + all_input_mapping = [(name, shape) for (name, shape) in zip(all_input_names, input_shapes)] + # Using an ordereddict maintains input ordering. + shape_dict = collections.OrderedDict(all_input_mapping) + # Get only feed input pairs + feed_shape_dict = {} + for name in net_feed_input_names: + feed_shape_dict[name] = shape_dict[name] + + irmod, params = relay.frontend.from_onnx(model, feed_shape_dict, opset=opset, freeze_params=freeze_params) + + # TODO(vvchernov): replace prints by logger, but investigate ORT logging system for python before + # Also see lines 91, 106 + # print("Build TVM graph executor") + # Tuning file can be set by client through ep options + if tuning_logfile == "": + tuning_logfile = os.getenv("AUTOTVM_TUNING_LOG") + if tuning_type == ANSOR_TYPE: + if tuning_logfile: + desired_layouts = { + "nn.conv2d": ["NHWC", "default"], + "nn.conv2d_transpose": ["NHWC", "default"], + "nn.upsampling": ["NHWC", "default"], + "vision.roi_align": ["NHWC", "default"], + } + # print("Use tuning file from ", ANSOR_TYPE, ": ", tuning_logfile) + with auto_scheduler.ApplyHistoryBest(tuning_logfile): + with tvm.transform.PassContext(opt_level=opt_level, config={"relay.backend.use_auto_scheduler": True}): + if nhwc: + irmod = relay.transform.InferType()(irmod) + model_nhwc = relay.transform.ConvertLayout(desired_layouts)(irmod) + model_nhwc = tvm.relay.transform.EliminateCommonSubexpr()(model_nhwc) + irmod = tvm.relay.transform.FoldConstant()(model_nhwc) + lib = relay.build(irmod, target=target, target_host=target_host) + else: + with tvm.transform.PassContext(opt_level=opt_level): + lib = relay.build(irmod, target=target, target_host=target_host, params=params) + elif tuning_type == AUTO_TVM_TYPE: + with relay.build_config(opt_level=opt_level): + if tuning_logfile: + # print("Use tuning file from ", AUTO_TVM_TYPE, ": ", tuning_logfile) + with autotvm.apply_history_best(tuning_logfile): + # XXX: do not pass parameters to relay.build otherwise they will be inline into the module + lib = relay.build(irmod, target_host=target_host, target=target) + else: + lib = relay.build(irmod, target_host=target_host, target=target) + else: + # TODO(vvchernov): replace prints by logger, but investigate ORT logging system for python before + # print is not commented out while it declares error + print("ERROR: Tuning log type {} is unsupported. ".format(tuning_type), + "Only {} and {} types are supported".format(ANSOR_TYPE, AUTO_TVM_TYPE)) + return None + + ctx = tvm.device(target, 0) + m = graph_executor.GraphModule(lib["default"](ctx)) + return m.module diff --git a/onnxruntime/test/contrib_ops/fused_conv_test.cc b/onnxruntime/test/contrib_ops/fused_conv_test.cc index 8cbec7ee51..1e31f66e80 100644 --- a/onnxruntime/test/contrib_ops/fused_conv_test.cc +++ b/onnxruntime/test/contrib_ops/fused_conv_test.cc @@ -26,6 +26,7 @@ static std::unordered_set providers_except_cpu = { kDnnlExecutionProvider, kOpenVINOExecutionProvider, kNupharExecutionProvider, + kStvmExecutionProvider, kVitisAIExecutionProvider, kTensorrtExecutionProvider, kNnapiExecutionProvider, @@ -40,6 +41,7 @@ static std::unordered_set providers_except_cpu_cuda = { kDnnlExecutionProvider, kOpenVINOExecutionProvider, kNupharExecutionProvider, + kStvmExecutionProvider, kVitisAIExecutionProvider, kTensorrtExecutionProvider, kNnapiExecutionProvider, @@ -167,6 +169,7 @@ static std::unordered_set providers_except_cuda = { kDnnlExecutionProvider, kOpenVINOExecutionProvider, kNupharExecutionProvider, + kStvmExecutionProvider, kVitisAIExecutionProvider, kTensorrtExecutionProvider, kNnapiExecutionProvider, diff --git a/onnxruntime/test/providers/provider_test_utils.cc b/onnxruntime/test/providers/provider_test_utils.cc index 5400a22acc..4b666f621c 100644 --- a/onnxruntime/test/providers/provider_test_utils.cc +++ b/onnxruntime/test/providers/provider_test_utils.cc @@ -1112,6 +1112,7 @@ void OpTester::Run( if (provider_type == onnxruntime::kOpenVINOExecutionProvider || provider_type == onnxruntime::kTensorrtExecutionProvider || provider_type == onnxruntime::kNupharExecutionProvider || + // provider_type == onnxruntime::kStvmExecutionProvider || provider_type == onnxruntime::kNnapiExecutionProvider || provider_type == onnxruntime::kCoreMLExecutionProvider || provider_type == onnxruntime::kDnnlExecutionProvider) diff --git a/onnxruntime/test/util/default_providers.cc b/onnxruntime/test/util/default_providers.cc index b83c569d3c..978da66a0e 100644 --- a/onnxruntime/test/util/default_providers.cc +++ b/onnxruntime/test/util/default_providers.cc @@ -100,6 +100,14 @@ std::unique_ptr DefaultNupharExecutionProvider(bool allow_un #endif } +// std::unique_ptr DefaultStvmExecutionProvider() { +// #ifdef USE_STVM +// return CreateExecutionProviderFactory_Stvm("")->CreateProvider(); +// #else +// return nullptr; +// #endif +// } + std::unique_ptr DefaultNnapiExecutionProvider() { // For any non - Android system, NNAPI will only be used for ort model converter // Make it unavailable here, you can still manually append NNAPI EP to session for model conversion diff --git a/onnxruntime/test/util/include/default_providers.h b/onnxruntime/test/util/include/default_providers.h index 1171db9faf..6df390125a 100644 --- a/onnxruntime/test/util/include/default_providers.h +++ b/onnxruntime/test/util/include/default_providers.h @@ -16,6 +16,7 @@ std::shared_ptr CreateExecutionProviderFactory_MIGrap std::shared_ptr CreateExecutionProviderFactory_Nnapi( uint32_t flags, const optional& partitioning_stop_ops_list); std::shared_ptr CreateExecutionProviderFactory_Nuphar(bool, const char*); +//std::shared_ptr CreateExecutionProviderFactory_Stvm(const char*); std::shared_ptr CreateExecutionProviderFactory_OpenVINO( const char* device_type, bool enable_vpu_fast_compile, const char* device_id, size_t num_of_threads, bool use_compiled_network, const char* blob_dump_path); std::shared_ptr CreateExecutionProviderFactory_OpenVINO(const OrtOpenVINOProviderOptions* params); @@ -33,6 +34,7 @@ std::unique_ptr DefaultCpuExecutionProvider(bool enable_aren std::unique_ptr DefaultCudaExecutionProvider(); std::unique_ptr DefaultDnnlExecutionProvider(bool enable_arena = true); std::unique_ptr DefaultNupharExecutionProvider(bool allow_unaligned_buffers = true); +//std::unique_ptr DefaultStvmExecutionProvider(); std::unique_ptr DefaultTensorrtExecutionProvider(); std::unique_ptr TensorrtExecutionProviderWithOptions(const OrtTensorRTProviderOptions* params); std::unique_ptr DefaultMIGraphXExecutionProvider(); diff --git a/onnxruntime/test/util/include/providers.h b/onnxruntime/test/util/include/providers.h index de74c8f796..3ec1b79a9b 100644 --- a/onnxruntime/test/util/include/providers.h +++ b/onnxruntime/test/util/include/providers.h @@ -10,6 +10,9 @@ #ifdef USE_NUPHAR #include "core/providers/nuphar/nuphar_provider_factory.h" #endif +#ifdef USE_STVM +#include "core/providers/stvm/stvm_provider_factory.h" +#endif #ifdef USE_TENSORRT #include "core/providers/tensorrt/tensorrt_provider_factory.h" #endif diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 553e90ea6d..1ce6ae8ec4 100755 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -11,6 +11,7 @@ option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF) option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF) option(onnxruntime_USE_DNNL "Build with DNNL support" OFF) option(onnxruntime_USE_NUPHAR "Build with Nuphar" OFF) +option(onnxruntime_USE_STVM "Build with Stvm" OFF) option(onnxruntime_USE_TENSORRT "Build with TensorRT support" OFF) option(onnxruntime_USE_DML "Build with DirectML support" OFF) option(onnxruntime_USE_ACL "Build with ACL support" OFF) diff --git a/server/environment.cc b/server/environment.cc index 59d8e71764..ede884d110 100644 --- a/server/environment.cc +++ b/server/environment.cc @@ -17,6 +17,12 @@ #endif +#ifdef USE_STVM + +#include "core/providers/stvm/stvm_provider_factory.h" + +#endif + #ifdef USE_OPENVINO #include "core/providers/openvino/openvino_provider_factory.h" @@ -68,6 +74,10 @@ void ServerEnvironment::RegisterExecutionProviders(){ #ifdef USE_NUPHAR Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Nuphar(options_, 1, "")); #endif + + #ifdef USE_STVM + Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Stvm(options_, "")); + #endif #ifdef USE_OPENVINO Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_OpenVINO(options_, "")); diff --git a/setup.py b/setup.py index b28f48fcbd..2a1ec7f25d 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,8 @@ elif parse_arg_remove_boolean(sys.argv, '--use_dnnl'): package_name = 'onnxruntime-dnnl' elif parse_arg_remove_boolean(sys.argv, '--use_nuphar'): package_name = 'onnxruntime-nuphar' +elif parse_arg_remove_boolean(sys.argv, '--use_stvm'): + package_name = 'onnxruntime-stvm' elif parse_arg_remove_boolean(sys.argv, '--use_vitisai'): package_name = 'onnxruntime-vitisai' elif parse_arg_remove_boolean(sys.argv, '--use_acl'): @@ -72,7 +74,6 @@ elif parse_arg_remove_boolean(sys.argv, '--use_acl'): elif parse_arg_remove_boolean(sys.argv, '--use_armnn'): package_name = 'onnxruntime-armnn' - # PEP 513 defined manylinux1_x86_64 and manylinux1_i686 # PEP 571 defined manylinux2010_x86_64 and manylinux2010_i686 # PEP 599 defines the following platform tags: @@ -398,6 +399,9 @@ if package_name == 'onnxruntime-nuphar': packages += ["onnxruntime.nuphar"] extra += [path.join('nuphar', 'NUPHAR_CACHE_VERSION')] +if package_name == 'onnxruntime-stvm': + packages += ['onnxruntime.providers.stvm'] + package_data["onnxruntime"] = data + examples + extra version_number = '' diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 36aaa5da58..82c984608a 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -436,6 +436,10 @@ def parse_arguments(): "--use_vitisai", action='store_true', help="Build with Vitis-AI") parser.add_argument( "--use_nuphar", action='store_true', help="Build with nuphar") + parser.add_argument( + "--use_stvm", action='store_true', help="Build with standalone TVM") + parser.add_argument( + "--stvm_home", help="Path to TVM installation for the standalone TVM execution provider.") parser.add_argument( "--use_tensorrt", action='store_true', help="Build with TensorRT") parser.add_argument( @@ -765,6 +769,9 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home "-Donnxruntime_USE_NUPHAR=" + ("ON" if args.use_nuphar else "OFF"), "-Donnxruntime_USE_TENSORRT=" + ("ON" if args.use_tensorrt else "OFF"), "-Donnxruntime_TENSORRT_HOME=" + (tensorrt_home if args.use_tensorrt else ""), + # set vars for standalone TVM + "-Donnxruntime_USE_STVM=" + ("ON" if args.use_stvm else "OFF"), + "-Donnxruntime_STVM_HOME=" + (os.path.join(source_dir, "cmake", "external", "tvm_update")), # set vars for migraphx "-Donnxruntime_USE_MIGRAPHX=" + ("ON" if args.use_migraphx else "OFF"), "-Donnxruntime_MIGRAPHX_HOME=" + (migraphx_home if args.use_migraphx else ""), @@ -1707,7 +1714,7 @@ def run_nodejs_tests(nodejs_binding_dir): def build_python_wheel( source_dir, build_dir, configs, use_cuda, cuda_version, use_rocm, rocm_version, use_dnnl, - use_tensorrt, use_openvino, use_nuphar, use_vitisai, use_acl, use_armnn, use_dml, + use_tensorrt, use_openvino, use_nuphar, use_stvm, use_vitisai, use_acl, use_armnn, use_dml, wheel_name_suffix, enable_training, nightly_build=False, default_training_package_device=False, use_ninja=False, build_eager_mode=False): for config in configs: @@ -1746,6 +1753,8 @@ def build_python_wheel( args.append('--use_dnnl') elif use_nuphar: args.append('--use_nuphar') + elif use_stvm: + args.append('--use_stvm') elif use_vitisai: args.append('--use_vitisai') elif use_acl: @@ -1766,7 +1775,7 @@ def derive_linux_build_property(): def build_nuget_package(source_dir, build_dir, configs, use_cuda, use_openvino, use_tensorrt, use_dnnl, use_nuphar, - use_winml): + use_stvm, use_winml): if not (is_windows() or is_linux()): raise BuildError( 'Currently csharp builds and nuget package creation is only supportted ' @@ -1800,6 +1809,8 @@ def build_nuget_package(source_dir, build_dir, configs, use_cuda, use_openvino, package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.Gpu\"" elif use_nuphar: package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.Nuphar\"" + elif use_stvm: + package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.Stvm\"" else: # use the solution file that includes Xamarin mobile targets sln = "OnnxRuntime.CSharp.sln" @@ -2327,6 +2338,7 @@ def main(): args.use_tensorrt, args.use_openvino, args.use_nuphar, + args.use_stvm, args.use_vitisai, args.use_acl, args.use_armnn, @@ -2348,6 +2360,7 @@ def main(): args.use_tensorrt, args.use_dnnl, args.use_nuphar, + args.use_stvm, args.use_winml, ) From 4e73cc83d6d646f2c8ee52ba3ee90dc5669b1bef Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Thu, 16 Dec 2021 09:08:57 +0800 Subject: [PATCH 051/113] Fix building DNNL EP with clang (#10014) Before this change, building DNNL EP from onnxruntime 1.10.0 with clang fails with: In file included from /build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc:4: In file included from /build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.h:5: In file included from /build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.h:10: In file included from /build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/shared_library/provider_api.h:19: In file included from /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/common.h:36: /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:33:6: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup ss << t; ^ /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:39:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here MakeStringImpl(ss, args...); ^ /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:39:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:39:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:39:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:39:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:46:3: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here MakeStringImpl(ss, args...); ^ /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/make_string.h:93:18: note: in instantiation of function template specialization 'onnxruntime::detail::MakeStringImpl>' requested here return detail::MakeStringImpl(detail::if_char_array_make_ptr_t(args)...); ^ /build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc:46:7: note: in instantiation of function template specialization 'onnxruntime::MakeString>' requested here ORT_ENFORCE(data_dims[i] == 1, "Dimension of input ", i, " must be 1 instead of ", data_dims[i], ^ /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/common/common.h:184:64: note: expanded from macro 'ORT_ENFORCE' ::onnxruntime::MakeString(__VA_ARGS__)); \ ^ /build/python-onnxruntime/src/onnxruntime/include/onnxruntime/core/framework/tensor_shape.h:147:15: note: 'operator<<' should be declared prior to the call site std::ostream& operator<<(std::ostream& out, const TensorShape& shape); ^ 1 error generated. make[2]: *** [CMakeFiles/onnxruntime_providers_dnnl.dir/build.make:384: CMakeFiles/onnxruntime_providers_dnnl.dir/build/python-onnxruntime/src/onnxruntime/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc.o] Error 1 Two-phase lookups fail as: 1. visible in the template definition - fails as `std::ostream& operator<<(std::ostream& out, const TensorShape& shape)` (from include/onnxruntime/core/framework/tensor_shape.h) is defined after `template std::string MakeString(const Args&... args)` (from include/onnxruntime/core/common/make_string.h) as per `clang++ -E` 2. argument-dependent lookup - fails as the argument data_dims has type `std::vector` (via typedef in dnnl.hpp), while `std::ostream& operator<<(std::ostream& out, const TensorShape& shape)` is in namespace onnxruntime instead of std There are several possible fixes: * Make operator<< appear before MakeString by adjust the order of header files - I consider it fragile * Also define operator<< in namespace std - may results in namespace pollution * Use an argument of a class in onnxruntime namespace - this commit --- onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc index db66cb3a39..f9c2fe9b6b 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_squeeze.cc @@ -44,7 +44,7 @@ void DnnlSqueeze::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node) { if ((j < axes_data.size() && axes_data[j] == static_cast(i)) || (axes_data.size() == 0 && data_dims[i] == 1)) { ORT_ENFORCE(data_dims[i] == 1, "Dimension of input ", i, " must be 1 instead of ", data_dims[i], - ". shape=", data_dims); + ". shape=", TensorShape(data_dims)); ++j; continue; } From 3466ee45a3e851e176431c49a0a6ef35e35efaef Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Wed, 15 Dec 2021 19:07:17 -0800 Subject: [PATCH 052/113] Add hash value typedef. (#9710) Add a typedef for the various hash value variables. Use of a typedef conveys some additional meaning. --- include/onnxruntime/core/common/basic_types.h | 13 +++++++++++ .../core/framework/execution_provider.h | 22 ++++++++++--------- .../core/framework/kernel_def_builder.h | 4 ++-- .../core/framework/kernel_registry.h | 6 ++--- include/onnxruntime/core/graph/basic_types.h | 5 +++-- .../core/framework/execution_provider.cc | 6 ++--- .../core/framework/graph_partitioner.cc | 6 ++--- .../core/framework/graph_partitioner.h | 4 ++-- onnxruntime/core/framework/kernel_registry.cc | 2 +- .../core/framework/kernel_registry_manager.cc | 2 +- .../core/framework/kernel_registry_manager.h | 2 +- .../core/framework/prepacked_weights.cc | 4 ++-- .../core/framework/prepacked_weights.h | 3 ++- onnxruntime/core/framework/session_state.cc | 2 +- onnxruntime/core/framework/session_state.h | 6 ++--- .../session_state_flatbuffers_utils.h | 2 +- .../core/graph/runtime_optimization_record.h | 2 +- .../coreml/coreml_execution_provider.cc | 2 +- .../providers/dnnl/dnnl_execution_provider.cc | 4 ++-- .../nnapi_builtin/nnapi_execution_provider.cc | 2 +- .../provider_bridge_provider.cc | 2 +- .../shared_library/provider_interfaces.h | 3 ++- .../tensorrt/tensorrt_execution_provider.cc | 2 +- onnxruntime/core/session/inference_session.cc | 2 +- .../core/session/provider_bridge_ort.cc | 2 +- .../test/framework/execution_provider_test.cc | 10 ++++----- .../internal_testing_execution_provider.cc | 2 +- 27 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 include/onnxruntime/core/common/basic_types.h diff --git a/include/onnxruntime/core/common/basic_types.h b/include/onnxruntime/core/common/basic_types.h new file mode 100644 index 0000000000..56f958bf24 --- /dev/null +++ b/include/onnxruntime/core/common/basic_types.h @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include + +namespace onnxruntime { + +/** A computed hash value. */ +using HashValue = uint64_t; + +} // namespace onnxruntime diff --git a/include/onnxruntime/core/framework/execution_provider.h b/include/onnxruntime/core/framework/execution_provider.h index bea28f31b2..1091271966 100644 --- a/include/onnxruntime/core/framework/execution_provider.h +++ b/include/onnxruntime/core/framework/execution_provider.h @@ -4,13 +4,14 @@ #pragma once #ifndef SHARED_PROVIDER +#include #include #include -#include -#include "core/common/status.h" + #include "core/common/logging/logging.h" -#include "core/framework/tensor.h" +#include "core/common/status.h" #include "core/framework/data_transfer.h" +#include "core/framework/tensor.h" namespace onnxruntime { @@ -25,10 +26,11 @@ class KernelRegistryManager; #include #endif -#include "core/framework/provider_options.h" -#include "core/framework/func_api.h" -#include "core/framework/allocatormgr.h" +#include "core/common/basic_types.h" #include "core/common/profiler_common.h" +#include "core/framework/allocatormgr.h" +#include "core/framework/func_api.h" +#include "core/framework/provider_options.h" namespace onnxruntime { @@ -259,7 +261,7 @@ class IExecutionProvider { NOTE: Ideally this would be a protected method, but to work across the EP bridge it has to be public and virtual, and ModelMetadefIdGenerator but be defined in the header as well. */ - virtual int GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const; + virtual int GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const; /** Register allocators used for EP @@ -286,11 +288,11 @@ class IExecutionProvider { // multiple sessions. class ModelMetadefIdGenerator { public: - int GenerateId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash); + int GenerateId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash); private: - std::unordered_map main_graph_hash_; // map graph instance hash to model contents hash - std::unordered_map model_metadef_id_; // current unique id for model + std::unordered_map main_graph_hash_; // map graph instance hash to model contents hash + std::unordered_map model_metadef_id_; // current unique id for model }; std::unique_ptr metadef_id_generator_; diff --git a/include/onnxruntime/core/framework/kernel_def_builder.h b/include/onnxruntime/core/framework/kernel_def_builder.h index 07377f7c2f..a25599be6f 100644 --- a/include/onnxruntime/core/framework/kernel_def_builder.h +++ b/include/onnxruntime/core/framework/kernel_def_builder.h @@ -103,7 +103,7 @@ class KernelDef { bool IsConflict(const KernelDef& other) const; - uint64_t GetHash() const noexcept { + HashValue GetHash() const noexcept { // if we need to support different hash versions we can update CalculateHash to take a version number // and calculate any non-default versions dynamically. we only use this during kernel lookup so // it's not performance critical @@ -175,7 +175,7 @@ class KernelDef { OrtMemType default_outputs_mem_type_{OrtMemTypeDefault}; // hash of kernel definition for lookup in minimal build - uint64_t hash_ = 0; + HashValue hash_ = 0; }; class KernelDefBuilder { diff --git a/include/onnxruntime/core/framework/kernel_registry.h b/include/onnxruntime/core/framework/kernel_registry.h index b6187305a6..a9875df58d 100644 --- a/include/onnxruntime/core/framework/kernel_registry.h +++ b/include/onnxruntime/core/framework/kernel_registry.h @@ -8,7 +8,7 @@ namespace onnxruntime { using KernelCreateMap = std::multimap; -using KernelDefHashes = std::vector>; +using KernelDefHashes = std::vector>; /** * Each provider has a KernelRegistry. Often, the KernelRegistry only belongs to that specific provider. @@ -48,7 +48,7 @@ class KernelRegistry { #endif // Try to find the kernel given a kernel def hash. - bool TryFindKernelByHash(uint64_t kernel_def_hash, const KernelCreateInfo** out) const; + bool TryFindKernelByHash(HashValue kernel_def_hash, const KernelCreateInfo** out) const; bool IsEmpty() const { return kernel_creator_fn_map_.empty(); } @@ -97,6 +97,6 @@ class KernelRegistry { KernelCreateMap kernel_creator_fn_map_; // map from kernel def hash to entry in kernel_creator_fn_map_ - std::unordered_map kernel_def_hash_lookup_; + std::unordered_map kernel_def_hash_lookup_; }; } // namespace onnxruntime diff --git a/include/onnxruntime/core/graph/basic_types.h b/include/onnxruntime/core/graph/basic_types.h index 198c03b1eb..a79479b488 100644 --- a/include/onnxruntime/core/graph/basic_types.h +++ b/include/onnxruntime/core/graph/basic_types.h @@ -10,6 +10,8 @@ #include #include +#include "core/common/basic_types.h" + namespace ONNX_NAMESPACE { class ValueInfoProto; class TensorProto; @@ -30,6 +32,7 @@ using NodeArgInfo = ONNX_NAMESPACE::ValueInfoProto; using InitializedTensorSet = std::unordered_map; using ArgNameToTypeMap = std::unordered_map; using ProviderType = const std::string&; + // TODO - Evaluate switching the types below to support transparent comparators and enable // lookups based on gsl::cstring_span<> and std::string_view. This would reduces allocations // converting to std::string, but requires conversion to std::map> @@ -38,9 +41,7 @@ using ProviderType = const std::string&; using NodeAttributes = std::unordered_map; class IOnnxRuntimeOpSchemaCollection; using IOnnxRuntimeOpSchemaCollectionPtr = std::shared_ptr; -} // namespace onnxruntime -namespace onnxruntime { class OpKernel; class OpKernelInfo; diff --git a/onnxruntime/core/framework/execution_provider.cc b/onnxruntime/core/framework/execution_provider.cc index e40313c7b4..00d154f6d3 100644 --- a/onnxruntime/core/framework/execution_provider.cc +++ b/onnxruntime/core/framework/execution_provider.cc @@ -174,7 +174,7 @@ common::Status IExecutionProvider::Compile(const std::vector& #endif int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::GraphViewer& graph_viewer, - uint64_t& model_hash) { + HashValue& model_hash) { model_hash = 0; // find the top level graph @@ -191,7 +191,7 @@ int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::G // the same memory (unit tests prove this can occur). the raw bytes of the Graph instance should be a unique // fingerprint for the instance that can use used as the key to the hash of the model path/contents. MurmurHash3::x86_128(&main_graph, gsl::narrow_cast(sizeof(Graph)), instance_hash[0], &instance_hash); - uint64_t graph_instance_hash = instance_hash[0] | (uint64_t(instance_hash[1]) << 32); + HashValue graph_instance_hash = instance_hash[0] | (uint64_t(instance_hash[1]) << 32); // if we've already hashed this main graph instance use the cached value auto entry = main_graph_hash_.find(graph_instance_hash); @@ -234,7 +234,7 @@ int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::G return model_metadef_id_[model_hash]++; } -int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const { +int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const { ORT_ENFORCE(metadef_id_generator_, "IExecutionProvider constructor must be called with true for use_metadef_id_creator"); diff --git a/onnxruntime/core/framework/graph_partitioner.cc b/onnxruntime/core/framework/graph_partitioner.cc index 93ccc4b435..eff7992ce4 100644 --- a/onnxruntime/core/framework/graph_partitioner.cc +++ b/onnxruntime/core/framework/graph_partitioner.cc @@ -393,7 +393,7 @@ static Status PartitionOrtFormatModelImpl(Graph& graph, FuncManager& func_mgr, KernelRegistryManager& kernel_registry_mgr, KernelRegistry& fused_kernel_registry, IExecutionProvider& current_ep, - std::unordered_map& compiled_kernel_hashes, + std::unordered_map& compiled_kernel_hashes, int& fused_node_unique_id) { // recurse into nested graphs first to partition bottom up. for (auto& node : graph.Nodes()) { @@ -496,7 +496,7 @@ static Status PartitionOrtFormatModelImpl(Graph& graph, FuncManager& func_mgr, Status GraphPartitioner::PartitionOrtFormatModel( Graph& graph, FuncManager& func_mgr, KernelRegistry& fused_kernel_registry, - std::unordered_map& compiled_kernel_hashes, + std::unordered_map& compiled_kernel_hashes, int& fused_node_unique_id) const { // process full graph with each EP for (const auto& ep : providers_) { @@ -514,7 +514,7 @@ Status GraphPartitioner::PartitionOrtFormatModel( } Status GraphPartitioner::Partition(Graph& graph, bool export_dll, FuncManager& func_mgr, Mode mode, - std::unordered_map* compiled_kernel_hashes) const { + std::unordered_map* compiled_kernel_hashes) const { // It is a greedy partitioning algorithm per provider preferences user provided when calling ONNX RUNTIME right now. // 1. Execution providers' capabilities are checked one by one. // 2. All sub-graphs that an execution provider returns will be assigned to it if it's not assigned yet. diff --git a/onnxruntime/core/framework/graph_partitioner.h b/onnxruntime/core/framework/graph_partitioner.h index 48225f9c74..2926aaf410 100644 --- a/onnxruntime/core/framework/graph_partitioner.h +++ b/onnxruntime/core/framework/graph_partitioner.h @@ -33,7 +33,7 @@ class GraphPartitioner { // Run partitioning. Provide compiled_kernel_hashes if mode is kOrtFormatLoad. Status Partition(Graph& graph, bool export_dll, FuncManager& func_mgr, Mode mode = Mode::kNormal, - std::unordered_map* compiled_kernel_hashes = nullptr) const; + std::unordered_map* compiled_kernel_hashes = nullptr) const; private: ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(GraphPartitioner); @@ -44,7 +44,7 @@ class GraphPartitioner { #endif Status PartitionOrtFormatModel(Graph& graph, FuncManager& func_mgr, KernelRegistry& fused_kernel_registry, - std::unordered_map& compiled_kernel_hashes, + std::unordered_map& compiled_kernel_hashes, int& fused_node_unique_id) const; KernelRegistryManager& kernel_registry_mgr_; diff --git a/onnxruntime/core/framework/kernel_registry.cc b/onnxruntime/core/framework/kernel_registry.cc index 2e4f86e7c6..07db21c6b2 100644 --- a/onnxruntime/core/framework/kernel_registry.cc +++ b/onnxruntime/core/framework/kernel_registry.cc @@ -268,7 +268,7 @@ Status KernelRegistry::TryFindKernel(const Node& node, } #endif // !defined(ORT_MINIMAL_BUILD) -bool KernelRegistry::TryFindKernelByHash(uint64_t kernel_def_hash, const KernelCreateInfo** out) const { +bool KernelRegistry::TryFindKernelByHash(HashValue kernel_def_hash, const KernelCreateInfo** out) const { const auto hash_lookup_it = kernel_def_hash_lookup_.find(kernel_def_hash); if (hash_lookup_it == kernel_def_hash_lookup_.end()) { if (out) *out = nullptr; diff --git a/onnxruntime/core/framework/kernel_registry_manager.cc b/onnxruntime/core/framework/kernel_registry_manager.cc index d9d77f527b..e2137f072a 100644 --- a/onnxruntime/core/framework/kernel_registry_manager.cc +++ b/onnxruntime/core/framework/kernel_registry_manager.cc @@ -104,7 +104,7 @@ Status KernelRegistryManager::SearchKernelRegistry(const onnxruntime::Node& node } #endif -bool KernelRegistryManager::SearchKernelRegistriesByHash(uint64_t kernel_def_hash, +bool KernelRegistryManager::SearchKernelRegistriesByHash(HashValue kernel_def_hash, const KernelCreateInfo** kernel_create_info) const { #if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) for (const auto& registry : custom_kernel_registries_) { diff --git a/onnxruntime/core/framework/kernel_registry_manager.h b/onnxruntime/core/framework/kernel_registry_manager.h index dc0748f956..6a4fb6defc 100644 --- a/onnxruntime/core/framework/kernel_registry_manager.h +++ b/onnxruntime/core/framework/kernel_registry_manager.h @@ -74,7 +74,7 @@ class KernelRegistryManager { /** * Search the kernel registries given a kernel def hash. */ - bool SearchKernelRegistriesByHash(uint64_t kernel_def_hash, + bool SearchKernelRegistriesByHash(HashValue kernel_def_hash, const KernelCreateInfo** kernel_create_info) const; std::unique_ptr CreateKernel(const onnxruntime::Node& node, diff --git a/onnxruntime/core/framework/prepacked_weights.cc b/onnxruntime/core/framework/prepacked_weights.cc index 563c3a8bd5..6aee164dcf 100644 --- a/onnxruntime/core/framework/prepacked_weights.cc +++ b/onnxruntime/core/framework/prepacked_weights.cc @@ -6,7 +6,7 @@ namespace onnxruntime { -uint64_t PrePackedWeights::GetHash() const { +HashValue PrePackedWeights::GetHash() const { // Adaptation of the hashing logic of the KernelDef class uint32_t hash[4] = {0, 0, 0, 0}; @@ -22,7 +22,7 @@ uint64_t PrePackedWeights::GetHash() const { } } - uint64_t returned_hash = hash[0] & 0xfffffff8; // save low 3 bits for hash version info in case we need it in the future + HashValue returned_hash = hash[0] & 0xfffffff8; // save low 3 bits for hash version info in case we need it in the future returned_hash |= uint64_t(hash[1]) << 32; return returned_hash; diff --git a/onnxruntime/core/framework/prepacked_weights.h b/onnxruntime/core/framework/prepacked_weights.h index 7167c53fbc..41ef2631c9 100644 --- a/onnxruntime/core/framework/prepacked_weights.h +++ b/onnxruntime/core/framework/prepacked_weights.h @@ -5,6 +5,7 @@ #include +#include "core/common/basic_types.h" #include "core/framework/buffer_deleter.h" #include "core/framework/tensor_shape.h" @@ -19,7 +20,7 @@ struct PrePackedWeights final { std::vector buffer_sizes_; // cache sizes of pre-packed buffers (in bytes) // Produces a hash of the buffers stored in the given instance of this class - uint64_t GetHash() const; + HashValue GetHash() const; }; } // namespace onnxruntime diff --git a/onnxruntime/core/framework/session_state.cc b/onnxruntime/core/framework/session_state.cc index 374c044209..0414d99553 100644 --- a/onnxruntime/core/framework/session_state.cc +++ b/onnxruntime/core/framework/session_state.cc @@ -970,7 +970,7 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat ORT_RETURN_IF_ERROR(fbs_session_state_viewer.Validate()); auto add_kernel_by_hash = - [&kernel_registry_manager, this](const Node& node, uint64_t hash) { + [&kernel_registry_manager, this](const Node& node, HashValue hash) { const KernelCreateInfo* kci = nullptr; ORT_RETURN_IF_NOT(kernel_registry_manager.SearchKernelRegistriesByHash(hash, &kci), "Failed to find kernel def hash (", hash, ") in kernel registries for ", diff --git a/onnxruntime/core/framework/session_state.h b/onnxruntime/core/framework/session_state.h index aa8e65994f..bc3be7b01f 100644 --- a/onnxruntime/core/framework/session_state.h +++ b/onnxruntime/core/framework/session_state.h @@ -295,7 +295,7 @@ class SessionState { flatbuffers::Offset& fbs_session_state) const; #endif - void SetCompiledKernelHashes(std::unordered_map&& compiled_kernel_hashes) { + void SetCompiledKernelHashes(std::unordered_map&& compiled_kernel_hashes) { compiled_kernel_hashes_ = std::move(compiled_kernel_hashes); } @@ -390,7 +390,7 @@ class SessionState { #endif // the SessionState for the main Graph contains the compiled kernel hashes for the entire model - const std::unordered_map& GetCompiledKernelHashes() const { + const std::unordered_map& GetCompiledKernelHashes() const { return parent_ ? parent_->GetCompiledKernelHashes() : compiled_kernel_hashes_; } @@ -399,7 +399,7 @@ class SessionState { // If we compile kernels in a minimal build we need a way to find the kernel using the hash. // We populate this map when doing the kernel compilation in GraphPartitioner, and use it in LoadFromOrtFormat. - std::unordered_map compiled_kernel_hashes_; + std::unordered_map compiled_kernel_hashes_; // cache of the constructed kernels to avoid spending construction time per executor std::vector session_kernels_; diff --git a/onnxruntime/core/framework/session_state_flatbuffers_utils.h b/onnxruntime/core/framework/session_state_flatbuffers_utils.h index 2c95f64b00..96a51566e6 100644 --- a/onnxruntime/core/framework/session_state_flatbuffers_utils.h +++ b/onnxruntime/core/framework/session_state_flatbuffers_utils.h @@ -47,7 +47,7 @@ class FbsSessionStateViewer { struct NodeKernelInfo { NodeIndex node_index; - uint64_t kernel_def_hash; + HashValue kernel_def_hash; }; /** diff --git a/onnxruntime/core/graph/runtime_optimization_record.h b/onnxruntime/core/graph/runtime_optimization_record.h index e1f318e42d..9ed086113a 100644 --- a/onnxruntime/core/graph/runtime_optimization_record.h +++ b/onnxruntime/core/graph/runtime_optimization_record.h @@ -64,7 +64,7 @@ an ORT format model. This also means that non-empty node indices here must be in struct NodeIndexAndKernelDefHash { NodeIndex node_index; - uint64_t kernel_def_hash; + HashValue kernel_def_hash; }; /** Information for a single runtime optimization. diff --git a/onnxruntime/core/providers/coreml/coreml_execution_provider.cc b/onnxruntime/core/providers/coreml/coreml_execution_provider.cc index febd2e2528..68254d870d 100644 --- a/onnxruntime/core/providers/coreml/coreml_execution_provider.cc +++ b/onnxruntime/core/providers/coreml/coreml_execution_provider.cc @@ -63,7 +63,7 @@ CoreMLExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_vie const auto supported_nodes = coreml::GetSupportedNodes(graph_viewer, logger); const auto gen_metadef_name = [&]() { - uint64_t model_hash; + HashValue model_hash; int metadef_id = GenerateMetaDefId(graph_viewer, model_hash); return MakeString(COREML, "_", model_hash, "_", metadef_id); }; diff --git a/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc b/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc index c767d27cd8..713b8f414b 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_execution_provider.cc @@ -236,7 +236,7 @@ std::vector> DNNLExecutionProvider::GetCapabi } // Assign inputs and outputs to subgraph's meta_def - uint64_t model_hash; + HashValue model_hash; int metadef_id = GenerateMetaDefId(graph_viewer, model_hash); auto meta_def = ::onnxruntime::IndexedSubGraph_MetaDef::Create(); meta_def->name() = "DNNL_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id); @@ -271,7 +271,7 @@ std::vector> DNNLExecutionProvider::GetCapabi auto model_proto = model->ToProto(); ToGraphProtoInternal(graph_viewer, *model_proto->mutable_graph()); model_proto->set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - uint64_t model_hash; + HashValue model_hash; int metadef_id = GenerateMetaDefId(graph_viewer, model_hash); std::fstream dump("DNNL_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id) + ".onnx", std::ios::out | std::ios::trunc | std::ios::binary); model_proto->SerializeToOstream(dump); diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc index c049f2e292..6f7a0433ba 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc @@ -150,7 +150,7 @@ NnapiExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_view }; const auto gen_metadef_name = [&]() { - uint64_t model_hash; + HashValue model_hash; int metadef_id = GenerateMetaDefId(graph_viewer, model_hash); return MakeString(NNAPI, "_", model_hash, "_", metadef_id); }; diff --git a/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc b/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc index 7752d657f4..d2e0be2176 100644 --- a/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc +++ b/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc @@ -299,7 +299,7 @@ common::Status IExecutionProvider::Compile(const std::vector& return g_host->IExecutionProvider__Compile(this, fused_nodes_and_graphs, node_compute_funcs); } -int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const { +int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const { return g_host->IExecutionProvider__GenerateMetaDefId(this, graph_viewer, model_hash); } diff --git a/onnxruntime/core/providers/shared_library/provider_interfaces.h b/onnxruntime/core/providers/shared_library/provider_interfaces.h index 9735f83408..bd0c7a581c 100644 --- a/onnxruntime/core/providers/shared_library/provider_interfaces.h +++ b/onnxruntime/core/providers/shared_library/provider_interfaces.h @@ -82,6 +82,7 @@ struct TensorShapeProto_Dimension_Iterator { virtual const ONNX_NAMESPACE::TensorShapeProto_Dimension& operator*() = 0; }; +using HashValue = uint64_t; using NodeIndex = size_t; // We can't just reinterpret_cast this one, since it's an unordered_map of object BY VALUE (can't do anything by value on the real types) // using NodeAttributes = std::unordered_map; @@ -213,7 +214,7 @@ struct ProviderHost { virtual common::Status IExecutionProvider__Compile(IExecutionProvider* p, const std::vector& fused_nodes, std::string& dll_path) = 0; virtual common::Status IExecutionProvider__Compile(IExecutionProvider* p, const std::vector& fused_nodes_and_graphs, std::vector& node_compute_funcs) = 0; - virtual int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) = 0; + virtual int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) = 0; virtual void IExecutionProvider__RegisterAllocator(IExecutionProvider* p, std::shared_ptr allocator_manager) = 0; // Status diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc index 8617b8e2b6..ef06f69880 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc @@ -796,7 +796,7 @@ std::unique_ptr TensorrtExecutionProvider::GetSubGraph(SubGraph } // Generate unique kernel name for TRT subgraph - uint64_t model_hash = 0; + HashValue model_hash = 0; int id = GenerateMetaDefId(graph, model_hash); std::string subgraph_id = std::to_string(model_hash) + "_" + std::to_string(id); auto meta_def = IndexedSubGraph_MetaDef::Create(); diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 1c899c626f..b525224b79 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -1133,7 +1133,7 @@ Status PartitionOrtFormatModel(onnxruntime::Graph& graph, const ExecutionProviders& providers, KernelRegistryManager& kernel_registry_manager, SessionState& session_state) { - std::unordered_map compiled_kernel_hashes; + std::unordered_map compiled_kernel_hashes; GraphPartitioner partitioner(kernel_registry_manager, providers); ORT_RETURN_IF_ERROR(partitioner.Partition(graph, session_state.ExportDll(), diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index d5435bdf44..bafb803e11 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -269,7 +269,7 @@ struct ProviderHostImpl : ProviderHost { return p->IExecutionProvider::Compile(fused_nodes_and_graphs, node_compute_funcs); } - int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) override { + int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) override { return p->IExecutionProvider::GenerateMetaDefId(graph_viewer, model_hash); } diff --git a/onnxruntime/test/framework/execution_provider_test.cc b/onnxruntime/test/framework/execution_provider_test.cc index 10125a1d81..f43f8e39b6 100644 --- a/onnxruntime/test/framework/execution_provider_test.cc +++ b/onnxruntime/test/framework/execution_provider_test.cc @@ -20,7 +20,7 @@ class TestEP : public IExecutionProvider { public: TestEP() : IExecutionProvider{kEPType, true} {} - int GetId(const GraphViewer& viewer, uint64_t& model_hash) { + int GetId(const GraphViewer& viewer, HashValue& model_hash) { return GenerateMetaDefId(viewer, model_hash); } }; @@ -36,13 +36,13 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelPath) { GraphViewer viewer(graph); // check for stable non-zero model_hash, and incrementing id. - uint64_t model_hash; + HashValue model_hash; int id = ep.GetId(viewer, model_hash); ASSERT_EQ(id, 0); ASSERT_NE(model_hash, 0); for (int i = 1; i < 4; ++i) { - uint64_t cur_model_hash; + HashValue cur_model_hash; int cur_id = ep.GetId(viewer, cur_model_hash); ASSERT_EQ(cur_id, i); ASSERT_EQ(cur_model_hash, model_hash); @@ -67,7 +67,7 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelHashing) { GraphViewer viewer(graph); // get the hash for the model when loaded from file - uint64_t model_hash; + HashValue model_hash; int id = ep.GetId(viewer, model_hash); ASSERT_EQ(id, 0); ASSERT_NE(model_hash, 0); @@ -84,7 +84,7 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelHashing) { Graph& graph2 = model2->MainGraph(); GraphViewer viewer2(graph2); - uint64_t model_hash2; + HashValue model_hash2; int id2 = ep.GetId(viewer2, model_hash2); ASSERT_EQ(id2, 0) << "Id for new model should always start at zero"; ASSERT_NE(model_hash, model_hash2) << "Hash from model path should differ from hash based on model contents"; diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_execution_provider.cc b/onnxruntime/test/providers/internal_testing/internal_testing_execution_provider.cc index ccc552b581..bbf8ef053a 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_execution_provider.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_execution_provider.cc @@ -82,7 +82,7 @@ InternalTestingExecutionProvider::GetCapability(const onnxruntime::GraphViewer& // create functor to generate a guaranteed unique metadef id auto generate_metadef_name = [this, &graph_viewer]() { - uint64_t model_hash; + HashValue model_hash; int metadef_id = GenerateMetaDefId(graph_viewer, model_hash); auto meta_def = std::make_unique<::onnxruntime::IndexedSubGraph::MetaDef>(); return ep_name_ + "_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id); From 7922a8c22f42d06abff2682b047e62f604e9755e Mon Sep 17 00:00:00 2001 From: George Nash Date: Wed, 15 Dec 2021 20:28:34 -0800 Subject: [PATCH 053/113] Optimization Convolution op when using dnnl ep (#10051) If Group attr = 1 allow the OneDNN library to optimize the memory layout for the device the Convolution operator is being run on. With out this optimization the default NCHW memory layout is used on CPUs the NCHW memory layout can result in a significant performance decrease. Signed-off-by: George Nash --- onnxruntime/core/providers/dnnl/subgraph/dnnl_conv.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_conv.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_conv.cc index d28cb9cf0f..a076633ca8 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_conv.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_conv.cc @@ -21,10 +21,12 @@ void DnnlConv::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node) { auto conv_src_mem = sp.GetMemory(node.Input(IN_X)); auto src_md = conv_src_mem.get_desc(); + src_md.data.format_kind = dnnl_format_kind_t::dnnl_format_kind_any; auto src_dims = conv_src_mem.get_desc().dims(); auto conv_weights_mem = sp.GetMemory(node.Input(IN_W)); auto weight_md = conv_weights_mem.get_desc(); + weight_md.data.format_kind = dnnl_format_kind_t::dnnl_format_kind_any; auto weight_dims_original = conv_weights_mem.get_desc().dims(); dnnl::memory::dims weight_dims = weight_dims_original; From 6357c1297798705f173a0b990e7a118233b8cfa0 Mon Sep 17 00:00:00 2001 From: "Tang, Cheng" Date: Wed, 15 Dec 2021 21:17:29 -0800 Subject: [PATCH 054/113] use inplace reshape (#9991) Co-authored-by: Cheng Tang --- orttraining/orttraining/eager/ort_aten.cpp | 18 ++++++++++++------ orttraining/orttraining/eager/ort_ops.h | 12 +++++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index 9493c18f12..ca33b09d12 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -255,22 +255,28 @@ at::Tensor _reshape_alias( ORT_LOG_FN(self, size, stride); // TODO: support stride auto& invoker = GetORTInvoker(self.device()); + auto ort_input = create_ort_value(invoker, self); return aten_tensor_from_ort( - reshape_copy( + reshape_invoke( invoker, - create_ort_value(invoker, self), - size), + ort_input, + size, + // invoke reshape kernel inplace + true), self.options()); } at::Tensor view(const at::Tensor& self, at::IntArrayRef size) { ORT_LOG_FN(self, size); auto& invoker = GetORTInvoker(self.device()); + auto ort_input = create_ort_value(invoker, self); return aten_tensor_from_ort( - reshape_copy( + reshape_invoke( invoker, - create_ort_value(invoker, self), - size), + ort_input, + size, + // invoke reshape kernel inplace + true), self.options()); } diff --git a/orttraining/orttraining/eager/ort_ops.h b/orttraining/orttraining/eager/ort_ops.h index 13f7c30be4..b949c329a2 100644 --- a/orttraining/orttraining/eager/ort_ops.h +++ b/orttraining/orttraining/eager/ort_ops.h @@ -11,10 +11,11 @@ namespace torch_ort { namespace eager { template class V> -OrtValue reshape_copy( +OrtValue reshape_invoke( onnxruntime::ORTInvoker& invoker, - const OrtValue& input, - V shape) { + OrtValue& input, + V shape, + bool in_place) { // TODO: actual reshape on buffer const onnxruntime::Tensor& input_tensor = input.Get(); auto new_shape = at::infer_size(shape, input_tensor.Shape().Size()); @@ -26,6 +27,11 @@ OrtValue reshape_copy( auto* ort_shape_tensor = shape_tensor.GetMutable(); CopyVectorToTensor(invoker, new_shape, *ort_shape_tensor); std::vector result(1); + if (in_place){ + auto* input_ort_tensor = input.GetMutable(); + CreateMLValue(input_ort_tensor->MutableDataRaw(), + element_type, new_shape, &result[0]); + } ORT_THROW_IF_ERROR(invoker.Invoke("Reshape", {input, shape_tensor}, result, nullptr)); return result[0]; } From 44c701192b3ea3f927f9eaee7a05b30b87ba9b1f Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Wed, 15 Dec 2021 23:38:45 -0800 Subject: [PATCH 055/113] Revert a bad change in bfc_arena.cc (#10057) --- onnxruntime/core/framework/bfc_arena.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/framework/bfc_arena.cc b/onnxruntime/core/framework/bfc_arena.cc index 4b41222474..57e4fea00b 100644 --- a/onnxruntime/core/framework/bfc_arena.cc +++ b/onnxruntime/core/framework/bfc_arena.cc @@ -164,7 +164,7 @@ Status BFCArena::Extend(size_t rounded_bytes) { static constexpr float kBackpedalFactor = 0.9f; // Try allocating less memory. while (mem_addr == nullptr) { - bytes = RoundedBytes(static_cast(bytes) * static_cast(kBackpedalFactor)); + bytes = RoundedBytes(static_cast(bytes * kBackpedalFactor)); // give up if we can't satisfy the requested size, or we're attempting an allocation of less than 8K. // From 93636cbd207ab9f28ebdc6deecaa320f05240d95 Mon Sep 17 00:00:00 2001 From: George Nash Date: Thu, 16 Dec 2021 07:31:16 -0800 Subject: [PATCH 056/113] Reduce ops for DNNL ep (#10056) * Add Reduce Ops to DNNL ep Combine the Reduction ops into one class Add ReduceL1, ReduceL2, ReduceSum, ReduceMax, ReduceMin, and ReduceProd, ReduceSumSquare, ReduceLogSum, and ReduceLogSumExp Reduce code now also handles the keepdims attribute Also updated code to use HandleNegativeAxis function from the providers/common.h code instead of manually calculating. In code documentation exists to help explain complex reduction op code Add elementwise ops to Reduction op capability code removed keepdims check from the Reduction op capability code. Updated the error_tolerance for LogGrad(DNNL EP only) after finding a few instances that the tests were a little out of tolerance. Signed-off-by: George Nash * Documentation cleanup in dnnl_qattention Cleaned up the Comments documenting the QAttention operator For some reason a bunch of new lines were introduced to the comment making it harder to read. Signed-off-by: George Nash --- .../providers/dnnl/dnnl_node_capability.cc | 25 +- .../providers/dnnl/dnnl_node_capability.h | 31 +- .../core/providers/dnnl/dnnl_op_manager.cc | 11 +- .../dnnl/subgraph/dnnl_qattention.cc | 74 +--- .../providers/dnnl/subgraph/dnnl_reduce.cc | 342 ++++++++++++++++++ .../{dnnl_reducemean.h => dnnl_reduce.h} | 11 +- .../dnnl/subgraph/dnnl_reducemean.cc | 75 ---- .../providers/dnnl/subgraph/dnnl_subgraph.cc | 4 + .../providers/dnnl/subgraph/dnnl_subgraph.h | 1 + .../dnnl/subgraph/dnnl_subgraph_primitive.cc | 7 +- .../cpu/reduction/reduction_ops_test.cc | 42 ++- .../test/gradient/gradient_ops_test.cc | 2 +- 12 files changed, 451 insertions(+), 174 deletions(-) create mode 100644 onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.cc rename onnxruntime/core/providers/dnnl/subgraph/{dnnl_reducemean.h => dnnl_reduce.h} (73%) delete mode 100644 onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.cc diff --git a/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc b/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc index d4c72840dd..ab6fbb5f5d 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_node_capability.cc @@ -191,34 +191,31 @@ bool DnnlBatchNormalizationNodeCapability::IsDimensionSupported(const Node* node return true; } -// DnnlReduceMeanNodeCapability class +// DnnlReduceNodeCapability class //------------------------------------- -bool DnnlReduceMeanNodeCapability::Supported(const Node* node, const GraphViewer& graph_viewer) const { - ORT_UNUSED_PARAMETER(graph_viewer); +bool DnnlReduceNodeCapability::Supported(const Node* node, const GraphViewer& graph_viewer) const { + // These reduction operators use elementwise ops so elementwise operators must also be supported. + if(node->OpType() == "ReduceLogSum" || + node->OpType() == "ReduceLogSumExp" || + node->OpType() == "ReduceSumSquare") { + if(!_eltwise.Supported(node, graph_viewer)) return false; + } if (!IsTypeSupported(node)) return false; - if (!IsAttributeSupported(node)) return false; if (!IsDimensionSupported(node)) return false; return true; } -bool DnnlReduceMeanNodeCapability::IsAttributeSupported(const Node* node) const { - const NodeAttributes& attributes = node->GetAttributes(); - auto attr = attributes.find("keepdims"); - if (attr != attributes.end() && attr->second().i() == 0) { - return false; - } - return true; -} - -bool DnnlReduceMeanNodeCapability::IsDimensionSupported(const Node* node) const { +bool DnnlReduceNodeCapability::IsDimensionSupported(const Node* node) const { auto node_inputs = node->InputDefs(); if (node_inputs[0]->Shape() != nullptr && node_inputs[0]->Shape()->dim_size() == 0) { + LOGS_DEFAULT(INFO) << "Reduction op not supported because input data is a scalar\n"; return false; } return true; } // DnnlSoftmaxNodeCapability class +//------------------------------------- bool DnnlSoftmaxNodeCapability::Supported(const Node* node, const GraphViewer& graph_viewer) const { ORT_UNUSED_PARAMETER(graph_viewer); if (!IsTypeSupported(node)) return false; diff --git a/onnxruntime/core/providers/dnnl/dnnl_node_capability.h b/onnxruntime/core/providers/dnnl/dnnl_node_capability.h index 0e3a3ef131..e81f80f320 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_node_capability.h +++ b/onnxruntime/core/providers/dnnl/dnnl_node_capability.h @@ -145,22 +145,6 @@ class DnnlBatchNormalizationNodeCapability : public DnnlDefaultNodeCapability { bool IsDimensionSupported(const Node* node) const; }; -/** - * Decide if a ReduceMean op is supported by DnnlExecutionProvider - * - * Dnnl does not support the "keepdims" attribute when it is `0` - */ -class DnnlReduceMeanNodeCapability : public DnnlDefaultNodeCapability { - public: - DnnlReduceMeanNodeCapability() : DnnlDefaultNodeCapability({type_float32}) {} - - bool Supported(const Node* node, const GraphViewer& graph_viewer) const override; - - private: - bool IsAttributeSupported(const Node* node) const; - bool IsDimensionSupported(const Node* node) const; -}; - /** * Decide if a Softmax op is supported by DnnlExecutionProvider * @@ -249,6 +233,21 @@ class DnnlElementwiseCapability : public DnnlDefaultNodeCapability { bool IsDimensionSupported(const Node* node) const; }; +/** + * Decide if a Reduce op is supported by DnnlExecutionProvider + */ +class DnnlReduceNodeCapability : public DnnlDefaultNodeCapability { + public: + DnnlReduceNodeCapability() : DnnlDefaultNodeCapability({type_float32}) {} + + bool Supported(const Node* node, const GraphViewer& graph_viewer) const override; + + private: + bool IsDimensionSupported(const Node* node) const; + DnnlElementwiseCapability _eltwise; + +}; + class DnnlPowNodeCapability : public DnnlDefaultMultiInputNodeCapability { public: DnnlPowNodeCapability() diff --git a/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc b/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc index fa58933a47..43e3dc1508 100644 --- a/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc +++ b/onnxruntime/core/providers/dnnl/dnnl_op_manager.cc @@ -31,7 +31,16 @@ DnnlOpManager::DnnlOpManager() { dnnl_ops_map_.emplace(std::make_pair("Mul", std::unique_ptr(new DnnlBinaryNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Pow", std::unique_ptr(new DnnlPowNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("QAttention", std::unique_ptr(new DnnlQAttentionNodeCapability()))); - dnnl_ops_map_.emplace(std::make_pair("ReduceMean", std::unique_ptr(new DnnlReduceMeanNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceL1", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceL2", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceLogSum", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceLogSumExp", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceMax", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceMean", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceMin", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceProd", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceSum", std::unique_ptr(new DnnlReduceNodeCapability()))); + dnnl_ops_map_.emplace(std::make_pair("ReduceSumSquare", std::unique_ptr(new DnnlReduceNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Relu", std::unique_ptr(new DnnlElementwiseCapability()))); dnnl_ops_map_.emplace(std::make_pair("Reshape", std::unique_ptr(new DnnlReshapeNodeCapability()))); dnnl_ops_map_.emplace(std::make_pair("Round", std::unique_ptr(new DnnlElementwiseCapability()))); diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc index d3f2361a0b..b08c1d1bb9 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_qattention.cc @@ -45,97 +45,53 @@ dnnl::memory DnnlQAttention::ComputeTotalScale(DnnlSubgraphPrimitive& sp, DnnlNo } /* -input_tensor weight_tensor - + input_tensor weight_tensor \ / - \ / - \ / - \ / - - matmulinteger + matmulinteger with input and weight zero point, input and weight scale and bias | - | - | QKV - | - slice - - / | \ - / | \ - / | \ - / | \ - + / | \ |Q |K |V - | | | - reshape reshape reshape - | | | - permute permute permute - | | | - | transpose | - - \ | | - \ | | - \ | | - \ | | - - matmul | - - | | - - | | - - sqrt(head_dim) | | - - \ | | - - \ | | - \ | | - + matmul | + | | + | | + sqrt(head_dim) | | + \ | | + \ | | + \ | | div | - - | | - - (mask) | - - | / - - softmax / - - | / - + | | + (mask) / + | / + softmax / + | / matmul - | - permute - | - reshape - | - output */ /* diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.cc new file mode 100644 index 0000000000..7be31bb49c --- /dev/null +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.cc @@ -0,0 +1,342 @@ +// Copyright(C) 2021 Intel Corporation +// Licensed under the MIT License +#include "dnnl_reduce.h" +#include "dnnl_subgraph.h" +#include "dnnl_subgraph_primitive.h" +#include "core/providers/common.h" + +namespace onnxruntime { +namespace ort_dnnl { + +DnnlReduce::DnnlReduce() {} + +// assume all dims are available +void DnnlReduce::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node) { + + using namespace dnnl; + + // get the engine, currently only support either single gpu or single cpu device + auto dnnl_engine = sp.GetEngine(); + + enum ReduceOp { + ReduceL1, + ReduceL2, + ReduceLogSum, + ReduceLogSumExp, + ReduceMax, + ReduceMean, + ReduceMin, + ReduceProd, + ReduceSum, + ReduceSumSquare + }; + + ReduceOp reduce_op = ReduceSum; + dnnl::algorithm algo = dnnl::algorithm::reduction_sum; + if (node.OpType() == "ReduceL1") { + reduce_op = ReduceL1; + algo = dnnl::algorithm::reduction_norm_lp_power_p_sum; + } else if (node.OpType() == "ReduceL2") { + reduce_op = ReduceL2; + algo = dnnl::algorithm::reduction_norm_lp_sum; + } else if(node.OpType() == "ReduceLogSum") { + reduce_op = ReduceLogSum; + algo = dnnl::algorithm::reduction_sum; + } else if(node.OpType() == "ReduceLogSumExp") { + reduce_op = ReduceLogSumExp; + algo = dnnl::algorithm::reduction_sum; + } else if (node.OpType() == "ReduceMax") { + reduce_op = ReduceMax; + algo = dnnl::algorithm::reduction_max; + } else if (node.OpType() == "ReduceMean") { + reduce_op = ReduceMean; + algo = dnnl::algorithm::reduction_mean; + } else if (node.OpType() == "ReduceMin") { + reduce_op = ReduceMin; + algo = dnnl::algorithm::reduction_min; + } else if (node.OpType() == "ReduceProd") { + reduce_op = ReduceProd; + algo = dnnl::algorithm::reduction_mul; + } else if (node.OpType() == "ReduceSum") { + reduce_op = ReduceSum; + algo = dnnl::algorithm::reduction_sum; + } else if (node.OpType() == "ReduceSumSquare") { + reduce_op = ReduceSumSquare; + algo = dnnl::algorithm::reduction_sum; + } + + + + auto opset = node.SinceVersion(); + dnnl::memory::dims axes; + if (reduce_op == ReduceSum) { + // in ReduceSum opset older than version 13 the Axes came in as an attribute + // after version 13 the axis is an optional tensor input. + if (opset < 13) { + axes = ReadAxes(node); + } else { + if (node.Input(IN_AXES).Exists()) { + auto axes_mem = sp.GetMemory(node.Input(IN_AXES)); + dnnl::memory::dims axes_dims = axes_mem.get_desc().dims(); + int64_t* p_axes_data = (int64_t*)axes_mem.get_data_handle(); + axes = std::vector(p_axes_data, p_axes_data + axes_dims[0]); + } + } + } else { + axes = ReadAxes(node); + } + + auto src_mem = sp.GetMemoryInOrtFormat(node.Input(IN_DATA), dnnl_engine); + auto src_md = src_mem.get_desc(); + + if (reduce_op == ReduceSum) { + // If axes is empty and the noop_with_empty_axes != 0 return the IN_DATA as the output. + if (axes.empty()) { + if (NoOpWithEmptyAxes(node)) { + sp.SetMemory(node.Output(OUT_REDUCED), src_mem, true); + return; + } + } + } + + //We need to calculate output tensor shape + //First we initialize it with input shape and then we modify it based on the attribute values + //This is because the DNNL primitive functionality is determined by the input and output shapes. + auto src_dims = src_md.dims(); + auto ndim = src_dims.size(); + + // convert negative axis values to the positive axis + for (size_t i = 0; i < axes.size(); ++i) { + axes[i] = HandleNegativeAxis(axes[i], ndim); + } + // Handle out of order and repeating dims. + std::sort(axes.begin(), axes.end()); + axes.erase(std::unique(axes.begin(), axes.end()), axes.end()); + + // if axes is empty change all non-zero shape dims to 1 + if (axes.size() == 0) { + for (size_t i = 0; i < ndim; ++i) { + if (src_dims[i] != 0) + src_dims[i] = 1; + } + //If there is axis, then make the respective dimensions 1, keeping the other dimension values untouched. + } else { + for (size_t i = 0; i < axes.size(); i++) { + if (src_dims[axes[i]] != 0) + src_dims[axes[i]] = 1; + } + } + + auto dst_shape = TensorShape(src_dims.data(), ndim); + dnnl::memory::dims dst_dims_mkl(dst_shape.GetDims().begin(), dst_shape.GetDims().end()); + auto dst_md = dnnl::memory::desc({dst_dims_mkl}, src_md.data_type(), dnnl::memory::format_tag::any); + + // Check to see if the destination shape and source shape are the same. + bool src_and_dst_dims_equal = true; + if (src_md.dims().size() == dst_md.dims().size()) { + for (size_t i = 0; i < src_md.dims().size(); ++i) { + if (src_md.dims()[i] != dst_md.dims()[i]) { + src_and_dst_dims_equal = false; + break; + } + } + } + + /* + * OneDNN will return an error if a reduction algorithm is called that does not result in a + * shape reduction. For this reason we have code paths that are taken if the source dimensions and + * destination dimensions are equal that will not call the reduction op. + * + * "ReduceLogSum" is equivelent to Log(ReduceSum(input)) + * - if the reduction op is called then the eltwise_log post op will added to the reduction primitive. + * - if the reduction op is not called then the eltwise_log primitive is added as its own primitive + * - NOTE "ReduceLogSum" follows the code flow of "All other reduce ops" with the exception of the added + * post op and an extra check if src_dims == dest_dims. + * "ReduceLogSumExp" is equivelent to Log(ReduceSum(Exp(input))) + * - if the reduction op is called then the eltwise_exp primitive is added before the reduction op + * the eletwise_log post op will be added to the reduction primitive + * - if the reduction op is not called then the input is not modified since Log(Exp(input) == input + * "ReduceSumSquare" is equivelent to ReduceSum(Square(input)) + * - the eltwise_square primitive is added before the reduction op + * - if the source and destination dimensions are not equal the reduction op is called + * All other reduce ops + * - if the source and destination dimensions are not equal call the reduction op + * - otherwise don't modify the input. + * + * After the Reduction check the "KeepDims" attribute + * - if KeepDims == 1 the output is the result of the reduction op + * - if KeepDims == 0 we perform a squeeze operation on the output of the reduction op + * - NOTE: Even if reduction op is not called KeepDims attribute can result in the output being modified + */ + dnnl::memory reduce_src_mem; + dnnl::memory reduce_dst_mem; + dnnl::primitive_attr dnnl_primitive_attr; + if ((reduce_op == ReduceLogSum || reduce_op == ReduceLogSumExp ) && !src_and_dst_dims_equal) { + dnnl::post_ops eltwise_post_op; + eltwise_post_op.append_eltwise(1.0f, dnnl::algorithm::eltwise_log, 1.0f, 1.0f); + dnnl_primitive_attr.set_post_ops(eltwise_post_op); + } + + if (reduce_op == ReduceLogSumExp) { + if (!src_and_dst_dims_equal) { + auto elementwise_desc = dnnl::eltwise_forward::desc(dnnl::prop_kind::forward_inference, dnnl::algorithm::eltwise_exp, src_md); + auto elementwise_pd = dnnl::eltwise_forward::primitive_desc(elementwise_desc, dnnl_engine); + + auto elementwise_dst_mem = dnnl::memory(elementwise_pd.dst_desc(), dnnl_engine); + + auto elemenwise_primitive = dnnl::eltwise_forward(elementwise_pd); + sp.AddPrimitive(elemenwise_primitive, {{DNNL_ARG_SRC, src_mem}, + {DNNL_ARG_DST, elementwise_dst_mem}}); + auto reduce_desc = dnnl::reduction::desc(algo, src_md, dst_md, 0.f, 0.f); + auto reduce_pd = dnnl::reduction::primitive_desc(reduce_desc, dnnl_primitive_attr, dnnl_engine); + + reduce_dst_mem = dnnl::memory(reduce_pd.dst_desc(), dnnl_engine); + + auto reducemean_op = dnnl::reduction(reduce_pd); + sp.AddPrimitive(reducemean_op, {{DNNL_ARG_SRC, elementwise_dst_mem}, + {DNNL_ARG_DST, reduce_dst_mem}}); + } else { + reduce_dst_mem = src_mem; + } + } else if(reduce_op == ReduceSumSquare) { + auto elementwise_desc = dnnl::eltwise_forward::desc(dnnl::prop_kind::forward_inference, dnnl::algorithm::eltwise_square, src_md); + auto elementwise_pd = dnnl::eltwise_forward::primitive_desc(elementwise_desc, dnnl_engine); + + auto elementwise_dst_mem = dnnl::memory(elementwise_pd.dst_desc(), dnnl_engine); + + auto elemenwise_primitive = dnnl::eltwise_forward(elementwise_pd); + sp.AddPrimitive(elemenwise_primitive, {{DNNL_ARG_SRC, src_mem}, + {DNNL_ARG_DST, elementwise_dst_mem}}); + if (!src_and_dst_dims_equal) { + auto reduce_desc = dnnl::reduction::desc(algo, src_md, dst_md, 0.f, 0.f); + auto reduce_pd = dnnl::reduction::primitive_desc(reduce_desc, dnnl_engine); + + reduce_dst_mem = dnnl::memory(reduce_pd.dst_desc(), dnnl_engine); + + auto reducemean_op = dnnl::reduction(reduce_pd); + sp.AddPrimitive(reducemean_op, {{DNNL_ARG_SRC, elementwise_dst_mem}, + {DNNL_ARG_DST, reduce_dst_mem}}); + } else { + reduce_dst_mem = elementwise_dst_mem; + } + } else { + // If calculated source and destination shape are the same do not do the reduction operation. + if (!src_and_dst_dims_equal) { + float p_val = 0.f; + if (reduce_op == ReduceL1) { + p_val = 1.0f; + } else if (reduce_op == ReduceL2) { + p_val = 2.0f; + } + + auto reduce_desc = dnnl::reduction::desc(algo, src_md, dst_md, p_val, 0.f); + auto reduce_pd = dnnl::reduction::primitive_desc(reduce_desc, dnnl_primitive_attr, dnnl_engine); + + // If using GPU this will move the memory from the CPU to the GPU. + reduce_src_mem = sp.GetMemoryAndReshape(node.Input(IN_DATA), reduce_pd.src_desc(), dnnl_engine); + reduce_dst_mem = dnnl::memory(reduce_pd.dst_desc(), dnnl_engine); + + auto reducemean_op = dnnl::reduction(reduce_pd); + sp.AddPrimitive(reducemean_op, {{DNNL_ARG_SRC, reduce_src_mem}, + {DNNL_ARG_DST, reduce_dst_mem}}); + } else { + if (reduce_op == ReduceLogSum) { + auto elementwise_desc = dnnl::eltwise_forward::desc(dnnl::prop_kind::forward_inference, dnnl::algorithm::eltwise_log, src_md); + auto elementwise_pd = dnnl::eltwise_forward::primitive_desc(elementwise_desc, dnnl_engine); + + reduce_dst_mem = dnnl::memory(elementwise_pd.dst_desc(), dnnl_engine); + + auto elemenwise_primitive = dnnl::eltwise_forward(elementwise_pd); + sp.AddPrimitive(elemenwise_primitive, {{DNNL_ARG_SRC, src_mem}, + {DNNL_ARG_DST, reduce_dst_mem}}); + } else { + reduce_dst_mem = src_mem; + } + } + } + + + // If keepdims != 0 set the output to the reduce op results + auto keepdims = Keepdims(node); + if (keepdims) { + if (src_and_dst_dims_equal) { + sp.SetMemory(node.Output(OUT_REDUCED), reduce_dst_mem, true); + } else { + sp.SetMemory(node.Output(OUT_REDUCED), reduce_dst_mem); + } + // if keepdims == 0 we do a squeeze operation on reduce output shape. + } else { + std::vector output_shape; + size_t j = 0; + for (size_t i = 0; i < ndim; ++i) { + if ((j < axes.size() && axes[j] == static_cast(i)) || + (axes.size() == 0 && src_dims[i] == 1)) { + ORT_ENFORCE(src_dims[i] == 1, "Dimension of input ", i, " must be 1 instead of ", src_dims[i], + ". shape=", src_dims); + ++j; + continue; + } + + if ((j < axes.size() && axes[j] == static_cast(i) && src_dims[i] == 0) || + (axes.size() == 0 && src_dims[i] == 0)) { + ORT_ENFORCE(keepdims, + "Can't reduce on dim with value of 0 if 'keepdims' is false. " + "Invalid output shape would be produced. input_shape:", + TensorShape(src_md.dims())); + } + output_shape.push_back(src_dims[i]); + } + + // OneDNN does not support scalar output if the output shape is {} change it to {1} + bool is_scalar_output = false; + if (output_shape.empty()) { + output_shape.push_back(1); + is_scalar_output = true; + } + dnnl::memory::desc squeeze_md(output_shape, node.Input(IN_DATA).Type(), sp.GetDnnlFormat(output_shape.size())); + dnnl::memory squeeze_mem = dnnl::memory(squeeze_md, dnnl_engine, nullptr); + // if the src and dst dims are equal then we will have a valid data handle here. + // Otherwise we must get the data handle at runtime using the AddReshape function. + // reading the data handle directy is more efficent if is it possible. + if (!src_and_dst_dims_equal) { + squeeze_mem.set_data_handle(reduce_dst_mem.get_data_handle()); + } else { + sp.AddReshape(reduce_dst_mem, squeeze_mem); + } + sp.SetMemory(node.Output(OUT_REDUCED), squeeze_mem, true, is_scalar_output); + } +} + +std::vector DnnlReduce::ReadAxes(DnnlNode& node) { + auto attr = node.Attributes().find("axes"); + std::vector axes; + if (attr != node.Attributes().end()) { + auto& proto = attr->second(); + axes.reserve(proto.ints_size()); + for (int i = 0; i < proto.ints_size(); i++) { + axes.push_back(proto.ints(i)); + } + } + return axes; +} + +bool DnnlReduce::Keepdims(DnnlNode& node) { + auto attr = node.Attributes().find("keepdims"); + if (attr != node.Attributes().end() && + attr->second().i() == 0) { + return false; + } + return true; +} + +bool DnnlReduce::NoOpWithEmptyAxes(DnnlNode& node) { + auto attr = node.Attributes().find("noop_with_empty_axes"); + if (attr != node.Attributes().end() && + attr->second().i() != 0) { + return true; + } + return false; +} + +} // namespace ort_dnnl +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.h b/onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.h similarity index 73% rename from onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.h rename to onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.h index 675fa0f0ec..b5a89fd53a 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.h +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_reduce.h @@ -8,18 +8,21 @@ namespace onnxruntime { namespace ort_dnnl { -class DnnlReduceMean { +class DnnlReduce { public: enum InputTensors : int { - IN_X = 0 + IN_DATA = 0, + IN_AXES = 1 }; enum OutputTensors : int { - OUT_Y = 0 + OUT_REDUCED = 0 }; - DnnlReduceMean(); + DnnlReduce(); void CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node); std::vector ReadAxes(DnnlNode& node); + bool Keepdims(DnnlNode& node); + bool NoOpWithEmptyAxes(DnnlNode& node); }; } // namespace ort_dnnl diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.cc deleted file mode 100644 index 8f6f7c12c6..0000000000 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_reducemean.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright(C) 2021 Intel Corporation -// Licensed under the MIT License -#include "dnnl_reducemean.h" -#include "dnnl_subgraph.h" -#include "dnnl_subgraph_primitive.h" - -namespace onnxruntime { -namespace ort_dnnl { - - -DnnlReduceMean::DnnlReduceMean() {} - -// assume all dims are available -void DnnlReduceMean::CreatePrimitive(DnnlSubgraphPrimitive& sp, DnnlNode& node) { - - using namespace dnnl; - - // get the engine, currently only support either single gpu or single cpu device - auto dnnl_engine = sp.GetEngine(); - - auto axes = ReadAxes(node); - - auto reducemean_src_mem = sp.GetMemory(node.Input(IN_X)); - auto src_md = reducemean_src_mem.get_desc(); - - //We need to calculate output tensor shape - //First we initialize it with input shape and then we modify it based on the attribute values - //This is because the DNNL primitive functionality is determined by the input and output shapes. - - auto src_dims = src_md.dims(); - auto ndim = src_dims.size(); - for (unsigned long int i = 0; i < ndim; i++) { - if (axes.size() == 0) - src_dims[i] = 1; //If no axis is specified, then output shape is just all 1's - else if (i < axes.size()) { - if (axes[i] < 0) - src_dims[ndim + axes[i]] = 1; - else - src_dims[axes[i]] = 1; - } //If there is axis, then make the respective dimensions 1, keeping the other dimension values untouched. - } - - auto dst_shape = TensorShape(src_dims.data(), ndim); - dnnl::memory::dims dst_dims_mkl(dst_shape.GetDims().begin(), dst_shape.GetDims().end()); - auto dst_md = dnnl::memory::desc({dst_dims_mkl}, src_md.data_type(), dnnl::memory::format_tag::any); - - auto reducemean_desc = dnnl::reduction::desc(dnnl::algorithm::reduction_mean, src_md, dst_md, 0.f, 0.f); - auto reducemean_pd = dnnl::reduction::primitive_desc(reducemean_desc, dnnl_engine); - - // If using GPU this will move the memory from the CPU to the GPU. - reducemean_src_mem = sp.GetMemoryAndReshape(node.Input(IN_X), reducemean_pd.src_desc(), dnnl_engine); - auto reducemean_dst_mem = dnnl::memory(reducemean_pd.dst_desc(), dnnl_engine); - - auto reducemean_op = dnnl::reduction(reducemean_pd); - sp.AddPrimitive(reducemean_op, {{DNNL_ARG_SRC, reducemean_src_mem}, - {DNNL_ARG_DST, reducemean_dst_mem}}); - - sp.SetMemory(node.Output(OUT_Y), reducemean_dst_mem); -} - -std::vector DnnlReduceMean::ReadAxes(DnnlNode& node) { - auto attr = node.Attributes().find("axes"); - std::vector axes; - if (attr != node.Attributes().end()) { - auto& proto = attr->second(); - axes.reserve(proto.ints_size()); - for (int i = 0; i < proto.ints_size(); i++) { - axes.push_back(proto.ints(i)); - } - } - return axes; -} - -} // namespace ort_dnnl -} // namespace onnxruntime diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.cc index 2b56943bdc..b32402f1d0 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.cc @@ -175,6 +175,10 @@ NodeAttributes& DnnlNode::Attributes() { return *attr_; } +int DnnlNode::SinceVersion() { + return onnx_node_->SinceVersion(); +} + DnnlSubgraph::DnnlSubgraph(const GraphViewer& graph_viewer) : graph_viewer_(graph_viewer) { Build(); is_dynamic_ = false; diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.h b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.h index 6283bcda5d..963ed815c3 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.h +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph.h @@ -76,6 +76,7 @@ class DnnlNode { NodeAttributes& Attributes(); std::vector& Inputs(); std::vector& Outputs(); + int SinceVersion(); private: const Node* onnx_node_ = nullptr; diff --git a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc index 583e6151b5..6860b1039d 100644 --- a/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc +++ b/onnxruntime/core/providers/dnnl/subgraph/dnnl_subgraph_primitive.cc @@ -16,7 +16,7 @@ #include "dnnl_pool.h" #include "dnnl_pow.h" #include "dnnl_qattention.h" -#include "dnnl_reducemean.h" +#include "dnnl_reduce.h" #include "dnnl_reshape.h" #include "dnnl_softmax.h" #include "dnnl_softmaxgrad.h" @@ -126,6 +126,7 @@ void DnnlSubgraphPrimitive::AddKernels() { std::unordered_set binary_ops = {"Add", "Div", "Mul", "Sub"}; std::unordered_set elementwise_ops = {"Abs", "Elu", "Exp", "LeakyRelu", "Log", "Relu", "Round", "Sigmoid", "Softplus", "Sqrt", "Tanh"}; std::unordered_set pool_ops = {"AveragePool", "GlobalAveragePool", "GlobalMaxPool", "MaxPool"}; + std::unordered_set reduce_ops = {"ReduceL1", "ReduceL2", "ReduceLogSum", "ReduceLogSumExp", "ReduceMax", "ReduceMean", "ReduceMin", "ReduceProd", "ReduceSum", "ReduceSumSquare"}; auto indices = subgraph_->GetDnnlNodesInTopologicalOrder(); for (auto index : indices) { @@ -158,8 +159,8 @@ void DnnlSubgraphPrimitive::AddKernels() { DnnlPow().CreatePrimitive(*this, node); } else if (node.OpType() == "QAttention") { DnnlQAttention().CreatePrimitive(*this, node); - } else if (node.OpType() == "ReduceMean") { - DnnlReduceMean().CreatePrimitive(*this, node); + } else if (reduce_ops.count(node.OpType())) { + DnnlReduce().CreatePrimitive(*this, node); } else if (node.OpType() == "Reshape") { DnnlReshape().CreatePrimitive(*this, node); } else if (node.OpType() == "Softmax") { diff --git a/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc b/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc index c841f28f79..55f516bed7 100644 --- a/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc +++ b/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc @@ -557,6 +557,28 @@ TEST(ReductionOpTest, ReduceLogSumExp_double) { test.Run(); } +TEST(ReductionOpTest, ReduceLogSumExp_float_no_reduction) { + OpTester test("ReduceLogSumExp"); + test.AddAttribute("axes", std::vector{0}); + test.AddAttribute("keepdims", (int64_t)0); + test.AddInput("data", {1, 2, 2}, + {1.0f, 2.0f, + 3.0f, 4.0f}); + test.AddOutput("reduced", {2, 2}, {1.f, 2.f, 3.f, 4.f}); + test.Run(); +} + +TEST(ReductionOpTest, ReduceLogSumExp_float_no_reduction_keepdims) { + OpTester test("ReduceLogSumExp"); + test.AddAttribute("axes", std::vector{0}); + test.AddAttribute("keepdims", (int64_t)1); + test.AddInput("data", {1, 2, 2}, + {1.0f, 2.0f, + 3.0f, 4.0f}); + test.AddOutput("reduced", {1, 2, 2}, {1.f, 2.f, 3.f, 4.f}); + test.Run(); +} + #if defined(USE_CUDA) || defined(USE_ROCM) TEST(ReductionOpTest, ReduceLogSumExp_half) { OpTester test("ReduceLogSumExp"); @@ -1082,6 +1104,24 @@ TEST(ReductionOpTest, ReduceMean0DTensor_double) { } #endif // !(defined USE_TVM) +TEST(ReductionOpTest, ReduceMean_keepdims_results_in_noop) { + OpTester test("ReduceMean"); + test.AddAttribute("axes", std::vector{0}); + test.AddAttribute("keepdims", (int64_t)1); + test.AddInput("data", {1, 3}, {1.0, 2.0, 3.0}); + test.AddOutput("reduced", {1, 3}, {1.0, 2.0, 3.0}); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); +} + +TEST(ReductionOpTest, ReduceMean_keepdims_results_in_shape_change) { + OpTester test("ReduceMean"); + test.AddAttribute("axes", std::vector{0}); + test.AddAttribute("keepdims", (int64_t)0); + test.AddInput("data", {1, 3}, {1.0, 2.0, 3.0}); + test.AddOutput("reduced", {3}, {1.0, 2.0, 3.0}); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); +} + TEST(ReductionOpTest, ReduceMin_default_axes_keepdims) { OpTester test("ReduceMin"); test.AddAttribute("keepdims", (int64_t)1); @@ -2450,7 +2490,7 @@ TEST(ReductionOpTest, OptimizeShapeForFastReduce_ReduceDimWithZero3) { ASSERT_EQ(fast_kind, FastReduceKind::kKR); } -TEST(ReductionOpTest, ReduceDimWithZero3) { +TEST(ReductionOpTest, ReduceSum_ReduceDimWithZero3) { auto run = [](OpTester& tester, const std::string& error_msg = "") { auto expect = error_msg.empty() ? OpTester::ExpectResult::kExpectSuccess : OpTester::ExpectResult::kExpectFailure; diff --git a/orttraining/orttraining/test/gradient/gradient_ops_test.cc b/orttraining/orttraining/test/gradient/gradient_ops_test.cc index 84e35add8c..9b95925410 100644 --- a/orttraining/orttraining/test/gradient/gradient_ops_test.cc +++ b/orttraining/orttraining/test/gradient/gradient_ops_test.cc @@ -443,7 +443,7 @@ TEST(GradientCheckerTest, LogGrad) { float max_error; #ifdef USE_DNNL - float error_tolerance = 3e-3f; + float error_tolerance = 4e-3f; #else float error_tolerance = 1e-3f; #endif From 102f9b05e17366e7fa474fb9faed6371c09ac644 Mon Sep 17 00:00:00 2001 From: Bowen Bao Date: Thu, 16 Dec 2021 08:08:06 -0800 Subject: [PATCH 057/113] Support new symbolic function api from PyTorch with PythonOp (#9880) * Support new symbolic function api from PyTorch with PythonOp * Specify exact exception * add comments * move comments and arg --- .../ortmodule/_custom_autograd_function_exporter.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/orttraining/orttraining/python/training/ortmodule/_custom_autograd_function_exporter.py b/orttraining/orttraining/python/training/ortmodule/_custom_autograd_function_exporter.py index e1120d08de..5a3057e8ec 100644 --- a/orttraining/orttraining/python/training/ortmodule/_custom_autograd_function_exporter.py +++ b/orttraining/orttraining/python/training/ortmodule/_custom_autograd_function_exporter.py @@ -23,7 +23,7 @@ BANNED_AUTOGRAD_FUNCTION_NAMES = set( [torch.utils.checkpoint.CheckpointFunction.__name__]) -def _export(g, n, *args, **kwargs): +def _export_pt_1_10(g, n, *args, **kwargs): ''' This function exports PythonOp (input: "n") into a graph node in "g". "args" and "kwargs" are inputs to that PythonOp. @@ -164,6 +164,17 @@ def _export(g, n, *args, **kwargs): sys.stderr.flush() raise wrap_exception(ORTModuleONNXModelException, e) +# Starting from PyTorch 1.11, there has been a change to symbolic function signature +# in terms of how additional context is accessed. More info at +# https://github.com/pytorch/pytorch/blob/6b02648479d3615fa3260961e24f38dd0f22da94/torch/onnx/symbolic_helper.py#L48 +# This code can be cleaned up once support for PyTorch version < 1.11 is dropped. +try: + from torch.onnx import SymbolicContext + def _export(ctx: SymbolicContext, g, *args, **kwargs): + n = ctx.cur_node + return _export_pt_1_10(g, n, *args, **kwargs) +except ImportError: + _export = _export_pt_1_10 def _post_process_after_export(exported_model, enable_custom_autograd_function, log_level): if enable_custom_autograd_function: From fab39b470439423ee2ee7fcad70bd122055183c7 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Thu, 16 Dec 2021 13:49:18 -0800 Subject: [PATCH 058/113] Update optimization level message in perf_test tool (#9972) --- onnxruntime/test/perftest/command_args_parser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/test/perftest/command_args_parser.cc b/onnxruntime/test/perftest/command_args_parser.cc index d2f3d78a88..7d1a4e8b47 100644 --- a/onnxruntime/test/perftest/command_args_parser.cc +++ b/onnxruntime/test/perftest/command_args_parser.cc @@ -49,7 +49,7 @@ namespace perftest { "\t-F [free_dimension_override]: Specifies a free dimension by denotation to override to a specific value for performance optimization. " "Syntax is [dimension_denotation:override_value]. override_value must > 0\n" "\t-P: Use parallel executor instead of sequential executor.\n" - "\t-o [optimization level]: Default is 1. Valid values are 0 (disable), 1 (basic), 2 (extended), 99 (all).\n" + "\t-o [optimization level]: Default is 99 (all). Valid values are 0 (disable), 1 (basic), 2 (extended), 99 (all).\n" "\t\tPlease see onnxruntime_c_api.h (enum GraphOptimizationLevel) for the full list of all optimization levels.\n" "\t-u [optimized_model_path]: Specify the optimized model path for saving.\n" "\t-d [cudnn_conv_algorithm]: Specify CUDNN convolution algothrithms: 0(benchmark), 1(heuristic), 2(default). \n" From ef36488df024c96a37ab712a2a8de53176dbadcb Mon Sep 17 00:00:00 2001 From: Tianlei Wu Date: Thu, 16 Dec 2021 16:08:05 -0800 Subject: [PATCH 059/113] Add BeamSearch operator for GPT-2 decoding (#9680) * Add BeamSearch operator and CPU implementation * Add ONNX conversion script --- docs/ContribOperators.md | 70 ++ docs/OperatorKernels.md | 1 + .../contrib_ops/cpu/cpu_contrib_kernels.cc | 2 + .../cpu/transformers/beam_search.cc | 650 ++++++++++++++++++ .../cpu/transformers/beam_search.h | 48 ++ .../transformers/beam_search_parameters.cc | 72 ++ .../cpu/transformers/beam_search_parameters.h | 55 ++ .../cpu/transformers/beam_search_scorer.cc | 285 ++++++++ .../cpu/transformers/beam_search_scorer.h | 144 ++++ .../cpu/transformers/dump_tensor.cc | 73 ++ .../cpu/transformers/dump_tensor.h | 148 ++++ .../cpu/transformers/gpt_subgraph.cc | 451 ++++++++++++ .../cpu/transformers/gpt_subgraph.h | 82 +++ .../cpu/transformers/logits_processor.cc | 192 ++++++ .../cpu/transformers/logits_processor.h | 99 +++ .../contrib_ops/cpu/transformers/sequences.cc | 76 ++ .../contrib_ops/cpu/transformers/sequences.h | 80 +++ .../core/graph/contrib_ops/contrib_defs.cc | 137 +++- onnxruntime/core/graph/graph.cc | 9 + onnxruntime/core/providers/cpu/math/top_k.cc | 50 ++ onnxruntime/core/providers/cpu/math/top_k.h | 7 + .../tools/transformers/convert_beam_search.py | 459 +++++++++++++ .../tools/transformers/convert_to_onnx.py | 1 - .../python/transformers/test_beam_search.py | 70 ++ .../kernel_def_hashes/contrib.cpu.json | 4 + 25 files changed, 3262 insertions(+), 3 deletions(-) create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/dump_tensor.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/dump_tensor.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/logits_processor.h create mode 100644 onnxruntime/contrib_ops/cpu/transformers/sequences.cc create mode 100644 onnxruntime/contrib_ops/cpu/transformers/sequences.h create mode 100644 onnxruntime/python/tools/transformers/convert_beam_search.py create mode 100644 onnxruntime/test/python/transformers/test_beam_search.py diff --git a/docs/ContribOperators.md b/docs/ContribOperators.md index 3a0171a064..a982999f0a 100644 --- a/docs/ContribOperators.md +++ b/docs/ContribOperators.md @@ -5,6 +5,7 @@ Do not modify directly.* * com.microsoft * com.microsoft.Attention * com.microsoft.AttnLSTM + * com.microsoft.BeamSearch * com.microsoft.BiasDropout * com.microsoft.BiasGelu * com.microsoft.BiasSoftmax @@ -337,6 +338,75 @@ This version of the operator has been available since version 1 of the 'com.micr +### **com.microsoft.BeamSearch** + + Beam Search for text generation. Supports GPT-2 decoder. + +#### Version + +This version of the operator has been available since version 1 of the 'com.microsoft' operator set. + +#### Attributes + +
+
body : graph (required)
+
The GPT-2 subgraph with input_ids, position_ids, attention_mask, past_0, past_1, ... as inputs, and logits, present_0, present_1, ... as output
+
early_stopping : int
+
early stop or not
+
eos_token_id : int (required)
+
The id of the end-of-sequence token
+
no_repeat_ngram_size : int
+
no repeat ngrams size
+
pad_token_id : int (required)
+
The id of the padding token
+
+ +#### Inputs (6 - 9) + +
+
input_ids : I
+
The sequence used as a prompt for the generation. Shape is (batch_size, sequence_length)
+
max_length : I
+
The maximum length of the sequence to be generated. Shape is (1)
+
min_length (optional) : I
+
The minimum length below which the score of eos_token_id is set to -Inf. Shape is (1)
+
num_beams : I
+
Number of beams for beam search. 1 means no beam search. Shape is (1)
+
num_return_sequences : I
+
The number of returned sequences in the batch. Shape is (1)
+
temperature : T
+
The value used to module the next token probabilities. Accepts value > 0.0. Shape is (1)
+
length_penalty (optional) : T
+
Exponential penalty to the length. Default value 1.0 means no penalty.Value > 1.0 encourages longer sequences, while values < 1.0 produces shorter sequences.Shape is (1,)
+
repetition_penalty (optional) : T
+
The parameter for repetition penalty. Default value 1.0 means no penalty. Accepts value > 0.0. Shape is (1)
+
vocab_mask (optional) : M
+
Mask of vocabulary. Words that masked with 0 are not allowed to be generated, and 1 is allowed. Shape is (vacab_size)
+
+ +#### Outputs (1 - 3) + +
+
sequences : I
+
Word IDs of generated sequences. Shape is (batch_size, num_return_sequences, max_sequence_length)
+
sequences_scores (optional) : T
+
Final beam score of the generated sequences. Shape is (batch_size, num_return_sequences)
+
scores (optional) : T
+
Processed beam scores for each vocabulary token at each generation step.Beam scores consisting of log softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this beam.Shape is (max_length - sequence_length, batch_size, num_beams, vocab_size)
+
+ +#### Type Constraints + +
+
T : tensor(float), tensor(float16)
+
Constrain input and output types to float tensors.
+
I : tensor(int32)
+
Constrain to integer types
+
M : tensor(int32)
+
Constrain mask to integer types
+
+ + ### **com.microsoft.BiasDropout** output, dropout_mask = Dropout(data + bias, ratio) + residual, Intended to specialize the dropout pattern commonly found in transformer models. diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md index 052367130e..6f09fb5026 100644 --- a/docs/OperatorKernels.md +++ b/docs/OperatorKernels.md @@ -377,6 +377,7 @@ Do not modify directly.* |**Operator Domain:** *com.microsoft*|||| |Attention|*in* input:**T**
*in* weight:**T**
*in* bias:**T**
*in* mask_index:**M**
*in* past:**T**
*in* extra_add:**T**
*out* output:**T**
*out* present:**T**|1+|**T** = tensor(float)| |AttnLSTM|*in* X:**T**
*in* W:**T**
*in* R:**T**
*in* B:**T**
*in* sequence_lens:**T1**
*in* initial_h:**T**
*in* initial_c:**T**
*in* P:**T**
*in* QW:**T**
*in* MW:**T**
*in* V:**T**
*in* M:**T**
*in* memory_seq_lens:**T1**
*in* AW:**T**
*out* Y:**T**
*out* Y_h:**T**
*out* Y_c:**T**|1+|**T** = tensor(double), tensor(float)
**T1** = tensor(int32)| +|BeamSearch|*in* input_ids:**I**
*in* max_length:**I**
*in* min_length:**I**
*in* num_beams:**I**
*in* num_return_sequences:**I**
*in* temperature:**T**
*in* length_penalty:**T**
*in* repetition_penalty:**T**
*in* vocab_mask:**M**
*out* sequences:**I**
*out* sequences_scores:**T**
*out* scores:**T**|1+|**T** = tensor(float)| |BiasGelu|*in* A:**T**
*in* B:**T**
*out* C:**T**|1+|**T** = tensor(float)| |BifurcationDetector|*in* src_tokens:**T**
*in* cur_tokens:**T**
*in* prev_suffix_match_idx:**T**
*in* pred_tokens:**T**
*out* tokens:**T**
*out* suffix_match_idx:**T**|1+|**T** = tensor(int64)| |CDist|*in* A:**T**
*in* B:**T**
*out* C:**T**|1+|**T** = tensor(double), tensor(float)| diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc index 77669f74ea..1f0ee6d17e 100644 --- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc @@ -22,6 +22,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, GridSample); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, Attention); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, BeamSearch); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, EmbedLayerNormalization); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, ExpandDims); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, float, FusedConv); @@ -199,6 +200,7 @@ Status RegisterCpuContribKernels(KernelRegistry& kernel_registry) { // add more kernels here BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc b/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc new file mode 100644 index 0000000000..1225442192 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc @@ -0,0 +1,650 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// there's no way to use a raw pointer as the copy destination with std::copy_n +// (which gsl::copy uses with span::data() which returns a raw pointer) with the 14.11 toolset +// without generating a 4996 warning. going through an iterator is way too much overhead so turn off the warning. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + +#include +#include "core/providers/cpu/controlflow/utils.h" +#include "core/providers/cpu/math/top_k.h" +#include "core/framework/allocator.h" +#include "core/framework/framework_common.h" +#include "core/framework/op_kernel_context_internal.h" +#include "core/framework/session_state.h" +#include "core/framework/tensorprotoutils.h" +#include "core/framework/utils.h" +#include "core/providers/cpu/tensor/utils.h" +#include "core/framework/session_options.h" +#include "core/framework/TensorSeq.h" +#include "gsl/gsl" +#include "core/providers/cpu/math/softmax_shared.h" +#include "beam_search.h" +#include "logits_processor.h" +#include "sequences.h" +#include "dump_tensor.h" + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +using namespace ONNX_NAMESPACE; +using namespace onnxruntime::common; + +namespace onnxruntime { +namespace contrib { + +#define REGISTER_KERNEL_TYPED(T) \ + ONNX_OPERATOR_TYPED_KERNEL_EX( \ + BeamSearch, \ + kMSDomain, \ + 1, \ + T, \ + kCpuExecutionProvider, \ + (*KernelDefBuilder::Create()) \ + .TypeConstraint("T", DataTypeImpl::GetTensorType()), \ + transformers::BeamSearch); + +REGISTER_KERNEL_TYPED(float) + +namespace transformers { + +template +struct BeamSearchState { + gsl::span beam_scores; // shape (batch_size, num_beams) + gsl::span next_token_logits; // shape (batch_size * num_beams, vocab_size) + gsl::span next_token_scores; // shape (batch_size, num_beams * vocab_size) + gsl::span next_tokens; // shape (batch_size, 2 * num_beams) + gsl::span next_indices; // shape (batch_size, 2 * num_beams) + gsl::span next_positions; // shape (batch_size, num_beams). Next position value for position_ids. + + gsl::span scores; // shape (max_length - sequence_length + 1, batch_size, num_beams * vocab_size) + gsl::span remaining_scores; // subspan that is avaiable for appending next token scores. + + Sequences sequences; + + void Init(AllocatorPtr allocator, + int batch_size, + int num_beams, + int vocab_size, + int sequence_length, + int max_length, + bool output_scores) { + size_t batch_beam_size = SafeInt(batch_size) * num_beams; + beam_scores = AllocateBuffer(allocator, beam_scores_buffer_, batch_beam_size, true, static_cast(0)); + + // Initialize score of first beam of each group with 0 and the rest with -1e9. + // This ensures that the beams in the same group don't produce same tokens every time. + for (int i = 0; i < batch_size; i++) { + for (int j = 1; j < num_beams; j++) { + beam_scores[i * num_beams + j] = -1e9; + } + } + + size_t next_token_size = SafeInt(batch_beam_size) * vocab_size; + next_token_logits = AllocateBuffer(allocator, next_token_logits_buffer_, next_token_size, true, static_cast(0)); + next_token_scores = AllocateBuffer(allocator, next_token_scores_buffer_, next_token_size, true, static_cast(0)); + + next_tokens = AllocateBuffer(allocator, next_tokens_buffer_, SafeInt(2) * batch_beam_size, true, static_cast(0)); + + next_indices = AllocateBuffer(allocator, next_indices_buffer_, SafeInt(2) * batch_beam_size, true, static_cast(0)); + + next_positions = AllocateBuffer(allocator, next_positions_buffer_, batch_beam_size, true, static_cast(0)); + + if (output_scores) { + size_t elements = SafeInt(max_length - sequence_length) * batch_size * num_beams * vocab_size; + scores = AllocateBuffer(allocator, scores_buffer_, elements); + remaining_scores = scores; + } + + // sequences will be initialized later since it has dependency on input_ids + } + + private: + BufferUniquePtr beam_scores_buffer_; + BufferUniquePtr next_token_logits_buffer_; + BufferUniquePtr next_token_scores_buffer_; + BufferUniquePtr next_tokens_buffer_; + BufferUniquePtr next_indices_buffer_; + BufferUniquePtr next_positions_buffer_; + BufferUniquePtr scores_buffer_; +}; + +template +class BeamSearchImpl { + public: + BeamSearchImpl(OpKernelContextInternal& context, + const SessionState& session_state, + GptSubgraph& gpt_subgraph, + concurrency::ThreadPool* thread_pool, + void* stream, + BeamSearchParameters& params); + + // Initialize by validating all the inputs, and allocating the output tensors. + Status Initialize(); + + // Execute beam search in iterations util stopping criteria is reached. + // In each iteration, GPT subgraph is called, and next token for each sequence is generated. + Status Execute(const FeedsFetchesManager& cached_ffm); + + private: + // Validate inputs. + Status CheckInputs(const OpKernelContextInternal& context); + + // Prepare the inputs for first inference of subgraph + void CreateInitialFeeds(gsl::span& next_positions, std::vector& feeds); + + // Update the input for next iteration. + Status UpdateFeeds( + const std::vector& last_outputs, + std::vector& next_inputs, + int current_length, + gsl::span& next_positions, + gsl::span beam_next_tokens, + gsl::span beam_indices); + + // Process logits and append next tokens to sequences. + Status GenerateNextToken(const OrtValue& logits, + gsl::span& beam_next_tokens, + gsl::span& beam_indices, + BeamSearchState& beam_state); + + // Calculate scores from logits, then apply filtering and select next token for each beam. + Status ProcessLogits(const OrtValue& logits, // logits output of subgraph + BeamSearchState& beam_state, + AllocatorPtr& allocator); + + OpKernelContextInternal& context_; + + const SessionState& session_state_; + + GptSubgraph& gpt_subgraph_; + + concurrency::ThreadPool* thread_pool_; + + const std::vector& implicit_inputs_; + + // Not used in CPU. Stream is for CUDA only. + void* stream_; + + BeamSearchParameters* parameters_; + + LogitsProcessorList logits_processors_; + + std::unique_ptr> beam_scorer_; + + AllocatorPtr allocator_; +}; + +template +void BeamSearch::Init(const OpKernelInfo& info) { + // Make sure the body attribute was present even though we don't need it here. + ONNX_NAMESPACE::GraphProto proto; + ORT_ENFORCE(info.GetAttr("body", &proto).IsOK()); + ORT_IGNORE_RETURN_VALUE(proto); + + parameters_.ParseFromAttributes(info); + + stream_ = nullptr; +} + +template +std::unique_ptr BeamSearch::Create(const OpKernelInfo& info, + void* stream) { + auto result = std::make_unique(info); + result->SetComputeStream(stream); + return result; +} + +template +common::Status BeamSearch::SetupSubgraphExecutionInfo(const SessionState& session_state, + const std::string& attribute_name, + const SessionState& subgraph_session_state) { + ORT_ENFORCE(gpt_subgraph_ == nullptr, "SetupSubgraphExecutionInfo should only be called once for each subgraph."); + const auto& node = Node(); + gpt_subgraph_ = std::make_unique(node, attribute_name, subgraph_session_state.GetGraphViewer()); + ORT_RETURN_IF_ERROR(gpt_subgraph_->Setup(session_state, subgraph_session_state)); + feeds_fetches_manager_ = gpt_subgraph_->GetFeedsFetchesManager(); + parameters_.SetSubgraphParameters(gpt_subgraph_->vocab_size, + gpt_subgraph_->num_heads, + gpt_subgraph_->head_size, + gpt_subgraph_->num_layers); + return Status::OK(); +} + +template +Status BeamSearch::Compute(OpKernelContext* ctx) const { + auto* ctx_internal = static_cast(ctx); + auto* session_state = ctx_internal->SubgraphSessionState("body"); + ORT_ENFORCE(session_state, "Subgraph SessionState was not found for 'body' attribute."); + ORT_ENFORCE(feeds_fetches_manager_, "CreateFeedsFetchesManager must be called prior to execution of graph."); + + concurrency::ThreadPool* thread_pool = ctx->GetOperatorThreadPool(); + + BeamSearchParameters parameters = parameters_; // make a copy since we will update the parameters based on inputs later + + BeamSearchImpl impl{*ctx_internal, *session_state, *gpt_subgraph_, thread_pool, stream_, parameters}; + + auto status = impl.Initialize(); + ORT_RETURN_IF_ERROR(status); + + status = impl.Execute(*feeds_fetches_manager_); + + return status; +} + +template +BeamSearchImpl::BeamSearchImpl(OpKernelContextInternal& context, + const SessionState& session_state, + GptSubgraph& gpt_subgraph, + concurrency::ThreadPool* thread_pool, + void* stream, + BeamSearchParameters& params) + : context_(context), + session_state_(session_state), + gpt_subgraph_(gpt_subgraph), + thread_pool_(thread_pool), + implicit_inputs_(context_.GetImplicitInputs()), + stream_(stream), + parameters_(¶ms), + allocator_(nullptr) { + parameters_->ParseFromInputs(&context); + + allocator_ = session_state.GetExecutionProviders() + .Get(onnxruntime::kCpuExecutionProvider) + ->GetAllocator(0, OrtMemTypeDefault); +} + +template +Status BeamSearchImpl::CheckInputs(const OpKernelContextInternal& context) { + // Input shapes: + // input_ids : (batch_size, sequence_length) + // vocab_mask : (vocab_size) or nullptr + + const Tensor* input_ids = context.Input(0); + const auto& dims = input_ids->Shape().GetDims(); + if (dims.size() != 2) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Input 'input_ids' is expected to have 2 dimensions, got ", + dims.size()); + } + + const Tensor* vocab_mask = context.Input(8); + if (vocab_mask != nullptr) { // vocab_mask is optional + const auto& vocab_mask_dims = vocab_mask->Shape().GetDims(); + if (vocab_mask_dims.size() != 1) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Input 'vocab_mask' is expected to have 1 dimension, got ", + vocab_mask_dims.size()); + } + + // There is dependency on vocab_size parameter, which shall be set before calling this function. + if (static_cast(vocab_mask_dims[0]) != parameters_->vocab_size) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Input 'vocab_mask' shape does not match with vocab_size, got ", + vocab_mask_dims[0]); + } + + // store vocab mask in parameters. + parameters_->vocab_mask = vocab_mask->DataAsSpan(); + } + + return Status::OK(); +} + +template +Status BeamSearchImpl::Initialize() { + auto status = Status::OK(); + +#define CHECK_SCALAR_INPUT(name, index, required) \ + auto* name##_tensor = context_.Input(index); \ + if (name##_tensor) { \ + if (!name##_tensor->Shape().IsScalar()) { \ + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "'BeamSearch' input " #name " should be a scalar. Got shape of ", \ + name##_tensor->Shape()); \ + } \ + } else if (required) { \ + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "'BeamSearch' input " #name " is required"); \ + } + + CHECK_SCALAR_INPUT(min_length, 1, false); + + CHECK_SCALAR_INPUT(max_length, 2, true); + + CHECK_SCALAR_INPUT(num_beams, 3, true); + + CHECK_SCALAR_INPUT(num_return_sequences, 4, true); + + CHECK_SCALAR_INPUT(temperature, 5, true); + + CHECK_SCALAR_INPUT(length_penalty, 6, true); + + ORT_RETURN_IF(parameters_->num_return_sequences > parameters_->num_beams, "'num_return_sequences' has to be smaller or equal to 'num_beams'."); + + ORT_RETURN_IF_ERROR(CheckInputs(context_)); + + // This flag will be updated later when the scores output exists. + parameters_->output_scores = false; + + // Initialize processsors after CheckInputs so that parameters_->vocab_mask is ready. + logits_processors_.Init(*parameters_); + + return status; +} + +template +void BeamSearchImpl::CreateInitialFeeds(gsl::span& next_positions, std::vector& feeds) { + const OrtValue* input_ids_value = context_.GetInputOrtValue(0); + const Tensor& input_ids = input_ids_value->Get(); + gpt_subgraph_.CreateInitialFeeds(input_ids, implicit_inputs_, parameters_->num_beams, parameters_->pad_token_id, next_positions, feeds); +} + +template +Status BeamSearchImpl::ProcessLogits( + const OrtValue& logits, + BeamSearchState& beam_state, + AllocatorPtr& allocator) { + const int64_t batch_beam_size = static_cast(parameters_->BatchBeamSize()); + const int& vocab_size = parameters_->vocab_size; + + const T* logits_data = logits.Get().Data(); + + // Logits has shape (batch_size * num_beams, input_length, vocab_size), + // where input_length equals to parameters_->sequence_length for first subgraph call, and 1 for the remaining calls. + const TensorShape& logits_shape = logits.Get().Shape(); + ORT_ENFORCE(logits_shape.NumDimensions() == 3); + auto input_length = logits_shape[1]; + + // Get logits for the last token: + // next_token_logits = logits[:, -1, :], and the result shape is (batch_size * num_beams, vocab_size) + // When input_length == 1, use logits directly in SoftmaxCPU below so it only need for input_length > 1. + gsl::span& next_token_logits = beam_state.next_token_logits; + if (input_length > 1) { + const T* current_logits = logits_data + (input_length - 1) * vocab_size; + for (int i = 0; i < batch_beam_size; i++) { + gsl::span source(current_logits, vocab_size); + gsl::span target = next_token_logits.subspan(i * vocab_size, vocab_size); + gsl::copy(source, target); + current_logits += input_length * vocab_size; + } + } + +#ifdef DEBUG_BEAM_SEARCH + //DumpOrtValue("logits", logits); + DumpTensor("next_token_logits", next_token_logits.data(), parameters_->batch_size, parameters_->num_beams, vocab_size); +#endif + + // Get scores for candidates of next token: next_token_scores = log_softmax(next_token_logits, dim=-1) + gsl::span& next_token_scores = beam_state.next_token_scores; + Status status = SoftmaxCPU(batch_beam_size, // rows + vocab_size, // elements per row + input_length > 1 ? next_token_logits.data() : logits_data, + next_token_scores.data(), + true, + thread_pool_); + if (!status.IsOK()) { + return status; + } + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("next_token_scores after softmax", next_token_scores.data(), parameters_->batch_size, parameters_->num_beams, vocab_size); +#endif + + // Apply all score processors that updates scores + logits_processors_.Process(&(beam_state.sequences), next_token_scores); + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("next_token_scores after logits processor", next_token_scores.data(), parameters_->batch_size, parameters_->num_beams, vocab_size); +#endif + + // Add beam score to next token scores. Corresponding python code is like: + // next_token_scores = next_token_scores + beam_scores[:, None].expand_as(next_token_scores) + // TODO: use thread pool to parrellel + int offset = 0; + int batch_beam_index = 0; + for (int i = 0; i < parameters_->batch_size; i++) { + for (int j = 0; j < parameters_->num_beams; j++, batch_beam_index++) { + for (int k = 0; k < parameters_->vocab_size; k++, offset++) { + next_token_scores[offset] += beam_state.beam_scores[batch_beam_index]; + } + } + } + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("next_token_scores after adding beam_scores", next_token_scores.data(), parameters_->batch_size, parameters_->num_beams, vocab_size); +#endif + + if (parameters_->output_scores) { + // Append next token scores to the scores output. + gsl::copy(next_token_scores, beam_state.remaining_scores); + beam_state.remaining_scores = beam_state.remaining_scores.subspan(next_token_scores.size()); + } + + // Apply top-k selection like the following: + // next_token_scores = next_token_scores.view(batch_size, num_beams * vocab_size) + // next_token_scores, next_tokens = torch.topk(next_token_scores, 2 * num_beams, dim=1, largest=True, sorted=True) + int64_t next_token_scores_dims[] = {parameters_->batch_size, parameters_->num_beams * vocab_size}; + TensorShape next_token_scores_shape(&next_token_scores_dims[0], 2); + auto element_type = DataTypeImpl::GetType(); + OrtValue next_token_scores_value; + Tensor::InitOrtValue(element_type, next_token_scores_shape, next_token_scores.data(), allocator->Info(), next_token_scores_value); + const Tensor& input = next_token_scores_value.Get(); + + const int axis = 1; + const unsigned top_k = static_cast(2 * parameters_->num_beams); + const bool largest = true; + const bool sorted = true; // results returned in sorted order. + + std::unique_ptr topk_scores; + std::unique_ptr topk_indices; + status = GetTopK(&input, axis, top_k, largest, sorted, allocator, thread_pool_, topk_scores, topk_indices); + if (!status.IsOK()) { + return status; + } + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("topk_scores", *(topk_scores.get())); + DumpTensor("topk_indices", *(topk_indices.get())); +#endif + + // Convert indices in range [0, num_beams * vocab_size) to token ID of range [0, vocab_size) like the following: + // next_indices = (next_tokens / vocab_size).long() + // next_tokens = next_tokens % vocab_size + gsl::span next_token_indices = topk_indices->DataAsSpan(); + offset = 0; + for (int i = 0; i < parameters_->batch_size; i++) { + for (unsigned int j = 0; j < top_k; j++, offset++) { + beam_state.next_indices[offset] = next_token_indices[offset] / vocab_size; + beam_state.next_tokens[offset] = next_token_indices[offset] % vocab_size; + } + } + + gsl::span next_scores = topk_scores->DataAsSpan(); + gsl::span next_tokens(beam_state.next_tokens.data(), beam_state.next_tokens.size()); + gsl::span next_indices(beam_state.next_indices.data(), beam_state.next_indices.size()); + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("next_scores before scorer", next_scores.data(), parameters_->batch_size, top_k); + DumpTensor("next_tokens before scorer", next_tokens.data(), parameters_->batch_size, top_k); + DumpTensor("next_indices before scorer", next_indices.data(), parameters_->batch_size, top_k); +#endif + + beam_scorer_->Process( + &(beam_state.sequences), + next_scores, + next_tokens, + next_indices); + + return Status::OK(); +} + +template +Status BeamSearchImpl::GenerateNextToken( + const OrtValue& logits, + gsl::span& beam_next_tokens, + gsl::span& beam_indices, + BeamSearchState& beam_state) { + // Process logits to get next token scores + ORT_RETURN_IF_ERROR(ProcessLogits(logits, beam_state, allocator_)); + + gsl::span& beam_scores = beam_scorer_->GetNextScores(); + // It is optional to clone beam_scores. Change it to use same buffer also works: + // beam_state.beam_scores = beam_scores + // Here we make a copy to reduce the coupling with little cost (the buffer size is small). + gsl::copy(beam_scores, beam_state.beam_scores); + + beam_next_tokens = beam_scorer_->GetNextTokens(); + beam_indices = beam_scorer_->GetNextIndices(); + +#ifdef DEBUG_BEAM_SEARCH + DumpTensor("beam_scores after scorer", beam_scores.data(), parameters_->batch_size, parameters_->num_beams); + DumpTensor("beam_next_tokens after scorer", beam_next_tokens.data(), parameters_->batch_size, parameters_->num_beams); + DumpTensor("beam_indices after scorer", beam_indices.data(), parameters_->batch_size, parameters_->num_beams); +#endif + + beam_state.sequences.AppendNextTokenToSequences(beam_indices, beam_next_tokens); + +#ifdef DEBUG_BEAM_SEARCH + beam_state.sequences.PrintSequences(); +#endif + return Status::OK(); +} + +template +Status BeamSearchImpl::UpdateFeeds( + const std::vector& last_outputs, + std::vector& next_inputs, + int current_length, + gsl::span& next_positions, + gsl::span beam_next_tokens, + gsl::span beam_indices) { + return gpt_subgraph_.UpdateFeeds(last_outputs, next_inputs, current_length, next_positions, + beam_next_tokens, beam_indices, parameters_->num_beams); +} + +template +Status BeamSearchImpl::Execute(const FeedsFetchesManager& ffm) { + auto status = Status::OK(); + + std::vector sequences_dims{parameters_->batch_size, parameters_->num_return_sequences, parameters_->max_length}; + TensorShape sequences_shape(sequences_dims); + Tensor* output_sequences = context_.Output(0, sequences_shape); + + std::vector sequences_scores_dims{parameters_->batch_size, parameters_->num_return_sequences}; + TensorShape sequences_scores_shape(sequences_scores_dims); + Tensor* output_sequences_scores = context_.Output(1, sequences_scores_shape); + + std::vector scores_dims{ + parameters_->max_length - parameters_->sequence_length, + parameters_->batch_size, parameters_->num_beams, parameters_->vocab_size}; + TensorShape scores_shape(scores_dims); + Tensor* output_scores = context_.Output(2, scores_shape); + + // Update the flag to indicate whether scores exists in output + parameters_->output_scores = (output_scores != nullptr); + + std::vector feeds; + std::vector fetches; + + // Initialize resources + AllocatorPtr temp_space_allocator; + ORT_RETURN_IF_ERROR(context_.GetTempSpaceAllocator(&temp_space_allocator)); + + BeamSearchState beam_state; + beam_state.Init(temp_space_allocator, + parameters_->batch_size, + parameters_->num_beams, + parameters_->vocab_size, + parameters_->sequence_length, + parameters_->max_length, + parameters_->output_scores); + + beam_scorer_ = std::make_unique>(parameters_->batch_size, + parameters_->num_beams, + parameters_->max_length, + parameters_->length_penalty, + parameters_->early_stopping, + parameters_->num_return_sequences, + parameters_->pad_token_id, + parameters_->eos_token_id); + beam_scorer_->Initialize(allocator_, parameters_->sequence_length); // TODO: use temp_space_allocator + + CreateInitialFeeds(beam_state.next_positions, feeds); + const OrtValue& input_ids = feeds[0]; + beam_state.sequences.Init(temp_space_allocator, + input_ids, + parameters_->BatchBeamSize(), + parameters_->sequence_length, + parameters_->max_length); + +#ifdef DEBUG_BEAM_SEARCH + DumpOrtValue("input_ids", input_ids); + DumpOrtValue("position_ids", feeds[1]); + DumpOrtValue("attention_mask", feeds[2]); +#endif + + int current_length = parameters_->sequence_length; + while (current_length < parameters_->max_length) { +#ifdef DEBUG_BEAM_SEARCH + DumpString("***CurrentLength", std::to_string(current_length), true); +#endif + + status = utils::ExecuteSubgraph(session_state_, ffm, feeds, fetches, {}, + ExecutionMode::ORT_SEQUENTIAL, context_.GetTerminateFlag(), context_.Logger()); + + ORT_RETURN_IF_ERROR(status); + + const OrtValue& logits = fetches[0]; + gsl::span beam_next_tokens; + gsl::span beam_indices; + ORT_RETURN_IF_ERROR(GenerateNextToken(logits, beam_next_tokens, beam_indices, beam_state)); + + // When all batches are finished, stop earlier to avoid wasting computation. + if (beam_scorer_->IsDone()) { + break; + } + + // Increase sequence length after a new token is generated. + ++current_length; + + // Prepare inputs for next round of subgraph call. + if (current_length < parameters_->max_length) { + ORT_RETURN_IF_ERROR(UpdateFeeds(fetches, feeds, current_length, + beam_state.next_positions, + beam_next_tokens.as_span(), + beam_indices.as_span())); + } + fetches.clear(); + +#ifdef DEBUG_BEAM_SEARCH + if (current_length - parameters_->sequence_length == 3) { // only dump a few steps. + DisableTensorDump(); + } +#endif + } + + gsl::span beam_scores(beam_state.beam_scores.data(), beam_state.beam_scores.size()); + beam_scorer_->Finalize(&(beam_state.sequences), + beam_scores, + output_sequences, + output_sequences_scores); + + // Output per token scores + if (output_scores != nullptr) { + gsl::span target = output_scores->MutableDataAsSpan(); + gsl::span source = gsl::span(beam_state.scores.data(), beam_state.scores.size()); + assert(target.length() == source.length()); + gsl::copy(source, target); + } + + return status; +} + +// Instantiation +template class BeamSearchImpl; +template class BeamSearch; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search.h b/onnxruntime/contrib_ops/cpu/transformers/beam_search.h new file mode 100644 index 0000000000..9dc5cac408 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search.h @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include +#include "gsl/gsl" +#include "core/common/common.h" +#include "core/framework/feeds_fetches_manager.h" +#include "core/framework/op_kernel.h" +#include "core/providers/cpu/controlflow/utils.h" +#include "beam_search_parameters.h" +#include "beam_search_scorer.h" +#include "gpt_subgraph.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +template +class BeamSearch : public controlflow::IControlFlowKernel { + public: + BeamSearch(const OpKernelInfo& info) : IControlFlowKernel(info) { Init(info); } + void Init(const OpKernelInfo& info); + + Status Compute(OpKernelContext* ctx) const override; + + Status SetupSubgraphExecutionInfo(const SessionState& session_state, + const std::string& attribute_name, + const SessionState& subgraph_session_state) override; + + static std::unique_ptr Create(const OpKernelInfo& info, void* stream); + + protected: + void SetComputeStream(void* stream) { stream_ = stream; } + + private: + // Subgraph and FeedsFetchesManager re-used for each subgraph execution. + std::unique_ptr gpt_subgraph_; + FeedsFetchesManager* feeds_fetches_manager_; + + void* stream_; + + BeamSearchParameters parameters_; +}; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.cc b/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.cc new file mode 100644 index 0000000000..fee3ec4753 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.cc @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#include "beam_search_parameters.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +constexpr int kMaxSequenceLength = 4096; + +Status BeamSearchParameters::Validate() const { + ORT_RETURN_IF(eos_token_id < 0, "eos_token_id is invalid"); + ORT_RETURN_IF(pad_token_id < 0, "pad_token_id is invalid"); + ORT_RETURN_IF(min_length >= max_length, "min_length shall be smaller than max_length"); + return Status::OK(); +} + +void BeamSearchParameters::ParseFromAttributes(const OpKernelInfo& info) { + early_stopping = info.GetAttrOrDefault("early_stopping", 0) == 1; + eos_token_id = static_cast(info.GetAttrOrDefault("eos_token_id", -1)); + pad_token_id = static_cast(info.GetAttrOrDefault("pad_token_id", -1)); + no_repeat_ngram_size = static_cast(info.GetAttrOrDefault("no_repeat_ngram_size", 0)); +} + +void BeamSearchParameters::ParseFromInputs(OpKernelContext* context) { + ORT_ENFORCE(context != nullptr); + const Tensor* input_ids = context->Input(0); + const auto& dims = input_ids->Shape().GetDims(); + ORT_ENFORCE(dims.size() == 2, "input_ids shall have 2 dimensions. Got ", dims.size()); + batch_size = static_cast(dims[0]); + sequence_length = static_cast(dims[1]); + + auto* max_length_tensor = context->Input(1); + max_length = max_length_tensor ? static_cast(*max_length_tensor->Data()) : kMaxSequenceLength; + ORT_ENFORCE(max_length > sequence_length, "max_length (", max_length, ") shall be greater than input sequence length (", sequence_length, ")"); + ORT_ENFORCE(max_length <= kMaxSequenceLength, "max_length (", max_length, ") shall be no more than ", kMaxSequenceLength); + + auto* min_length_tensor = context->Input(2); + min_length = min_length_tensor ? static_cast(*min_length_tensor->Data()) : 0; + + auto* num_beams_tensor = context->Input(3); + num_beams = num_beams_tensor ? static_cast(*num_beams_tensor->Data()) : 1; + // TODO: limit num_beams > 1 when we can have another operator for greedy search. + ORT_ENFORCE(num_beams >= 1, "num_beams shall be a positive integer, got ", num_beams); + + auto* num_return_sequences_tensor = context->Input(4); + num_return_sequences = num_return_sequences_tensor ? static_cast(*num_return_sequences_tensor->Data()) : 1; + ORT_ENFORCE(num_return_sequences >= 1, "num_return_sequences shall be a positive integer, got ", num_return_sequences); + ORT_ENFORCE(num_beams >= num_return_sequences, "num_return_sequences (", num_return_sequences, ") shall be be no more than num_beams (", num_beams, ")"); + + auto* temperature_tensor = context->Input(5); + temperature = temperature_tensor ? static_cast(*temperature_tensor->Data()) : 1; + ORT_ENFORCE(temperature > 0.0f, "temperature shall be greater than 0, got ", temperature); + + auto* length_penalty_tensor = context->Input(6); + length_penalty = length_penalty_tensor ? static_cast(*length_penalty_tensor->Data()) : 1; + + auto* repetition_penalty_tensor = context->Input(7); + repetition_penalty = repetition_penalty_tensor ? static_cast(*repetition_penalty_tensor->Data()) : 1.0f; + ORT_ENFORCE(repetition_penalty > 0.0f, "repetition_penalty shall be greater than 0, got ", repetition_penalty); +} + +void BeamSearchParameters::SetSubgraphParameters(int vocabulary_size, int heads, int hidden_size_per_head, int layers) { + vocab_size = vocabulary_size; + num_heads = heads; + head_size = hidden_size_per_head; + num_layers = layers; +} + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.h b/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.h new file mode 100644 index 0000000000..26de2a9840 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search_parameters.h @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include "core/common/common.h" +#include "core/framework/op_kernel.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +struct BeamSearchParameters { + // Parameters from node attributes + int eos_token_id; + int pad_token_id; + int no_repeat_ngram_size; + bool early_stopping; + + // Parameters from inputs + int min_length; + int max_length; + int num_beams; + int num_return_sequences; + float temperature; + float length_penalty; + float repetition_penalty; + int batch_size; // deduce from first dimension of input_ids + int sequence_length; // deduce from second dimension of input_ids + + gsl::span vocab_mask; + + // Parameters from outputs. + bool output_scores; // whether scores existed in output + + // Parameters from subgraph. + int vocab_size; + // Below are used in CPU, reserved for CUDA. + int num_heads; + int head_size; + int num_layers; + + Status Validate() const; + + int BatchBeamSize() const { return batch_size * num_beams; } + + void ParseFromAttributes(const OpKernelInfo& info); + + void ParseFromInputs(OpKernelContext* context); + + void SetSubgraphParameters(int vocab_size, int num_heads, int head_size, int num_layers); +}; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc new file mode 100644 index 0000000000..bb7aeb989e --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc @@ -0,0 +1,285 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include +#include "core/common/common.h" +#include "core/framework/allocator.h" +#include "core/framework/tensorprotoutils.h" +#include "core/framework/utils.h" +#include "core/providers/cpu/tensor/utils.h" +#include "core/providers/cpu/rnn/rnn_helpers.h" +#include "beam_search_scorer.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { +using ::onnxruntime::rnn::detail::Allocate; + +template +BeamHypotheses::BeamHypotheses(int num_beams, T length_penalty, bool early_stopping) + : num_beams_(num_beams), + length_penalty_(length_penalty), + early_stopping_(early_stopping), + worst_score_(1e9) {} + +template +void BeamHypotheses::Add(gsl::span& hypothesis, T sum_logprobs) { + auto length = hypothesis.size(); + // TODO: when T is FP16, compute in FP32, then cast result back to FP16. length_penalty_ might also be float. + T score = sum_logprobs / pow(static_cast(length), length_penalty_); + + if (this->Size() < num_beams_ || score > worst_score_) { + HypothesisScore item(hypothesis, score); + beams_.push(item); + if (this->Size() > num_beams_) { + beams_.pop(); + } + worst_score_ = beams_.top().score; + } +} + +template +bool BeamHypotheses::IsDone(T best_sum_logprobs, int current_length) { + // If there are enough hypotheses and that none of the hypotheses being generated can become better + // than the worst one in the heap, then we are done with this sentence. + + if (Size() < num_beams_) + return false; + + if (early_stopping_) + return true; + + T current_score = best_sum_logprobs / pow(static_cast(current_length), length_penalty_); + return worst_score_ >= current_score; +} + +template +void BeamHypotheses::Output( + int top_k, + int max_length, + gsl::span& sequences, // buffer filled with pad token ID, shape (num_return_sequences, max_length) + gsl::span& sequences_scores) // buffer of shape (num_return_sequences) or empty +{ + ORT_ENFORCE(top_k <= Size()); + int remove_count = Size() - top_k; + for (int i = 0; i < remove_count; i++) { + beams_.pop(); + } + + // Since pop get the worst sequence, so output it in the reverse order. + // The frist (worst) beam shall be put at the last position among top_k sequences. + int index = top_k - 1; + while (!beams_.empty()) { + auto item = beams_.top(); + gsl::span& source = item.hypothesis; + gsl::span target = sequences.subspan(index * max_length, max_length); + + // Note that word_ids might be less than max_length. + // Since the sequences has been filled with pad token ID, so padding is not needed here. + // Since data type need cast from int64_t to int32_t, we cannot use gsl::copy(word_ids, sequence) here. + for (size_t i = 0; i < source.length(); i++) { + target[i] = static_cast(source[i]); + } + + if (!sequences_scores.empty()) + sequences_scores[index] = item.score; + + beams_.pop(); + index--; + } +} + +template +BeamSearchScorer::BeamSearchScorer(int batch_size, + int num_beams, + int max_length, + T length_penalty, + bool early_stopping, + int num_return_sequences, + int pad_token_id, + int eos_token_id) + : batch_size_(batch_size), + num_beams_(num_beams), + max_length_(max_length), + num_beam_hyps_to_keep_(num_return_sequences), + pad_token_id_(pad_token_id), + eos_token_id_(eos_token_id), + hypothesis_buffer_length_(0), + hypothesis_buffer_offset_(0) { + for (int batch = 0; batch < batch_size; batch++) { + beam_hyps.push_back(BeamHypotheses(num_beams, length_penalty, early_stopping)); + } +} + +template +bool BeamSearchScorer::IsDone() { + for (int batch = 0; batch < batch_size_; batch++) { + if (!done_[batch]) + return false; + } + return true; +} + +template +void BeamSearchScorer::Initialize(AllocatorPtr& allocator, int sequence_length){ + ORT_ENFORCE(next_beam_scores_.empty()); // Make sure this is called only once. + + size_t batch_beam_size = static_cast(batch_size_ * num_beams_); + const bool no_fill = false; // do not fill values after allocation + next_beam_scores_ = Allocate(allocator, batch_beam_size, next_beam_scores_ptr_, no_fill); + next_beam_tokens_ = Allocate(allocator, batch_beam_size, next_beam_tokens_ptr_, no_fill); + next_beam_indices_ = Allocate(allocator, batch_beam_size, next_beam_indices_ptr_, no_fill); + + // Space to store intermediate sequence with length sequence_length, sequence_length + 1, ..., max_sequence_length. + int buffer_per_beam = (max_length_ * (max_length_ + 1) - (sequence_length - 1) * sequence_length) / 2; + hypothesis_buffer_length_ = batch_beam_size * static_cast(buffer_per_beam); + hypothesis_buffer_ = Allocate(allocator, hypothesis_buffer_length_, hypothesis_buffer_ptr_, no_fill); + + done_ = Allocate(allocator, static_cast(batch_size_), done_ptr_, no_fill); + std::fill_n(done_.data(), done_.size(), false); +} + +template +void BeamSearchScorer::Process(ISequences* sequences, + gsl::span& next_scores, + gsl::span& next_tokens, + gsl::span& next_indices) { + // Sequences shape is (batch_size * num_beams, total_sequence_length) + // It contains word ID of whole sequence generated so far. + // It is different from subgraph input_ids, which only need one word when past state is not empty. + + const int sequence_length = sequences->GetSequenceLength(); + + ORT_ENFORCE(next_scores.size() == next_tokens.size()); + ORT_ENFORCE(next_scores.size() == next_indices.size()); + + for (int batch = 0; batch < batch_size_; batch++) { + BeamHypotheses& beam_hyp = beam_hyps[batch]; + if (done_[batch]) { + ORT_ENFORCE(beam_hyp.Size() >= num_beams_, "Batch can only be done if all beams have been generated"); + + // Pad the batch. + for (int j = 0; j < num_beams_; j++) { + next_beam_scores_[batch * num_beams_ + j] = 0.0f; + next_beam_tokens_[batch * num_beams_ + j] = pad_token_id_; + next_beam_indices_[batch * num_beams_ + j] = 0; + } + continue; + } + + // Next tokens for this sentence. + int beam_idx = 0; + int top_k = 2 * num_beams_; + for (int j = 0; j < top_k; j++) { + int64_t next_token = next_tokens[batch * top_k + j]; + T next_score = next_scores[batch * top_k + j]; + int64_t next_index = next_indices[batch * top_k + j]; + + int batch_beam_idx = batch * num_beams_ + static_cast(next_index); + // Add to generated hypotheses if end of sentence. + if ((eos_token_id_ >= 0) && (next_token == eos_token_id_)) { + bool is_beam_token_worse_than_top_num_beams = (j >= num_beams_); + if (is_beam_token_worse_than_top_num_beams) { + continue; + } + + // Clone the sequence and append to buffer. + gsl::span src = sequences->GetSequence(batch_beam_idx); + auto clone = hypothesis_buffer_.subspan(hypothesis_buffer_offset_, sequence_length); + gsl::copy(src, clone); + hypothesis_buffer_offset_ += sequence_length; + auto sequence = clone.template as_span(); + beam_hyp.Add(sequence, next_score); + } else { + // Add next predicted token since it is not eos_token. + next_beam_scores_[batch * num_beams_ + beam_idx] = next_score; + next_beam_tokens_[batch * num_beams_ + beam_idx] = next_token; + next_beam_indices_[batch * num_beams_ + beam_idx] = batch_beam_idx; + ++beam_idx; + } + + // Once the beam for next step is full, don't add more tokens to it. + if (beam_idx == num_beams_) + break; + } + + ORT_ENFORCE(beam_idx == num_beams_); + ORT_ENFORCE(hypothesis_buffer_offset_ <= batch_size_ * num_beams_ * max_length_); + + // Check if we are done so that we can save a pad step if all(done) + if (!done_[batch]) { + gsl::span topk_scores = next_scores.subspan(batch * num_beams_, top_k); + const T* best_sum_logprobs = std::max_element(topk_scores.begin(), topk_scores.end()); + if (beam_hyp.IsDone(*best_sum_logprobs, sequence_length)) { + done_[batch] = true; + } + } + } +} + +template +void BeamSearchScorer::Finalize(ISequences* sequences, + gsl::span& final_beam_scores, + Tensor* output_sequences, + Tensor* output_sequence_scores) { + ORT_ENFORCE(sequences != nullptr); + ORT_ENFORCE(output_sequences != nullptr); + + // Finalize all open beam hypotheses and add to generated hypotheses. + for (int batch_index = 0; batch_index < batch_size_; batch_index++) { + BeamHypotheses& beam_hyp = beam_hyps[batch_index]; + if (done_[batch_index]) { + continue; + } + + for (int beam_index = 0; beam_index < num_beams_; beam_index++) { + int batch_beam_index = batch_index * num_beams_ + beam_index; + T final_score = final_beam_scores[batch_beam_index]; + auto final_tokens = sequences->GetSequence(batch_beam_index); + beam_hyp.Add(final_tokens, final_score); + } + } + + // Word IDs of each sequence, with shape (batch_size * num_return_sequences, max_sequence_length). + gsl::span output = output_sequences->MutableDataAsSpan(); + + // Fill output sequences with pad token ID so that we do not need append it later. + std::fill_n(output.data(), output.size(), pad_token_id_); + + // Score of each sequence, with shape (batch_size * num_return_sequences). + gsl::span sequence_scores; + if (output_sequence_scores != nullptr) { + sequence_scores = output_sequence_scores->MutableDataAsSpan(); + } + + // Span is empty when output_sequence_scores is NULL. + gsl::span batch_sequence_score; + + // Select the best hypotheses according to number of sequences to return. + for (int batch_index = 0; batch_index < batch_size_; batch_index++) { + BeamHypotheses& beam_hyp = beam_hyps[batch_index]; + + const int num_return_sequences = num_beam_hyps_to_keep_; + auto batch_output = output.subspan(batch_index * num_return_sequences * max_length_, num_return_sequences * max_length_); + + if (output_sequence_scores != nullptr) { + batch_sequence_score = sequence_scores.subspan(batch_index * num_return_sequences, num_return_sequences); + } + + beam_hyp.Output( + num_return_sequences, + max_length_, + batch_output, + batch_sequence_score); + } +} + +// Instantiation +template class HypothesisScoreCompare; +template class BeamHypotheses; +template class BeamSearchScorer; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.h b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.h new file mode 100644 index 0000000000..2a15080236 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.h @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// The implementation is based on huggingface transformers generation_beam_search.py + +#pragma once +#include +#include +#include "core/common/common.h" +#include "core/framework/allocator.h" +#include "core/framework/tensorprotoutils.h" +#include "core/framework/utils.h" +#include "core/providers/cpu/tensor/utils.h" +#include "sequences.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +// Interface for all scorers for beam search or beam sample. +template +class IBeamScorer { + public: + virtual ~IBeamScorer() {} + + virtual void Initialize(AllocatorPtr& allocator, int sequence_length) = 0; + + virtual void Process(ISequences* sequences, + gsl::span& next_scores, + gsl::span& next_tokens, + gsl::span& next_indices) = 0; + + virtual void Finalize(ISequences* sequences, + gsl::span& final_beam_scores, + Tensor* output_sequences, + Tensor* output_sequence_scores) = 0; +}; + +template +struct HypothesisScore { + HypothesisScore(gsl::span& _hypothesis, T _score) + : hypothesis(_hypothesis), score(_score) {} + + gsl::span hypothesis; + T score; +}; + +template +class HypothesisScoreCompare { + public: + bool operator()(const HypothesisScore& a, const HypothesisScore& b) { + return a.score > b.score; + } +}; + +template +class BeamHypotheses { + public: + BeamHypotheses(int num_beams, T length_penalty, bool early_stopping); + + // Number of hypotheses + int Size() { return static_cast(beams_.size()); } + + // Add a new hypothesis + void Add(gsl::span& hypothesis, T sum_logprobs); + + bool IsDone(T best_sum_logprobs, int current_length); + + // Output results. Note that it will clear all beams. + void Output(int top_k, // number of sequences to return + int max_length, // max sequence length + gsl::span& sequences, // buffer filled with pad token ID, with shape (num_return_sequences, max_length) + gsl::span& sequences_scores); // buffer for sequence scores, with shape (num_return_sequences) + + private: + int num_beams_; + T length_penalty_; + bool early_stopping_; + T worst_score_; + std::priority_queue, std::vector>, HypothesisScoreCompare> beams_; // min-heap for top k +}; + +template +class BeamSearchScorer : public IBeamScorer { + public: + BeamSearchScorer(int batch_size, + int num_beams, + int max_length, + T length_penalty, + bool early_stopping, + int num_return_sequences, + int pad_token_id, + int eos_token_id); + + void Initialize(AllocatorPtr& allocator, int sequence_length) override; + + void Process(ISequences* sequences, + gsl::span& next_scores, + gsl::span& next_tokens, + gsl::span& next_indices) override; + + void Finalize(ISequences* sequences, + gsl::span& final_beam_scores, + Tensor* output_sequences, + Tensor* output_sequence_scores) override; + + bool IsDone(); + + gsl::span& GetNextScores() { return next_beam_scores_; } + gsl::span& GetNextTokens() { return next_beam_tokens_; } + gsl::span& GetNextIndices() { return next_beam_indices_; } + + private: + int batch_size_; + int num_beams_; + int max_length_; + int num_beam_hyps_to_keep_; + int pad_token_id_; + int eos_token_id_; + + // TODO: use ORT allocator to avoid allocating from heap directly + std::vector> beam_hyps; // List of batch result of beam search. Its shape is (batch_size) + + IAllocatorUniquePtr done_ptr_; // List of flags indicates whether each batch is finished or not. Its shape is (batch_size). + gsl::span done_; + + IAllocatorUniquePtr next_beam_scores_ptr_; + gsl::span next_beam_scores_; + + IAllocatorUniquePtr next_beam_tokens_ptr_; + gsl::span next_beam_tokens_; + + IAllocatorUniquePtr next_beam_indices_ptr_; + gsl::span next_beam_indices_; + + IAllocatorUniquePtr hypothesis_buffer_ptr_; // Allocated buffer to hold all hypotheses + gsl::span hypothesis_buffer_; // Span of the allocated buffer + size_t hypothesis_buffer_length_; // Total number of elements + int hypothesis_buffer_offset_; // Offset of avaiable buffer, or length of used buffer. +}; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.cc b/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.cc new file mode 100644 index 0000000000..8aa9e8907f --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.cc @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "dump_tensor.h" +#include "core/platform/env.h" +#include "core/platform/env_var_utils.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +namespace dump_tensor_env_vars { +constexpr const char* kDumpBeamSearch = "ORT_DUMP_BEAM_SEARCH"; +} + +#ifdef NDEBUG +bool g_enable_tensor_dump = false; +#else +bool g_enable_tensor_dump = true; +#endif + +void DumpOrtValue(const char* name, const OrtValue& value) { + if (!g_enable_tensor_dump) + return; + std::cout << std::string(name) << "\n"; + const Tensor& tensor = value.Get(); + MLDataType dataType = tensor.DataType(); + if (dataType == DataTypeImpl::GetType()) { + DumpTensor(nullptr, tensor); + } else if (dataType == DataTypeImpl::GetType()) { + DumpTensor(nullptr, tensor); + } else if (dataType == DataTypeImpl::GetType()) { + DumpTensor(nullptr, tensor); + } else { + std::cout << "not float/int32/int64"; + } +} + +void ConfigureTensorDump() { + const auto parsed = ParseEnvironmentVariable(dump_tensor_env_vars::kDumpBeamSearch); + if (parsed.has_value()) { + g_enable_tensor_dump = *parsed; + } +} + +void DisableTensorDump() { + g_enable_tensor_dump = false; +} + +void DumpString(const char* name, int index, bool end_line) { + if (!g_enable_tensor_dump) + return; + std::cout << std::string(name) << "[" << index << "]"; + + if (end_line) { + std::cout << std::endl; + } +} + +void DumpString(const char* name, std::string value, bool end_line) { + if (!g_enable_tensor_dump) + return; + + std::cout << std::string(name) << "=" << value; + + if (end_line) { + std::cout << std::endl; + } +} + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.h b/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.h new file mode 100644 index 0000000000..2f80410011 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/dump_tensor.h @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include +#include +#include "core/framework/tensorprotoutils.h" + +#ifndef NDEBUG +//#define DEBUG_BEAM_SEARCH 1 // uncomment it for debugging beam search +#endif + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +#define MAX_ROW_OR_COLUMN 8 + +#define SKIP_IF_MORE_THAN(row_or_column_size, i, max_n, new_line) \ + if (row_or_column_size > max_n && i >= max_n / 2 && i + max_n / 2 < row_or_column_size) { \ + if (i == max_n / 2) { \ + std::cout << ", ..."; \ + if (new_line) \ + std::cout << std::endl; \ + } \ + continue; \ + } + +#define SKIP_IF_TOO_MANY(row_or_column_size, i, new_line) SKIP_IF_MORE_THAN(row_or_column_size, i, MAX_ROW_OR_COLUMN, new_line) + +extern bool g_enable_tensor_dump; // global variance to turn on/off dump + +template +void PrintValue(const T& value) { + if (std::is_floating_point::value) + std::cout << std::setprecision(8) << value; + else + std::cout << value; +} + +template +void DumpTensor(const char* name, const Tensor& tensor) { + if (!g_enable_tensor_dump) + return; + + if (nullptr != name) { + std::cout << std::string(name) << std::endl; + } + + const auto& shape = tensor.Shape(); + auto num_items = shape.Size(); + + if (num_items == 0) { + std::cout << "no data"; + return; + } + + size_t num_dims = shape.NumDimensions(); + size_t num_rows = 1; + if (num_dims > 1) { + num_rows = static_cast(shape[0]); + } + + size_t row_size = num_items / num_rows; + + auto data = tensor.DataAsSpan(); + + for (size_t row = 0; row < num_rows; ++row) { + SKIP_IF_TOO_MANY(num_rows, row, true); + std::cout << "[" << row << "]:"; + for (size_t i = 0; i < row_size; ++i) { + SKIP_IF_TOO_MANY(row_size, i, false); + + if (i > 0) + std::cout << ", "; + + PrintValue(data[row * row_size + i]); + } + std::cout << "\n"; + } + + std::cout << std::endl; +} + +void DumpOrtValue(const char* name, const OrtValue& value); + +template +void DumpTensor(const char* name, const T* tensor, int dim0, int dim1) { + if (!g_enable_tensor_dump) + return; + + if (nullptr != name) { + std::cout << std::string(name) << std::endl; + } + + for (int i = 0; i < dim0; i++) { + SKIP_IF_TOO_MANY(dim0, i, true); + std::cout << "[" << i << "]:"; + for (int j = 0; j < dim1; j++) { + SKIP_IF_TOO_MANY(dim1, j, false); + if (j > 0) + std::cout << ", "; + T value = tensor[i * dim1 + j]; + PrintValue(value); + } + std::cout << std::endl; + } +} + +void DumpString(const char* name, int index, bool end_line); + +void DumpString(const char* name, std::string value, bool end_line); + +template +void DumpTensor(const char* name, const T* tensor, int dim0, int dim1, int dim2) { + if (!g_enable_tensor_dump) + return; + + if (nullptr != name) { + std::cout << std::string(name) << std::endl; + } + + for (int i = 0; i < dim0; i++) { + SKIP_IF_TOO_MANY(dim0, i, true); + for (int j = 0; j < dim1; j++) { + SKIP_IF_TOO_MANY(dim1, j, true); + std::cout << "[" << i << "][" << j << "]:"; + for (int k = 0; k < dim2; k++) { + SKIP_IF_TOO_MANY(dim2, k, false); + if (k > 0) + std::cout << ", "; + T value = tensor[i * dim1 * dim2 + j * dim2 + k]; + PrintValue(value); + } + std::cout << std::endl; + } + std::cout << std::endl; + } + std::cout << std::endl; +} + +void ConfigureTensorDump(); + +void DisableTensorDump(); + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc new file mode 100644 index 0000000000..80825c7e26 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc @@ -0,0 +1,451 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// there's no way to use a raw pointer as the copy destination with std::copy_n +// (which gsl::copy uses with span::data() which returns a raw pointer) with the 14.11 toolset +// without generating a 4996 warning. going through an iterator is way too much overhead so turn off the warning. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + +#include "core/framework/framework_common.h" +#include "core/framework/session_state.h" +#include "core/framework/tensorprotoutils.h" +#include "core/framework/utils.h" +#include "core/providers/cpu/tensor/utils.h" +#include "gsl/gsl" +#include "gpt_subgraph.h" +#include "dump_tensor.h" + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +using namespace ONNX_NAMESPACE; +using namespace onnxruntime::common; + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +GptSubgraph::GptSubgraph( + const onnxruntime::Node& node_in, + const std::string& attribute_name, + const GraphViewer& subgraph_in) + : node(node_in), attribute(attribute_name), subgraph(subgraph_in), allocator_(nullptr) { + num_implicit_inputs = static_cast(node.ImplicitInputDefs().size()); + + auto& subgraph_inputs = subgraph.GetInputs(); + auto& subgraph_outputs = subgraph.GetOutputs(); + + // inputs: input_ids, position_ids, attention_mask, past_0, past_1, ... + // outputs: logits, present_0, present_1, ... + num_subgraph_inputs = static_cast(subgraph_inputs.size()); + num_subgraph_outputs = static_cast(subgraph_outputs.size()); + + // CheckSubgraph will verify inputs and outputs later. + subgraph_input_names.reserve(num_subgraph_inputs); + for (int i = 0; i < num_subgraph_inputs; ++i) { + subgraph_input_names.push_back(subgraph_inputs[i]->Name()); + } + + subgraph_output_names.reserve(num_subgraph_outputs); + for (int i = 0; i < num_subgraph_outputs; ++i) { + subgraph_output_names.push_back(subgraph_outputs[i]->Name()); + } +} + +Status GptSubgraph::Validate(const std::vector& subgraph_inputs, + const std::vector& subgraph_outputs) { + ORT_RETURN_IF(num_subgraph_outputs <= 1, + "Invalid GPT-2 subgraph: number of outputs shall be larger than 1 (Need past state in inputs and outputs)."); + + ORT_RETURN_IF(num_subgraph_inputs != num_subgraph_outputs + 2, + "Invalid GPT-2 subgraph: number of inputs shall be number of outputs plus 2"); + + ORT_RETURN_IF(subgraph_inputs[0]->Name() != "input_ids", "subgraph input 0 shall be named as input_ids, got: ", + subgraph_inputs[0]->Name()); + ORT_RETURN_IF(subgraph_inputs[1]->Name() != "position_ids", "subgraph input 1 shall be named as position_ids, got: ", + subgraph_inputs[1]->Name()); + ORT_RETURN_IF(subgraph_inputs[2]->Name() != "attention_mask", "subgraph input 2 shall be named as attention_mask, got: ", + subgraph_inputs[2]->Name()); + ORT_RETURN_IF(subgraph_inputs[3]->Name() != "past_0", "subgraph input 3 shall be named as past_0, got: ", + subgraph_inputs[3]->Name()); + + // Past state shape is like (2, batch_size, 12, past_seq_len, 64). Here 12 and 64 are constants of num_heads and hidden_size/num_heads. + const ONNX_NAMESPACE::TensorShapeProto* past_shape = subgraph_inputs[3]->Shape(); + ORT_RETURN_IF(past_shape->dim_size() != 5, "subgraph past state is expected to have 5 dimension, got ", + past_shape->dim_size()); + + ORT_RETURN_IF(!past_shape->dim(0).has_dim_value() || past_shape->dim(0).dim_value() != 2, + "subgraph past state dimension 0 shall have length of 2"); + + ORT_RETURN_IF(!past_shape->dim(2).has_dim_value() || past_shape->dim(2).dim_value() <= 0, + "subgraph past state dimension 2 shall have a positive value for number of heads"); + + ORT_RETURN_IF(!past_shape->dim(4).has_dim_value() || past_shape->dim(4).dim_value() <= 0, + "subgraph past state dimension 4 shall have a positive value for hidden size per head"); + + // check subgraph outputs + ORT_RETURN_IF(subgraph_outputs[0]->Name() != "logits", "subgraph output 0 shall be named as logits, got: ", + subgraph_outputs[0]->Name()); + + ORT_RETURN_IF(subgraph_outputs[1]->Name() != "present_0", "subgraph input 1 shall be named as present_0, got: ", + subgraph_outputs[1]->Name()); + + // Logits shape is like (batch_size, seq_len, 50257). Here 50257 is the vocabulary size. + const ONNX_NAMESPACE::TensorShapeProto* logits_shape = subgraph_outputs[0]->Shape(); + ORT_RETURN_IF(logits_shape->dim_size() != 3, "subgraph logits output is expected to have 3 dimension, got ", + logits_shape->dim_size()); + + ORT_RETURN_IF(!logits_shape->dim(2).has_dim_value() || logits_shape->dim(2).dim_value() <= 0, + "subgraph past state dimension 2 shall have a positive value for vocabulary size"); + + // Save parameters related to the subgraph. + num_heads = static_cast(past_shape->dim(2).dim_value()); + head_size = static_cast(past_shape->dim(4).dim_value()); + vocab_size = static_cast(logits_shape->dim(2).dim_value()); + num_layers = static_cast(subgraph_outputs.size()) - 1; + + ORT_RETURN_IF(subgraph_inputs[0]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT64, + "subgraph input 0 (input_ids) shall have int64 type"); + ORT_RETURN_IF(subgraph_inputs[1]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT64, + "subgraph input 1 (position_ids) shall have int64 type"); + // TODO: support float16 + ORT_RETURN_IF(subgraph_inputs[2]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_FLOAT, + "subgraph input 2 (attention_mask) shall have float type"); + ORT_RETURN_IF(subgraph_inputs[3]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_FLOAT, + "subgraph input 3 (past_0) shall have float type"); + ORT_RETURN_IF(subgraph_outputs[0]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_FLOAT, + "subgraph output 0 (logits) shall have float type"); + ORT_RETURN_IF(subgraph_outputs[1]->TypeAsProto()->tensor_type().elem_type() != ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_FLOAT, + "subgraph output 1 (present_0) shall have float type"); + + return Status::OK(); +} + +Status GptSubgraph::Setup(const SessionState& session_state, + const SessionState& subgraph_session_state) { + session_state_ = &session_state; + subgraph_session_state_ = &subgraph_session_state; + + std::vector feed_names; + feed_names.reserve(num_subgraph_inputs + num_implicit_inputs); + + // First, get the location of input_ids of current operator. + const auto& node_inputs = node.InputDefs(); + const OrtMemoryInfo& input_ids_location = utils::FindMemoryInfoForValue(session_state, node_inputs[0]->Name()); + + // position_ids, attention_mask, past_0, ... are created by this operator so the name doesn't matter. + // as we skip them when we call FindDevicesForValues, and default them to be in the same device as input_ids + feed_names.insert(feed_names.end(), subgraph_input_names.begin(), subgraph_input_names.end()); + + for (auto& entry : node.ImplicitInputDefs()) { + feed_names.push_back(entry->Name()); + } + + std::vector feed_locations; + feed_locations.resize(feed_names.size()); + + for (size_t i = 0, end = feed_names.size(); i < end; ++i) { + if (i >= subgraph_input_names.size()) { // implicit inputs + const auto& location = utils::FindMemoryInfoForValue(session_state, feed_names[i]); + feed_locations[i] = location.device; + } else { + feed_locations[i] = input_ids_location.device; + } + } + + std::unique_ptr ffm; + ORT_RETURN_IF_ERROR(FeedsFetchesManager::Create(feed_names, subgraph_output_names, + subgraph_session_state.GetOrtValueNameIdxMap(), ffm)); + ORT_RETURN_IF_ERROR(utils::InitializeFeedFetchCopyInfo(subgraph_session_state, *ffm)); + + // setup the locations where we want the subgraph output to end up on + std::vector fetch_locations; + fetch_locations.reserve(num_subgraph_outputs); + + // past state need to be where we can feed them in to the next iteration, so set the fetch location to match the feed location. + for (int i = 0; i < num_subgraph_outputs; ++i) { + fetch_locations.push_back(&input_ids_location); + } + + utils::FinalizeFeedFetchCopyInfo(*ffm, feed_locations, fetch_locations); + + feeds_fetches_manager_ = std::move(ffm); + + // Check subgraph only need once so put in Setup function. + auto& inputs = subgraph.GetInputs(); + auto& outputs = subgraph.GetOutputs(); + ORT_RETURN_IF_ERROR(Validate(inputs, outputs)); + + return Status::OK(); +} + +void GptSubgraph::CreateInitialFeeds( + const Tensor& input_ids, + const std::vector& implicit_inputs, + int num_beams, + int pad_token_id, + gsl::span& next_positions, + std::vector& feeds) { + ORT_ENFORCE(session_state_ != nullptr, "Setup must be called before CreateInitialFeeds"); + + // Subgraph inputs: + // input_ids: shape (B, S) wher B is batch size, and S is sequence length + // position_ids: shape (B, S) + // attention_mask: shape (B, P+S), where past_sequence_length (P) is 0 + // After expansion, their shapes will become (B, M*S), where M is num_beams. + + // Allocate subgraph inputs to be same device as input_ids + AllocatorPtr alloactor = session_state_->GetAllocator(input_ids.Location()); + + // Store allocator, which is needed in ExpandInputs. + allocator_ = alloactor; + + const TensorShape& input_ids_shape = input_ids.Shape(); + ORT_ENFORCE(input_ids_shape.NumDimensions() == 2); + const int64_t& batch_size = input_ids_shape[0]; + const int64_t& sequence_length = input_ids_shape[1]; + + // Allocate position_ids and attention_mask based on shape of input_ids + auto element_type = DataTypeImpl::GetType(); + + // input_ids for subgraph is int64, so we need Cast input_ids from int32 to int64. + OrtValue subgraph_input_ids; + // Current shape is (batch_size, sequence_length) + // Note that we will expand it to (batch_size * num_beams, sequence_length) later. + Tensor::InitOrtValue(element_type, input_ids_shape, alloactor, subgraph_input_ids); + + int64_t* subgraph_input_data = subgraph_input_ids.GetMutable()->MutableData(); + const int32_t* source = input_ids.Data(); + int64_t* target = subgraph_input_data; + for (int i = 0; i < batch_size; i++) { + for (int j = 0; j < sequence_length; j++, source++, target++) { + *target = static_cast(*source); + } + } + + OrtValue position_ids; + Tensor::InitOrtValue(element_type, input_ids_shape, alloactor, position_ids); + + OrtValue attention_mask; + auto mask_type = DataTypeImpl::GetType(); + Tensor::InitOrtValue(mask_type, input_ids_shape, alloactor, attention_mask); + + // Set attention mask to be 0 for pad tokens, and 1 for all other tokens. + // Set position id to be 0 for pad tokens, and cumulated sum of mask in a batch for other tokens + float* mask_data = attention_mask.GetMutable()->MutableData(); + int64_t* position_data = position_ids.GetMutable()->MutableData(); + source = input_ids.Data(); + float* mask = mask_data; + int64_t* position = position_data; + for (int i = 0; i < batch_size; i++) { + int64_t abs_position = 0; + for (int j = 0; j < sequence_length; j++, source++, mask++, position++) { + if (*source == pad_token_id) { + *mask = 0.0f; + *position = 0; + } else { + *mask = 1.0f; + *position = abs_position; + abs_position++; + } + } + for (int k = 0; k < num_beams; k++) { + next_positions[i * num_beams + k] = abs_position; + } + } + + // Initialize empty past state + auto past_type = DataTypeImpl::GetType(); + int64_t past_state_dims[] = {2, batch_size * num_beams, num_heads, 0, head_size}; + TensorShape past_shape(&past_state_dims[0], 5); + OrtValue empty_past; + Tensor::InitOrtValue(past_type, past_shape, allocator_, empty_past); + + // Expand (batch_size, sequence_length) to (batch_size * num_beams, sequence_length) for input_ids, position_ids and attention_mask + // TODO: Try expand inputs/outputs after first subgraph call instead. That may get better peroformance, but more complex to implement. + OrtValue expanded_input_ids = ExpandInputs(subgraph_input_ids, num_beams); + OrtValue expanded_position_ids = ExpandInputs(position_ids, num_beams); + OrtValue expanded_attention_mask = ExpandInputs(attention_mask, num_beams); + + // The ordering is the same as used in Setup + feeds.reserve(num_subgraph_inputs + num_implicit_inputs); + feeds.push_back(expanded_input_ids); + feeds.push_back(expanded_position_ids); + feeds.push_back(expanded_attention_mask); + + // The remaing inputs are past state. + for (int i = 3; i < num_subgraph_inputs; ++i) { + feeds.push_back(empty_past); + } + + // pass in implicit inputs + for (const auto* entry : implicit_inputs) { + feeds.push_back(*entry); + } +} + +OrtValue GptSubgraph::ExpandInputs(const OrtValue& input, int num_beams) const { + // Input shape (batch_size, sequence_length) + // Output shape (batch_size * num_beams, sequence_length) + if (num_beams == 1) + return input; + + const TensorShape& input_shape = input.Get().Shape(); + const int64_t& batch_size = input_shape[0]; + const int64_t& sequence_length = input_shape[1]; + + int64_t dims[] = {batch_size * num_beams, sequence_length}; + TensorShape expanded_shape(&dims[0], 2); + + OrtValue expanded; + MLDataType element_type = input.Get().DataType(); + Tensor::InitOrtValue(element_type, expanded_shape, allocator_, expanded); + + if (element_type == DataTypeImpl::GetType()) { + const int64_t* input_data = input.Get().Data(); + int64_t* expanded_data = expanded.GetMutable()->MutableData(); + int64_t* target = expanded_data; + for (int i = 0; i < batch_size; i++) { + for (int j = 0; j < num_beams; j++) { + memcpy(target, input_data + i * sequence_length, sizeof(int64_t) * sequence_length); + target += sequence_length; + } + } + } else if (element_type == DataTypeImpl::GetType()) { + const float* input_data = input.Get().Data(); + float* expanded_data = expanded.GetMutable()->MutableData(); + float* target = expanded_data; + for (int i = 0; i < batch_size; i++) { + for (int j = 0; j < num_beams; j++) { + memcpy(target, input_data + i * sequence_length, sizeof(float) * sequence_length); + target += sequence_length; + } + } + } + + return expanded; +} + +// TODO: support float16 +void GptSubgraph::PickPastState(const std::vector& last_outputs, + std::vector& next_inputs, + gsl::span& beam_indices) { + for (int i = 3; i < num_subgraph_inputs; ++i) { + const OrtValue& present = last_outputs[i - 2]; // shape is like (2, batch_beam_size, 12, past_seq_len, 64) + const TensorShape& past_shape = present.Get().Shape(); + + // Create a tensor with same shape. + OrtValue past; + auto past_type = DataTypeImpl::GetType(); + Tensor::InitOrtValue(past_type, past_shape, allocator_, past); + + auto block_size_per_beam = past_shape[2] * past_shape[3] * past_shape[4]; + auto past_key_size = past_shape[1] * past_shape[2] * past_shape[3] * past_shape[4]; + + gsl::span past_span = past.GetMutable()->MutableDataAsSpan(); + gsl::span present_span = present.Get().DataAsSpan(); + for (gsl::index j = 0; j < beam_indices.length(); j++) { + int64_t beam_index = beam_indices[j]; + gsl::span present_key = present_span.subspan(beam_index * block_size_per_beam, block_size_per_beam); + gsl::span present_value = present_span.subspan(past_key_size + beam_index * block_size_per_beam, block_size_per_beam); + + gsl::span past_key = past_span.subspan(j * block_size_per_beam, block_size_per_beam); + gsl::span past_value = past_span.subspan(past_key_size + j * block_size_per_beam, block_size_per_beam); + gsl::copy(present_key, past_key); + gsl::copy(present_value, past_value); +#ifdef DEBUG_BEAM_SEARCH + if (i == 3) // only dump past_0 + { + DumpString("past_key of beam", static_cast(j), true); + DumpTensor(nullptr, past_key.data(), 1, static_cast(block_size_per_beam)); + + DumpString("past_value of beam", static_cast(j), true); + DumpTensor(nullptr, past_value.data(), 1, static_cast(block_size_per_beam)); + } +#endif + } + + next_inputs[i] = past; + } +} + +Status GptSubgraph::UpdateFeeds( + const std::vector& last_outputs, + std::vector& next_inputs, + int current_length, + gsl::span& next_positions, + gsl::span beam_next_tokens, + gsl::span beam_indices, + int num_beams) { + // last_outputs: logits, present_0, present_1, ... + // next_inputs: input_ids, position_id, attention_mask, past_0, past_1 + + // The following updates inputs for subgraph + // TODO: Reuse buffer for input_ids and position_ids to reduce memory allocation. + + // Update input_ids with next tokens. + int batch_beam_size = static_cast(beam_next_tokens.length()); + int64_t dims[] = {batch_beam_size, 1}; + TensorShape input_ids_shape(&dims[0], 2); + auto element_type = DataTypeImpl::GetType(); + OrtValue input_ids; + Tensor::InitOrtValue(element_type, input_ids_shape, allocator_, input_ids); + int64_t* input_ids_data = input_ids.GetMutable()->MutableData(); + for (int i = 0; i < batch_beam_size; i++) { + input_ids_data[i] = beam_next_tokens[i]; + } + next_inputs[0] = input_ids; + + // Update position IDs + OrtValue position_ids; + Tensor::InitOrtValue(element_type, input_ids_shape, allocator_, position_ids); + int64_t* position_data = position_ids.GetMutable()->MutableData(); + for (int i = 0; i < batch_beam_size; i++) { + position_data[i] = next_positions[i]; + next_positions[i]++; + } + next_inputs[1] = position_ids; + + // Update attention mask + const OrtValue& old_mask = next_inputs[2]; + const float* old_mask_data = old_mask.Get().Data(); + int64_t mask_dims[] = {batch_beam_size, current_length}; + TensorShape mask_shape(&mask_dims[0], 2); + OrtValue attention_mask; + auto mask_type = DataTypeImpl::GetType(); + Tensor::InitOrtValue(mask_type, mask_shape, allocator_, attention_mask); + float* mask_data = attention_mask.GetMutable()->MutableData(); + for (int i = 0; i < batch_beam_size; i++) { + for (int j = 0; j < current_length - 1; j++) { + mask_data[i * current_length + j] = old_mask_data[i * (current_length - 1) + j]; + } + mask_data[i * current_length + current_length - 1] = 1.0f; + } + next_inputs[2] = attention_mask; + +#ifdef DEBUG_BEAM_SEARCH + DumpOrtValue("input_ids", input_ids); + DumpOrtValue("position_ids", position_ids); + DumpOrtValue("attention_mask", attention_mask); +#endif + + // Update past state + if (num_beams == 1) { + // feed present_* output to past_* inputs one by one + for (int i = 3; i < num_subgraph_inputs; ++i) { + next_inputs[i] = last_outputs[i - 2]; + } + } else { + PickPastState(last_outputs, next_inputs, beam_indices); + } + + return Status::OK(); +} + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.h b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.h new file mode 100644 index 0000000000..75d879c7fe --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.h @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +//#include +#include "gsl/gsl" +#include "core/framework/allocator.h" +#include "core/framework/session_state.h" +#include "core/framework/feeds_fetches_manager.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +// A class for GPT-2 subgraph inputs and outputs preparation. +struct GptSubgraph { + GptSubgraph( + const onnxruntime::Node& node_in, + const std::string& attribute_name, + const GraphViewer& subgraph_in); + + const onnxruntime::Node& node; // node that contains the subgraph + const std::string& attribute; // attribute of th node that contains the subgraph. Not used yet. + const GraphViewer& subgraph; // the subgraph + + int num_implicit_inputs; + + int num_subgraph_inputs; // same as subgraph_input_names.size(), keep it for convenience. + int num_subgraph_outputs; // same as subgraph_output_names.size() + + std::vector subgraph_input_names; + std::vector subgraph_output_names; + + // Parameters deduced from the subgraph + int num_heads; + int head_size; + int vocab_size; + int num_layers; + + // Setup exectuion + Status Setup(const SessionState& session_state, + const SessionState& subgraph_session_state); + + // Create inputs for first inference of subgraph. + void CreateInitialFeeds( + const Tensor& input_ids, + const std::vector& implicit_inputs, + int num_beams, + int pad_token_id, + gsl::span& next_positions, + std::vector& feeds); + + Status UpdateFeeds( + const std::vector& last_outputs, + std::vector& next_inputs, + int current_length, + gsl::span& next_positions, + gsl::span beam_next_tokens, + gsl::span beam_indices, + int num_beams); + + FeedsFetchesManager* GetFeedsFetchesManager() const { return feeds_fetches_manager_.get(); } + + protected: + Status Validate(const std::vector& subgraph_inputs, + const std::vector& subgraph_outputs); + + OrtValue ExpandInputs(const OrtValue& input, int num_beams) const; + + void PickPastState(const std::vector& last_outputs, + std::vector& next_inputs, + gsl::span& beam_indices); + + AllocatorPtr allocator_; + const SessionState* session_state_; + const SessionState* subgraph_session_state_; + std::unique_ptr feeds_fetches_manager_; +}; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime diff --git a/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc new file mode 100644 index 0000000000..10ef8b6f69 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc @@ -0,0 +1,192 @@ +#include +#include "logits_processor.h" +#include "dump_tensor.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +template +gsl::span NextTokenScores::GetScores(int batch_beam_index) { + assert(batch_beam_index >= 0 && batch_beam_index < batch_beam_size); + return scores.subspan(batch_beam_index * vocab_size, vocab_size); +} + +template +void NextTokenScores::SetScore(int token_id, T score) { + assert(token_id >= 0 && token_id < vocab_size); + for (int i = 0; i < batch_beam_size; i++) { + scores[i * vocab_size + token_id] = score; + } +} + +#ifdef DEBUG_BEAM_SEARCH +template +void DumpScores(const char* name, gsl::span& scores) { + DumpString(name, 0, true); + ORT_UNUSED_PARAMETER(scores); +} +#endif + +// Interface for all scorers for beam search or beam sample. +template +MinLengthLogitsProcessor::MinLengthLogitsProcessor(int min_length, int eos_token_id) + : min_length_(min_length), eos_token_id_(eos_token_id) {} + +template +void MinLengthLogitsProcessor::Process(const ISequences* sequences, + NextTokenScores& next_token_scores) { + if (sequences->GetSequenceLength() < min_length_) { + next_token_scores.SetScore(eos_token_id_, std::numeric_limits::lowest()); + } + +#ifdef DEBUG_BEAM_SEARCH + DumpScores("MinLengthLogitsProcessor", next_token_scores.scores); +#endif +} + +template +RepetitionPenaltyLogitsProcessor::RepetitionPenaltyLogitsProcessor(float penalty) : penalty_(penalty) { +} + +template +void RepetitionPenaltyLogitsProcessor::Process(const ISequences* sequences, + NextTokenScores& next_token_scores) { + const int batch_beam_size = next_token_scores.batch_beam_size; + for (int i = 0; i < batch_beam_size; i++) { + gsl::span beam_token_scores = next_token_scores.GetScores(i); + gsl::span sequence = sequences->GetSequence(i); + + // Find unique word IDs in sequence. + std::unordered_set unique_word_ids; + for (const auto& word_id : sequence) { + unique_word_ids.insert(word_id); + } + + for (const int64_t word_id : unique_word_ids) { + T score = beam_token_scores[word_id]; + + // If score < 0, then repetition penalty > 1.0 has to multiplied to reduce the previous token probability, + // This assumes that scores are either positive (like ctrl) or negative (like GPT-2), but not a mixture. + beam_token_scores[word_id] = (score < 0 ? score * penalty_ : score / penalty_); + } + } + +#ifdef DEBUG_BEAM_SEARCH + DumpScores("RepetitionPenaltyLogitsProcessor", next_token_scores.scores); +#endif +} + +template +NoRepeatNGramLogitsProcessor::NoRepeatNGramLogitsProcessor(int ngram_size) : ngram_size_(ngram_size) { +} + +template +void NoRepeatNGramLogitsProcessor::Process(const ISequences* sequences, + NextTokenScores& next_token_scores) { + if (ngram_size_ == 0 || ngram_size_ > sequences->GetSequenceLength()) { + return; + } + + const gsl::index prefix_length = static_cast(ngram_size_ - 1); + int batch_beam_size = next_token_scores.batch_beam_size; + + for (int i = 0; i < batch_beam_size; i++) { + gsl::span beam_token_scores = next_token_scores.GetScores(i); + gsl::span sequence = sequences->GetSequence(i); + + gsl::span prefix = sequence.subspan(sequence.length() - prefix_length); + ORT_ENFORCE(prefix.length() == prefix_length); + + std::unordered_set blocked_word_ids; + for (int j = 0; j <= static_cast(sequence.length()) - ngram_size_; j++) { + // Here we use naive algorithm for matching. The complexity is O(batch_beam_size * ngram_size * sequence_length) + // TODO: build N-Gram index (hash table with prefix of length NGram - 1 as key, and list of last word of NGram as value) for fast matching. + if (ngram_size_ == 1 || prefix == sequence.subspan(j, prefix_length)) { + blocked_word_ids.insert(sequence[j + prefix_length]); + } + } + + for (const int64_t word_id : blocked_word_ids) { + beam_token_scores[word_id] = std::numeric_limits::lowest(); + } + } + +#ifdef DEBUG_BEAM_SEARCH + DumpScores("NoRepeatNGramLogitsProcessor", next_token_scores.scores); +#endif +} + +template +VocabMaskLogitsProcessor::VocabMaskLogitsProcessor(const gsl::span& vocab_mask) : vocab_mask_(vocab_mask) { +} + +template +void VocabMaskLogitsProcessor::Process(const ISequences* /*sequences*/, + NextTokenScores& next_token_scores) { + assert(!vocab_mask_.empty()); + + // Process vocabulary mask and set tokens with mask value 0 to -inf. + T* p = next_token_scores.scores.data(); + // next_token_scores shape (batch_size * num_beams, vocab_size) + // vocab_mask shape (vocab_size). TODO: support shape (batch_size, vocab_size) + for (int i = 0; i < next_token_scores.batch_beam_size; i++) { + for (int j = 0; j < next_token_scores.vocab_size; j++, p++) { + if (vocab_mask_[j] == 0) { + *p = std::numeric_limits::lowest(); + } + } + } + +#ifdef DEBUG_BEAM_SEARCH + DumpScores("VocabMaskLogitsProcessor", next_token_scores.scores); +#endif +} + +template +void LogitsProcessorList::Init(const BeamSearchParameters& parameters) { + processor_list_.clear(); + + if (parameters.repetition_penalty != 1.0f) { // 1.0 means no penalty + repetition_penalty_processor_ = std::make_unique>(parameters.repetition_penalty); + processor_list_.push_back(repetition_penalty_processor_.get()); + } + + if (parameters.no_repeat_ngram_size > 0) { + no_repeat_ngram_processor_ = std::make_unique>(parameters.no_repeat_ngram_size); + processor_list_.push_back(no_repeat_ngram_processor_.get()); + } + + if (!parameters.vocab_mask.empty()) { + vocab_mask_processor_ = std::make_unique>(parameters.vocab_mask); + processor_list_.push_back(vocab_mask_processor_.get()); + } + + if (parameters.min_length > 0) { + min_length_processor_ = std::make_unique>(parameters.min_length, parameters.eos_token_id); + processor_list_.push_back(min_length_processor_.get()); + } + + batch_beam_size_ = parameters.BatchBeamSize(); + vocab_size_ = parameters.vocab_size; +} + +template +void LogitsProcessorList::Process(const ISequences* sequences, + gsl::span& next_token_scores) { + NextTokenScores input_scores = {next_token_scores, batch_beam_size_, vocab_size_}; + for (size_t i = 0; i < processor_list_.size(); i++) { + processor_list_[i]->Process(sequences, input_scores); + } +} + +// Instantiation +template class MinLengthLogitsProcessor; +template class RepetitionPenaltyLogitsProcessor; +template class NoRepeatNGramLogitsProcessor; +template class VocabMaskLogitsProcessor; +template class LogitsProcessorList; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/logits_processor.h b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.h new file mode 100644 index 0000000000..78fe9acf63 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.h @@ -0,0 +1,99 @@ +#pragma once +#include "sequences.h" +#include "beam_search_parameters.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +template +struct NextTokenScores { + gsl::span& scores; + int batch_beam_size; + int vocab_size; + + gsl::span GetScores(int batch_beam_index); + + void SetScore(int token_id, T score); +}; + +// Interface for all scorers for beam search or beam sample. +template +class ILogitsProcessor { + public: + virtual ~ILogitsProcessor() {} + + virtual void Process(const ISequences* sequences, + NextTokenScores& next_token_scores) = 0; +}; + +template +class MinLengthLogitsProcessor : public ILogitsProcessor { + public: + MinLengthLogitsProcessor(int min_length, int eos_token_id); + + void Process(const ISequences* sequences, + NextTokenScores& next_token_scores) override; + + private: + int min_length_; + int eos_token_id_; +}; + +template +class RepetitionPenaltyLogitsProcessor : public ILogitsProcessor { + public: + RepetitionPenaltyLogitsProcessor(float penalty); + + void Process(const ISequences* sequences, + NextTokenScores& next_token_scores) override; + + private: + float penalty_; +}; + +template +class NoRepeatNGramLogitsProcessor : public ILogitsProcessor { + public: + NoRepeatNGramLogitsProcessor(int ngram_size); + + void Process(const ISequences* sequences, + NextTokenScores& next_token_scores) override; + + private: + int ngram_size_; +}; + +template +class VocabMaskLogitsProcessor : public ILogitsProcessor { + public: + VocabMaskLogitsProcessor(const gsl::span& vocab_mask); + + void Process(const ISequences* sequences, + NextTokenScores& next_token_scores) override; + + private: + gsl::span vocab_mask_; +}; + +template +class LogitsProcessorList { +public: + LogitsProcessorList() = default ; + void Init(const BeamSearchParameters& parameters); + void Process(const ISequences* sequences, gsl::span& next_token_scores); + +private: + int batch_beam_size_; + int vocab_size_; + std::vector*> processor_list_; + + std::unique_ptr> repetition_penalty_processor_; + std::unique_ptr> no_repeat_ngram_processor_; + std::unique_ptr> vocab_mask_processor_; + std::unique_ptr> min_length_processor_; +}; + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/sequences.cc b/onnxruntime/contrib_ops/cpu/transformers/sequences.cc new file mode 100644 index 0000000000..a9c70ef410 --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/sequences.cc @@ -0,0 +1,76 @@ +#include "sequences.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +void Sequences::Init(AllocatorPtr allocator, const OrtValue& input_ids, int batch_beam_size, int sequence_length, int max_length) { + size_t sequences_size = SafeInt(batch_beam_size) * max_length; + size_t buffer_size = sequences_size + sequences_size; + gsl::span buffer = AllocateBuffer(allocator, sequences_space_buffer_, buffer_size, true, static_cast(0)); + + sequences[0] = buffer.subspan(0, sequences_size); + sequences[1] = buffer.subspan(sequences_size); + + // Copy input_ids to sequences[0]. + gsl::span input = input_ids.Get().DataAsSpan(); + gsl::span output = sequences[0]; + for (int i = 0; i < batch_beam_size; i++) { + gsl::span source = input.subspan(i * sequence_length, sequence_length); + gsl::span target = output.subspan(i * max_length, sequence_length); + gsl::copy(source, target); + } + current_sequences_buffer = 0; + + batch_beam_size_ = batch_beam_size; + max_length_ = max_length; + current_length_ = sequence_length; +} + +gsl::span Sequences::GetSequence(int beam_index) const { + gsl::span buffer(sequences[current_sequences_buffer].data(), sequences[current_sequences_buffer].size()); + gsl::span sequence = buffer.subspan(beam_index * max_length_, current_length_); + return sequence; +} + +int Sequences::GetSequenceLength() const { + return current_length_; +} + +void Sequences::PrintSequences() { +#ifdef DEBUG_BEAM_SEARCH + for (int i = 0; i < batch_beam_size_; i++) { + gsl::span sequence = GetSequence(i); + DumpString("sequences", i, false); + DumpTensor(nullptr, sequence.data(), 1, current_length_); + } +#endif +} + +void Sequences::AppendNextTokenToSequences( + gsl::span& beam_indices, + gsl::span& beam_next_tokens) { + gsl::span input(sequences[current_sequences_buffer].data(), sequences[current_sequences_buffer].size()); + gsl::span output = sequences[1 - current_sequences_buffer]; + + for (int i = 0; i < batch_beam_size_; i++) { + int beam_index = static_cast(beam_indices[i]); + gsl::span source = input.subspan(beam_index * max_length_, current_length_); + gsl::span target = output.subspan(i * max_length_, current_length_); + gsl::copy(source, target); + } + + // Append next token to each beam. + for (int i = 0; i < batch_beam_size_; i++) { + output[i * max_length_ + current_length_] = beam_next_tokens[i]; + } + + ++current_length_; + + // Rotate buffer for next round. + current_sequences_buffer = 1 - current_sequences_buffer; +} + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/contrib_ops/cpu/transformers/sequences.h b/onnxruntime/contrib_ops/cpu/transformers/sequences.h new file mode 100644 index 0000000000..9950330dae --- /dev/null +++ b/onnxruntime/contrib_ops/cpu/transformers/sequences.h @@ -0,0 +1,80 @@ +#pragma once + +#include "gsl/gsl" +#include "core/common/safeint.h" +#include "core/framework/allocator.h" +#include "core/framework/ort_value.h" + +namespace onnxruntime { +namespace contrib { +namespace transformers { + +class ISequences { + public: + virtual ~ISequences() {} + virtual gsl::span GetSequence(int beam_index) const = 0; + virtual int GetSequenceLength() const = 0; +}; + +// This class keeps track of sequences generated. +class Sequences : public ISequences { + public: + Sequences() {} + + // Initialize the sequence with initial input_ids and related parameters. + void Init(AllocatorPtr allocator, const OrtValue& input_ids, int batch_beam_size, int sequence_length, int max_length); + + // Returns a sequence of word IDs for a given beam index ( beam_index < batch_beam_size). + gsl::span GetSequence(int beam_index) const override; + + // Returns current sequence length. + int GetSequenceLength() const override; + + // Print the sequences to StdOut in debug mode + void PrintSequences(); + + // Select sequences based on beam indices, then append next token to selected sequences. + void AppendNextTokenToSequences( + gsl::span& beam_indices, + gsl::span& beam_next_tokens); + + private: + gsl::span sequences_space; // shape (2, batch_size, num_beams, max_seq_length) + BufferUniquePtr sequences_space_buffer_; + + // Two buffers of shape (batch_size, num_beams, max_seq_length) to store sequences. + // At each time, there is only one buffer is active. The other one will be active in next token. + // Each AppendNextTokenToSequences call will trigger a rotation of active buffer. + gsl::span sequences[2]; + + // Index (either 0 or 1) of two buffers that is currently is active. + int current_sequences_buffer; + + int batch_beam_size_; + int max_length_; + int current_length_; +}; + +template +gsl::span AllocateBuffer(AllocatorPtr allocator, + BufferUniquePtr& buffer, + size_t elements, + bool fill = false, + T fill_value = T{}) { + size_t bytes = SafeInt(sizeof(T)) * elements; + void* data = allocator->Alloc(bytes); + BufferUniquePtr temp_buffer(data, BufferDeleter(allocator)); + buffer = std::move(temp_buffer); + T* first = reinterpret_cast(buffer.get()); + auto span = gsl::make_span(first, elements); + + if (fill) { + std::fill_n(first, elements, fill_value); + } + + return span; +} + +} // namespace transformers +} // namespace contrib +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc index 74d3b1d74d..6eb90e969c 100644 --- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc @@ -568,6 +568,139 @@ void DecoderAttentionTypeAndShapeInference(ONNX_NAMESPACE::InferenceContext& ctx } } +bool ParseScalar(const TensorProto* initializer, int& value) { + std::vector parsed_data; + if (initializer->data_type() == TensorProto::INT32) { + const auto& data = ParseData(initializer); + parsed_data.insert(parsed_data.end(), data.begin(), data.end()); + + if (parsed_data.size() == 1) { + value = parsed_data[0]; + return true; + } + } + + return false; +} + +void BeamSearchShapeInference(ONNX_NAMESPACE::InferenceContext& ctx) { + // Type inference + ONNX_NAMESPACE::propagateElemTypeFromInputToOutput(ctx, 0, 0); + + if (ctx.getNumOutputs() > 1) { + // Here we assume that the third output exist only if second output exists. + ONNX_NAMESPACE::propagateElemTypeFromInputToOutput(ctx, 5, 1); + if (ctx.getNumOutputs() > 2) { + ONNX_NAMESPACE::propagateElemTypeFromInputToOutput(ctx, 5, 2); + } + } + + // Shape inference + // input 0 (input_ids) shape: (batch_size, sequence_length) + // output 0 (sequences) shape: (batch_size, num_return_sequences, max_length) + // output 1 (sequences_scores) shape: (batch_size, num_return_sequences) + // output 2 (scores) shape: (max_length - sequence_length, batch_size, num_beams, vocab_size) + if (!hasInputShape(ctx, 0)) { + return; + } + auto& input_ids_shape = getInputShape(ctx, 0); + auto& input_ids_dims = input_ids_shape.dim(); + if (input_ids_dims.size() != 2) { + fail_shape_inference("Inputs 0 shall be 2 dimensions"); + } + if (!(input_ids_dims[0].has_dim_value() && input_ids_dims[1].has_dim_value())) { + return; + } + + int64_t batch_size = input_ids_dims[0].dim_value(); + int64_t sequence_length = input_ids_dims[1].dim_value(); + + const auto max_length = ctx.getInputData(1); + const auto num_beams = ctx.getInputData(3); + const auto num_return_sequences = ctx.getInputData(4); + if (num_beams == nullptr || max_length == nullptr || num_return_sequences == nullptr) { // not initializer + return; + } + + int max_length_value = 0; + if (!ParseScalar(max_length, max_length_value) || max_length_value <= 0) { + fail_shape_inference("Failed to parse max_length or it is not positive integer scalar"); + } + + int num_beams_value = 0; + if (!ParseScalar(num_beams, num_beams_value) || num_beams_value <= 0) { + fail_shape_inference("Failed to parse num_beams or it is not positive integer scalar"); + } + + int num_return_sequences_value = 0; + if (!ParseScalar(num_return_sequences, num_return_sequences_value) || num_return_sequences_value <= 0) { + fail_shape_inference("Failed to parse num_return_sequences or it is not positive integer scalar"); + } + + ONNX_NAMESPACE::TensorShapeProto sequences_shape; + sequences_shape.add_dim()->set_dim_value(batch_size); + sequences_shape.add_dim()->set_dim_value(num_return_sequences_value); + sequences_shape.add_dim()->set_dim_value(max_length_value); + updateOutputShape(ctx, 0, sequences_shape); + + if (ctx.getNumOutputs() > 1) { + ONNX_NAMESPACE::TensorShapeProto sequences_scores_shape; + sequences_shape.add_dim()->set_dim_value(batch_size); + sequences_shape.add_dim()->set_dim_value(num_return_sequences_value); + updateOutputShape(ctx, 1, sequences_scores_shape); + + if (ctx.getNumOutputs() > 2) { + ONNX_NAMESPACE::TensorShapeProto scores_shape; + scores_shape.add_dim()->set_dim_value(max_length_value - sequence_length); + scores_shape.add_dim()->set_dim_value(batch_size); + scores_shape.add_dim()->set_dim_value(num_beams_value); + scores_shape.add_dim(); // vocab_size is unknown + updateOutputShape(ctx, 2, scores_shape); + } + } +} + +void RegisterTextGenerationSchemas() { + ONNX_CONTRIB_OPERATOR_SCHEMA(BeamSearch) + .SetDomain(kMSDomain) + .SinceVersion(1) + .SetDoc("Beam Search for text generation. Supports GPT-2 decoder.") + .Attr("eos_token_id", "The id of the end-of-sequence token", AttributeProto::INT) + .Attr("pad_token_id", "The id of the padding token", AttributeProto::INT) + .Attr("no_repeat_ngram_size", "no repeat ngrams size", AttributeProto::INT, static_cast(0)) + .Attr("early_stopping", "early stop or not", AttributeProto::INT, static_cast(0)) + .Attr( + "body", + "The GPT-2 subgraph with input_ids, position_ids, attention_mask, past_0, past_1, ... as inputs, and logits, present_0, present_1, ... as output", + AttributeProto::GRAPH) + .Input(0, "input_ids", "The sequence used as a prompt for the generation. Shape is (batch_size, sequence_length)", "I") + .Input(1, "max_length", "The maximum length of the sequence to be generated. Shape is (1)", "I") + .Input(2, "min_length", "The minimum length below which the score of eos_token_id is set to -Inf. Shape is (1)", "I", OpSchema::Optional) + .Input(3, "num_beams", "Number of beams for beam search. 1 means no beam search. Shape is (1)", "I") + .Input(4, "num_return_sequences", "The number of returned sequences in the batch. Shape is (1)", "I") + .Input(5, "temperature", "The value used to module the next token probabilities. Accepts value > 0.0. Shape is (1)", "T") + .Input(6, "length_penalty", + "Exponential penalty to the length. Default value 1.0 means no penalty." + "Value > 1.0 encourages longer sequences, while values < 1.0 produces shorter sequences." + "Shape is (1,)", + "T", OpSchema::Optional) + .Input(7, "repetition_penalty", "The parameter for repetition penalty. Default value 1.0 means no penalty. Accepts value > 0.0. Shape is (1)", "T", OpSchema::Optional) + .Input(8, "vocab_mask", "Mask of vocabulary. Words that masked with 0 are not allowed to be generated, and 1 is allowed. Shape is (vacab_size)", "M", OpSchema::Optional) + .Output(0, "sequences", "Word IDs of generated sequences. Shape is (batch_size, num_return_sequences, max_sequence_length)", "I") + .Output(1, "sequences_scores", "Final beam score of the generated sequences. Shape is (batch_size, num_return_sequences)", "T", OpSchema::Optional) + .Output(2, "scores", + "Processed beam scores for each vocabulary token at each generation step." + "Beam scores consisting of log softmax scores for each vocabulary token and sum of log softmax of previously generated tokens in this beam." + "Shape is (max_length - sequence_length, batch_size, num_beams, vocab_size)", + "T", OpSchema::Optional) + .TypeConstraint("T", {"tensor(float)", "tensor(float16)"}, "Constrain input and output types to float tensors.") + .TypeConstraint("I", {"tensor(int32)"}, "Constrain to integer types") + .TypeConstraint("M", {"tensor(int32)"}, "Constrain mask to integer types") + .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { + BeamSearchShapeInference(ctx); + }); +} + void RegisterBertSchemas() { static const char* Attention_ver1_doc = R"DOC( Multi-Head Self Attention that can be either unidirectional (like GPT-2) or bidirectional (like BERT). @@ -750,8 +883,7 @@ Some boolean parameters are passed by runtime input for generic purpose .TypeConstraint("B", {"tensor(bool)"}, "Constrain key_padding_mask to bool tensors.") .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { DecoderAttentionTypeAndShapeInference(ctx); - }); - + }); static const char* EmbedLayerNormalization_ver1_doc = R"DOC( EmbedLayerNormalization is the fusion of embedding layer in BERT model, with optional mask processing. @@ -3146,6 +3278,7 @@ It's an extension of Gelu. It takes the sum of input A and bias input B as the i RegisterNhwcSchemas(); RegisterBertSchemas(); + RegisterTextGenerationSchemas(); #ifdef BUILD_MS_EXPERIMENTAL_OPS onnxruntime::signal::RegisterSignalSchemas(); diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 03acfec47f..3e81f43850 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -2587,6 +2587,15 @@ Status Graph::VerifyNodeAndOpMatch(const ResolveOptions& options) { } } + // verify subgraphs + for (auto node_index : nodes_in_topological_order_) { + auto& node = *GetNode(node_index); + for (auto& entry : node.GetAttributeNameToMutableSubgraphMap()) { + Graph* subgraph = entry.second; + ORT_RETURN_IF_ERROR(subgraph->VerifyNodeAndOpMatch(options)); + } + } + return Status::OK(); } diff --git a/onnxruntime/core/providers/cpu/math/top_k.cc b/onnxruntime/core/providers/cpu/math/top_k.cc index db0b5086e6..f9b2c7d736 100644 --- a/onnxruntime/core/providers/cpu/math/top_k.cc +++ b/onnxruntime/core/providers/cpu/math/top_k.cc @@ -370,6 +370,56 @@ static Status TopKImpl(OpKernelContext* p_op_kernel_context, const Tensor* input return Status::OK(); } +// Wrapper over core TopK implementation +template +Status GetTopK(const Tensor* input, const int axis, const unsigned k, bool largest, bool sorted, + AllocatorPtr allocator, + onnxruntime::concurrency::ThreadPool* threadpool, + std::unique_ptr& output_values, + std::unique_ptr& output_indices) { + const TensorShape& input_shape = input->Shape(); + + // Will return axis_ as is if positive or fixes it in case it is negative + const auto axis_parsed = HandleNegativeAxis(axis, static_cast(input_shape.NumDimensions())); + + // Check to ensure k is within the bounds of what is available in that specific axis + if (input_shape[axis_parsed] < k) { + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "k argument [", k, + "] should not be greater than specified axis dim value [", input_shape[axis_parsed], "]"); + } + + // Resize output tensors to be the same shape as the input except + // for the specified dimension ((i.e.) axis_parsed), which will be of size k. E.x. for an input tensor + // of shape [3, 4, 5] and k=2 with axis_parsed=1, both of the outputs will be shape [3, 2, 5] + TensorShape output_shape = input_shape; + output_shape[axis_parsed] = k; + + output_values = Tensor::Create(input->DataType(), output_shape, allocator); + output_indices = Tensor::Create(DataTypeImpl::GetType(), output_shape, allocator); + + // no-op - no output buffers to fill - return silently + if (k == 0) { + return Status::OK(); + } + + if (largest) { + FindTopKElements>(input, input_shape, output_values.get(), output_indices.get(), output_shape, k, sorted, + gsl::narrow_cast(axis_parsed), threadpool); + } else { + FindTopKElements>(input, input_shape, output_values.get(), output_indices.get(), output_shape, k, sorted, + gsl::narrow_cast(axis_parsed), threadpool); + } + + return Status::OK(); +} + +// explicit instantiation +template Status GetTopK(const Tensor* input, const int axis, const unsigned k, bool largest, bool sorted, + AllocatorPtr allocator, + onnxruntime::concurrency::ThreadPool* threadpool, + std::unique_ptr& output_values, + std::unique_ptr& output_indices); + // Opset ver - 1 to 9 static void TopkOpset9ConstructorCommon(const OpKernelInfo& op_kernel_info, int& axis, unsigned int& k) { diff --git a/onnxruntime/core/providers/cpu/math/top_k.h b/onnxruntime/core/providers/cpu/math/top_k.h index 6cea1c7d6e..596f10a8e6 100644 --- a/onnxruntime/core/providers/cpu/math/top_k.h +++ b/onnxruntime/core/providers/cpu/math/top_k.h @@ -19,4 +19,11 @@ class TopK final : public OpKernel { bool largest_; // opset-11 only bool sorted_; // opset-11 only }; + +template +Status GetTopK(const Tensor* input, const int axis, const unsigned k, bool largest, bool sorted, + AllocatorPtr allocator, + onnxruntime::concurrency::ThreadPool* threadpool, + std::unique_ptr& output_values, + std::unique_ptr& output_indices); } // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/python/tools/transformers/convert_beam_search.py b/onnxruntime/python/tools/transformers/convert_beam_search.py new file mode 100644 index 0000000000..3f251fb9ad --- /dev/null +++ b/onnxruntime/python/tools/transformers/convert_beam_search.py @@ -0,0 +1,459 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os +import time +import onnx +import logging +import argparse +from pathlib import Path +from onnx import helper +import numpy as np +from typing import List +import torch +from transformers import GPT2Config +from gpt2_helper import PRETRAINED_GPT2_MODELS +from convert_to_onnx import main as convert_gpt2_to_onnx +from benchmark_helper import Precision +""" +This converts GPT2 model to onnx with beam search operator. + +Examples: + python convert_beam_search.py -m gpt2 --gpt2_onnx .\onnx_models\gpt2_past_fp32.onnx --output .\onnx_models\gpt2_beam_search.onnx --output_sequences_scores +""" + +config: GPT2Config = None + +logger = logging.getLogger('') + + +def parse_arguments(argv=None): + parser = argparse.ArgumentParser() + + parser.add_argument('-m', + '--model_name_or_path', + required=True, + type=str, + help='Model path, or pretrained model name in the list: ' + ', '.join(PRETRAINED_GPT2_MODELS)) + + parser.add_argument('--cache_dir', + required=False, + type=str, + default=os.path.join('.', 'cache_models'), + help='Directory to cache pre-trained models') + + parser.add_argument('--gpt2_onnx', + required=True, + type=str, + help='Output directory for GPT-2 onnx model, or model path ends with .onnx') + + parser.add_argument('--output', + required=False, + type=str, + help='Output directory for beam search model, or model path ends with .onnx') + + parser.add_argument("-p", + "--precision", + required=False, + type=Precision, + default=Precision.FLOAT32, + choices=[Precision.FLOAT32, Precision.FLOAT16], + help="Precision of model to run. fp32 for full precision, fp16 for half or mixed precision") + + parser.add_argument('--use_gpu', required=False, action='store_true', help="use GPU for inference") + parser.set_defaults(use_gpu=False) + + parser.add_argument('-e', '--use_external_data_format', required=False, action='store_true') + parser.set_defaults(use_external_data_format=False) + + parser.add_argument('--disable_parity', required=False, action='store_true', help="do not run parity test") + parser.set_defaults(disable_parity=False) + + parser.add_argument('--total_runs', + required=False, + type=int, + default=1, + help='Number of times of inference for latency measurement') + + beam_search_group = parser.add_argument_group("beam search options") + + beam_search_group.add_argument('--output_sequences_scores', + required=False, + action='store_true', + help="output sequences scores") + beam_search_group.set_defaults(output_sequences_scores=False) + + beam_search_group.add_argument('--output_token_scores', + required=False, + action='store_true', + help="output token scores") + beam_search_group.set_defaults(output_token_scores=False) + + beam_search_group.add_argument('--early_stopping', required=False, action='store_true') + beam_search_group.set_defaults(early_stopping=False) + + beam_search_group.add_argument('--min_length', type=int, required=False, default=1, help='Min sequence length') + + beam_search_group.add_argument('--max_length', type=int, required=False, default=50, help='Max sequence length') + + beam_search_group.add_argument('--no_repeat_ngram_size', + type=int, + required=False, + default=0, + help='No repeat ngram size') + + beam_search_group.add_argument('--num_beams', type=int, required=False, default=4, help='Beam size') + + beam_search_group.add_argument('--num_return_sequences', + type=int, + required=False, + default=1, + help='Number of return sequence <= num_beams') + + beam_search_group.add_argument('--temperature', + type=float, + required=False, + default=1, + help='Softmax temperature for output logits.') + + beam_search_group.add_argument('--length_penalty', + type=float, + required=False, + default=1, + help='Positive. >1 to penalize and <1 to encorage short sentence.') + + beam_search_group.add_argument('--repetition_penalty', + type=float, + required=False, + default=1, + help='Positive. >1 to penalize and <1 to encorage.') + + mixed_precision_option_group = parser.add_argument_group( + "mixed precision conversion parameters that works when \"--precision fp16\" is specified") + + mixed_precision_option_group.add_argument('--io_block_list', + nargs='+', + required=False, + default=[], + help='List of inputs or outputs in float32') + + mixed_precision_option_group.add_argument( + '--op_block_list', + nargs='+', + required=False, + default=[], + help='List of operators (like Add LayerNormalization FastGelu) to compute in float32.') + + mixed_precision_option_group.add_argument('--node_block_list', + nargs='+', + required=False, + default=[], + help='List of node names to compute in float32.') + + mixed_precision_option_group.add_argument('--force_fp16_initializers', + required=False, + action='store_true', + help='Convert all float initializers to float16.') + mixed_precision_option_group.set_defaults(force_fp16_initializers=False) + + args = parser.parse_args(argv) + + return args + + +def gpt2_to_onnx(args): + model_name = args.model_name_or_path + + print(f"use convert_to_onnx.py to convert model {model_name} to onnx {args.gpt2_onnx} ...") + arguments = [ + '--model_name_or_path', model_name, '--output', args.gpt2_onnx, '--optimize_onnx', '--precision', + 'fp32' if args.precision == Precision.FLOAT32 else 'fp16', '--test_runs', '1', '--test_cases', '10' + ] + if args.use_gpu: + arguments.append('--use_gpu') + if args.use_external_data_format: + arguments.append('--use_external_data_format') + + # mixed precision conversion options + if args.precision == Precision.FLOAT16: + assert args.use_gpu, "fp16 or mixed precision model cannot run in CPU. Please add --use_gpu" + if args.io_block_list: + arguments.append('--io_block_list') + arguments.extend(args.io_block_list) + if args.op_block_list: + arguments.append('--op_block_list') + arguments.extend(args.op_block_list) + if args.node_block_list: + arguments.append('--node_block_list') + arguments.extend(args.node_block_list) + if args.force_fp16_initializers: + arguments.append('--force_fp16_initializers') + + convert_gpt2_to_onnx(arguments) + + +def shape_inference(gpt2_onnx_path): + # Run symbolic shape inference to walk around ORT shape inference issue for subgraph. + from onnxruntime.tools.symbolic_shape_infer import SymbolicShapeInference + out = SymbolicShapeInference.infer_shapes(onnx.load(gpt2_onnx_path), auto_merge=True, guess_output_rank=False) + if out: + # TODO: Use external format if input has extra data. + onnx.save(out, gpt2_onnx_path) + else: + print("Failed to run symbolic shape inference on the model.") + + +def create_ort_session(model_path, use_gpu): + from onnxruntime import SessionOptions, InferenceSession, __version__ as ort_version, GraphOptimizationLevel + sess_options = SessionOptions() + sess_options.graph_optimization_level = GraphOptimizationLevel.ORT_DISABLE_ALL + execution_providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if use_gpu else ['CPUExecutionProvider'] + + ort_session = InferenceSession(model_path, sess_options, providers=execution_providers) + return ort_session + + +def convert_model(args): + if os.path.exists(args.gpt2_onnx): + print(f"skip convert_to_onnx since path existed: {args.gpt2_onnx}") + else: + gpt2_to_onnx(args) + + print(f"Run symbolic shape inference on {args.gpt2_onnx}. The file will be overwritten.") + shape_inference(args.gpt2_onnx) + + global config + config = GPT2Config.from_pretrained(args.model_name_or_path, cache_dir=args.cache_dir) + print(config) + + eos_token_id = config.eos_token_id + pad_token_id = config.eos_token_id + vocab_size = config.vocab_size + + model = onnx.load(args.gpt2_onnx) + model.graph.name = "gpt2 subgraph" + inputs = [ + "input_ids", "max_length", "min_length", "num_beams", "num_return_sequences", "temperature", "length_penalty", + "repetition_penalty", "vocab_mask" + ] + + outputs = ["sequences"] + if args.output_sequences_scores: + outputs.append("sequences_scores") + + if args.output_token_scores: + assert args.output_sequences_scores, "--output_token_scores requires --output_sequences_scores" + outputs.append("scores") + + node = helper.make_node('BeamSearch', inputs=inputs, outputs=outputs, name='BeamSearch_GPT2') + node.domain = "com.microsoft" + node.attribute.extend([ + helper.make_attribute("eos_token_id", eos_token_id), + helper.make_attribute("pad_token_id", pad_token_id), + helper.make_attribute("no_repeat_ngram_size", args.no_repeat_ngram_size), + helper.make_attribute("early_stopping", 1 if args.early_stopping else 0), + helper.make_attribute("body", model.graph), + ]) + + from onnx import TensorProto + + # graph inputs + input_ids = helper.make_tensor_value_info('input_ids', TensorProto.INT32, ['batch_size', 'sequence_length']) + max_length = helper.make_tensor_value_info('max_length', TensorProto.INT32, [1]) + min_length = helper.make_tensor_value_info('min_length', TensorProto.INT32, [1]) + num_beams = helper.make_tensor_value_info('num_beams', TensorProto.INT32, [1]) + num_return_sequences = helper.make_tensor_value_info('num_return_sequences', TensorProto.INT32, [1]) + temperature = helper.make_tensor_value_info('temperature', TensorProto.FLOAT, [1]) + length_penalty = helper.make_tensor_value_info('length_penalty', TensorProto.FLOAT, [1]) + repetition_penalty = helper.make_tensor_value_info('repetition_penalty', TensorProto.FLOAT, [1]) + vocab_mask = helper.make_tensor_value_info('vocab_mask', TensorProto.INT32, [vocab_size]) + + graph_inputs = [ + input_ids, max_length, min_length, num_beams, num_return_sequences, temperature, length_penalty, + repetition_penalty, vocab_mask + ] + + # graph outputs + sequences = helper.make_tensor_value_info('sequences', TensorProto.INT32, + ['batch_size', 'num_return_sequences', 'max_length']) + + sequences_scores = helper.make_tensor_value_info('sequences_scores', TensorProto.FLOAT, + ['batch_size', 'num_return_sequences']) + + scores = helper.make_tensor_value_info('scores', TensorProto.FLOAT, + ['max_length - sequence_length', 'batch_size', 'num_beams', vocab_size]) + + initializers = [] + + graph_outputs = [sequences] + + if args.output_sequences_scores: + graph_outputs.append(sequences_scores) + + if args.output_token_scores: + graph_outputs.append(scores) + + new_graph = helper.make_graph([node], 'gpt2-beam-search', graph_inputs, graph_outputs, initializers) + + # Create the model + new_model = helper.make_model(new_graph, producer_name='onnxruntime.transformers', opset_imports=model.opset_import) + onnx.save(new_model, args.output) + + +def test_model(args, use_vocab_mask: bool = False, sentences: List[str] = None): + from transformers import GPT2Tokenizer, GPT2LMHeadModel + + tokenizer = GPT2Tokenizer.from_pretrained(args.model_name_or_path, cache_dir=args.cache_dir) + tokenizer.padding_side = "left" + tokenizer.pad_token = tokenizer.eos_token + + model = GPT2LMHeadModel.from_pretrained(args.model_name_or_path, + cache_dir=args.cache_dir, + pad_token_id=tokenizer.eos_token_id) + + # Use different length sentences to test batching + if sentences is None: + sentences = ["The product is released", "I enjoy walking in the park", "Test best way to invest"] + + inputs = tokenizer(sentences, return_tensors='pt', padding=True) + input_ids = inputs["input_ids"] + attention_mask = inputs["attention_mask"] + + bad_words = "walk in park" + bad_words_ids = tokenizer.encode(bad_words, add_prefix_space=True) + bad_words_ids = [[word_id] for word_id in bad_words_ids] # Convert to list of list + if use_vocab_mask: + print("bad_words_ids", bad_words_ids) + else: + bad_words_ids = None + + global config + config = model.config + eos_token_id = config.eos_token_id + pad_token_id = config.eos_token_id + vocab_size = config.vocab_size + + torch_decoded_sequences = [] + if not args.disable_parity: + print('-' * 50) + print("Test PyTorch model and beam search with huggingface transformers...") + beam_outputs = model.generate(input_ids=input_ids, + attention_mask=attention_mask, + max_length=args.max_length, + min_length=args.min_length, + num_beams=args.num_beams, + early_stopping=args.early_stopping, + no_repeat_ngram_size=args.no_repeat_ngram_size, + eos_token_id=eos_token_id, + pad_token_id=pad_token_id, + num_return_sequences=args.num_return_sequences, + temperature=args.temperature, + length_penalty=args.length_penalty, + repetition_penalty=args.repetition_penalty, + bad_words_ids=bad_words_ids, + return_dict_in_generate=True, + output_scores=True) + print("input_ids", input_ids) + print("huggingface transformers outputs:") + print("sequences", beam_outputs.sequences) + if args.output_sequences_scores: + print("sequences_scores", beam_outputs.sequences_scores) + if args.output_token_scores: + print("scores", beam_outputs.scores) + for i, sequence in enumerate(beam_outputs.sequences): + decoded_sequence = tokenizer.decode(sequence, skip_special_tokens=True) + torch_decoded_sequences.append(decoded_sequence) + print("{}: {}".format(i, decoded_sequence)) + + print('-' * 50) + print("Test ONNX model and bream search with onnxruntime...") + + ort_session = create_ort_session(args.output, args.use_gpu) + + vocab_mask = np.ones((vocab_size), dtype=np.int32) + if use_vocab_mask: + for bad_word_id in bad_words_ids: + vocab_mask[bad_word_id] = 0 + + inputs = { + "input_ids": input_ids.cpu().numpy().astype(np.int32), + "max_length": np.array([args.max_length], dtype=np.int32), + "min_length": np.array([args.min_length], dtype=np.int32), + "num_beams": np.array([args.num_beams], dtype=np.int32), + "num_return_sequences": np.array([args.num_return_sequences], dtype=np.int32), + "temperature": np.array([args.temperature], dtype=np.float32), + "length_penalty": np.array([args.length_penalty], dtype=np.float32), + "repetition_penalty": np.array([args.repetition_penalty], dtype=np.float32), + "vocab_mask": vocab_mask + } + + test_data_dir = Path(args.output).parent.as_posix() + print("test_data_dir", test_data_dir) + from bert_test_data import output_test_data + all_inputs = [inputs] + for i, inputs in enumerate(all_inputs): + dir = os.path.join(test_data_dir, 'test_data_set_' + str(i)) + output_test_data(dir, inputs) + + print("inputs", inputs) + + # Test performance + latency = [] + for _ in range(args.total_runs): + start = time.time() + result = ort_session.run(None, inputs) + latency.append(time.time() - start) + batch_size = input_ids.shape[0] + from benchmark_helper import get_latency_result + output = get_latency_result(latency, batch_size) + + print("ORT outputs:") + sequences = result[0] + print("sequences", sequences) + if args.output_sequences_scores: + print("sequences_scores", result[1]) + if args.output_token_scores: + print("scores", result[2]) + + (batch_size, num_sequences, max_length) = sequences.shape + ort_decoded_sequences = [] + for i in range(batch_size): + for j in range(num_sequences): + decoded_sequence = tokenizer.decode(sequences[i][j], skip_special_tokens=True) + ort_decoded_sequences.append(decoded_sequence) + print(f"batch {i} sequence {j}: {decoded_sequence}") + + if not args.disable_parity: + torch_sequences = beam_outputs.sequences.reshape(batch_size, args.num_return_sequences, -1) + ort_sequences = torch.LongTensor(sequences) + print("-" * 50) + print("Torch Sequences:") + print(torch_sequences) + print(torch_decoded_sequences) + print("-" * 50) + print("ORT Sequences:") + print(ort_sequences) + print(ort_decoded_sequences) + print("-" * 50) + # Compare the generated text instead of word IDs since ORT pads to max sequence length but Torch not. + is_same = (torch_decoded_sequences == ort_decoded_sequences) + print("Torch and ORT result is ", "same" if is_same else "different") + output["parity"] = is_same + + print(output) + return output + + +def main(argv=None, sentences=None): + args = parse_arguments(argv) + + if os.path.exists(args.output): + print(f"skip conversion since path existed: {args.output}") + else: + convert_model(args) + + return test_model(args, use_vocab_mask=True, sentences=sentences) + + +if __name__ == '__main__': + main() diff --git a/onnxruntime/python/tools/transformers/convert_to_onnx.py b/onnxruntime/python/tools/transformers/convert_to_onnx.py index 500a3f3b90..28120d5e80 100644 --- a/onnxruntime/python/tools/transformers/convert_to_onnx.py +++ b/onnxruntime/python/tools/transformers/convert_to_onnx.py @@ -17,7 +17,6 @@ This converts GPT2 model to onnx. Examples: import os import argparse -import coloredlogs import logging import torch import numpy diff --git a/onnxruntime/test/python/transformers/test_beam_search.py b/onnxruntime/test/python/transformers/test_beam_search.py new file mode 100644 index 0000000000..f469cdaaaa --- /dev/null +++ b/onnxruntime/test/python/transformers/test_beam_search.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import unittest +import os +import pytest + +from parity_utilities import find_transformers_source +if find_transformers_source(): + from convert_beam_search import main as run +else: + from onnxruntime.transformers.convert_beam_search import main as run + + +class TestBeamSearch(unittest.TestCase): + def setUp(self): + #TODO: use a smaller model and enable tests in CI pipeline + self.model_name = "gpt2" + self.gpt2_onnx_path = os.path.join('.', 'onnx_models', 'gpt2_past_fp32_shape.onnx') + self.beam_search_onnx_path = os.path.join('.', 'onnx_models', 'gpt2_beam_search.onnx') + self.cpu_params = f'-m {self.model_name} --gpt2_onnx {self.gpt2_onnx_path} --output {self.beam_search_onnx_path} --output_sequences_score --repetition_penalty 2.0' + + def run_beam_search(self, arguments: str, sentences=None): + return run(arguments.split(), sentences=sentences) + + @pytest.mark.slow + def test_cpu(self): + result = self.run_beam_search(self.cpu_params + " --num_return_sequences 2", + sentences=["The product is released"]) + os.remove(self.gpt2_onnx_path) + os.remove(self.beam_search_onnx_path) + self.assertTrue(result["parity"], "ORT and PyTorch result is different") + + @pytest.mark.slow + def test_early_stopping(self): + result = self.run_beam_search(self.cpu_params + " --early_stopping") + os.remove(self.gpt2_onnx_path) + os.remove(self.beam_search_onnx_path) + self.assertTrue(result["parity"], "ORT and PyTorch result is different") + + @pytest.mark.slow + def test_temperature(self): + result = self.run_beam_search(self.cpu_params + " --temperature 0.5") + os.remove(self.gpt2_onnx_path) + os.remove(self.beam_search_onnx_path) + self.assertTrue(result["parity"], "ORT and PyTorch result is different") + + @pytest.mark.slow + def test_length_penalty(self): + result = self.run_beam_search(self.cpu_params + " --length_penalty 0.5") + os.remove(self.gpt2_onnx_path) + os.remove(self.beam_search_onnx_path) + self.assertTrue(result["parity"], "ORT and PyTorch result is different") + + @pytest.mark.slow + def test_no_repeat_ngram(self): + for ngram_size in [1, 2]: + result = self.run_beam_search(self.cpu_params + f' --no_repeat_ngram_size {ngram_size}') + os.remove(self.gpt2_onnx_path) + os.remove(self.beam_search_onnx_path) + self.assertTrue(result["parity"], "ORT and PyTorch result is different") + + +if __name__ == '__main__': + unittest.main() diff --git a/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json index 410625083c..120e6de7c0 100644 --- a/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json +++ b/onnxruntime/test/testdata/kernel_def_hashes/contrib.cpu.json @@ -3,6 +3,10 @@ "Affine ai.onnx CPUExecutionProvider", 7811918192248490408 ], + [ + "BeamSearch com.microsoft CPUExecutionProvider", + 6968087233460196528 + ], [ "Crop ai.onnx CPUExecutionProvider", 6914973556202621376 From f3c72de718f304102f1864c2dd5284c432f2e64a Mon Sep 17 00:00:00 2001 From: Guoyu Wang <62914304+gwang-msft@users.noreply.github.com> Date: Thu, 16 Dec 2021 17:37:51 -0800 Subject: [PATCH 060/113] [QDQ] Add shared NodeUnit class (#10052) * initial change * move more function to node_unit * Remove commented code * Minor update * Update onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.cc Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com> * address CR comments Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com> --- cmake/onnxruntime_providers.cmake | 2 + .../nnapi/nnapi_builtin/builders/helper.cc | 22 +- .../nnapi/nnapi_builtin/builders/helper.h | 5 +- .../nnapi_builtin/builders/model_builder.cc | 21 +- .../nnapi_builtin/builders/op_builder.cc | 232 +++++++----- .../nnapi/nnapi_builtin/builders/op_builder.h | 26 +- .../builders/op_support_checker.cc | 331 ++++++++++-------- .../builders/op_support_checker.h | 6 +- .../nnapi_builtin/nnapi_execution_provider.cc | 13 +- .../providers/shared/node_unit/node_unit.cc | 45 +++ .../providers/shared/node_unit/node_unit.h | 81 +++++ 11 files changed, 525 insertions(+), 259 deletions(-) create mode 100644 onnxruntime/core/providers/shared/node_unit/node_unit.cc create mode 100644 onnxruntime/core/providers/shared/node_unit/node_unit.h diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index 396f8b17db..a2f6d6bc22 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -820,6 +820,8 @@ if (onnxruntime_USE_NNAPI_BUILTIN) file(GLOB_RECURSE onnxruntime_providers_shared_utils_cc_srcs CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.h" "${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.cc" + "${ONNXRUNTIME_ROOT}/core/providers/shared/node_unit/node_unit.h" + "${ONNXRUNTIME_ROOT}/core/providers/shared/node_unit/node_unit.cc" ) if(CMAKE_SYSTEM_NAME STREQUAL "Android") diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.cc index 1108318835..2fc1afd435 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.cc @@ -12,16 +12,18 @@ #include #include +#include "core/providers/shared/node_unit/node_unit.h" #include "core/providers/shared/utils/utils.h" #include "helper.h" #include "op_support_checker.h" -namespace onnxruntime { -namespace nnapi { - +using onnxruntime::NodeUnit; using std::string; using std::vector; +namespace onnxruntime { +namespace nnapi { + std::string GetErrorCause(int error_code) { switch (error_code) { case ANEURALNETWORKS_NO_ERROR: @@ -434,22 +436,24 @@ bool IsInternalQuantizationSupported(const Node& node, const std::unordered_set< return true; } -bool IsNodeSupported(const Node& node, const GraphViewer& graph_viewer, const OpSupportCheckParams& params) { +bool IsNodeSupported(const NodeUnit& node_unit, const GraphViewer& graph_viewer, const OpSupportCheckParams& params) { const auto& op_support_checkers = GetOpSupportCheckers(); - if (!Contains(op_support_checkers, node.OpType())) + if (!Contains(op_support_checkers, node_unit.OpType())) return false; - const auto* op_support_checker = op_support_checkers.at(node.OpType()); - return op_support_checker->IsOpSupported(graph_viewer.GetAllInitializedTensors(), node, params); + const auto* op_support_checker = op_support_checkers.at(node_unit.OpType()); + return op_support_checker->IsOpSupported(graph_viewer.GetAllInitializedTensors(), node_unit, params); } -bool IsNodeSupportedInGroup(const Node& node, const GraphViewer& graph_viewer, +bool IsNodeSupportedInGroup(const NodeUnit& node_unit, const GraphViewer& graph_viewer, const OpSupportCheckParams& params, const std::unordered_set& node_outputs_in_group) { - if (!IsNodeSupported(node, graph_viewer, params)) + if (!IsNodeSupported(node_unit, graph_viewer, params)) return false; + // TODO, ignore this step if the node_unit is qdq node_unit // We also want to check if the node is supported as an internal quantized node + const auto& node = node_unit.GetNode(); if (IsInternalQuantizedNode(node)) return IsInternalQuantizationSupported(node, node_outputs_in_group); else // This is not a internal quantized node, it is supported diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.h b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.h index 915460f091..d8d89269c9 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.h +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.h @@ -28,6 +28,7 @@ using InitializerMap = std::unordered_map& node_outputs_in_group); diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc index 8c7004d793..645ab23a85 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc @@ -6,6 +6,7 @@ #include #include "core/providers/common.h" +#include "core/providers/shared/node_unit/node_unit.h" #include "core/providers/shared/utils/utils.h" #include "core/providers/nnapi/nnapi_builtin/nnapi_lib/nnapi_implementation.h" #include "helper.h" @@ -13,12 +14,13 @@ #include "op_builder.h" #include "op_support_checker.h" -namespace onnxruntime { -namespace nnapi { - +using onnxruntime::NodeUnit; using namespace android::nn::wrapper; using std::vector; +namespace onnxruntime { +namespace nnapi { + ModelBuilder::ModelBuilder(const GraphViewer& graph_viewer) : nnapi_(NnApiImplementation()), graph_viewer_(graph_viewer) {} @@ -120,7 +122,8 @@ void ModelBuilder::PreprocessInitializers() { for (size_t i = 0; i < node_indices.size(); i++) { const auto* node(graph_viewer_.GetNode(node_indices[i])); if (const auto* op_builder = GetOpBuilder(*node)) { - op_builder->AddInitializersToSkip(*this, *node); + const NodeUnit node_unit(*node); + op_builder->AddInitializersToSkip(*this, node_unit); } } } @@ -192,7 +195,7 @@ static Status GetInputDataType( case ONNX_NAMESPACE::TensorProto_DataType_FLOAT: type = Type::TENSOR_FLOAT32; break; - case ONNX_NAMESPACE::TensorProto_DataType_UINT8: + case ONNX_NAMESPACE::TensorProto_DataType_UINT8: { // For ONNX the quantized input/initializer does not carry scale and zero point info // So we will need to search the operator using this input // And dig out the scale and zero point as the input initializers to the operator @@ -205,9 +208,12 @@ static Status GetInputDataType( } // TODO, verify the scale and zero point match if there are multiple op using same input + const auto* node = all_quantized_op_inputs.at(name)[0]; + const NodeUnit node_unit(*node); ORT_RETURN_IF_ERROR(GetQuantizedInputScaleAndZeroPoint( - initializers, *all_quantized_op_inputs.at(name)[0], name, scale, zero_point)); + initializers, node_unit, name, scale, zero_point)); break; + } // case ONNX_NAMESPACE::TensorProto_DataType_INT8: // We also do not consider ONNX_NAMESPACE::TensorProto_DataType_INT8 case here, since that can only // be input 2 of Qlinear[Conv/MatMul], which has to be an initializer tensor and will be added @@ -488,7 +494,8 @@ Status ModelBuilder::AddOperations() { for (size_t i = 0; i < node_indices.size(); i++) { const auto* node(graph_viewer_.GetNode(node_indices[i])); if (const auto* op_builder = GetOpBuilder(*node)) { - ORT_RETURN_IF_ERROR(op_builder->AddToModelBuilder(*this, *node)); + const NodeUnit node_unit(*node); + ORT_RETURN_IF_ERROR(op_builder->AddToModelBuilder(*this, node_unit)); } else { return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Node [", node->Name(), "], type [", node->OpType(), "] is not supported"); diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.cc index a351a5c483..66f870df15 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.cc @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include "op_builder.h" + #include #include #include @@ -8,18 +10,19 @@ #include #include "core/providers/shared/utils/utils.h" +#include "core/providers/shared/node_unit/node_unit.h" #include "core/providers/cpu/tensor/slice_helper.h" #include "helper.h" #include "model_builder.h" -#include "op_builder.h" #include "op_support_checker.h" +using onnxruntime::NodeUnit; +using namespace android::nn::wrapper; +using std::vector; + namespace onnxruntime { namespace nnapi { -using namespace android::nn::wrapper; -using std::vector; - #pragma region helpers struct OpBuilderRegistrations { @@ -653,7 +656,8 @@ static Status IsValidConvWeightQuantizedType(const ModelBuilder& model_builder, return Status::OK(); } -static void AddBinaryOpQuantizationScaleAndZeroPointToSkip(ModelBuilder& model_builder, const Node& node) { +static void AddBinaryOpQuantizationScaleAndZeroPointToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); model_builder.AddInitializerToSkip(input_defs[1]->Name()); // a_scale model_builder.AddInitializerToSkip(input_defs[2]->Name()); // a_zero_point @@ -664,10 +668,11 @@ static void AddBinaryOpQuantizationScaleAndZeroPointToSkip(ModelBuilder& model_b } Status GetQuantizedInputScaleAndZeroPoint(const InitializedTensorSet& initializers, - const Node& node, + const NodeUnit& node_unit, const std::string& input_name, float& scale, int32_t& zero_point) { + const auto& node = node_unit.GetNode(); const auto& op_type = node.OpType(); auto qlinear_op_type = GetQLinearOpType(node); assert(qlinear_op_type != QLinearOpType::Unknown && @@ -725,23 +730,24 @@ void CreateSharedOpBuilderImpl(const std::string& op_type, class BaseOpBuilder : public IOpBuilder { public: virtual ~BaseOpBuilder() = default; - virtual void AddInitializersToSkip(ModelBuilder& /* model_builder */, const Node& /* node */) const override {} - Status AddToModelBuilder(ModelBuilder& model_builder, const Node& node) const override final ORT_MUST_USE_RESULT; + virtual void AddInitializersToSkip(ModelBuilder& /* model_builder */, const NodeUnit& /* node_unit */) const override {} + Status AddToModelBuilder(ModelBuilder& model_builder, const NodeUnit& node_unit) const override final ORT_MUST_USE_RESULT; protected: - virtual Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const ORT_MUST_USE_RESULT = 0; + virtual Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const ORT_MUST_USE_RESULT = 0; }; -Status BaseOpBuilder::AddToModelBuilder(ModelBuilder& model_builder, const Node& node) const { +Status BaseOpBuilder::AddToModelBuilder(ModelBuilder& model_builder, const NodeUnit& node_unit) const { OpSupportCheckParams params{ model_builder.GetNNAPIFeatureLevel(), model_builder.UseNCHW(), }; - ORT_RETURN_IF_NOT(IsNodeSupported(node, model_builder.GetGraphViewer(), params), "Unsupported operator ", node.OpType()); - ORT_RETURN_IF_ERROR(AddToModelBuilderImpl(model_builder, node)); - LOGS_DEFAULT(VERBOSE) << "Operator name: [" << node.Name() - << "] type: [" << node.OpType() << "] was added"; + ORT_RETURN_IF_NOT(IsNodeSupported(node_unit, model_builder.GetGraphViewer(), params), + "Unsupported operator ", node_unit.OpType()); + ORT_RETURN_IF_ERROR(AddToModelBuilderImpl(model_builder, node_unit)); + LOGS_DEFAULT(VERBOSE) << "Operator name: [" << node_unit.Name() + << "] type: [" << node_unit.OpType() << "] was added"; return Status::OK(); } @@ -751,17 +757,17 @@ Status BaseOpBuilder::AddToModelBuilder(ModelBuilder& model_builder, const Node& class BinaryOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static void CreateSharedOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations); private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void BinaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { - const auto& op = node.OpType(); +void BinaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& op = node_unit.OpType(); if (op == "QLinearAdd") { - AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node); + AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node_unit); } } @@ -779,7 +785,8 @@ void BinaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const N }); } -Status BinaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status BinaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto& op_type(node.OpType()); const auto input_defs(node.InputDefs()); @@ -850,10 +857,11 @@ Status BinaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const class ReluOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status ReluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ReluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -884,10 +892,11 @@ Status ReluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class TransposeOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status TransposeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status TransposeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); auto input = node.InputDefs()[0]->Name(); @@ -928,16 +937,17 @@ Status TransposeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, co class ReshapeOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static Status AddReshapeOperator(ModelBuilder& model_builder, const Node& node, const std::string& input, const std::vector& shape) ORT_MUST_USE_RESULT; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; static bool CanSkipReshape(const ModelBuilder& model_builder, const Node& node, size_t input_rank, size_t output_rank); }; -void ReshapeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void ReshapeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); model_builder.AddInitializerToSkip(node.InputDefs()[1]->Name()); } @@ -1040,7 +1050,8 @@ void ReshapeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const return Status::OK(); } -Status ReshapeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ReshapeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& initializers(model_builder.GetInitializerTensors()); @@ -1073,13 +1084,14 @@ Status ReshapeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, cons class BatchNormalizationOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void BatchNormalizationOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void BatchNormalizationOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); // skip everything except input0 for BatchNormalization model_builder.AddInitializerToSkip(node.InputDefs()[1]->Name()); // scale model_builder.AddInitializerToSkip(node.InputDefs()[2]->Name()); // B @@ -1087,7 +1099,8 @@ void BatchNormalizationOpBuilder::AddInitializersToSkip(ModelBuilder& model_buil model_builder.AddInitializerToSkip(node.InputDefs()[4]->Name()); //var } -Status BatchNormalizationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status BatchNormalizationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_types(model_builder.GetOperandTypes()); const auto& initializers(model_builder.GetInitializerTensors()); @@ -1184,14 +1197,15 @@ Status BatchNormalizationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_bu class PoolOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static void CreateSharedOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations); private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void PoolOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void PoolOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto& op = node.OpType(); if (op != "QLinearAveragePool") return; @@ -1220,7 +1234,9 @@ void PoolOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod }); } -Status PoolOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status PoolOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -1341,11 +1357,11 @@ Status PoolOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class ConvOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static void CreateSharedOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations); private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; /* static */ void ConvOpBuilder::CreateSharedOpBuilder( @@ -1358,13 +1374,14 @@ class ConvOpBuilder : public BaseOpBuilder { }); } -void ConvOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void ConvOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto& op = node.OpType(); const auto input_defs = node.InputDefs(); // skip the weight for conv as we need to transpose if (op == "QLinearConv") { - AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node); + AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node_unit); model_builder.AddInitializerToSkip(input_defs[3]->Name()); // w if (input_defs.size() > 8) model_builder.AddInitializerToSkip(input_defs[8]->Name()); // B @@ -1373,7 +1390,8 @@ void ConvOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod } } -Status ConvOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ConvOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -1610,10 +1628,11 @@ Status ConvOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class CastOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status CastOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status CastOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); NodeAttrHelper helper(node); @@ -1650,10 +1669,11 @@ Status CastOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class SoftMaxOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status SoftMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status SoftMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -1701,10 +1721,12 @@ Status SoftMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, cons class IdentityOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status IdentityOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status IdentityOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + // Identity is not really going to do anything // Just register the dimension and type, with same index and new name auto& shaper(model_builder.GetShaper()); @@ -1730,11 +1752,11 @@ Status IdentityOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, con class GemmOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static void CreateSharedOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations); private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; /* static */ void GemmOpBuilder::CreateSharedOpBuilder( @@ -1748,7 +1770,9 @@ class GemmOpBuilder : public BaseOpBuilder { }); } -void GemmOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void GemmOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + const auto& op = node.OpType(); const auto input_defs(node.InputDefs()); if (op == "MatMul") { @@ -1759,12 +1783,14 @@ void GemmOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod if (transB == 0) model_builder.AddInitializerToSkip(input_defs[1]->Name()); } else if (op == "QLinearMatMul") { - AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node); + AddBinaryOpQuantizationScaleAndZeroPointToSkip(model_builder, node_unit); model_builder.AddInitializerToSkip(input_defs[3]->Name()); // b } } -Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -1885,14 +1911,15 @@ Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class UnaryOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; static void CreateSharedOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations); private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void UnaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void UnaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto& op = node.OpType(); if (op != "QLinearSigmoid") return; @@ -1926,7 +1953,8 @@ void UnaryOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const No }); } -Status UnaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status UnaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -1993,10 +2021,11 @@ Status UnaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const class ConcatOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status ConcatOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ConcatOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -2085,14 +2114,15 @@ Status ConcatOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const class SqueezeOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; static Status GetAxes(ModelBuilder& model_builder, const Node& node, vector& axes); }; -void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); if (node.SinceVersion() > 12 && node.InputDefs().size() > 1) { model_builder.AddInitializerToSkip(node.InputDefs()[1]->Name()); } @@ -2124,7 +2154,9 @@ void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const return Status::OK(); } -Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto input = node.InputDefs()[0]->Name(); if (model_builder.IsOperandNHWC(input)) { // We want to transpose nhwc operand back to nchw before squeeze @@ -2142,13 +2174,14 @@ Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, cons class QuantizeLinearOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void QuantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void QuantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); model_builder.AddInitializerToSkip(input_defs[1]->Name()); @@ -2157,7 +2190,8 @@ void QuantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, model_builder.AddInitializerToSkip(input_defs[2]->Name()); } -Status QuantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status QuantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto input_defs(node.InputDefs()); @@ -2190,13 +2224,14 @@ Status QuantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builde class DequantizeLinearOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void DequantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void DequantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); model_builder.AddInitializerToSkip(input_defs[1]->Name()); @@ -2205,7 +2240,9 @@ void DequantizeLinearOpBuilder::AddInitializersToSkip(ModelBuilder& model_builde model_builder.AddInitializerToSkip(input_defs[2]->Name()); } -Status DequantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status DequantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto input_defs(node.InputDefs()); @@ -2239,10 +2276,11 @@ Status DequantizeLinearOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_buil class LRNOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status LRNOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status LRNOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -2297,13 +2335,14 @@ Status LRNOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const No class ClipOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void ClipOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void ClipOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); if (node.InputDefs().size() > 1) model_builder.AddInitializerToSkip(node.InputDefs()[1]->Name()); // min @@ -2311,7 +2350,9 @@ void ClipOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod model_builder.AddInitializerToSkip(node.InputDefs()[2]->Name()); // max } -Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -2354,13 +2395,14 @@ Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N class ResizeOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void ResizeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void ResizeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); // We don't really use ROI here, so add them to skipped list model_builder.AddInitializerToSkip(node.InputDefs()[1]->Name()); // ROI @@ -2372,7 +2414,8 @@ void ResizeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const N model_builder.AddInitializerToSkip(node.InputDefs()[3]->Name()); // sizes } -Status ResizeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status ResizeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -2462,10 +2505,12 @@ Status ResizeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const class FlattenOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status FlattenOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status FlattenOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto input = node.InputDefs()[0]->Name(); if (model_builder.IsOperandNHWC(input)) { // We want to transpose nhwc operand back to nchw before reshape @@ -2499,7 +2544,7 @@ class MinMaxOpBuilder : public BaseOpBuilder { bool output_is_nhwc) ORT_MUST_USE_RESULT; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; /* static */ void MinMaxOpBuilder::CreateSharedOpBuilder( @@ -2542,7 +2587,8 @@ class MinMaxOpBuilder : public BaseOpBuilder { return Status::OK(); } -Status MinMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status MinMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); std::string input1 = input_defs[0]->Name(); std::string input2 = input_defs[1]->Name(); @@ -2561,10 +2607,12 @@ Status MinMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const class EluOpBuilder : public BaseOpBuilder { private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -Status EluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status EluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); @@ -2588,13 +2636,15 @@ Status EluOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const No class SliceOpBuilder : public BaseOpBuilder { public: - void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const override; + void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const override; private: - Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const override ORT_MUST_USE_RESULT; + Status AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const override ORT_MUST_USE_RESULT; }; -void SliceOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const { +void SliceOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + // Skip everything except input0 for Slice const auto input_defs = node.InputDefs(); model_builder.AddInitializerToSkip(input_defs[1]->Name()); // starts @@ -2607,7 +2657,9 @@ void SliceOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const No } } -Status SliceOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node) const { +Status SliceOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const NodeUnit& node_unit) const { + const auto& node = node_unit.GetNode(); + auto& shaper(model_builder.GetShaper()); const auto& operand_indices(model_builder.GetOperandIndices()); const auto& operand_types(model_builder.GetOperandTypes()); diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.h b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.h index 55d1dfe627..46acbc4eff 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.h +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_builder.h @@ -3,7 +3,21 @@ #pragma once +#include +#include + +#include "core/graph/basic_types.h" +#include "core/session/onnxruntime_c_api.h" + namespace onnxruntime { + +class Node; +class NodeUnit; + +namespace common { +class Status; +} + namespace nnapi { class ModelBuilder; @@ -14,10 +28,10 @@ class IOpBuilder { // Check if the initializers of this operator need preprocess // which will not be copied - virtual void AddInitializersToSkip(ModelBuilder& model_builder, const Node& node) const = 0; + virtual void AddInitializersToSkip(ModelBuilder& model_builder, const NodeUnit& node_unit) const = 0; // Add the operator to NNAPI model - virtual Status AddToModelBuilder(ModelBuilder& model_builder, const Node& node) const ORT_MUST_USE_RESULT = 0; + virtual common::Status AddToModelBuilder(ModelBuilder& model_builder, const NodeUnit& node_unit) const ORT_MUST_USE_RESULT = 0; }; // Get the lookup table with IOpBuilder delegates for different onnx operators @@ -26,13 +40,13 @@ class IOpBuilder { const std::unordered_map& GetOpBuilders(); // Transpose the NHWC input to NCHW output -Status TransposeNHWCToNCHW(ModelBuilder& model_builder, const std::string& input, const std::string& output) +common::Status TransposeNHWCToNCHW(ModelBuilder& model_builder, const std::string& input, const std::string& output) ORT_MUST_USE_RESULT; // Get the quantized input's scale and zero point for the given input -Status GetQuantizedInputScaleAndZeroPoint(const InitializedTensorSet& initializers, - const Node& node, const std::string& input_name, - float& scale, int32_t& zero_point) ORT_MUST_USE_RESULT; +common::Status GetQuantizedInputScaleAndZeroPoint(const InitializedTensorSet& initializers, + const NodeUnit& node_unit, const std::string& input_name, + float& scale, int32_t& zero_point) ORT_MUST_USE_RESULT; } // namespace nnapi } // namespace onnxruntime diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.cc index 1486cf60cf..ca2ba5e90f 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.cc @@ -7,15 +7,17 @@ #include #include "core/providers/common.h" +#include "core/providers/shared/node_unit/node_unit.h" #include "core/providers/shared/utils/utils.h" #include "helper.h" #include "op_support_checker.h" +using onnxruntime::NodeUnit; +using std::vector; + namespace onnxruntime { namespace nnapi { -using std::vector; - #pragma region helpers struct OpSupportCheckerRegistrations { @@ -62,7 +64,7 @@ void CreateSharedOpSupportCheckerImpl(const std::string& op_type, class BaseOpSupportChecker : public IOpSupportChecker { public: virtual ~BaseOpSupportChecker() = default; - bool IsOpSupported(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupported(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; // This is for ops which are by default supported and do not have their own impl of OpSupportChecker @@ -71,26 +73,26 @@ class BaseOpSupportChecker : public IOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); protected: - virtual bool IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& /* node */, + virtual bool IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const { return true; } - virtual int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + virtual int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const { // ANEURALNETWORKS_FEATURE_LEVEL_1 is the baseline version of NNAPI, // There is no NNAPI support for Android API level 26- return ANEURALNETWORKS_FEATURE_LEVEL_1; } - virtual bool HasSupportedInputsImpl(const Node& node) const; + virtual bool HasSupportedInputsImpl(const NodeUnit& node_unit) const; - virtual int GetMinSupportedOpSet(const Node& /* node */) const { return 1; } - virtual int GetMaxSupportedOpSet(const Node& /* node */) const { return 15; } + virtual int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const { return 1; } + virtual int GetMaxSupportedOpSet(const NodeUnit& /* node_unit */) const { return 15; } private: - bool HasSupportedOpSet(const Node& node) const; - bool HasSupportedInputs(const Node& node) const; + bool HasSupportedOpSet(const NodeUnit& node_unit) const; + bool HasSupportedInputs(const NodeUnit& node_unit) const; }; /* static */ void BaseOpSupportChecker::CreateSharedOpSupportChecker( @@ -103,53 +105,70 @@ class BaseOpSupportChecker : public IOpSupportChecker { }); } -bool BaseOpSupportChecker::IsOpSupported(const InitializedTensorSet& initializers, const Node& node, +bool BaseOpSupportChecker::IsOpSupported(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { - int32_t required_feature_level = GetMinSupportedNNAPIFeatureLevel(node, params); + int32_t required_feature_level = GetMinSupportedNNAPIFeatureLevel(node_unit, params); if (required_feature_level > params.android_feature_level) { LOGS_DEFAULT(VERBOSE) << "Current Android API level [" << params.android_feature_level - << "], Operator [" << node.OpType() + << "], Operator [" << node_unit.OpType() << "] is only supported on API >" << required_feature_level; return false; } - if (!HasSupportedInputs(node)) + if (!HasSupportedInputs(node_unit)) return false; + const auto& node = node_unit.GetNode(); + // We do not support external initializers for now if (HasExternalInitializer(initializers, node)) return false; - if (!HasSupportedOpSet(node)) + if (!HasSupportedOpSet(node_unit)) return false; - return IsOpSupportedImpl(initializers, node, params); + return IsOpSupportedImpl(initializers, node_unit, params); } -bool BaseOpSupportChecker::HasSupportedInputs(const Node& node) const { +bool BaseOpSupportChecker::HasSupportedInputs(const NodeUnit& node_unit) const { // We do not support unknown(null) input shape - for (const auto* input : node.InputDefs()) { - if (!input->Shape()) { - LOGS_DEFAULT(VERBOSE) << "Node [" << node.Name() << "] type [" << node.OpType() - << "] Input [" << input->Name() << "] has no shape"; + auto has_shape = [](const NodeArg& node_arg, const std::string& name, const std::string op_type) { + if (!node_arg.Shape()) { + LOGS_DEFAULT(VERBOSE) << "Node [" << name << "] type [" << op_type + << "] Input [" << node_arg.Name() << "] has no shape"; return false; } - } + return true; + }; - return HasSupportedInputsImpl(node); + for (const auto& input : node_unit.Inputs()) { + if (!has_shape(input.node_arg, node_unit.Name(), node_unit.OpType())) + return false; + + if (input.quant_param.has_value()) { + if (!has_shape(input.quant_param->scale, node_unit.Name(), node_unit.OpType())) + return false; + + // zero point is optional + if (input.quant_param->zero_point && + !has_shape(*input.quant_param->zero_point, node_unit.Name(), node_unit.OpType())) + return false; + } + } + return HasSupportedInputsImpl(node_unit); } -bool BaseOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool BaseOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { // We only check the type of input 0 by default // specific op builder can override this - const auto& input = *node.InputDefs()[0]; + const auto& input = node_unit.Inputs()[0].node_arg; int32_t input_type; if (!GetType(input, input_type)) return false; if (input_type != ONNX_NAMESPACE::TensorProto_DataType_FLOAT) { - LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() + LOGS_DEFAULT(VERBOSE) << "[" << node_unit.OpType() << "] Input type: [" << input_type << "] is not supported for now"; return false; @@ -158,13 +177,13 @@ bool BaseOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { return true; } -bool BaseOpSupportChecker::HasSupportedOpSet(const Node& node) const { - auto since_version = node.SinceVersion(); - if (since_version < GetMinSupportedOpSet(node) || since_version > GetMaxSupportedOpSet(node)) { - LOGS_DEFAULT(VERBOSE) << node.OpType() << " opset [" << since_version +bool BaseOpSupportChecker::HasSupportedOpSet(const NodeUnit& node_unit) const { + auto since_version = node_unit.SinceVersion(); + if (since_version < GetMinSupportedOpSet(node_unit) || since_version > GetMaxSupportedOpSet(node_unit)) { + LOGS_DEFAULT(VERBOSE) << node_unit.OpType() << " opset [" << since_version << "] is only supported for opset [" - << GetMinSupportedOpSet(node) << ", " - << GetMaxSupportedOpSet(node) << "]"; + << GetMinSupportedOpSet(node_unit) << ", " + << GetMaxSupportedOpSet(node_unit) << "]"; return false; } @@ -181,11 +200,12 @@ class BinaryOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& node, const OpSupportCheckParams& params) const override; - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& node_unit, + const OpSupportCheckParams& params) const override; + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - bool HasSupportedInputsImpl(const Node& node) const override; - int GetMinSupportedOpSet(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; + int GetMinSupportedOpSet(const NodeUnit& node_unit) const override; }; /* static */ void BinaryOpSupportChecker::CreateSharedOpSupportChecker( @@ -203,8 +223,8 @@ class BinaryOpSupportChecker : public BaseOpSupportChecker { } int32_t BinaryOpSupportChecker::GetMinSupportedNNAPIFeatureLevel( - const Node& node, const OpSupportCheckParams& /* params */) const { - const auto& op(node.OpType()); + const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& op(node_unit.OpType()); if (op == "Sub" || op == "Div") { return ANEURALNETWORKS_FEATURE_LEVEL_2; } @@ -216,8 +236,8 @@ int32_t BinaryOpSupportChecker::GetMinSupportedNNAPIFeatureLevel( return ANEURALNETWORKS_FEATURE_LEVEL_1; } -int BinaryOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { - const auto& op(node.OpType()); +int BinaryOpSupportChecker::GetMinSupportedOpSet(const NodeUnit& node_unit) const { + const auto& op(node_unit.OpType()); // Add/Sub/Mul/Div/Pow opset 6- has broadcast attributes we do not support now if (op != "QLinearAdd") @@ -226,11 +246,13 @@ int BinaryOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { return 1; } -bool BinaryOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool BinaryOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { + // TODO, change to use node unit and quant_param of IODef + const auto& node = node_unit.GetNode(); bool is_qlinear_add = node.OpType() == "QLinearAdd"; bool is_pow = node.OpType() == "Pow"; if (!is_qlinear_add && !is_pow) - return BaseOpSupportChecker::HasSupportedInputsImpl(node); + return BaseOpSupportChecker::HasSupportedInputsImpl(node_unit); if (is_qlinear_add) { // QLinearAdd @@ -262,8 +284,10 @@ bool BinaryOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { return true; } -bool BinaryOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool BinaryOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); + const auto& op_type(node.OpType()); const auto input_defs(node.InputDefs()); bool op_is_qlinear = op_type == "QLinearAdd"; @@ -317,19 +341,20 @@ bool BinaryOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initi class TransposeOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_2; } - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; -bool TransposeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool TransposeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -344,14 +369,14 @@ bool TransposeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* return true; } -bool TransposeOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool TransposeOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { int32_t input_type; - if (!GetType(*node.InputDefs()[0], input_type)) + if (!GetType(node_unit.Inputs()[0].node_arg, input_type)) return false; if (input_type != ONNX_NAMESPACE::TensorProto_DataType_FLOAT && input_type != ONNX_NAMESPACE::TensorProto_DataType_UINT8) { - LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() + LOGS_DEFAULT(VERBOSE) << "[" << node_unit.OpType() << "] Input type: [" << input_type << "] is not supported for now"; return false; @@ -366,15 +391,16 @@ bool TransposeOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { class ReshapeOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; // Reshape opset 4- uses attributes for new shape which we do not support for now - int GetMinSupportedOpSet(const Node& /* node */) const override { return 5; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 5; } }; -bool ReshapeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool ReshapeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); const auto& perm_name = node.InputDefs()[1]->Name(); if (!Contains(initializers, perm_name)) { LOGS_DEFAULT(VERBOSE) << "New shape of reshape must be known"; @@ -427,15 +453,16 @@ bool ReshapeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& init class BatchNormalizationOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; // BatchNormalization opset 6- has unsupported attributes - int GetMinSupportedOpSet(const Node& /* node */) const override { return 7; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 7; } }; -bool BatchNormalizationOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool BatchNormalizationOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); if (node.OutputDefs().size() != 1) { LOGS_DEFAULT(VERBOSE) << "Your onnx model may be in training mode, please export " "it in test mode."; @@ -495,15 +522,15 @@ class PoolOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& params) const override { return params.use_nchw ? ANEURALNETWORKS_FEATURE_LEVEL_3 : ANEURALNETWORKS_FEATURE_LEVEL_2; } - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; /* static */ void PoolOpSupportChecker::CreateSharedOpSupportChecker( @@ -519,8 +546,9 @@ class PoolOpSupportChecker : public BaseOpSupportChecker { }); } -bool PoolOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool PoolOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); const auto& op_name = node.Name(); const auto& op_type = node.OpType(); const auto& input_defs = node.InputDefs(); @@ -652,11 +680,13 @@ bool PoolOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initial return true; } -bool PoolOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool PoolOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { + // TODO, change to use node unit and quant_param of IODef + const auto& node = node_unit.GetNode(); bool is_max_pool = node.OpType() == "MaxPool"; bool is_qlinear_average_pool = node.OpType() == "QLinearAveragePool"; if (!is_max_pool && !is_qlinear_average_pool) - return BaseOpSupportChecker::HasSupportedInputsImpl(node); + return BaseOpSupportChecker::HasSupportedInputsImpl(node_unit); if (is_qlinear_average_pool) { return HasValidUnaryOpQuantizedInputs(node); @@ -689,15 +719,15 @@ class ConvOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& params) const override { return params.use_nchw ? ANEURALNETWORKS_FEATURE_LEVEL_3 : ANEURALNETWORKS_FEATURE_LEVEL_2; } - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; /* static */ void ConvOpSupportChecker::CreateSharedOpSupportChecker( @@ -710,9 +740,11 @@ class ConvOpSupportChecker : public BaseOpSupportChecker { }); } -bool ConvOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool ConvOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { + // TODO, change to use node unit and quant_param of IODef + const auto& node = node_unit.GetNode(); if (node.OpType() != "QLinearConv") - return BaseOpSupportChecker::HasSupportedInputsImpl(node); + return BaseOpSupportChecker::HasSupportedInputsImpl(node_unit); // QLinearConv only supports input of uint8 for now if (!HasValidBinaryOpQuantizedInputs(node)) @@ -721,8 +753,9 @@ bool ConvOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { return true; } -bool ConvOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool ConvOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); const auto& op_type = node.OpType(); const bool is_qlinear_conv = (op_type == "QLinearConv"); @@ -798,20 +831,21 @@ bool ConvOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initial class CastOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_3; } // Cast opset 5- uses string attribute for to type, is not supported for now - int GetMinSupportedOpSet(const Node& /* node */) const override { return 6; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 6; } }; -bool CastOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool CastOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); NodeAttrHelper helper(node); const auto to = helper.Get("to", 0); if (to != ONNX_NAMESPACE::TensorProto::FLOAT && @@ -829,17 +863,18 @@ bool CastOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* init class SoftMaxOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_2; } }; -bool SoftMaxOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool SoftMaxOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -875,15 +910,17 @@ class GemmOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - bool HasSupportedInputsImpl(const Node& node) const override; - int GetMinSupportedOpSet(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; + int GetMinSupportedOpSet(const NodeUnit& node_unit) const override; }; -bool GemmOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool GemmOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { + // TODO, change to use node unit and quant_param of IODef + const auto& node = node_unit.GetNode(); if (node.OpType() != "QLinearMatMul") - return BaseOpSupportChecker::HasSupportedInputsImpl(node); + return BaseOpSupportChecker::HasSupportedInputsImpl(node_unit); // QLinearMatMul if (!HasValidBinaryOpQuantizedInputs(node)) @@ -936,8 +973,8 @@ static bool GetBiasSize(const Shape& c_shape, int32_t android_feature_level, uin return true; } -int GemmOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { - const auto& op(node.OpType()); +int GemmOpSupportChecker::GetMinSupportedOpSet(const NodeUnit& node_unit) const { + const auto& op(node_unit.OpType()); // Gemm opset 6- has broadcast attributes we do not support now if (op == "Gemm") @@ -946,8 +983,9 @@ int GemmOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { return 1; } -bool GemmOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool GemmOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); const auto& op_type = node.OpType(); const auto input_defs(node.InputDefs()); size_t a_idx = 0, b_idx = 1, c_idx = 2; // A*B+C @@ -1068,15 +1106,15 @@ class UnaryOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& node, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& params) const override; - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; - int GetMinSupportedOpSet(const Node& node) const override; + int GetMinSupportedOpSet(const NodeUnit& node_unit) const override; static bool IsQuantizedOpSupported(const InitializedTensorSet& initializers, const Node& node, const OpSupportCheckParams& params); @@ -1100,17 +1138,18 @@ class UnaryOpSupportChecker : public BaseOpSupportChecker { }); } -bool UnaryOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool UnaryOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); if (node.OpType() == "QLinearSigmoid") return IsQuantizedOpSupported(initializers, node, params); else // Everything except "QLinearSigmoid" are by default supported return true; } -int32_t UnaryOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const Node& node, +int32_t UnaryOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { - const auto& op(node.OpType()); + const auto& op(node_unit.OpType()); if (op == "Abs" || op == "Exp" || op == "Neg" || @@ -1123,10 +1162,12 @@ int32_t UnaryOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const Node& node return ANEURALNETWORKS_FEATURE_LEVEL_1; } -bool UnaryOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool UnaryOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { + // TODO, change to use node unit and quant_param of IODef + const auto& node = node_unit.GetNode(); // We only need to override input check for QLinearSigmoid if (node.OpType() != "QLinearSigmoid") - return BaseOpSupportChecker::HasSupportedInputsImpl(node); + return BaseOpSupportChecker::HasSupportedInputsImpl(node_unit); return HasValidUnaryOpQuantizedInputs(node); } @@ -1134,8 +1175,8 @@ bool UnaryOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { // All ops except "Sin" opset 5- uses consumed_inputs attribute which is not supported for now // "Sin" op has support from opset 7, return 6 here for all ops // "QLinearSigmoid" is a contrib op, OpSet will always be 1 -int UnaryOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { - if (node.OpType() == "QLinearSigmoid") +int UnaryOpSupportChecker::GetMinSupportedOpSet(const NodeUnit& node_unit) const { + if (node_unit.OpType() == "QLinearSigmoid") return 1; return 6; @@ -1205,14 +1246,15 @@ int UnaryOpSupportChecker::GetMinSupportedOpSet(const Node& node) const { class ConcatOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; -bool ConcatOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool ConcatOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -1227,14 +1269,14 @@ bool ConcatOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* in return true; } -bool ConcatOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool ConcatOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { int32_t input_type; - if (!GetType(*node.InputDefs()[0], input_type)) + if (!GetType(node_unit.Inputs()[0].node_arg, input_type)) return false; if (input_type != ONNX_NAMESPACE::TensorProto_DataType_FLOAT && input_type != ONNX_NAMESPACE::TensorProto_DataType_UINT8) { - LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() + LOGS_DEFAULT(VERBOSE) << "[" << node_unit.OpType() << "] Input type: [" << input_type << "] is not supported for now"; return false; @@ -1249,17 +1291,18 @@ bool ConcatOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { class SqueezeOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_2; } }; -bool SqueezeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool SqueezeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -1289,17 +1332,18 @@ bool SqueezeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& init class QuantizeLinearOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_3; } }; -bool QuantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool QuantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); const auto output_defs(node.OutputDefs()); @@ -1331,18 +1375,19 @@ bool QuantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSe class DequantizeLinearOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_1; } - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; -bool DequantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool DequantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); const auto input_defs(node.InputDefs()); if (!HasValidQuantizationScales(initializers, node, {1}, params)) return false; @@ -1355,13 +1400,13 @@ bool DequantizeLinearOpSupportChecker::IsOpSupportedImpl(const InitializedTensor return true; } -bool DequantizeLinearOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool DequantizeLinearOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { int32_t input_type; - if (!GetType(*node.InputDefs()[0], input_type)) + if (!GetType(node_unit.Inputs()[0].node_arg, input_type)) return false; if (input_type != ONNX_NAMESPACE::TensorProto_DataType_UINT8) { - LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() + LOGS_DEFAULT(VERBOSE) << "[" << node_unit.OpType() << "] Input type: [" << input_type << "] is not supported for now"; return false; @@ -1376,17 +1421,18 @@ bool DequantizeLinearOpSupportChecker::HasSupportedInputsImpl(const Node& node) class LRNOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_2; } }; -bool LRNOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool LRNOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -1407,12 +1453,13 @@ bool LRNOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initi class ClipOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; }; -bool ClipOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool ClipOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); float min, max; if (!GetClipMinMax(initializers, node, min, max, logging::LoggingManager::DefaultLogger())) return false; @@ -1434,21 +1481,22 @@ bool ClipOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initial class ResizeOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override; // Resize opset 10- is very different than Resize opset 11+, with many key attributes missing // We only support Resize opset 11+ here - int GetMinSupportedOpSet(const Node& /* node */) const override { return 11; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 11; } - bool HasSupportedInputsImpl(const Node& node) const override; + bool HasSupportedInputsImpl(const NodeUnit& node_unit) const override; }; -bool ResizeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool ResizeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -1569,12 +1617,12 @@ bool ResizeOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initi return true; } -int32_t ResizeOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const Node& node, +int32_t ResizeOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { int32_t input_type; // This should not happen, but if it happens make sure this will require an impossible version - if (!GetType(*node.InputDefs()[0], input_type)) + if (!GetType(node_unit.Inputs()[0].node_arg, input_type)) return std::numeric_limits::max(); if (input_type != ONNX_NAMESPACE::TensorProto_DataType_UINT8) @@ -1583,14 +1631,14 @@ int32_t ResizeOpSupportChecker::GetMinSupportedNNAPIFeatureLevel(const Node& nod return ANEURALNETWORKS_FEATURE_LEVEL_2; } -bool ResizeOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { +bool ResizeOpSupportChecker::HasSupportedInputsImpl(const NodeUnit& node_unit) const { int32_t input_type; - if (!GetType(*node.InputDefs()[0], input_type)) + if (!GetType(node_unit.Inputs()[0].node_arg, input_type)) return false; if (input_type != ONNX_NAMESPACE::TensorProto_DataType_FLOAT && input_type != ONNX_NAMESPACE::TensorProto_DataType_UINT8) { - LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() + LOGS_DEFAULT(VERBOSE) << "[" << node_unit.OpType() << "] Input type: [" << input_type << "] is not supported for now"; return false; @@ -1605,12 +1653,13 @@ bool ResizeOpSupportChecker::HasSupportedInputsImpl(const Node& node) const { class FlattenOpSupportChecker : public BaseOpSupportChecker { private: - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; }; -bool FlattenOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool FlattenOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; @@ -1644,15 +1693,15 @@ class MinMaxOpSupportChecker : public BaseOpSupportChecker { const std::string& op_type, OpSupportCheckerRegistrations& op_registrations); private: - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_3; } // Min/Max opset 5- uses consumed_inputs attribute which is not supported for now - int GetMinSupportedOpSet(const Node& /* node */) const override { return 6; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 6; } - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; }; @@ -1666,8 +1715,9 @@ class MinMaxOpSupportChecker : public BaseOpSupportChecker { }); } -bool MinMaxOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const Node& node, +bool MinMaxOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); // TODO support 2+ inputs for Min/Max op if (node.InputDefs().size() != 2) { LOGS_DEFAULT(VERBOSE) << "[" << node.OpType() << "] only supports 2 inputs, " @@ -1684,13 +1734,13 @@ bool MinMaxOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& /* in class EluOpSupportChecker : public BaseOpSupportChecker { private: - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_4; } // Elu opset 5- uses consumed_inputs attribute which is not supported for now - int GetMinSupportedOpSet(const Node& /* node */) const override { return 6; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 6; } }; #pragma endregion @@ -1699,20 +1749,21 @@ class EluOpSupportChecker : public BaseOpSupportChecker { class SliceOpSupportChecker : public BaseOpSupportChecker { private: - int32_t GetMinSupportedNNAPIFeatureLevel(const Node& /* node */, + int32_t GetMinSupportedNNAPIFeatureLevel(const NodeUnit& /* node_unit */, const OpSupportCheckParams& /* params */) const override { return ANEURALNETWORKS_FEATURE_LEVEL_2; } // We only support slice from opset 10 - int GetMinSupportedOpSet(const Node& /* node */) const override { return 10; } + int GetMinSupportedOpSet(const NodeUnit& /* node_unit */) const override { return 10; } - bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, + bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& params) const override; }; -bool SliceOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node, +bool SliceOpSupportChecker::IsOpSupportedImpl(const InitializedTensorSet& initializers, const NodeUnit& node_unit, const OpSupportCheckParams& /* params */) const { + const auto& node = node_unit.GetNode(); Shape input_shape; if (!GetShape(*node.InputDefs()[0], input_shape)) return false; diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.h b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.h index 24fa96e71c..049a239222 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.h +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/op_support_checker.h @@ -6,6 +6,9 @@ #include "helper.h" namespace onnxruntime { + +class NodeUnit; + namespace nnapi { struct OpSupportCheckParams { @@ -23,7 +26,8 @@ class IOpSupportChecker { virtual ~IOpSupportChecker() = default; // Check if an operator is supported - virtual bool IsOpSupported(const InitializedTensorSet& initializers, const Node& node, const OpSupportCheckParams& params) const = 0; + virtual bool IsOpSupported(const InitializedTensorSet& initializers, const NodeUnit& node_unit, + const OpSupportCheckParams& params) const = 0; }; // Get the lookup table with IOpSupportChecker delegates for different onnx operators diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc index 6f7a0433ba..fa876a7ef6 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.cc @@ -13,6 +13,7 @@ #include "core/providers/nnapi/nnapi_builtin/builders/op_support_checker.h" #include "core/providers/nnapi/nnapi_builtin/nnapi_lib/nnapi_implementation.h" #include "core/providers/partitioning_utils.h" +#include "core/providers/shared/node_unit/node_unit.h" #include "core/session/onnxruntime_cxx_api.h" #ifdef __ANDROID__ @@ -20,6 +21,8 @@ #include "core/providers/nnapi/nnapi_builtin/model.h" #endif +using onnxruntime::NodeUnit; + namespace onnxruntime { namespace { @@ -123,12 +126,14 @@ NnapiExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_view const auto is_node_supported = [&](const Node& node) -> bool { const bool excluded = check_excluded_nodes && Contains(excluded_nodes, &node); + // TODO, cache NodeUnit(s) and not generate new instance every time + const NodeUnit node_unit(node); const bool supported = !excluded && - nnapi::IsNodeSupportedInGroup(node, graph_viewer, params, + nnapi::IsNodeSupportedInGroup(node_unit, graph_viewer, params, node_outputs_in_current_group); - LOGS_DEFAULT(VERBOSE) << "Operator type: [" << node.OpType() - << "] index: [" << node.Index() - << "] name: [" << node.Name() + LOGS_DEFAULT(VERBOSE) << "Operator type: [" << node_unit.OpType() + << "] index: [" << node_unit.Index() + << "] name: [" << node_unit.Name() << "] supported: [" << supported << "]"; diff --git a/onnxruntime/core/providers/shared/node_unit/node_unit.cc b/onnxruntime/core/providers/shared/node_unit/node_unit.cc new file mode 100644 index 0000000000..80492ce701 --- /dev/null +++ b/onnxruntime/core/providers/shared/node_unit/node_unit.cc @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "node_unit.h" +#include "core/graph/graph.h" + +namespace onnxruntime { + +NodeUnit::NodeUnit(const Node& node) + : nodes_{&node}, + node_(node), + type_(Type::SingleNode) { + InitForNode(); +} + +const std::string& NodeUnit::Domain() const noexcept { return node_.Domain(); } +const std::string& NodeUnit::OpType() const noexcept { return node_.OpType(); } +const std::string& NodeUnit::Name() const noexcept { return node_.Name(); } +int NodeUnit::SinceVersion() const noexcept { return node_.SinceVersion(); } +NodeIndex NodeUnit::Index() const noexcept { return node_.Index(); } +const Path& NodeUnit::ModelPath() const noexcept { return node_.ModelPath(); } +ProviderType NodeUnit::GetExecutionProviderType() const noexcept { return node_.GetExecutionProviderType(); } + +void NodeUnit::InitForNode() { + const auto& input_defs = node_.InputDefs(); + const auto& output_defs = node_.OutputDefs(); + // The 1st step is to hookup the NodeUnit with the NNAPI builder interface + // So we are not handling quantization here now + // TODO, enable quantization + // auto qlinear_type = GetQLinearOpType(node_); + // if (qlinear_type == QLinearOpType::Unknown) { + // Not a Qlinear op, add all inputs/outputs + auto add_all_io = [](std::vector& defs, + const ConstPointerContainer>& node_defs) { + defs.reserve(node_defs.size()); + + for (const auto def : node_defs) { + defs.push_back(NodeUnit::IODef{*def, std::nullopt}); + } + }; + add_all_io(input_defs_, input_defs); + add_all_io(output_defs_, output_defs); +} + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/shared/node_unit/node_unit.h b/onnxruntime/core/providers/shared/node_unit/node_unit.h new file mode 100644 index 0000000000..d94b0e2fc5 --- /dev/null +++ b/onnxruntime/core/providers/shared/node_unit/node_unit.h @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include +#include +#include + +#include "core/graph/basic_types.h" + +namespace onnxruntime { + +class Graph; +class GraphViewer; +class Node; +class NodeArg; +class Path; + +namespace QDQ { +struct NodeGroup; +} + +/** +@class NodeUnit +Class to represent a single node or a QDQ group of nodes, which will be used as a single unit. +*/ +class NodeUnit { + public: + // NodeUnit type + enum class Type : uint8_t { + SingleNode, // The NodeUnit contains a single node + QDQGroup, // The NodeUnit contain a QDQ group of nodes, such as "DQ->Sigmoid->Q" + }; + + // Definition of one input or output + // If the optional quant_param is present, then this is a quantized input, + // otherwise this is a regular input + struct IODef { + // The quantization parmeter, scale is manadatory, and zero_point is optional + struct QuantParam { + const NodeArg& scale; + const NodeArg* zero_point{nullptr}; + }; + + const NodeArg& node_arg; + const std::optional quant_param; + }; + + public: + explicit NodeUnit(const Node& node); + + Type UnitType() const noexcept { return type_; } + + const std::vector& Inputs() const noexcept { return input_defs_; } + const std::vector& Outputs() const noexcept { return output_defs_; } + + const std::string& Domain() const noexcept; + const std::string& OpType() const noexcept; + const std::string& Name() const noexcept; + int SinceVersion() const noexcept; + NodeIndex Index() const noexcept; + const Path& ModelPath() const noexcept; + ProviderType GetExecutionProviderType() const noexcept; + + const Node& GetNode() const noexcept { return node_; } + + const std::vector GetAllNodes() const noexcept { return nodes_; } + + private: + std::vector input_defs_; + std::vector output_defs_; + + const std::vector nodes_; // all nodes in this NodeUnit + const Node& node_; // target Node + Type type_; + + void InitForNode(); // Initializing for single Node +}; + +} // namespace onnxruntime From d42feae042c3078cdf93b10865f78edf1a8c6a50 Mon Sep 17 00:00:00 2001 From: Faith Xu Date: Thu, 16 Dec 2021 19:56:21 -0800 Subject: [PATCH 061/113] Add citation file (#10061) * Add citation file * Fix typos --- CITATION.cff | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000000..2a9c47093a --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,15 @@ +cff-version: 1.2.0 +title: ONNX Runtime +message: "Please use this information to cite ONNX Runtime in + research or other publications." +authors: + - affiliation: Microsoft Corporation + given-names: ONNX Runtime developers +title: "ONNX Runtime" +date-released: 2018-11-29 +url: "https://onnxruntime.ai" +repository-code: "https://github.com/microsoft/onnxruntime" +license: "MIT License" +keywords: + - deep learning + - machine learning From 4fd85cd97a82e2bf76e84425861deb99a42f9585 Mon Sep 17 00:00:00 2001 From: Moshe David Date: Fri, 17 Dec 2021 19:00:33 +0200 Subject: [PATCH 062/113] Fix broken link to TRT doc in exception details (#9496) Co-authored-by: Moshe --- .../core/providers/tensorrt/tensorrt_execution_provider.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc index ef06f69880..3f0751151f 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc @@ -926,7 +926,7 @@ SubGraphCollection_t TensorrtExecutionProvider::GetSupportedList(SubGraphCollect ORT_THROW_IF_ERROR(ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "TensorRT input: " + input_arg->Name() + " has no shape specified. " + "Please run shape inference on the onnx model first. Details can be found in " + - "https://www.onnxruntime.ai/docs/reference/execution-providers/TensorRT-ExecutionProvider.html#shape-inference-for-tensorrt-subgraphs")); + "https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#shape-inference-for-tensorrt-subgraphs")); } } } From 12ee2e942f4626d55f07725e4aaa0b8b346d5279 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Fri, 17 Dec 2021 15:36:09 -0800 Subject: [PATCH 063/113] add int8_t for Resize (#10067) As we support quantization for format s8s8, we need Resize to support int8_t. --- docs/OperatorKernels.md | 10 +-- .../providers/cpu/cpu_execution_provider.cc | 15 ++++ .../core/providers/cpu/tensor/resize.cc | 22 ++++++ .../core/providers/cpu/tensor/upsample.cc | 2 + .../providers/cpu/tensor/resize_op_test.cc | 68 +++++++++++++++++++ .../testdata/kernel_def_hashes/onnx.cpu.json | 20 ++++++ 6 files changed, 132 insertions(+), 5 deletions(-) diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md index 6f09fb5026..ee92269f1b 100644 --- a/docs/OperatorKernels.md +++ b/docs/OperatorKernels.md @@ -265,9 +265,9 @@ Do not modify directly.* |||13|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**shape** = tensor(int64)| |||[5, 12]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**shape** = tensor(int64)| |||[1, 4]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| -|Resize|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**

or

*in* X:**T1**
*in* roi:**T2**
*in* scales:**tensor(float)**
*in* sizes:**tensor(int64)**
*out* Y:**T1**|13+|**T1** = tensor(float), tensor(int32), tensor(uint8)| -|||[11, 12]|**T1** = tensor(float), tensor(int32), tensor(uint8)| -|||10|**T** = tensor(float), tensor(int32), tensor(uint8)| +|Resize|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**

or

*in* X:**T1**
*in* roi:**T2**
*in* scales:**tensor(float)**
*in* sizes:**tensor(int64)**
*out* Y:**T1**|13+|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)| +|||[11, 12]|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)| +|||10|**T** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)| |ReverseSequence|*in* input:**T**
*in* sequence_lens:**tensor(int64)**
*out* Y:**T**|10+|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| |RoiAlign|*in* X:**T1**
*in* rois:**T1**
*in* batch_indices:**T2**
*out* Y:**T1**|10+|**T** = tensor(double), tensor(float)
**T2** = tensor(int64)| |Round|*in* X:**T**
*out* Y:**T**|11+|**T** = tensor(double), tensor(float), tensor(float16)| @@ -346,8 +346,8 @@ Do not modify directly.* |Unsqueeze|*in* data:**T**
*in* axes:**tensor(int64)**
*out* expanded:**T**

or

*in* data:**T**
*out* expanded:**T**|13+|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| |||[11, 12]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| |||[1, 10]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| -|Upsample|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**

or

*in* X:**T**
*out* Y:**T**|9|**T** = tensor(float), tensor(int32), tensor(uint8)| -|||[7, 8]|**T** = tensor(float), tensor(int32), tensor(uint8)| +|Upsample|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**

or

*in* X:**T**
*out* Y:**T**|9|**T** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)| +|||[7, 8]|**T** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)| |Where|*in* condition:**B**
*in* X:**T**
*in* Y:**T**
*out* output:**T**|9+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(string), tensor(uint8)| |Xor|*in* A:**T**
*in* B:**T**
*out* C:**T1**|7+|**T** = tensor(bool)
**T1** = tensor(bool)| | | diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index c2fad48e06..1732170145 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -219,6 +219,7 @@ class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDoma class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 10, Unsqueeze); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 8, float, Upsample); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 8, int32_t, Upsample); +class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 8, int8_t, Upsample); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 8, uint8_t, Upsample); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, 12, float, Expand); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, 12, double, Expand); @@ -298,6 +299,7 @@ class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOn class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, PRelu); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, float, Upsample); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, int32_t, Upsample); +class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, int8_t, Upsample); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, uint8_t, Upsample); // Opset 10 @@ -308,6 +310,7 @@ class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDoma class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 12, Mod); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, float, Resize); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, int32_t, Resize); +class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, int8_t, Resize); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, uint8_t, Resize); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, ThresholdedRelu); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 12, uint8_t, DequantizeLinear); @@ -442,6 +445,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, int64_t_float_int32_t, OneHot); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, 12, float, Resize); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, 12, int32_t, Resize); +class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, 12, int8_t, Resize); class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, 12, uint8_t, Resize); // opset 12 @@ -659,6 +663,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, int64_t, ReduceSum); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, float, Resize); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, int32_t, Resize); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, int8_t, Resize); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, uint8_t, Resize); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, 15, Loop); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 13, 15, If); @@ -1042,6 +1047,8 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { float, Upsample)>, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -1201,6 +1210,8 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { float, Resize)>, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -1366,6 +1377,8 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { float, Resize)>, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, diff --git a/onnxruntime/core/providers/cpu/tensor/resize.cc b/onnxruntime/core/providers/cpu/tensor/resize.cc index 03468d6b97..6ff605b7a3 100644 --- a/onnxruntime/core/providers/cpu/tensor/resize.cc +++ b/onnxruntime/core/providers/cpu/tensor/resize.cc @@ -21,6 +21,14 @@ ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Resize); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + Resize, + 10, + 10, + int8_t, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), + Resize); + ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( Resize, 10, @@ -43,6 +51,13 @@ ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()), Resize); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + Resize, + 11, 12, + int8_t, + KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()), + Resize); + ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( Resize, 11, 12, @@ -64,6 +79,13 @@ ONNX_CPU_OPERATOR_TYPED_KERNEL( KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()), Resize); +ONNX_CPU_OPERATOR_TYPED_KERNEL( + Resize, + 13, + int8_t, + KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()), + Resize); + ONNX_CPU_OPERATOR_TYPED_KERNEL( Resize, 13, diff --git a/onnxruntime/core/providers/cpu/tensor/upsample.cc b/onnxruntime/core/providers/cpu/tensor/upsample.cc index af6ef46d09..55422654ff 100644 --- a/onnxruntime/core/providers/cpu/tensor/upsample.cc +++ b/onnxruntime/core/providers/cpu/tensor/upsample.cc @@ -20,11 +20,13 @@ namespace onnxruntime { REGISTER_VERSIONED_TYPED_KERNEL(float, 7, 8); REGISTER_VERSIONED_TYPED_KERNEL(int32_t, 7, 8); +REGISTER_VERSIONED_TYPED_KERNEL(int8_t, 7, 8); REGISTER_VERSIONED_TYPED_KERNEL(uint8_t, 7, 8); // Upsample was deprecated in opset 10 REGISTER_VERSIONED_TYPED_KERNEL(float, 9, 9); REGISTER_VERSIONED_TYPED_KERNEL(int32_t, 9, 9); +REGISTER_VERSIONED_TYPED_KERNEL(int8_t, 9, 9); REGISTER_VERSIONED_TYPED_KERNEL(uint8_t, 9, 9); template diff --git a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc index 96556f8e8d..6a9b8fb06e 100644 --- a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc @@ -1224,5 +1224,73 @@ TEST(ResizeOpTest, ResizeOp_MissingRoiAndMissingScalesOptionalInputs) { test.AddOutput("Y", {H, W}, X); test.Run(); } + +template +void ResizeOpTypeCheck_Ver_10() { + OpTester test("Resize", 10); + std::vector scales{1.0f, 1.0f, 2.0f, 3.0f}; + + test.AddAttribute("mode", "nearest"); + + constexpr int64_t N = 1, C = 1, H = 2, W = 2; + std::vector X = {1, 2, 3, 4}; + + test.AddInput("X", {N, C, H, W}, X); + test.AddInput("scales", {4}, scales); + + std::vector Y = {1, 1, 1, 2, 2, 2, + 1, 1, 1, 2, 2, 2, + 3, 3, 3, 4, 4, 4, + 3, 3, 3, 4, 4, 4}; + + test.AddOutput("Y", {N, C, static_cast(H * scales[2]), static_cast(W * scales[3])}, Y); + test.Run(); +} + +TEST(ResizeOpTest, ResizeOpTypeCheck_Ver_10) { + ResizeOpTypeCheck_Ver_10(); + ResizeOpTypeCheck_Ver_10(); + ResizeOpTypeCheck_Ver_10(); + ResizeOpTypeCheck_Ver_10(); +} + +template +void ResizeOpTypeCheck_Ver_11_13(int opset_version) { + OpTester test("Resize", opset_version); + std::vector roi{}; + std::vector scales{1.0f, 1.0f, 2.0f, 3.0f}; + + test.AddAttribute("mode", "nearest"); + + constexpr int64_t N = 1, C = 1, H = 2, W = 2; + std::vector X = {1, 2, 3, 4}; + + test.AddInput("X", {N, C, H, W}, X); + test.AddInput("roi", {0}, roi); + test.AddInput("scales", {4}, scales); + + std::vector Y = {1, 1, 1, 2, 2, 2, + 1, 1, 1, 2, 2, 2, + 3, 3, 3, 4, 4, 4, + 3, 3, 3, 4, 4, 4}; + + test.AddOutput("Y", {N, C, static_cast(H * scales[2]), static_cast(W * scales[3])}, Y); + test.Run(); +} + +TEST(ResizeOpTest, ResizeOpTypeCheck_Ver11) { + ResizeOpTypeCheck_Ver_11_13(11); + ResizeOpTypeCheck_Ver_11_13(11); + ResizeOpTypeCheck_Ver_11_13(11); + ResizeOpTypeCheck_Ver_11_13(11); +} + +TEST(ResizeOpTest, ResizeOpTypeCheck_Ver13) { + ResizeOpTypeCheck_Ver_11_13(13); + ResizeOpTypeCheck_Ver_11_13(13); + ResizeOpTypeCheck_Ver_11_13(13); + ResizeOpTypeCheck_Ver_11_13(13); +} + } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json b/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json index 9de2bbd54c..41027eff75 100644 --- a/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json +++ b/onnxruntime/test/testdata/kernel_def_hashes/onnx.cpu.json @@ -2095,6 +2095,18 @@ "Resize ai.onnx CPUExecutionProvider", 16654410418270805888 ], + [ + "Resize ai.onnx CPUExecutionProvider", + 11612050915202267528 + ], + [ + "Resize ai.onnx CPUExecutionProvider", + 17391179092212899176 + ], + [ + "Resize ai.onnx CPUExecutionProvider", + 18197536715869401872 + ], [ "ReverseSequence ai.onnx CPUExecutionProvider", 777686786711298232 @@ -2543,6 +2555,14 @@ "Upsample ai.onnx CPUExecutionProvider", 17854969343220970496 ], + [ + "Upsample ai.onnx CPUExecutionProvider", + 4881414272874428968 + ], + [ + "Upsample ai.onnx CPUExecutionProvider", + 7886741677344006832 + ], [ "Where ai.onnx CPUExecutionProvider", 4809895774227191528 From cdbd678192b09655a14d63bc7f5f9005176cf5ea Mon Sep 17 00:00:00 2001 From: ashari4 <70242157+ashari4@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:55:15 -0800 Subject: [PATCH 064/113] Check kMSDomain already exists before registering it (#10078) * Check domain before registration --- onnxruntime/core/session/environment.cc | 13 +++++++++---- .../orttraining/core/graph/training_op_defs.cc | 11 ++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/onnxruntime/core/session/environment.cc b/onnxruntime/core/session/environment.cc index 54fc2e75eb..89b1559c9d 100644 --- a/onnxruntime/core/session/environment.cc +++ b/onnxruntime/core/session/environment.cc @@ -212,11 +212,16 @@ Status Environment::Initialize(std::unique_ptr logging_ #if !defined(ORT_MINIMAL_BUILD) // Register Microsoft domain with min/max op_set version as 1/1. std::call_once(schemaRegistrationOnceFlag, []() { - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSNchwcDomain, 1, 1); + auto& domainToVersionRangeInstance = ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance(); + if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) + { + // External shared providers may have already added kMSDomain + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); + } + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSNchwcDomain, 1, 1); #ifdef USE_DML - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSDmlDomain, 1, 1); + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSDmlDomain, 1, 1); #endif // Register contributed schemas. // The corresponding kernels are registered inside the appropriate execution provider. diff --git a/orttraining/orttraining/core/graph/training_op_defs.cc b/orttraining/orttraining/core/graph/training_op_defs.cc index a0b9f707e3..b293a748a5 100644 --- a/orttraining/orttraining/core/graph/training_op_defs.cc +++ b/orttraining/orttraining/core/graph/training_op_defs.cc @@ -3444,9 +3444,14 @@ Return true if all elements are true and false otherwise. } // namespace training void RegisterOrtOpSchemas() { - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); - ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance().AddDomainToVersion(onnxruntime::kMSNchwcDomain, 1, 1); + auto& domainToVersionRangeInstance = ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance(); + if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) + { + // External shared providers may have already added kMSDomain + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); + } + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); + domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSNchwcDomain, 1, 1); onnxruntime::contrib::RegisterContribSchemas(); onnxruntime::training::RegisterTrainingOpSchemas(); From bd4fb4c5da0e774e5b7272a133904a31b7d60bfc Mon Sep 17 00:00:00 2001 From: satyajandhyala Date: Sat, 18 Dec 2021 12:05:48 -0800 Subject: [PATCH 065/113] Coding style fix. (#10080) --- onnxruntime/core/session/environment.cc | 7 +++---- orttraining/orttraining/core/graph/training_op_defs.cc | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/onnxruntime/core/session/environment.cc b/onnxruntime/core/session/environment.cc index 89b1559c9d..563159ca93 100644 --- a/onnxruntime/core/session/environment.cc +++ b/onnxruntime/core/session/environment.cc @@ -119,7 +119,7 @@ Status Environment::CreateAndRegisterAllocator(const OrtMemoryInfo& mem_info, co // We use these allocators instead of the arena create_arena = false; #elif !(defined(__amd64__) || defined(_M_AMD64)) - //Disable Arena allocator for x86_32 build because it may run into infinite loop when integer overflow happens + // Disable Arena allocator for x86_32 build because it may run into infinite loop when integer overflow happens create_arena = false; #endif @@ -213,9 +213,8 @@ Status Environment::Initialize(std::unique_ptr logging_ // Register Microsoft domain with min/max op_set version as 1/1. std::call_once(schemaRegistrationOnceFlag, []() { auto& domainToVersionRangeInstance = ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance(); - if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) - { - // External shared providers may have already added kMSDomain + if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) { + // External shared providers may have already added kMSDomain domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); } domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); diff --git a/orttraining/orttraining/core/graph/training_op_defs.cc b/orttraining/orttraining/core/graph/training_op_defs.cc index b293a748a5..d732f0b4ae 100644 --- a/orttraining/orttraining/core/graph/training_op_defs.cc +++ b/orttraining/orttraining/core/graph/training_op_defs.cc @@ -3445,9 +3445,8 @@ Return true if all elements are true and false otherwise. void RegisterOrtOpSchemas() { auto& domainToVersionRangeInstance = ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance(); - if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) - { - // External shared providers may have already added kMSDomain + if (domainToVersionRangeInstance.Map().find(onnxruntime::kMSDomain) == domainToVersionRangeInstance.Map().end()) { + // External shared providers may have already added kMSDomain domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSDomain, 1, 1); } domainToVersionRangeInstance.AddDomainToVersion(onnxruntime::kMSExperimentalDomain, 1, 1); From 4e9e01cb3c008335a2471c27dbdf7dd5d12e4224 Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Sun, 19 Dec 2021 20:54:29 -0800 Subject: [PATCH 066/113] Fix SDL warnings in CPU EP (#9975) --- cmake/CMakeLists.txt | 9 +- cmake/EnableVisualStudioCodeAnalysis.props | 12 + cmake/Sdl.ruleset | 268 ++++++++++++++++++ cmake/onnxruntime_common.cmake | 5 - cmake/onnxruntime_graph.cmake | 5 +- cmake/onnxruntime_mlas.cmake | 3 + cmake/onnxruntime_providers.cmake | 4 + cmake/onnxruntime_unittests.cmake | 29 +- include/onnxruntime/core/common/common.h | 8 +- .../onnxruntime/core/common/gsl_suppress.h | 15 + include/onnxruntime/core/common/status.h | 36 +-- .../core/framework/kernel_def_builder.h | 6 +- .../core/framework/kernel_registry.h | 2 +- .../onnxruntime/core/framework/op_kernel.h | 18 +- .../core/framework/op_kernel_info.h | 4 - include/onnxruntime/core/graph/basic_types.h | 5 +- include/onnxruntime/core/graph/graph.h | 30 +- include/onnxruntime/core/graph/node_arg.h | 4 +- .../platform/EigenNonBlockingThreadPool.h | 2 +- .../onnxruntime/core/session/environment.h | 12 +- .../core/session/onnxruntime_c_api.h | 1 + .../core/session/onnxruntime_cxx_api.h | 8 +- onnxruntime/contrib_ops/cpu/activations.h | 2 +- .../cpu/attnlstm/bahdanau_attention.cc | 3 +- .../cpu/attnlstm/deep_cpu_attn_lstm.cc | 1 + .../cpu/attnlstm/uni_dir_attn_lstm.cc | 1 + .../contrib_ops/cpu/bert/attention_cpu_base.h | 1 + .../contrib_ops/cpu/crop_and_resize.cc | 1 + onnxruntime/contrib_ops/cpu/nchwc_ops.cc | 6 +- .../cpu/quantization/qlinear_pool.cc | 12 +- onnxruntime/contrib_ops/cpu/tokenizer.cc | 4 +- .../cpu/transformers/beam_search.cc | 8 +- .../cpu/transformers/beam_search_scorer.cc | 7 +- .../cpu/transformers/gpt_subgraph.cc | 5 +- .../cpu/transformers/logits_processor.cc | 5 +- .../contrib_ops/cpu/transformers/sequences.cc | 5 +- onnxruntime/core/common/threadpool.cc | 19 +- onnxruntime/core/framework/allocator.cc | 12 +- onnxruntime/core/framework/bfc_arena.cc | 13 +- onnxruntime/core/framework/bfc_arena.h | 6 +- onnxruntime/core/framework/callback.cc | 4 +- onnxruntime/core/framework/data_types.cc | 5 +- onnxruntime/core/framework/error_code.cc | 5 +- onnxruntime/core/framework/func_kernel.h | 32 ++- .../core/framework/fuse_nodes_funcs.cc | 4 +- onnxruntime/core/framework/fuse_nodes_funcs.h | 8 +- .../core/framework/graph_partitioner.cc | 22 +- onnxruntime/core/framework/kernel_registry.cc | 6 +- .../core/framework/kernel_registry_manager.cc | 13 +- .../core/framework/kernel_registry_manager.h | 8 +- .../framework/onnxruntime_map_type_info.cc | 4 +- .../onnxruntime_sequence_type_info.cc | 18 +- .../core/framework/onnxruntime_typeinfo.cc | 4 +- .../core/framework/onnxruntime_typeinfo.h | 1 + onnxruntime/core/framework/op_kernel_info.cc | 7 +- onnxruntime/core/framework/run_options.cc | 4 +- onnxruntime/core/framework/session_options.h | 1 + onnxruntime/core/framework/session_state.cc | 6 +- onnxruntime/core/framework/session_state.h | 45 ++- onnxruntime/core/framework/sparse_tensor.cc | 4 +- .../core/framework/tensor_type_and_shape.cc | 12 +- .../core/framework/tensorprotoutils.cc | 12 +- onnxruntime/core/framework/utils.cc | 6 +- onnxruntime/core/graph/graph.cc | 31 +- onnxruntime/core/graph/model.cc | 6 +- onnxruntime/core/graph/model.h | 2 +- onnxruntime/core/mlas/lib/convolve.cpp | 1 + onnxruntime/core/mlas/lib/dgemm.cpp | 1 + .../core/mlas/lib/qgemm_kernel_default.cpp | 4 +- onnxruntime/core/mlas/lib/sgemm.cpp | 1 + .../optimizer/optimizer_execution_frame.cc | 5 +- .../qdq_selector_action_transformer.cc | 24 +- onnxruntime/core/platform/windows/env.cc | 71 ++++- .../core/platform/windows/stacktrace.cc | 2 +- onnxruntime/core/providers/common.h | 6 +- .../providers/cpu/activation/activations.h | 7 +- .../core/providers/cpu/controlflow/loop.cc | 30 +- .../core/providers/cpu/controlflow/scan_8.cc | 6 +- .../core/providers/cpu/controlflow/scan_9.cc | 6 +- .../providers/cpu/controlflow/scan_utils.cc | 4 +- .../providers/cpu/controlflow/scan_utils.h | 12 +- .../providers/cpu/cpu_provider_factory.cc | 4 +- .../cpu/element_wise_ranged_transform.h | 2 + .../core/providers/cpu/generator/range.cc | 5 +- onnxruntime/core/providers/cpu/math/clip.h | 4 +- onnxruntime/core/providers/cpu/math/det.cc | 5 + .../einsum_compute_preprocessor.cc | 2 +- .../providers/cpu/math/element_wise_ops.cc | 4 +- .../providers/cpu/math/element_wise_ops.h | 10 +- onnxruntime/core/providers/cpu/ml/ml_common.h | 2 +- .../core/providers/cpu/ml/svmclassifier.cc | 5 + .../core/providers/cpu/nn/batch_norm.h | 8 +- .../core/providers/cpu/nn/batch_norm_helper.h | 10 +- .../core/providers/cpu/nn/conv_attributes.h | 4 +- .../core/providers/cpu/nn/conv_transpose.cc | 2 +- .../cpu/nn/conv_transpose_attributes.h | 2 +- onnxruntime/core/providers/cpu/nn/lrn.cc | 8 +- .../core/providers/cpu/nn/pool_attributes.h | 9 +- onnxruntime/core/providers/cpu/nn/pool_base.h | 6 +- onnxruntime/core/providers/cpu/nn/shrink.cc | 5 +- .../core/providers/cpu/nn/tfidfvectorizer.cc | 6 +- .../object_detection/non_max_suppression.cc | 2 +- .../cpu/object_detection/roialign.cc | 10 +- .../providers/cpu/quantization/qlinearconv.cc | 2 +- .../providers/cpu/reduction/reduction_ops.cc | 15 +- .../providers/cpu/reduction/reduction_ops.h | 11 +- .../core/providers/cpu/rnn/deep_cpu_gru.cc | 12 +- .../core/providers/cpu/rnn/deep_cpu_lstm.cc | 2 +- .../core/providers/cpu/rnn/lstm_base.cc | 5 +- onnxruntime/core/providers/cpu/rnn/rnn.cc | 6 +- .../core/providers/cpu/rnn/rnn_helpers.cc | 32 ++- .../core/providers/cpu/rnn/rnn_helpers.h | 2 +- .../providers/cpu/rnn/uni_directional_lstm.cc | 8 +- .../providers/cpu/sequence/sequence_ops.cc | 4 +- .../core/providers/cpu/tensor/expand.cc | 6 +- .../core/providers/cpu/tensor/gather_nd.cc | 2 +- .../core/providers/cpu/tensor/nonzero_op.cc | 2 +- .../core/providers/cpu/tensor/onehot.cc | 2 +- .../providers/cpu/tensor/reverse_sequence.cc | 8 +- .../core/providers/cpu/tensor/scatter_nd.cc | 2 +- .../providers/cpu/tensor/space_depth_ops.cc | 2 +- .../core/providers/cpu/tensor/split.cc | 2 +- .../core/providers/cpu/tensor/transpose.cc | 2 +- .../core/providers/cpu/tensor/upsample.h | 13 +- onnxruntime/core/providers/cuda/cuda_kernel.h | 2 +- .../src/AbiCustomRegistry.cpp | 5 +- .../src/GraphPartitioner.cpp | 5 +- onnxruntime/core/session/IOBinding.h | 42 +-- .../core/session/abi_session_options.cc | 1 + .../core/session/allocator_adapters.cc | 4 +- onnxruntime/core/session/custom_ops.cc | 5 +- onnxruntime/core/session/environment.cc | 2 +- onnxruntime/core/session/inference_session.cc | 3 +- onnxruntime/core/session/onnxruntime_c_api.cc | 2 + onnxruntime/core/session/ort_env.cc | 31 +- onnxruntime/core/session/ort_env.h | 13 +- .../core/session/provider_bridge_ort.cc | 4 +- onnxruntime/core/util/qmath.h | 8 +- onnxruntime/core/util/thread_utils.cc | 11 +- onnxruntime/python/numpy_helper.h | 12 + .../python/onnxruntime_pybind_mlvalue.cc | 8 +- .../python/onnxruntime_pybind_mlvalue.h | 2 - .../python/onnxruntime_pybind_ortvalue.cc | 1 + .../onnxruntime_pybind_sparse_tensor.cc | 1 + .../python/onnxruntime_pybind_state.cc | 10 +- .../python/onnxruntime_pybind_state_common.h | 15 +- .../test/contrib_ops/tensor_op_test.cc | 18 +- onnxruntime/test/eager/ort_invoker_test.cc | 5 +- .../test/framework/allocation_planner_test.cc | 6 +- onnxruntime/test/framework/float_16_test.cc | 2 +- .../test/framework/kernel_registry_test.cc | 5 +- .../framework/local_kernel_registry_test.cc | 10 +- .../test/framework/opaque_kernels_test.cc | 4 +- .../test/framework/parallel_executor_test.cc | 6 +- .../test/framework/session_state_test.cc | 8 +- .../test/framework/sparse_kernels_test.cc | 30 +- onnxruntime/test/mlas/bench/bench_qgemm.cpp | 6 +- .../test/mlas/unittest/test_conv2d_nchwc.h | 8 +- onnxruntime/test/onnx/TestCase.cc | 24 +- onnxruntime/test/onnx/dataitem_request.cc | 2 +- onnxruntime/test/onnx/dataitem_request.h | 5 +- .../test/onnx/microbenchmark/activation.cc | 2 +- onnxruntime/test/onnx/tensorprotoutils.cc | 6 +- onnxruntime/test/onnx/testcase_request.cc | 2 +- onnxruntime/test/onnx/testcase_request.h | 6 +- .../test/optimizer/graph_transform_test.cc | 16 +- onnxruntime/test/perftest/TFModelInfo.cc | 5 +- onnxruntime/test/perftest/TFModelInfo.h | 2 +- .../test/perftest/performance_runner.cc | 5 +- .../cpu/activation/activation_op_test.cc | 30 +- .../providers/cpu/generator/random_test.cc | 64 ++--- .../cpu/math/element_wise_ops_test.cc | 3 +- .../cpu/math/quantize_linear_matmul_test.cc | 6 +- .../cpu/reduction/reduction_ops_test.cc | 18 +- .../test/providers/cpu/tensor/copy_test.cc | 20 +- .../providers/cpu/tensor/split_op_test.cc | 46 +-- .../providers/cpu/tensor/tensor_op_test.cc | 4 +- .../providers/cpu/tensor/unique_op_test.cc | 16 +- .../internal_testing_partitioning_tests.cc | 12 +- .../internal_testing_tests.cc | 14 +- .../my_allocator.cc | 1 + onnxruntime/test/util/test_allocator.cc | 1 + tools/ci_build/build.py | 3 +- .../azure-pipelines/nuget/templates/gpu.yml | 8 +- .../{ => nuget}/templates/win-ci-2019.yml | 10 +- .../azure-pipelines/templates/win-cpu-ci.yml | 41 +-- .../azure-pipelines/templates/win-gpu-ci.yml | 57 ++-- .../azure-pipelines/win-gpu-ci-pipeline.yml | 255 +++-------------- 188 files changed, 1328 insertions(+), 953 deletions(-) create mode 100644 cmake/EnableVisualStudioCodeAnalysis.props create mode 100644 cmake/Sdl.ruleset create mode 100644 include/onnxruntime/core/common/gsl_suppress.h create mode 100644 onnxruntime/python/numpy_helper.h rename tools/ci_build/github/azure-pipelines/{ => nuget}/templates/win-ci-2019.yml (97%) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 59a9bb9688..adfaa4c11f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1114,7 +1114,6 @@ if (onnxruntime_USE_MIGRAPHX) list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_MIGRAPHX=1) list(APPEND ONNXRUNTIME_PROVIDER_NAMES migraphx) endif() - if (onnxruntime_USE_ARMNN) list(APPEND ORT_PROVIDER_FLAGS -DUSE_ARMNN=1) list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_ARMNN=1) @@ -1142,8 +1141,8 @@ function(onnxruntime_set_compile_flags target_name) set_target_properties(${target_name} PROPERTIES VS_GLOBAL_CAExcludePath "${ORT_BINARY_DIR};${ORT_SOURCE_DIR}") if (onnxruntime_ENABLE_STATIC_ANALYSIS) - target_compile_options(${target_name} PRIVATE "$<$>:/analyze:stacksize 131072>") - target_compile_options(${target_name} PRIVATE "$<$>:/analyze:external->") + target_compile_options(${target_name} PRIVATE "$<$:SHELL:--compiler-options /analyze>" "$<$>:/analyze>") + target_compile_options(${target_name} PRIVATE "$<$:SHELL:--compiler-options /analyze:external->" "$<$>:/analyze:external->") endif() else() # Enable warning @@ -1190,6 +1189,10 @@ function(onnxruntime_configure_target target_name) target_link_directories(${target_name} PRIVATE ${onnxruntime_LINK_DIRS}) onnxruntime_set_compile_flags(${target_name}) onnxruntime_set_source_file_properties(${target_name}) + #Uncomment the following three lines to reproduce static analysis errors locally + #if(WIN32 AND onnxruntime_ENABLE_STATIC_ANALYSIS) + # set_target_properties(${target_name} PROPERTIES VS_USER_PROPS ${PROJECT_SOURCE_DIR}/EnableVisualStudioCodeAnalysis.props) + #endif() target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${ONNXRUNTIME_ROOT}) if (onnxruntime_ENABLE_LTO) set_target_properties(${target_name} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) diff --git a/cmake/EnableVisualStudioCodeAnalysis.props b/cmake/EnableVisualStudioCodeAnalysis.props new file mode 100644 index 0000000000..44f93c37bf --- /dev/null +++ b/cmake/EnableVisualStudioCodeAnalysis.props @@ -0,0 +1,12 @@ + + + + $(MSBuildThisFileDirectory)Sdl.ruleset + + $(SolutionDir);$(MSBuildThisFileDirectory) + true + + diff --git a/cmake/Sdl.ruleset b/cmake/Sdl.ruleset new file mode 100644 index 0000000000..2909df90a1 --- /dev/null +++ b/cmake/Sdl.ruleset @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cmake/onnxruntime_common.cmake b/cmake/onnxruntime_common.cmake index 3ee4a14e4c..9b8b5bf818 100644 --- a/cmake/onnxruntime_common.cmake +++ b/cmake/onnxruntime_common.cmake @@ -127,11 +127,6 @@ install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/common DEST set_target_properties(onnxruntime_common PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(onnxruntime_common PROPERTIES FOLDER "ONNXRuntime") -if(WIN32) - # Add Code Analysis properties to enable C++ Core checks. Have to do it via a props file include. - set_target_properties(onnxruntime_common PROPERTIES VS_USER_PROPS ${PROJECT_SOURCE_DIR}/EnableVisualStudioCodeAnalysis.props) -endif() - # check if we need to link against librt on Linux include(CheckLibraryExists) include(CheckFunctionExists) diff --git a/cmake/onnxruntime_graph.cmake b/cmake/onnxruntime_graph.cmake index dde1fbd138..db09ae7a36 100644 --- a/cmake/onnxruntime_graph.cmake +++ b/cmake/onnxruntime_graph.cmake @@ -120,8 +120,5 @@ if (WIN32) target_compile_options(onnxruntime_graph PRIVATE /EHsc # exception handling - C++ may throw, extern "C" will not ) - endif() - - # Add Code Analysis properties to enable C++ Core checks. Have to do it via a props file include. - set_target_properties(onnxruntime_graph PROPERTIES VS_USER_PROPS ${PROJECT_SOURCE_DIR}/EnableVisualStudioCodeAnalysis.props) + endif() endif() diff --git a/cmake/onnxruntime_mlas.cmake b/cmake/onnxruntime_mlas.cmake index 263f580977..d1ddc06301 100644 --- a/cmake/onnxruntime_mlas.cmake +++ b/cmake/onnxruntime_mlas.cmake @@ -475,4 +475,7 @@ endforeach() set_target_properties(onnxruntime_mlas PROPERTIES FOLDER "ONNXRuntime") if (WIN32) target_compile_options(onnxruntime_mlas PRIVATE "/wd6385" "/wd4127") + if (onnxruntime_ENABLE_STATIC_ANALYSIS) + target_compile_options(onnxruntime_mlas PRIVATE "/analyze:stacksize 131072") + endif() endif() diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index a2f6d6bc22..90240c5f68 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -454,6 +454,10 @@ if (onnxruntime_USE_DNNL) source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_dnnl_cc_srcs}) onnxruntime_add_shared_library_module(onnxruntime_providers_dnnl ${onnxruntime_providers_dnnl_cc_srcs}) target_link_directories(onnxruntime_providers_dnnl PRIVATE ${DNNL_LIB_DIR}) + if (MSVC AND onnxruntime_ENABLE_STATIC_ANALYSIS) + # dnnl_convgrad.cc(47,0): Warning C6262: Function uses '38816' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap. + target_compile_options(onnxruntime_providers_dnnl PRIVATE "/analyze:stacksize 131072") + endif() add_dependencies(onnxruntime_providers_dnnl onnxruntime_providers_shared project_dnnl ${onnxruntime_EXTERNAL_DEPENDENCIES}) target_include_directories(onnxruntime_providers_dnnl PRIVATE ${ONNXRUNTIME_ROOT} ${eigen_INCLUDE_DIRS} ${DNNL_INCLUDE_DIR} ${DNNL_OCL_INCLUDE_DIR}) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 2a9eeca37e..ee3c33dea2 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -81,6 +81,9 @@ function(AddTest) # Lot of such things came from gtest target_compile_options(${_UT_TARGET} PRIVATE "$<$:-Xcompiler /wd6326>" "$<$>:/wd6326>") + # Raw new and delete. A lot of such things came from googletest. + target_compile_options(${_UT_TARGET} PRIVATE "$<$:-Xcompiler /wd26409>" + "$<$>:/wd26409>") endif() target_compile_options(${_UT_TARGET} PRIVATE ${disabled_warnings}) else() @@ -681,7 +684,12 @@ AddTest( onnx_test_data_proto nlohmann_json::nlohmann_json DEPENDS ${all_dependencies} ) -if(NOT MSVC) +if (MSVC) + # The warning means the type of two integral values around a binary operator is narrow than their result. + # If we promote the two input values first, it could be more tolerant to integer overflow. + # However, this is test code. We are less concerned. + target_compile_options(onnxruntime_test_all PRIVATE "/wd26451") +else() target_compile_options(onnxruntime_test_all PRIVATE "-Wno-parentheses") endif() # the default logger tests conflict with the need to have an overall default logger @@ -846,6 +854,15 @@ if (NOT onnxruntime_ENABLE_TRAINING_TORCH_INTEROP) if(WIN32) target_compile_options(onnxruntime_benchmark PRIVATE "$<$:-Xcompiler /wd4141>" "$<$>:/wd4141>") + # Avoid using new and delete. But this is a benchmark program, it's ok if it has a chance to leak. + target_compile_options(onnxruntime_benchmark PRIVATE "$<$:-Xcompiler /wd26409>" + "$<$>:/wd26409>") + target_compile_options(onnxruntime_benchmark PRIVATE "$<$:-Xcompiler /wd26400>" + "$<$>:/wd26400>") + target_compile_options(onnxruntime_benchmark PRIVATE "$<$:-Xcompiler /wd26814>" + "$<$>:/wd26814>") + target_compile_options(onnxruntime_benchmark PRIVATE "$<$:-Xcompiler /wd26814>" + "$<$>:/wd26497>") target_compile_options(onnxruntime_benchmark PRIVATE "$<$:SHELL:--compiler-options /utf-8>" "$<$>:/utf-8>") endif() @@ -858,7 +875,11 @@ if (NOT onnxruntime_ENABLE_TRAINING_TORCH_INTEROP) onnxruntime_add_executable(onnxruntime_mlas_benchmark ${MLAS_BENCH_SOURCE_FILES}) target_include_directories(onnxruntime_mlas_benchmark PRIVATE ${ONNXRUNTIME_ROOT}/core/mlas/inc) target_link_libraries(onnxruntime_mlas_benchmark PRIVATE benchmark::benchmark onnxruntime_util onnxruntime_framework ${ONNXRUNTIME_MLAS_LIBS} onnxruntime_common ${CMAKE_DL_LIBS}) - if(NOT WIN32) + if(WIN32) + target_link_libraries(onnxruntime_mlas_benchmark PRIVATE debug Dbghelp) + # Avoid using new and delete. But this is a benchmark program, it's ok if it has a chance to leak. + target_compile_options(onnxruntime_mlas_benchmark PRIVATE /wd26409) + else() target_link_libraries(onnxruntime_mlas_benchmark PRIVATE nsync_cpp ${CMAKE_DL_LIBS}) endif() set_target_properties(onnxruntime_mlas_benchmark PROPERTIES FOLDER "ONNXRuntimeTest") @@ -1100,6 +1121,8 @@ if (NOT onnxruntime_ENABLE_TRAINING_TORCH_INTEROP) ) onnxruntime_add_executable(onnxruntime_mlas_test ${onnxruntime_mlas_test_src}) if(MSVC) + target_compile_options(onnxruntime_mlas_test PRIVATE "$<$:-Xcompiler /wd26409>" + "$<$>:/wd26409>") target_compile_options(onnxruntime_mlas_test PRIVATE "$<$:SHELL:--compiler-options /utf-8>" "$<$>:/utf-8>") target_compile_options(onnxruntime_mlas_test PRIVATE "$<$:-Xcompiler /wd6326>" @@ -1147,6 +1170,8 @@ if(UNIX) endif() else() set(ONNXRUNTIME_CUSTOM_OP_LIB_LINK_FLAG "-DEF:${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.def") + target_compile_options(custom_op_library PRIVATE "$<$:-Xcompiler /wd26409>" + "$<$>:/wd26409>") endif() set_property(TARGET custom_op_library APPEND_STRING PROPERTY LINK_FLAGS ${ONNXRUNTIME_CUSTOM_OP_LIB_LINK_FLAG}) diff --git a/include/onnxruntime/core/common/common.h b/include/onnxruntime/core/common/common.h index 233311596d..6860bd169c 100644 --- a/include/onnxruntime/core/common/common.h +++ b/include/onnxruntime/core/common/common.h @@ -35,6 +35,7 @@ #include "core/common/exceptions.h" #include "core/common/make_string.h" #include "core/common/status.h" +#include "core/common/gsl_suppress.h" namespace onnxruntime { @@ -253,13 +254,6 @@ void LogRuntimeError(uint32_t session_id, const common::Status& status, const ch } \ } while (0) -// C++ Core Guideline check suppression. -#if defined(_MSC_VER) && !defined(__NVCC__) && !defined(__clang__) -#define GSL_SUPPRESS(tag) [[gsl::suppress(tag)]] -#else -#define GSL_SUPPRESS(tag) -#endif - inline long long TimeDiffMicroSeconds(TimePoint start_time) { auto end_time = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast(end_time - start_time).count(); diff --git a/include/onnxruntime/core/common/gsl_suppress.h b/include/onnxruntime/core/common/gsl_suppress.h new file mode 100644 index 0000000000..66702d0424 --- /dev/null +++ b/include/onnxruntime/core/common/gsl_suppress.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#pragma once + +#ifndef GSL_SUPPRESS +#if defined(__clang__) && !defined(__NVCC__) +#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] +#else +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__NVCC__) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else +#define GSL_SUPPRESS(x) +#endif // _MSC_VER +#endif // __clang__ +#endif \ No newline at end of file diff --git a/include/onnxruntime/core/common/status.h b/include/onnxruntime/core/common/status.h index f348e7e653..b7c36df2b2 100644 --- a/include/onnxruntime/core/common/status.h +++ b/include/onnxruntime/core/common/status.h @@ -19,7 +19,7 @@ limitations under the License. #ifdef _WIN32 #include #endif - +#include "core/common/gsl_suppress.h" namespace onnxruntime { namespace common { @@ -80,35 +80,34 @@ constexpr const char* StatusCodeToString(StatusCode status) noexcept { #ifdef _WIN32 constexpr HRESULT StatusCodeToHRESULT(StatusCode status) noexcept { - switch (status) - { + switch (status) { case StatusCode::OK: - return S_OK; + return S_OK; case StatusCode::FAIL: - return E_FAIL; + return E_FAIL; case StatusCode::INVALID_ARGUMENT: - return E_INVALIDARG; + return E_INVALIDARG; case StatusCode::NO_SUCHFILE: - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); case StatusCode::NO_MODEL: - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); case StatusCode::ENGINE_ERROR: - return E_FAIL; + return E_FAIL; case StatusCode::RUNTIME_EXCEPTION: - return E_FAIL; + return E_FAIL; case StatusCode::INVALID_PROTOBUF: - return HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT); + return HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT); case StatusCode::MODEL_LOADED: - return HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR); + return HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR); case StatusCode::NOT_IMPLEMENTED: - return E_NOTIMPL; + return E_NOTIMPL; case StatusCode::INVALID_GRAPH: - return HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT); + return HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT); case StatusCode::EP_FAIL: - return HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR); + return HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR); default: - return E_FAIL; - } + return E_FAIL; + } } #endif @@ -122,9 +121,10 @@ class [[nodiscard]] Status { Status(StatusCategory category, int code); + GSL_SUPPRESS(r.11) Status(const Status& other) : state_((other.state_ == nullptr) ? nullptr : new State(*other.state_)) {} - + GSL_SUPPRESS(r.11) Status& operator=(const Status& other) { if (state_ != other.state_) { if (other.state_ == nullptr) { diff --git a/include/onnxruntime/core/framework/kernel_def_builder.h b/include/onnxruntime/core/framework/kernel_def_builder.h index a25599be6f..2d35c49ee9 100644 --- a/include/onnxruntime/core/framework/kernel_def_builder.h +++ b/include/onnxruntime/core/framework/kernel_def_builder.h @@ -183,7 +183,7 @@ class KernelDefBuilder { static std::unique_ptr Create() { return std::make_unique(); } explicit KernelDefBuilder() - : kernel_def_(new KernelDef()) {} + : kernel_def_(std::make_unique()) {} KernelDefBuilder& SetName(const std::string& op_name); KernelDefBuilder& SetName(const char* op_name); @@ -274,7 +274,7 @@ class KernelDefBuilder { KernelDefBuilder& Alias(int input_index, int output_index); /** - Apply variadic number of alias mapping from inputs to outputs. + Apply variadic number of alias mapping from inputs to outputs. This is effectively applying Alias(i + input_offset, i + output_offset) for i >= 0 */ KernelDefBuilder& VariadicAlias(int input_offset, int output_offset); @@ -290,7 +290,7 @@ class KernelDefBuilder { } /** - Specify that this kernel's output buffers are passed from external, + Specify that this kernel's output buffers are passed from external, i.e. not created or managed by ORT's memory allocator. */ KernelDefBuilder& ExternalOutputs() { diff --git a/include/onnxruntime/core/framework/kernel_registry.h b/include/onnxruntime/core/framework/kernel_registry.h index a9875df58d..1d068e7625 100644 --- a/include/onnxruntime/core/framework/kernel_registry.h +++ b/include/onnxruntime/core/framework/kernel_registry.h @@ -37,7 +37,7 @@ class KernelRegistry { // TODO(Task:132) Make usage of unique_ptr/shared_ptr as out param consistent Status TryCreateKernel(const Node& node, const IExecutionProvider& execution_provider, const std::unordered_map& constant_initialized_tensors, - const OrtValueNameIdxMap& mlvalue_name_idx_map, const FuncManager& funcs_mgr, + const OrtValueNameIdxMap& mlvalue_name_idx_map, FuncManager& funcs_mgr, const DataTransferManager& data_transfer_mgr, std::unique_ptr& op_kernel) const; diff --git a/include/onnxruntime/core/framework/op_kernel.h b/include/onnxruntime/core/framework/op_kernel.h index 434119986e..59cbef7c66 100644 --- a/include/onnxruntime/core/framework/op_kernel.h +++ b/include/onnxruntime/core/framework/op_kernel.h @@ -125,9 +125,9 @@ class OpKernel { ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(OpKernel); std::unique_ptr op_kernel_info_; }; - -using KernelCreateFn = std::function; -using KernelCreatePtrFn = std::add_pointer::type; +class FuncManager; +using KernelCreateFn = std::function& out)>; +using KernelCreatePtrFn = std::add_pointer& out)>::type; struct KernelCreateInfo { std::unique_ptr kernel_def; // Owned and stored in the global kernel registry. @@ -197,7 +197,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(ver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } #define ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(provider, domain, startver, endver, name) \ @@ -220,7 +220,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(startver, endver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } #define ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(provider, domain, ver, type, name) \ @@ -246,7 +246,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(ver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } #define ONNX_OPERATOR_TWO_TYPED_KERNEL_CLASS_NAME(provider, domain, ver, type1, type2, name) \ @@ -263,7 +263,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(ver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } #define ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type, name) \ @@ -293,7 +293,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(startver, endver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } #define ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type1, type2, name) \ @@ -312,7 +312,7 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); .SinceVersion(startver, endver) \ .Provider(provider) \ .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ + static_cast([](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique<__VA_ARGS__>(info); return Status::OK(); })); \ } template diff --git a/include/onnxruntime/core/framework/op_kernel_info.h b/include/onnxruntime/core/framework/op_kernel_info.h index 0259e7e68c..dca4df8192 100644 --- a/include/onnxruntime/core/framework/op_kernel_info.h +++ b/include/onnxruntime/core/framework/op_kernel_info.h @@ -26,7 +26,6 @@ class OpKernelInfo : public OpNodeProtoHelper { const IExecutionProvider& execution_provider, const std::unordered_map& constant_initialized_tensors, const OrtValueNameIdxMap& mlvalue_name_idx_map, - const FuncManager& funcs_mgr, const DataTransferManager& data_transfer_mgr); OpKernelInfo(const OpKernelInfo& other); @@ -45,8 +44,6 @@ class OpKernelInfo : public OpNodeProtoHelper { bool TryGetConstantInput(int input_index, const Tensor** constant_input_value) const; - common::Status GetFusedFuncs(NodeComputeInfo*& compute_info) const; - private: ORT_DISALLOW_MOVE(OpKernelInfo); ORT_DISALLOW_ASSIGNMENT(OpKernelInfo); @@ -58,7 +55,6 @@ class OpKernelInfo : public OpNodeProtoHelper { gsl::not_null execution_provider_; const std::unordered_map& constant_initialized_tensors_; const OrtValueNameIdxMap& ort_value_name_idx_map_; - const FuncManager& funcs_mgr_; const DataTransferManager& data_transfer_mgr_; ProtoHelperNodeContext proto_helper_context_; }; diff --git a/include/onnxruntime/core/graph/basic_types.h b/include/onnxruntime/core/graph/basic_types.h index a79479b488..36984d0405 100644 --- a/include/onnxruntime/core/graph/basic_types.h +++ b/include/onnxruntime/core/graph/basic_types.h @@ -11,6 +11,7 @@ #include #include "core/common/basic_types.h" +#include "core/common/status.h" namespace ONNX_NAMESPACE { class ValueInfoProto; @@ -44,6 +45,6 @@ using IOnnxRuntimeOpSchemaCollectionPtr = std::shared_ptr; +class FuncManager; +using KernelCreateFn = std::function& out)>; } // namespace onnxruntime diff --git a/include/onnxruntime/core/graph/graph.h b/include/onnxruntime/core/graph/graph.h index d54f145d40..3fe38fa7ef 100644 --- a/include/onnxruntime/core/graph/graph.h +++ b/include/onnxruntime/core/graph/graph.h @@ -401,8 +401,8 @@ class Node { } /** Sets initialized function body for node. This is called right after function body initialization for a node. - * or during function inlining when a nested function is encountered. - */ + * or during function inlining when a nested function is encountered. + */ void SetFunctionBody(Function& func); /** Call the provided function for all explicit inputs, implicit inputs, and outputs of this Node. @@ -500,15 +500,14 @@ class Node { ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Relationships); }; - private: - ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Node); - // NOTE: This friendship relationship should ONLY be used for calling methods of the Node class and not accessing // the data members directly, so that the Node can maintain its internal invariants. friend class Graph; - Node(NodeIndex index, Graph& graph) : index_(index), graph_(&graph) {} + private: + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Node); + #if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) void Init(const std::string& name, const std::string& op_type, @@ -648,7 +647,7 @@ class Graph { /** Check if a given name is a sparse initializer's name in the model * we currently convert sparse_initializer field in the model into dense Tensor instances. * However, we sometimes want to check if this initializer was stored as sparse in the model. - */ + */ bool IsSparseInitializer(const std::string& name) const; #endif @@ -978,7 +977,7 @@ class Graph { @remarks As a new Graph instance for the fused nodes is not created, a GraphViewer can be constructed with the IndexedSubGraph information to provide a view of the subgraph. The original nodes are left in place while this is in use. - Call FinalizeFuseSubGraph to remove them once the fused replacement node is fully created. + Call FinalizeFuseSubGraph to remove them once the fused replacement node is fully created. */ Node& BeginFuseSubGraph(const IndexedSubGraph& sub_graph, const std::string& fused_node_name); @@ -1200,9 +1199,6 @@ class Graph { } #endif - private: - ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Graph); - // This friendship relationship should only be used to call Graph::Graph and // Graph::LoadGraph All other access should be via the public API. friend class Model; @@ -1243,6 +1239,8 @@ class Graph { const std::vector& model_functions, const logging::Logger& logger); + private: + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Graph); void InitializeStateFromModelFileGraphProto(); // Add node with specified . @@ -1530,16 +1528,16 @@ std::ostream& operator<<(std::ostream& out, const NodeArg& node_arg); // Print Node as, // (operator's name, operator's type, domain, version) : (input0, input1, ...) -> (output0, output1, ...) // For example, -// ("Add_14", Add, "", 7) : ("110": tensor(float),"109": tensor(float),) -> ("111": tensor(float),) +// ("Add_14", Add, "", 7) : ("110": tensor(float),"109": tensor(float),) -> ("111": tensor(float),) std::ostream& operator<<(std::ostream& out, const Node& node); // Print Graph as, for example, // Inputs: // "Input": tensor(float) // Nodes: -// ("add0", Add, "", 7) : ("Input": tensor(float),"Bias": tensor(float),) -> ("add0_out": tensor(float),) -// ("matmul", MatMul, "", 9) : ("add0_out": tensor(float),"matmul_weight": tensor(float),) -> ("matmul_out": tensor(float),) -// ("add1", Add, "", 7) : ("matmul_out": tensor(float),"add_weight": tensor(float),) -> ("add1_out": tensor(float),) -// ("reshape", Reshape, "", 5) : ("add1_out": tensor(float),"concat_out": tensor(int64),) -> ("Result": tensor(float),) +// ("add0", Add, "", 7) : ("Input": tensor(float),"Bias": tensor(float),) -> ("add0_out": tensor(float),) +// ("matmul", MatMul, "", 9) : ("add0_out": tensor(float),"matmul_weight": tensor(float),) -> ("matmul_out": tensor(float),) +// ("add1", Add, "", 7) : ("matmul_out": tensor(float),"add_weight": tensor(float),) -> ("add1_out": tensor(float),) +// ("reshape", Reshape, "", 5) : ("add1_out": tensor(float),"concat_out": tensor(int64),) -> ("Result": tensor(float),) // Outputs: // "Result": tensor(float) // Inputs' and outputs' format is described in document of NodeArg's operator<< above. diff --git a/include/onnxruntime/core/graph/node_arg.h b/include/onnxruntime/core/graph/node_arg.h index ecb5bdc131..80f5dda2dc 100644 --- a/include/onnxruntime/core/graph/node_arg.h +++ b/include/onnxruntime/core/graph/node_arg.h @@ -106,12 +106,12 @@ class NodeArg { Optional inputs are allowed in ONNX and an empty #Name represents a non-existent input argument. */ bool Exists() const noexcept; - private: - ORT_DISALLOW_COPY_AND_ASSIGNMENT(NodeArg); friend class Graph; NodeArg(NodeArgInfo&& node_arg_info); + private: + ORT_DISALLOW_COPY_AND_ASSIGNMENT(NodeArg); #if !defined(ORT_MINIMAL_BUILD) void SetType(const std::string* p_type); void SetType(const ONNX_NAMESPACE::TypeProto& type_proto); diff --git a/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h b/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h index 0842400c2c..95bab63ba0 100644 --- a/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h +++ b/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h @@ -786,7 +786,7 @@ class ThreadPoolTempl : public onnxruntime::concurrency::ExtendedThreadPoolInter // unique_ptr. The explicit deleter avoids the Eigen-specific // definition of ThreadPoolParallelSection needing to be avilable in // threadpool.h where the user-facing parallel section API is defined. - +GSL_SUPPRESS(r.11) std::unique_ptr AllocateParallelSection() override { return std::unique_ptr (new ThreadPoolParallelSection, diff --git a/include/onnxruntime/core/session/environment.h b/include/onnxruntime/core/session/environment.h index f7a4638371..cc511ccad5 100644 --- a/include/onnxruntime/core/session/environment.h +++ b/include/onnxruntime/core/session/environment.h @@ -58,31 +58,31 @@ class Environment { /** * Registers an allocator for sharing between multiple sessions. * Return an error if an allocator with the same OrtMemoryInfo is already registered. - */ + */ Status RegisterAllocator(AllocatorPtr allocator); /** * Creates and registers an allocator for sharing between multiple sessions. * Return an error if an allocator with the same OrtMemoryInfo is already registered. - */ + */ Status CreateAndRegisterAllocator(const OrtMemoryInfo& mem_info, const OrtArenaCfg* arena_cfg = nullptr); /** * Returns the list of registered allocators in this env. - */ + */ const std::vector& GetRegisteredSharedAllocators() const { return shared_allocators_; } /** * Removes registered allocator that was previously registered for sharing between multiple sessions. - */ + */ Status UnregisterAllocator(const OrtMemoryInfo& mem_info); + Environment() = default; + private: ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Environment); - - Environment() = default; Status Initialize(std::unique_ptr logging_manager, const OrtThreadingOptions* tp_options = nullptr, bool create_global_thread_pools = false); diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 9384ad8700..8c32416061 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -129,6 +129,7 @@ extern "C" { // Used in *.cc files. Almost as same as ORT_API_STATUS, except without ORT_MUST_USE_RESULT and ORT_EXPORT #define ORT_API_STATUS_IMPL(NAME, ...) \ + GSL_SUPPRESS(r .11) \ _Success_(return == 0) _Check_return_ _Ret_maybenull_ OrtStatusPtr ORT_API_CALL NAME(__VA_ARGS__) NO_EXCEPTION #define ORT_CLASS_RELEASE(X) void(ORT_API_CALL * Release##X)(_Frees_ptr_opt_ Ort##X * input) diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_api.h b/include/onnxruntime/core/session/onnxruntime_cxx_api.h index 048421099b..1358d13072 100644 --- a/include/onnxruntime/core/session/onnxruntime_cxx_api.h +++ b/include/onnxruntime/core/session/onnxruntime_cxx_api.h @@ -950,8 +950,14 @@ struct CustomOpBase : OrtCustomOp { OrtCustomOp::GetOutputType = [](const OrtCustomOp* this_, size_t index) { return static_cast(this_)->GetOutputType(index); }; OrtCustomOp::KernelCompute = [](void* op_kernel, OrtKernelContext* context) { static_cast(op_kernel)->Compute(context); }; +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26409) +#endif OrtCustomOp::KernelDestroy = [](void* op_kernel) { delete static_cast(op_kernel); }; - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif OrtCustomOp::GetInputCharacteristic = [](const OrtCustomOp* this_, size_t index) { return static_cast(this_)->GetInputCharacteristic(index); }; OrtCustomOp::GetOutputCharacteristic = [](const OrtCustomOp* this_, size_t index) { return static_cast(this_)->GetOutputCharacteristic(index); }; } diff --git a/onnxruntime/contrib_ops/cpu/activations.h b/onnxruntime/contrib_ops/cpu/activations.h index a156af1405..3bd07bb27b 100644 --- a/onnxruntime/contrib_ops/cpu/activations.h +++ b/onnxruntime/contrib_ops/cpu/activations.h @@ -67,7 +67,7 @@ class Gelu : public OpKernel { concurrency::ThreadPool* tp = context->GetOperatorThreadPool(); int64_t elem_count = input->Shape().Size(); - static const int64_t length_per_task = 4096; // this number comes from FastGelu. + constexpr int64_t length_per_task = 4096; // this number comes from FastGelu. int64_t task_count = (elem_count + length_per_task - 1) / length_per_task; concurrency::ThreadPool::TryBatchParallelFor( tp, static_cast(task_count), diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc b/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc index fed268ed9c..6398ff2852 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/bahdanau_attention.cc @@ -8,8 +8,9 @@ #include using onnxruntime::rnn::detail::Allocate; -//TODO: fix the warnings +// TODO: fix the warnings #if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif namespace onnxruntime { diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc b/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc index 0a13083d9a..02a09e88db 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/deep_cpu_attn_lstm.cc @@ -12,6 +12,7 @@ #include "core/framework/allocator.h" //TODO: fix the warnings #if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif namespace onnxruntime { diff --git a/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc b/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc index 9c0246347a..f084e72dcd 100644 --- a/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc +++ b/onnxruntime/contrib_ops/cpu/attnlstm/uni_dir_attn_lstm.cc @@ -16,6 +16,7 @@ #endif //TODO: fix the warnings #if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif using namespace onnxruntime::rnn::detail; diff --git a/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h b/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h index 5ebb515575..db2c93e377 100644 --- a/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h +++ b/onnxruntime/contrib_ops/cpu/bert/attention_cpu_base.h @@ -12,6 +12,7 @@ //TODO: fix the warnings #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif namespace onnxruntime { diff --git a/onnxruntime/contrib_ops/cpu/crop_and_resize.cc b/onnxruntime/contrib_ops/cpu/crop_and_resize.cc index f0548f66de..2ed4d32bf2 100644 --- a/onnxruntime/contrib_ops/cpu/crop_and_resize.cc +++ b/onnxruntime/contrib_ops/cpu/crop_and_resize.cc @@ -24,6 +24,7 @@ limitations under the License. #include "core/providers/cpu/object_detection/roialign.h" //TODO: fix the warnings #if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif using namespace onnxruntime::concurrency; diff --git a/onnxruntime/contrib_ops/cpu/nchwc_ops.cc b/onnxruntime/contrib_ops/cpu/nchwc_ops.cc index 6439b2c8f4..c88ffd2dce 100644 --- a/onnxruntime/contrib_ops/cpu/nchwc_ops.cc +++ b/onnxruntime/contrib_ops/cpu/nchwc_ops.cc @@ -68,7 +68,7 @@ Status ReorderInput::Compute(OpKernelContext* context) const { if (channels_last_) { int64_t work_index = static_cast(work.start); - int64_t work_remaining = static_cast(work.end - work.start); + int64_t work_remaining = static_cast(work.end) - work.start; while (work_remaining > 0) { const int64_t batch_index = work_index / spatial_size; @@ -87,7 +87,7 @@ Status ReorderInput::Compute(OpKernelContext* context) const { } } else { int64_t work_index = static_cast(work.start) * nchwc_block_size; - int64_t work_remaining = static_cast(work.end - work.start) * nchwc_block_size; + int64_t work_remaining = (static_cast(work.end) - work.start) * nchwc_block_size; while (work_remaining > 0) { const int64_t batch_index = work_index / nchwc_channels; @@ -331,7 +331,7 @@ Status NchwcUpsample::Compute(OpKernelContext* context) const { auto upsample_worker = [&](ptrdiff_t batch) { auto work = concurrency::ThreadPool::PartitionWork(batch, worker_count, total_work); int64_t work_index = static_cast(work.start); - int64_t work_remaining = static_cast(work.end - work.start); + int64_t work_remaining = static_cast(work.end) - work.start; while (work_remaining > 0) { // Limit the current loop iteration to the same source image. diff --git a/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc b/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc index e97b654994..f06a80512a 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qlinear_pool.cc @@ -119,7 +119,7 @@ struct QLinearPoolNhwc1DTask final { int64_t batch = begin / y_image_size; int64_t offset = begin % y_image_size; - for (int64_t remains = end - begin; remains > 0; offset = 0, batch++) { + for (std::ptrdiff_t remains = end - begin; remains > 0; offset = 0, batch++) { if (offset + remains <= y_image_size) { operator()(std::ptrdiff_t(batch), std::ptrdiff_t(offset), std::ptrdiff_t(offset + remains)); remains = 0; @@ -247,7 +247,7 @@ struct QLinearPoolNhwc2DTask final { int64_t batch = begin / y_image_size; int64_t offset = begin % y_image_size; - for (int64_t remains = end - begin; remains > 0; offset = 0, batch++) { + for (int64_t remains = static_cast(end) - begin; remains > 0; offset = 0, batch++) { if (offset + remains <= y_image_size) { operator()(std::ptrdiff_t(batch), std::ptrdiff_t(offset), std::ptrdiff_t(offset + remains)); remains = 0; @@ -268,7 +268,7 @@ struct QLinearPoolNhwc2DTask final { start_pw -= (start_ph * pooled_width); int64_t pool_index = channels * begin; - int64_t remains = end - begin; + std::ptrdiff_t remains = end - begin; std::vector Yh(channels); for (int64_t ph = start_ph; remains > 0 && ph < pooled_height; ++ph) { @@ -281,7 +281,7 @@ struct QLinearPoolNhwc2DTask final { wstart = std::max(wstart, static_cast(0)); // do the pooling here - float pool_init_value = PoolType::Initialize(); + constexpr float pool_init_value = PoolType::Initialize(); std::fill(Yh.data(), Yh.data() + channels, pool_init_value); for (int64_t h = hstart; h < hend; ++h) { int64_t input_index = channels * (h * width + wstart); @@ -415,7 +415,7 @@ struct QLinearPoolNhwc3DTask final { int64_t batch = begin / y_image_size; int64_t offset = begin % y_image_size; - for (int64_t remains = end - begin; remains > 0; offset = 0, batch++) { + for (int64_t remains = static_cast(end) - begin; remains > 0; offset = 0, batch++) { if (offset + remains <= y_image_size) { operator()(std::ptrdiff_t(batch), std::ptrdiff_t(offset), std::ptrdiff_t(offset + remains)); remains = 0; @@ -437,7 +437,7 @@ struct QLinearPoolNhwc3DTask final { int64_t start_pw = start_pd / pooled_depth; start_pd = start_pd - start_pw * pooled_depth; int64_t pool_index = channels * begin; - int64_t remains = end - begin; + int64_t remains = static_cast(end) - begin; std::vector Yh(channels); diff --git a/onnxruntime/contrib_ops/cpu/tokenizer.cc b/onnxruntime/contrib_ops/cpu/tokenizer.cc index d972692950..b26fa11fe2 100644 --- a/onnxruntime/contrib_ops/cpu/tokenizer.cc +++ b/onnxruntime/contrib_ops/cpu/tokenizer.cc @@ -93,7 +93,7 @@ Tokenizer::Tokenizer(const OpKernelInfo& info) : OpKernel(info) { re2::RE2::Options options; options.set_longest_match(true); for (const auto& sep : separators) { - std::unique_ptr regex(new re2::RE2(sep, options)); + std::unique_ptr regex = std::make_unique(sep, options); if (!regex->ok()) { ORT_THROW("Can not digest separators: ", sep, " ", regex->error()); } @@ -104,7 +104,7 @@ Tokenizer::Tokenizer(const OpKernelInfo& info) : OpKernel(info) { assert(!tokenexp.empty()); re2::RE2::Options options; options.set_longest_match(true); - std::unique_ptr regex(new re2::RE2(tokenexp, options)); + std::unique_ptr regex = std::make_unique(tokenexp, options); if (!regex->ok()) { ORT_THROW("Can not digest tokenexp: ", regex->error()); } diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc b/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc index 1225442192..9925501b1d 100644 --- a/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search.cc @@ -30,6 +30,8 @@ #ifdef _MSC_VER #pragma warning(pop) +// Could reduce the chance of arithmetic overflow. TODO: fix it +#pragma warning(disable : 26451) #endif using namespace ONNX_NAMESPACE; @@ -431,10 +433,10 @@ Status BeamSearchImpl::ProcessLogits( Tensor::InitOrtValue(element_type, next_token_scores_shape, next_token_scores.data(), allocator->Info(), next_token_scores_value); const Tensor& input = next_token_scores_value.Get(); - const int axis = 1; + constexpr int axis = 1; const unsigned top_k = static_cast(2 * parameters_->num_beams); - const bool largest = true; - const bool sorted = true; // results returned in sorted order. + constexpr bool largest = true; + constexpr bool sorted = true; // results returned in sorted order. std::unique_ptr topk_scores; std::unique_ptr topk_indices; diff --git a/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc index bb7aeb989e..d2bb36e0b1 100644 --- a/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc +++ b/onnxruntime/contrib_ops/cpu/transformers/beam_search_scorer.cc @@ -10,7 +10,10 @@ #include "core/providers/cpu/tensor/utils.h" #include "core/providers/cpu/rnn/rnn_helpers.h" #include "beam_search_scorer.h" - +#ifdef _MSC_VER +// Could reduce the chance of arithmetic overflow. TODO: fix it +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { namespace transformers { @@ -126,7 +129,7 @@ void BeamSearchScorer::Initialize(AllocatorPtr& allocator, int sequence_lengt ORT_ENFORCE(next_beam_scores_.empty()); // Make sure this is called only once. size_t batch_beam_size = static_cast(batch_size_ * num_beams_); - const bool no_fill = false; // do not fill values after allocation + constexpr bool no_fill = false; // do not fill values after allocation next_beam_scores_ = Allocate(allocator, batch_beam_size, next_beam_scores_ptr_, no_fill); next_beam_tokens_ = Allocate(allocator, batch_beam_size, next_beam_tokens_ptr_, no_fill); next_beam_indices_ = Allocate(allocator, batch_beam_size, next_beam_indices_ptr_, no_fill); diff --git a/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc index 80825c7e26..db24804232 100644 --- a/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc +++ b/onnxruntime/contrib_ops/cpu/transformers/gpt_subgraph.cc @@ -21,7 +21,10 @@ #ifdef _MSC_VER #pragma warning(pop) #endif - +#ifdef _MSC_VER +// Could reduce the chance of arithmetic overflow. TODO: fix it +#pragma warning(disable : 26451) +#endif using namespace ONNX_NAMESPACE; using namespace onnxruntime::common; diff --git a/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc index 10ef8b6f69..ca8e722bf8 100644 --- a/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc +++ b/onnxruntime/contrib_ops/cpu/transformers/logits_processor.cc @@ -1,7 +1,10 @@ #include #include "logits_processor.h" #include "dump_tensor.h" - +#ifdef _MSC_VER +// Could reduce the chance of arithmetic overflow. TODO: fix it +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { namespace transformers { diff --git a/onnxruntime/contrib_ops/cpu/transformers/sequences.cc b/onnxruntime/contrib_ops/cpu/transformers/sequences.cc index a9c70ef410..87e6aabe95 100644 --- a/onnxruntime/contrib_ops/cpu/transformers/sequences.cc +++ b/onnxruntime/contrib_ops/cpu/transformers/sequences.cc @@ -1,5 +1,8 @@ #include "sequences.h" - +#ifdef _MSC_VER +// Could reduce the chance of arithmetic overflow. TODO: fix it +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace contrib { namespace transformers { diff --git a/onnxruntime/core/common/threadpool.cc b/onnxruntime/core/common/threadpool.cc index eb709dcadc..8357388884 100644 --- a/onnxruntime/core/common/threadpool.cc +++ b/onnxruntime/core/common/threadpool.cc @@ -36,7 +36,10 @@ limitations under the License. #include #endif #endif - +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace concurrency { @@ -66,7 +69,7 @@ void ThreadPoolProfiler::Start() { ThreadPoolProfiler::MainThreadStat& ThreadPoolProfiler::GetMainThreadStat() { static thread_local std::unique_ptr stat; if (!stat) { - stat.reset(new MainThreadStat()); + stat = std::make_unique(); } return *stat; } @@ -336,8 +339,8 @@ class alignas(CACHE_LINE_BYTES) LoopCounter { // Hence, at low thread counts, each of N threads will get its own // shard representing 1/N of the work. constexpr static unsigned GetNumShards(uint64_t num_iterations, - uint64_t d_of_p, - uint64_t block_size) { + uint64_t d_of_p, + uint64_t block_size) { unsigned num_shards = 0; auto num_blocks = num_iterations / block_size; if (num_blocks == 0) { @@ -376,10 +379,10 @@ ThreadPool::ThreadPool(Env* env, int threads_to_create = degree_of_parallelism - 1; extended_eigen_threadpool_ = std::make_unique >(name, - threads_to_create, - low_latency_hint, - *env, - thread_options_); + threads_to_create, + low_latency_hint, + *env, + thread_options_); underlying_threadpool_ = extended_eigen_threadpool_.get(); } } diff --git a/onnxruntime/core/framework/allocator.cc b/onnxruntime/core/framework/allocator.cc index 98a8bf4d98..c1d3366fdd 100644 --- a/onnxruntime/core/framework/allocator.cc +++ b/onnxruntime/core/framework/allocator.cc @@ -110,7 +110,10 @@ void CPUAllocator::Free(void* p) { } // namespace onnxruntime std::ostream& operator<<(std::ostream& out, const OrtMemoryInfo& info) { return (out << info.ToString()); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26409) +#endif ORT_API_STATUS_IMPL(OrtApis::CreateMemoryInfo, _In_ const char* name1, enum OrtAllocatorType type, int id1, enum OrtMemType mem_type1, _Outptr_ OrtMemoryInfo** out) { if (strcmp(name1, onnxruntime::CPU) == 0) { @@ -126,7 +129,7 @@ ORT_API_STATUS_IMPL(OrtApis::CreateMemoryInfo, _In_ const char* name1, enum OrtA } else if (strcmp(name1, onnxruntime::OpenVINO_GPU) == 0) { *out = new OrtMemoryInfo( onnxruntime::OpenVINO_GPU, type, OrtDevice(OrtDevice::GPU, OrtDevice::MemType::DEFAULT, static_cast(id1)), - id1, mem_type1); + id1, mem_type1); } else if (strcmp(name1, onnxruntime::DML) == 0) { *out = new OrtMemoryInfo( onnxruntime::DML, type, OrtDevice(OrtDevice::GPU, OrtDevice::MemType::DEFAULT, static_cast(id1)), @@ -138,7 +141,9 @@ ORT_API_STATUS_IMPL(OrtApis::CreateMemoryInfo, _In_ const char* name1, enum OrtA } ORT_API(void, OrtApis::ReleaseMemoryInfo, _Frees_ptr_opt_ OrtMemoryInfo* p) { delete p; } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif ORT_API_STATUS_IMPL(OrtApis::MemoryInfoGetName, _In_ const OrtMemoryInfo* ptr, _Out_ const char** out) { *out = ptr->name; return nullptr; @@ -164,4 +169,3 @@ ORT_API_STATUS_IMPL(OrtApis::CompareMemoryInfo, _In_ const OrtMemoryInfo* info1, *out = (*info1 == *info2) ? 0 : -1; return nullptr; } - diff --git a/onnxruntime/core/framework/bfc_arena.cc b/onnxruntime/core/framework/bfc_arena.cc index 57e4fea00b..9bbb2b419f 100644 --- a/onnxruntime/core/framework/bfc_arena.cc +++ b/onnxruntime/core/framework/bfc_arena.cc @@ -164,8 +164,19 @@ Status BFCArena::Extend(size_t rounded_bytes) { static constexpr float kBackpedalFactor = 0.9f; // Try allocating less memory. while (mem_addr == nullptr) { + // kBackpedalFactor is float, bytes is size_t. The result of bytes * kBackpedalFactor is float. When we cast it to + // size_t, which is a smaller type, it could loss data. This is what C4244 complains. The "static_cast" here + // is to suppress the warning. C26451 suggest we may change kBackpedalFactor to double to get better accuary. But if + // we do that, AMD GPU CI build pipeline will have an "out-of-memory" error. So I choose to keep this piece of code + // untouched and disable the warning first. +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif bytes = RoundedBytes(static_cast(bytes * kBackpedalFactor)); - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif // give up if we can't satisfy the requested size, or we're attempting an allocation of less than 8K. // // the latter protects against an infinite loop that occurs when bytes is less than 2560. at that point the 10% diff --git a/onnxruntime/core/framework/bfc_arena.h b/onnxruntime/core/framework/bfc_arena.h index f38d6b64e0..e664ba50d1 100644 --- a/onnxruntime/core/framework/bfc_arena.h +++ b/onnxruntime/core/framework/bfc_arena.h @@ -211,7 +211,7 @@ class BFCArena : public IAllocator { ORT_ENFORCE(0 == memory_size % kMinAllocationSize); const size_t n_handles = (memory_size + kMinAllocationSize - 1) / kMinAllocationSize; - handles_ = new ChunkHandle[n_handles]; + handles_ = std::make_unique(n_handles); for (size_t i = 0; i < n_handles; i++) { handles_[i] = kInvalidChunkHandle; } @@ -219,7 +219,7 @@ class BFCArena : public IAllocator { AllocationRegion() = default; - ~AllocationRegion() { delete[] handles_; } + ~AllocationRegion() = default; AllocationRegion(AllocationRegion&& other) noexcept { Swap(other); } @@ -266,7 +266,7 @@ class BFCArena : public IAllocator { // Array of size "memory_size / kMinAllocationSize". It is // indexed by (p-base) / kMinAllocationSize, contains ChunkHandle // for the memory allocation represented by "p" - ChunkHandle* handles_ = nullptr; + std::unique_ptr handles_; ORT_DISALLOW_ASSIGNMENT(AllocationRegion); }; diff --git a/onnxruntime/core/framework/callback.cc b/onnxruntime/core/framework/callback.cc index deb4d1e277..7e288b1a66 100644 --- a/onnxruntime/core/framework/callback.cc +++ b/onnxruntime/core/framework/callback.cc @@ -2,7 +2,9 @@ // Licensed under the MIT License. #include "core/framework/callback.h" - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif namespace onnxruntime { void OrtRunCallback(OrtCallback* f) noexcept { if (f == nullptr) return; diff --git a/onnxruntime/core/framework/data_types.cc b/onnxruntime/core/framework/data_types.cc index dc66fba500..90afec10e9 100644 --- a/onnxruntime/core/framework/data_types.cc +++ b/onnxruntime/core/framework/data_types.cc @@ -314,7 +314,10 @@ struct TensorTypeBase::Impl : public data_types_internal::TypeProtoImpl { const ONNX_NAMESPACE::TypeProto* TensorTypeBase::GetTypeProto() const { return impl_->GetProto(); } - +//TODO: Fix the warning +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif TensorTypeBase::TensorTypeBase() : DataTypeImpl{DataTypeImpl::GeneralType::kTensor, sizeof(Tensor)}, impl_(new Impl()) {} diff --git a/onnxruntime/core/framework/error_code.cc b/onnxruntime/core/framework/error_code.cc index 0bcad00233..d1d509fbe0 100644 --- a/onnxruntime/core/framework/error_code.cc +++ b/onnxruntime/core/framework/error_code.cc @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include "core/common/gsl_suppress.h" #include "core/session/onnxruntime_c_api.h" #include "core/session/ort_apis.h" #include "core/common/status.h" @@ -66,5 +67,7 @@ ORT_API(OrtErrorCode, OrtApis::GetErrorCode, _In_ const OrtStatus* status) { ORT_API(const char*, OrtApis::GetErrorMessage, _In_ const OrtStatus* status) { return status->msg; } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif ORT_API(void, OrtApis::ReleaseStatus, _Frees_ptr_opt_ OrtStatus* value) { delete[] reinterpret_cast(value); } diff --git a/onnxruntime/core/framework/func_kernel.h b/onnxruntime/core/framework/func_kernel.h index ece2c24304..9bf7a5bff6 100644 --- a/onnxruntime/core/framework/func_kernel.h +++ b/onnxruntime/core/framework/func_kernel.h @@ -13,21 +13,29 @@ void release_helper_func(void* allocator, void* p); //A kernel that wrapper the ComputeFunction call generated by execution provider when fuse the sub-graph class FunctionKernel : public OpKernel { public: + explicit FunctionKernel(const OpKernelInfo& info, const NodeComputeInfo* compute) : OpKernel(info), compute_info_(compute) {} + //The original design is we load the dll, find the entry point and wrapper it. //Here for quick prototype, we keep the entry pointer in the node. - explicit FunctionKernel(const OpKernelInfo& info) : OpKernel(info) { - num_inputs_ = info.node().InputDefs().size(); - num_outputs_ = info.node().OutputDefs().size(); - auto status = info.GetFusedFuncs(compute_info_); - ORT_ENFORCE(status.IsOK(), status.ErrorMessage()); - if (compute_info_->create_state_func) { + static Status Create(FuncManager& func_mgr, const OpKernelInfo& info, std::unique_ptr& out) { + const NodeComputeInfo* compute; + ORT_RETURN_IF_ERROR(func_mgr.GetFuncs(info.node().Name(), compute)); + std::unique_ptr funckernel = std::make_unique(info, compute); + funckernel->num_inputs_ = info.node().InputDefs().size(); + funckernel->num_outputs_ = info.node().OutputDefs().size(); + + if (compute->create_state_func) { //TODO: we are only provide host allocate method in compute context. //Do we need to hold the ref-counting here? - host_allocator_ = info.GetAllocator(0, OrtMemType::OrtMemTypeDefault); - ComputeContext context = {allocate_helper_func, release_helper_func, host_allocator_.get(), + funckernel->host_allocator_ = info.GetAllocator(0, OrtMemType::OrtMemTypeDefault); + ComputeContext context = {allocate_helper_func, release_helper_func, funckernel->host_allocator_.get(), info.node().Name().c_str()}; - ORT_ENFORCE(compute_info_->create_state_func(&context, &func_state_) == 0); + int ret = funckernel->compute_info_->create_state_func(&context, &funckernel->func_state_); + if (ret != 0) + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Create state function failed. Return value:", ret); } + out = std::move(funckernel); + return Status::OK(); } ~FunctionKernel() override { @@ -38,12 +46,14 @@ class FunctionKernel : public OpKernel { virtual Status Compute(OpKernelContext* context) const override { auto* context_internal = static_cast(context); - return compute_info_->compute_func(func_state_, OrtGetApiBase()->GetApi(ORT_API_VERSION), + const OrtApi* api = OrtGetApiBase()->GetApi(ORT_API_VERSION); + if (api == nullptr) return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "API VERSION ", ORT_API_VERSION, " is invalid."); + return compute_info_->compute_func(func_state_, api, reinterpret_cast(context_internal)); } private: - NodeComputeInfo* compute_info_{nullptr}; + const NodeComputeInfo* const compute_info_; FunctionState func_state_{nullptr}; size_t num_inputs_; size_t num_outputs_; diff --git a/onnxruntime/core/framework/fuse_nodes_funcs.cc b/onnxruntime/core/framework/fuse_nodes_funcs.cc index f4678afbed..d75b2eba16 100644 --- a/onnxruntime/core/framework/fuse_nodes_funcs.cc +++ b/onnxruntime/core/framework/fuse_nodes_funcs.cc @@ -22,7 +22,7 @@ Status FuncManager::AddFuncInfo(const std::string& name, NodeComputeInfo&& compu return Status::OK(); } -Status FuncManager::GetFuncs(const std::string& name, NodeComputeInfo*& compute_info) const { +Status FuncManager::GetFuncs(const std::string& name, const NodeComputeInfo*& compute_info) { auto it = fused_funcs_->find(name); if (it == fused_funcs_->end()) return Status(common::ONNXRUNTIME, common::FAIL, "func info for node: " + name + " not found."); @@ -30,7 +30,7 @@ Status FuncManager::GetFuncs(const std::string& name, NodeComputeInfo*& compute_ if (!it->second.compute_info.compute_func) { //load from path void* handle = nullptr; - ORT_RETURN_IF_ERROR(lib_loader_->LoadExternalLib(it->second.dso_path, &handle)); + ORT_RETURN_IF_ERROR(lib_loader_.LoadExternalLib(it->second.dso_path, &handle)); void* create_func_symbol_handle = nullptr; ORT_RETURN_IF_ERROR(Env::Default().GetSymbolFromLibrary(handle, kCreateStateFuncSymbol + name, diff --git a/onnxruntime/core/framework/fuse_nodes_funcs.h b/onnxruntime/core/framework/fuse_nodes_funcs.h index 665f7d5d22..628880b066 100644 --- a/onnxruntime/core/framework/fuse_nodes_funcs.h +++ b/onnxruntime/core/framework/fuse_nodes_funcs.h @@ -8,15 +8,15 @@ namespace onnxruntime { class FuncManager { public: FuncManager() - : fused_funcs_(std::make_shared >()), - lib_loader_(std::make_unique()) { + : fused_funcs_(std::make_shared >()) { } Status AddFuncInfo(const std::string& name, const std::string& dll_path); Status AddFuncInfo(const std::string& name, NodeComputeInfo&& compute_info); - Status GetFuncs(const std::string& name, NodeComputeInfo*& compute_info) const; + //Do not call AddFuncInfo after this function is called. + Status GetFuncs(const std::string& name, const NodeComputeInfo*& compute_info); size_t NumFuncs() const { return fused_funcs_->size(); } @@ -38,7 +38,7 @@ class FuncManager { // because it's filled in by the time main graph is traversed, // while subgraph session state is created later std::shared_ptr > fused_funcs_; - std::unique_ptr lib_loader_; + ExLibLoader lib_loader_; ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(FuncManager); }; } // namespace onnxruntime diff --git a/onnxruntime/core/framework/graph_partitioner.cc b/onnxruntime/core/framework/graph_partitioner.cc index eff7992ce4..1ebccacad4 100644 --- a/onnxruntime/core/framework/graph_partitioner.cc +++ b/onnxruntime/core/framework/graph_partitioner.cc @@ -258,10 +258,9 @@ static Status PartitionOnnxFormatModelImpl(Graph& graph, bool export_dll, FuncMa KernelDefBuilder builder; BuildFusedKernelDef(builder, *node); ORT_RETURN_IF_ERROR(fused_kernel_registry.Register(builder, - static_cast( - [](const OpKernelInfo& info) -> OpKernel* { - return new FunctionKernel(info); - }))); + [](FuncManager& func_mgr, const OpKernelInfo& info, std::unique_ptr& out) -> Status { + return FunctionKernel::Create(func_mgr, info, out); + })); } } else { @@ -298,10 +297,9 @@ static Status PartitionOnnxFormatModelImpl(Graph& graph, bool export_dll, FuncMa KernelDefBuilder builder; BuildFusedKernelDef(builder, metadef, type); ORT_RETURN_IF_ERROR(fused_kernel_registry.Register(builder, - static_cast( - [](const OpKernelInfo& info) -> OpKernel* { - return new FunctionKernel(info); - }))); + [](FuncManager& func_mgr, const OpKernelInfo& info, std::unique_ptr& out) -> Status { + return FunctionKernel::Create(func_mgr, info, out); + })); // now that we're done compiling we can remove the original nodes from the Graph and wire in the new one graph.FinalizeFuseSubGraph(indexed_sub_graph, *node); @@ -477,10 +475,10 @@ static Status PartitionOrtFormatModelImpl(Graph& graph, FuncManager& func_mgr, } ORT_RETURN_IF_ERROR(fused_kernel_registry.Register( - KernelCreateInfo(std::move(kernel_def), static_cast( - [](const OpKernelInfo& info) -> OpKernel* { - return new FunctionKernel(info); - })))); + KernelCreateInfo(std::move(kernel_def), + [](FuncManager& func_mgr, const OpKernelInfo& info, std::unique_ptr& out) -> Status { + return FunctionKernel::Create(func_mgr, info, out); + }))); // now that we're done compiling we can remove the original nodes from the Graph and wire in the new one graph.FinalizeFuseSubGraph(indexed_sub_graph, node); diff --git a/onnxruntime/core/framework/kernel_registry.cc b/onnxruntime/core/framework/kernel_registry.cc index 07db21c6b2..de6c47e018 100644 --- a/onnxruntime/core/framework/kernel_registry.cc +++ b/onnxruntime/core/framework/kernel_registry.cc @@ -206,7 +206,7 @@ Status KernelRegistry::TryCreateKernel(const Node& node, const IExecutionProvider& execution_provider, const std::unordered_map& constant_initialized_tensors, const OrtValueNameIdxMap& ort_value_name_idx_map, - const FuncManager& funcs_mgr, + FuncManager& funcs_mgr, const DataTransferManager& data_transfer_mgr, /*out*/ std::unique_ptr& op_kernel) const { const KernelCreateInfo* kernel_create_info = nullptr; @@ -216,10 +216,8 @@ Status KernelRegistry::TryCreateKernel(const Node& node, execution_provider, constant_initialized_tensors, ort_value_name_idx_map, - funcs_mgr, data_transfer_mgr); - op_kernel.reset(kernel_create_info->kernel_create_func(kernel_info)); - return Status::OK(); + return kernel_create_info->kernel_create_func(funcs_mgr, kernel_info, op_kernel); } static std::string ToString(const std::vector& error_strs) { diff --git a/onnxruntime/core/framework/kernel_registry_manager.cc b/onnxruntime/core/framework/kernel_registry_manager.cc index e2137f072a..2041b0d7ba 100644 --- a/onnxruntime/core/framework/kernel_registry_manager.cc +++ b/onnxruntime/core/framework/kernel_registry_manager.cc @@ -13,18 +13,17 @@ using namespace ONNX_NAMESPACE; using namespace ::onnxruntime::common; namespace onnxruntime { -std::unique_ptr KernelRegistryManager::CreateKernel(const onnxruntime::Node& node, - const IExecutionProvider& execution_provider, - const SessionState& session_state, - const KernelCreateInfo& kernel_create_info) const { +Status KernelRegistryManager::CreateKernel(const onnxruntime::Node& node, + const IExecutionProvider& execution_provider, + SessionState& session_state, + const KernelCreateInfo& kernel_create_info, + std::unique_ptr& out) const { OpKernelInfo kernel_info(node, *kernel_create_info.kernel_def, execution_provider, session_state.GetConstantInitializedTensors(), session_state.GetOrtValueNameIdxMap(), - session_state.GetFuncMgr(), session_state.GetDataTransferMgr()); - // OpKernel is abstract base class so can't use make_unique - return std::unique_ptr(kernel_create_info.kernel_create_func(kernel_info)); + return kernel_create_info.kernel_create_func(session_state.GetMutableFuncMgr(), kernel_info, out); } Status KernelRegistryManager::RegisterKernels(const ExecutionProviders& execution_providers) { diff --git a/onnxruntime/core/framework/kernel_registry_manager.h b/onnxruntime/core/framework/kernel_registry_manager.h index 6a4fb6defc..4d9da148af 100644 --- a/onnxruntime/core/framework/kernel_registry_manager.h +++ b/onnxruntime/core/framework/kernel_registry_manager.h @@ -77,10 +77,10 @@ class KernelRegistryManager { bool SearchKernelRegistriesByHash(HashValue kernel_def_hash, const KernelCreateInfo** kernel_create_info) const; - std::unique_ptr CreateKernel(const onnxruntime::Node& node, - const IExecutionProvider& execution_provider, - const SessionState& session_state, - const KernelCreateInfo& kernel_create_info) const ORT_MUST_USE_RESULT; + Status CreateKernel(const onnxruntime::Node& node, + const IExecutionProvider& execution_provider, + SessionState& session_state, + const KernelCreateInfo& kernel_create_info, std::unique_ptr& out) const; ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(KernelRegistryManager); diff --git a/onnxruntime/core/framework/onnxruntime_map_type_info.cc b/onnxruntime/core/framework/onnxruntime_map_type_info.cc index e0b5ffc538..9b18ba6703 100644 --- a/onnxruntime/core/framework/onnxruntime_map_type_info.cc +++ b/onnxruntime/core/framework/onnxruntime_map_type_info.cc @@ -32,7 +32,9 @@ ToONNXTensorElementDataType(ONNX_NAMESPACE::TensorProto_DataType data_type) { default: { return ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; } } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif OrtStatus* OrtMapTypeInfo::FromTypeProto(const ONNX_NAMESPACE::TypeProto* type_proto, OrtMapTypeInfo** out) { auto value_case = type_proto->value_case(); if (value_case != ONNX_NAMESPACE::TypeProto::kMapType) diff --git a/onnxruntime/core/framework/onnxruntime_sequence_type_info.cc b/onnxruntime/core/framework/onnxruntime_sequence_type_info.cc index 18427fd5fc..acae583c7a 100644 --- a/onnxruntime/core/framework/onnxruntime_sequence_type_info.cc +++ b/onnxruntime/core/framework/onnxruntime_sequence_type_info.cc @@ -6,21 +6,20 @@ #include "core/session/ort_apis.h" #include "core/framework/error_code_helper.h" -OrtSequenceTypeInfo::OrtSequenceTypeInfo(OrtTypeInfo* sequence_key_type) noexcept : - sequence_key_type_(sequence_key_type, &OrtApis::ReleaseTypeInfo) { +OrtSequenceTypeInfo::OrtSequenceTypeInfo(OrtTypeInfo* sequence_key_type) noexcept : sequence_key_type_(sequence_key_type, &OrtApis::ReleaseTypeInfo) { } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif OrtStatus* OrtSequenceTypeInfo::FromTypeProto(const ONNX_NAMESPACE::TypeProto* type_proto, OrtSequenceTypeInfo** out) { auto value_case = type_proto->value_case(); - if (value_case != ONNX_NAMESPACE::TypeProto::kSequenceType) - { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "type_proto is not of type sequence!");; + if (value_case != ONNX_NAMESPACE::TypeProto::kSequenceType) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "type_proto is not of type sequence!"); } auto type_proto_sequence = type_proto->sequence_type(); OrtTypeInfo* sequence_key_type_info = nullptr; - if (auto status = OrtTypeInfo::FromTypeProto(&type_proto_sequence.elem_type(), &sequence_key_type_info)) - { + if (auto status = OrtTypeInfo::FromTypeProto(&type_proto_sequence.elem_type(), &sequence_key_type_info)) { return status; } @@ -30,8 +29,7 @@ OrtStatus* OrtSequenceTypeInfo::FromTypeProto(const ONNX_NAMESPACE::TypeProto* t OrtStatus* OrtSequenceTypeInfo::Clone(OrtSequenceTypeInfo** out) { OrtTypeInfo* sequence_key_type_copy = nullptr; - if (auto status = sequence_key_type_->Clone(&sequence_key_type_copy)) - { + if (auto status = sequence_key_type_->Clone(&sequence_key_type_copy)) { return status; } *out = new OrtSequenceTypeInfo(sequence_key_type_copy); diff --git a/onnxruntime/core/framework/onnxruntime_typeinfo.cc b/onnxruntime/core/framework/onnxruntime_typeinfo.cc index 5a26fe2066..e3a07f84ef 100644 --- a/onnxruntime/core/framework/onnxruntime_typeinfo.cc +++ b/onnxruntime/core/framework/onnxruntime_typeinfo.cc @@ -27,7 +27,9 @@ using onnxruntime::Tensor; using onnxruntime::TensorShape; namespace on = ONNX_NAMESPACE; - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif OrtTypeInfo::OrtTypeInfo(ONNXType type1) noexcept : type(type1) { } diff --git a/onnxruntime/core/framework/onnxruntime_typeinfo.h b/onnxruntime/core/framework/onnxruntime_typeinfo.h index 5b9145d32e..67e270f5be 100644 --- a/onnxruntime/core/framework/onnxruntime_typeinfo.h +++ b/onnxruntime/core/framework/onnxruntime_typeinfo.h @@ -4,6 +4,7 @@ #pragma once #include #include +#include "core/common/gsl_suppress.h" #include "core/session/onnxruntime_c_api.h" namespace onnxruntime { diff --git a/onnxruntime/core/framework/op_kernel_info.cc b/onnxruntime/core/framework/op_kernel_info.cc index 4be25b5fe7..0ae43026e6 100644 --- a/onnxruntime/core/framework/op_kernel_info.cc +++ b/onnxruntime/core/framework/op_kernel_info.cc @@ -13,7 +13,6 @@ OpKernelInfo::OpKernelInfo(const onnxruntime::Node& node, const IExecutionProvider& execution_provider, const std::unordered_map& constant_initialized_tensors, const OrtValueNameIdxMap& ort_value_name_idx_map, - const FuncManager& funcs_mgr, const DataTransferManager& data_transfer_mgr) : OpNodeProtoHelper(&proto_helper_context_), node_(node), @@ -21,13 +20,12 @@ OpKernelInfo::OpKernelInfo(const onnxruntime::Node& node, execution_provider_(&execution_provider), constant_initialized_tensors_(constant_initialized_tensors), ort_value_name_idx_map_(ort_value_name_idx_map), - funcs_mgr_(funcs_mgr), data_transfer_mgr_(data_transfer_mgr), proto_helper_context_(node) {} OpKernelInfo::OpKernelInfo(const OpKernelInfo& other) : OpKernelInfo(other.node_, other.kernel_def_, *other.execution_provider_, other.constant_initialized_tensors_, - other.ort_value_name_idx_map_, other.funcs_mgr_, other.data_transfer_mgr_) {} + other.ort_value_name_idx_map_, other.data_transfer_mgr_) {} const OrtMemoryInfo& OpKernelInfo::GetMemoryInfo(int device_id, OrtMemType mem_type) const { AllocatorPtr alloc = GetAllocator(device_id, mem_type); @@ -79,7 +77,4 @@ bool OpKernelInfo::TryGetConstantInput(int input_index, const Tensor** constant_ return true; } -common::Status OpKernelInfo::GetFusedFuncs(NodeComputeInfo*& compute_info) const { - return funcs_mgr_.GetFuncs(node_.Name(), compute_info); -} } // namespace onnxruntime diff --git a/onnxruntime/core/framework/run_options.cc b/onnxruntime/core/framework/run_options.cc index 0a62265515..95c111009c 100644 --- a/onnxruntime/core/framework/run_options.cc +++ b/onnxruntime/core/framework/run_options.cc @@ -5,7 +5,9 @@ #include "core/session/onnxruntime_c_api.h" #include "core/session/ort_apis.h" #include "core/framework/error_code_helper.h" - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif ORT_API_STATUS_IMPL(OrtApis::CreateRunOptions, _Outptr_ OrtRunOptions** out) { API_IMPL_BEGIN *out = new OrtRunOptions(); diff --git a/onnxruntime/core/framework/session_options.h b/onnxruntime/core/framework/session_options.h index 2f17779238..09e679a657 100644 --- a/onnxruntime/core/framework/session_options.h +++ b/onnxruntime/core/framework/session_options.h @@ -5,6 +5,7 @@ #include #include +#include "core/common/gsl_suppress.h" #include "core/session/onnxruntime_c_api.h" #include "core/optimizer/graph_transformer_level.h" #include "core/util/thread_utils.h" diff --git a/onnxruntime/core/framework/session_state.cc b/onnxruntime/core/framework/session_state.cc index 0414d99553..f93b912618 100644 --- a/onnxruntime/core/framework/session_state.cc +++ b/onnxruntime/core/framework/session_state.cc @@ -164,7 +164,7 @@ Status SessionState::CreateKernels(const KernelRegistryManager& kernel_registry_ max_nodeid = std::max(max_nodeid, node.Index()); } session_kernels_.clear(); - session_kernels_.resize(max_nodeid + 1, nullptr); + session_kernels_.resize(max_nodeid + 1); for (const auto& node : nodes) { // construct and save the kernels const KernelCreateInfo& kci = GetNodeKernelCreateInfo(node.Index()); @@ -173,10 +173,8 @@ Status SessionState::CreateKernels(const KernelRegistryManager& kernel_registry_ onnxruntime::ProviderType exec_provider_name = node.GetExecutionProviderType(); const IExecutionProvider& exec_provider = *execution_providers_.Get(exec_provider_name); - auto op_kernel = kernel_registry_manager.CreateKernel(node, exec_provider, *this, kci); - // assumes vector is already resize()'ed to the number of nodes in the graph - session_kernels_[node.Index()] = op_kernel.release(); + ORT_RETURN_IF_ERROR(kernel_registry_manager.CreateKernel(node, exec_provider, *this, kci, session_kernels_[node.Index()])); } } node_index_info_ = std::make_unique(*graph_viewer_, ort_value_name_idx_map_); diff --git a/onnxruntime/core/framework/session_state.h b/onnxruntime/core/framework/session_state.h index bc3be7b01f..b8ec5cb4f8 100644 --- a/onnxruntime/core/framework/session_state.h +++ b/onnxruntime/core/framework/session_state.h @@ -109,9 +109,6 @@ class SessionState { } ~SessionState() { - for (auto* p : session_kernels_) { - delete p; - } for (auto& kvp : deleter_for_initialized_tensors_) { kvp.second.f(kvp.second.param); } @@ -124,11 +121,11 @@ class SessionState { // Get kernel for specified node. // It should called right before graph execution only. const OpKernel* GetKernel(size_t node_id) const { - return (node_id < session_kernels_.size()) ? session_kernels_[node_id] : nullptr; + return (node_id < session_kernels_.size()) ? session_kernels_[node_id].get() : nullptr; } OpKernel* GetMutableKernel(size_t node_id) { - return (node_id < session_kernels_.size()) ? session_kernels_[node_id] : nullptr; + return (node_id < session_kernels_.size()) ? session_kernels_[node_id].get() : nullptr; } const ExecutionProviders& GetExecutionProviders() const noexcept { return execution_providers_; } @@ -144,27 +141,27 @@ class SessionState { const OrtValueNameIdxMap& GetOrtValueNameIdxMap() const noexcept { return ort_value_name_idx_map_; } /** - * Adds an initialized tensor (weight) so that it can be used by the - * execution frame to setup the appropriate OrtValue vectors. - * This function will take a shallow copy of d if d is not NULL. - * If 'constant' is true the tensor value cannot be overridden by an input at runtime. - * If 'sparse' is true the tensor value represents a densified weight that was initially stored in the model - * as sparse tensor. - */ + * Adds an initialized tensor (weight) so that it can be used by the + * execution frame to setup the appropriate OrtValue vectors. + * This function will take a shallow copy of d if d is not NULL. + * If 'constant' is true the tensor value cannot be overridden by an input at runtime. + * If 'sparse' is true the tensor value represents a densified weight that was initially stored in the model + * as sparse tensor. + */ Status AddInitializedTensor(int ort_value_index, const OrtValue& ort_value, const OrtCallback* d, bool constant, bool sparse); /** - * Gets the map of ort_value_index to initialized tensors (weights) so that it can be used by the - * execution frame to setup the appropriate OrtValue vectors. - * The lifetime of returned OrtValues are limited by this SessionState object. - */ + * Gets the map of ort_value_index to initialized tensors (weights) so that it can be used by the + * execution frame to setup the appropriate OrtValue vectors. + * The lifetime of returned OrtValues are limited by this SessionState object. + */ const std::unordered_map& GetInitializedTensors() const; /** - * Gets the map of ort_value_index to initialized tensors (e.g. weights) that are constant - * and cannot be overridden at runtime. - * The lifetime of returned OrtValues are limited by this SessionState object. - */ + * Gets the map of ort_value_index to initialized tensors (e.g. weights) that are constant + * and cannot be overridden at runtime. + * The lifetime of returned OrtValues are limited by this SessionState object. + */ const std::unordered_map& GetConstantInitializedTensors() const; #if !defined(DISABLE_SPARSE_TENSORS) @@ -355,9 +352,9 @@ class SessionState { void CleanInitializedTensorsFromGraph(); /** - * Prepack the constant initialized tensors for better performance. - * The original constant initialized tensors will be removed to save memory. - */ + * Prepack the constant initialized tensors for better performance. + * The original constant initialized tensors will be removed to save memory. + */ Status PrepackConstantInitializedTensors(std::unordered_map& constant_initializers_use_count, const std::unordered_map& initializers_to_share_map); @@ -402,7 +399,7 @@ class SessionState { std::unordered_map compiled_kernel_hashes_; // cache of the constructed kernels to avoid spending construction time per executor - std::vector session_kernels_; + std::vector> session_kernels_; Graph& graph_; std::unique_ptr graph_viewer_; // GraphViewer for const access to Graph diff --git a/onnxruntime/core/framework/sparse_tensor.cc b/onnxruntime/core/framework/sparse_tensor.cc index 223670392a..83ada96c05 100644 --- a/onnxruntime/core/framework/sparse_tensor.cc +++ b/onnxruntime/core/framework/sparse_tensor.cc @@ -22,7 +22,7 @@ std::ostream& operator<<(std::ostream& os, SparseFormat flags) { namespace { // Round up size to a multiple of int64 constexpr size_t kIndexAlignment = alignof(int64_t); -inline int64_t Roundup(int64_t size) { +constexpr inline int64_t Roundup(int64_t size) { return ((SafeInt(size) + kIndexAlignment - 1) / kIndexAlignment) * kIndexAlignment; } @@ -31,7 +31,7 @@ inline int64_t Roundup(int64_t size) { /// after data and make sure indices start at int64_t aligned place ///
/// -inline int64_t CalculateRequiredBufferSize(int64_t data_size, int64_t indices_size) { +constexpr inline int64_t CalculateRequiredBufferSize(int64_t data_size, int64_t indices_size) { return SafeInt(Roundup(data_size)) + indices_size; } diff --git a/onnxruntime/core/framework/tensor_type_and_shape.cc b/onnxruntime/core/framework/tensor_type_and_shape.cc index e1dafc2f83..5f29fabcec 100644 --- a/onnxruntime/core/framework/tensor_type_and_shape.cc +++ b/onnxruntime/core/framework/tensor_type_and_shape.cc @@ -24,7 +24,9 @@ using onnxruntime::MLFloat16; using onnxruntime::SparseTensor; #endif using onnxruntime::Tensor; - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif ORT_API_STATUS_IMPL(OrtApis::CreateTensorTypeAndShapeInfo, _Outptr_ OrtTensorTypeAndShapeInfo** out) { API_IMPL_BEGIN *out = new OrtTensorTypeAndShapeInfo(); @@ -317,10 +319,10 @@ ORT_API_STATUS_IMPL(OrtApis::GetValueType, _In_ const OrtValue* v, _Out_ ONNXTyp } /** -* Get the type information of an OrtValue -* \param value -* \return The returned value should be freed by OrtReleaseTypeInfo after use -*/ + * Get the type information of an OrtValue + * \param value + * \return The returned value should be freed by OrtReleaseTypeInfo after use + */ ORT_API_STATUS_IMPL(OrtApis::GetTypeInfo, _In_ const OrtValue* v, _Outptr_result_maybenull_ struct OrtTypeInfo** out) { API_IMPL_BEGIN // TODO: This is consistent with the previous implementation but inconsistent with GetValueType which returns diff --git a/onnxruntime/core/framework/tensorprotoutils.cc b/onnxruntime/core/framework/tensorprotoutils.cc index ca7416fce0..2b6d2bbed1 100644 --- a/onnxruntime/core/framework/tensorprotoutils.cc +++ b/onnxruntime/core/framework/tensorprotoutils.cc @@ -533,7 +533,9 @@ ORT_API(void, OrtUninitializeBuffer, _In_opt_ void* input, size_t input_len, enu ptr[i].~string(); } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif class AutoDelete { public: OrtCallback d{nullptr, nullptr}; @@ -594,7 +596,7 @@ static Status GetFileContent( * @param tensor_proto tensor data in protobuf format * @param tensorp pre-allocated tensor object, where we store the data * @return -*/ + */ Status TensorProtoToTensor(const Env& env, const ORTCHAR_T* model_path, const ONNX_NAMESPACE::TensorProto& tensor_proto, Tensor& tensor) { @@ -830,7 +832,7 @@ common::Status ConstantNodeProtoToTensorProto(const ONNX_NAMESPACE::NodeProto& n break; } #else - ORT_UNUSED_PARAMETER(model_path); + ORT_UNUSED_PARAMETER(model_path); #endif default: ORT_THROW("Unsupported attribute value type of ", constant_attribute.type(), @@ -1098,7 +1100,6 @@ inline void CopyElement(void* dst, const void* src, int64_t dst_index, reinterpret_cast(dst)[dst_index] = reinterpret_cast(src)[src_index]; } - template static void SetIndices(gsl::span gathered_indices, std::string& raw_indices, @@ -1109,7 +1110,8 @@ static void SetIndices(gsl::span gathered_indices, for (auto src_index : gathered_indices) { ORT_IF_CONSTEXPR(sizeof(T) == sizeof(int8_t)) { ind_dest[dest_index] = static_cast(src_index); - } else { + } + else { auto* dst = ind_dest + dest_index; T v = static_cast(src_index); memcpy(dst, &v, sizeof(T)); diff --git a/onnxruntime/core/framework/utils.cc b/onnxruntime/core/framework/utils.cc index 840b0321ac..bf76d3bcbd 100644 --- a/onnxruntime/core/framework/utils.cc +++ b/onnxruntime/core/framework/utils.cc @@ -563,14 +563,14 @@ static common::Status ExecuteGraphImpl(const SessionState& session_state, const logging::Logger& logger, const bool only_execute_path_to_fetches = false) { std::unique_ptr p_exec; if (execution_mode == ExecutionMode::ORT_SEQUENTIAL) { - p_exec = std::unique_ptr(new SequentialExecutor(terminate_flag, only_execute_path_to_fetches)); + p_exec = std::make_unique(terminate_flag, only_execute_path_to_fetches); } else if (execution_mode == ExecutionMode::ORT_PARALLEL) { auto* p_inter_op_thread_pool = session_state.GetInterOpThreadPool(); if (!p_inter_op_thread_pool) { LOGS(logger, WARNING) << "Only one thread was configured for parallel execution. Hence will use sequential execution."; - p_exec = std::unique_ptr(new SequentialExecutor(terminate_flag, only_execute_path_to_fetches)); + p_exec = std::make_unique(terminate_flag, only_execute_path_to_fetches); } else { - p_exec = std::unique_ptr(new ParallelExecutor(session_state, terminate_flag)); + p_exec = std::make_unique(session_state, terminate_flag); } } diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 3e81f43850..f854839abe 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -705,7 +705,7 @@ flatbuffers::Offset Node::SaveEdgesToOrtFormat(flatbuffers::FlatB Status Node::LoadFromOrtFormat(const onnxruntime::fbs::Node& fbs_node, Graph& graph, const logging::Logger& logger, std::unique_ptr& node) { - node.reset(new Node(fbs_node.index(), graph)); + node = std::make_unique(fbs_node.index(), graph); return node->LoadFromOrtFormat(fbs_node, logger); } @@ -860,9 +860,9 @@ void Node::CreateSubgraph(const std::string& attr_name) { if (attr != attributes_.cend() && utils::HasGraph(attr->second)) { GraphProto& mutable_graph = *attr->second.mutable_g(); - std::unique_ptr subgraph{new Graph(*graph_, *this, mutable_graph)}; + std::unique_ptr subgraph = std::make_unique(*graph_, *this, mutable_graph); attr_to_subgraph_map_.insert({std::string(attr_name), gsl::not_null{subgraph.get()}}); - subgraphs_.push_back(std::move(subgraph)); + subgraphs_.emplace_back(std::move(subgraph)); } } @@ -3999,7 +3999,7 @@ Status Graph::InlineFunction(Node& node) { // main graph. const Graph& subgraph = node.GetFunctionBody()->Body(); auto output_edges = node.GetRelationships().output_edges; - for (auto output_edge : output_edges) { + for (const auto& output_edge : output_edges) { RemoveEdge(node.Index(), output_edge.GetNode().Index(), output_edge.GetSrcArgIndex(), output_edge.GetDstArgIndex()); } @@ -4130,7 +4130,7 @@ void Graph::SetNodeArgType(NodeArg& arg, const ONNX_NAMESPACE::TypeProto& type_p GraphResolveNeeded(true); } -#endif // !defined(ORT_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) Graph::~Graph() { // nothing to do, but we put it here so we don't need to fully define types in Graph that are held in unique_ptr @@ -4216,12 +4216,11 @@ Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph, IOnnxRuntimeOpSchemaCollectionPtr schema_registry, #endif const logging::Logger& logger, std::unique_ptr& graph) { - // can't use make_unique as we're calling a private ctor - graph.reset(new Graph(owning_model, domain_to_version, + graph = std::make_unique(owning_model, domain_to_version, #if !defined(ORT_MINIMAL_BUILD) - schema_registry, + schema_registry, #endif - nullptr, nullptr, logger)); + nullptr, nullptr, logger); ORT_RETURN_IF_ERROR(graph->LoadFromOrtFormat(fbs_graph)); @@ -4240,14 +4239,13 @@ Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph, Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph, Graph& parent_graph, const Node& parent_node, const logging::Logger& logger, std::unique_ptr& graph) { - // can't use make_unique as we're calling a private ctor - graph.reset(new Graph(parent_graph.owning_model_, - parent_graph.domain_to_version_, + graph = std::make_unique(parent_graph.owning_model_, + parent_graph.domain_to_version_, #if !defined(ORT_MINIMAL_BUILD) - parent_graph.schema_registry_, + parent_graph.schema_registry_, #endif - &parent_graph, &parent_node, - logger)); + &parent_graph, &parent_node, + logger); return graph->LoadFromOrtFormat(fbs_graph); } @@ -4348,8 +4346,7 @@ common::Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph ORT_RETURN_IF(nullptr == fbs_value_info, "NodeArg is missing. Invalid ORT format model."); NodeArgInfo node_arg_info; ORT_RETURN_IF_ERROR(fbs::utils::LoadValueInfoOrtFormat(*fbs_value_info, node_arg_info)); - // NodeArg ctor is private, cannot use make_unique - node_args_[fbs_value_info->name()->str()] = std::unique_ptr(new NodeArg(std::move(node_arg_info))); + node_args_[fbs_value_info->name()->str()] = std::make_unique(std::move(node_arg_info)); } } diff --git a/onnxruntime/core/graph/model.cc b/onnxruntime/core/graph/model.cc index f04b32d6b6..e9e34c17cd 100644 --- a/onnxruntime/core/graph/model.cc +++ b/onnxruntime/core/graph/model.cc @@ -347,7 +347,7 @@ Status Model::Load(const ModelProto& model_proto, auto status = Status::OK(); ORT_TRY { - model.reset(new Model(model_proto, model_path, local_registries, logger)); + model = std::make_unique(model_proto, model_path, local_registries, logger); } ORT_CATCH(const std::exception& ex) { ORT_HANDLE_EXCEPTION([&]() { @@ -386,7 +386,7 @@ Status Model::Load(ModelProto&& model_proto, GSL_SUPPRESS(r .11) auto status = Status::OK(); ORT_TRY { - model.reset(new Model(std::move(model_proto), model_path, local_registries, logger, allow_released_opsets_only)); + model = std::make_unique(std::move(model_proto), model_path, local_registries, logger, allow_released_opsets_only); } ORT_CATCH(const std::exception& ex) { ORT_HANDLE_EXCEPTION([&]() { @@ -730,7 +730,7 @@ common::Status Model::LoadFromOrtFormat(const fbs::Model& fbs_model, #endif const logging::Logger& logger, std::unique_ptr& model) { - model.reset(new Model()); + model = std::make_unique(); // Load the model metadata if (const auto* fbs_metadata_props = fbs_model.metadata_props()) { diff --git a/onnxruntime/core/graph/model.h b/onnxruntime/core/graph/model.h index 77cd279284..5425c3ee08 100644 --- a/onnxruntime/core/graph/model.h +++ b/onnxruntime/core/graph/model.h @@ -272,9 +272,9 @@ class Model { const logging::Logger& logger, std::unique_ptr& model); - private: Model(); + private: // Model data. #if !defined(ORT_MINIMAL_BUILD) ONNX_NAMESPACE::ModelProto model_proto_; diff --git a/onnxruntime/core/mlas/lib/convolve.cpp b/onnxruntime/core/mlas/lib/convolve.cpp index 78eceda4fc..4b5c682384 100644 --- a/onnxruntime/core/mlas/lib/convolve.cpp +++ b/onnxruntime/core/mlas/lib/convolve.cpp @@ -1018,6 +1018,7 @@ Return Value: } #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif void diff --git a/onnxruntime/core/mlas/lib/dgemm.cpp b/onnxruntime/core/mlas/lib/dgemm.cpp index 3688699843..b98d6f8bb2 100644 --- a/onnxruntime/core/mlas/lib/dgemm.cpp +++ b/onnxruntime/core/mlas/lib/dgemm.cpp @@ -805,6 +805,7 @@ Return Value: #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif void diff --git a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp index c968c2aae5..eb8ef4e274 100644 --- a/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp +++ b/onnxruntime/core/mlas/lib/qgemm_kernel_default.cpp @@ -34,7 +34,7 @@ constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::Strides; constexpr MLAS_GEMM_QUANT_STRIDES MLAS_GEMM_QUANT_KERNEL_DEFAULT::PackedStrides; template<> -MLAS_FORCEINLINE constexpr +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointA( int32_t ZeroPointA, @@ -49,7 +49,7 @@ MlasGemmQuantFixupZeroPointA( } template<> -MLAS_FORCEINLINE +MLAS_FORCEINLINE constexpr int32_t MlasGemmQuantFixupZeroPointB( int32_t ZeroPointB, diff --git a/onnxruntime/core/mlas/lib/sgemm.cpp b/onnxruntime/core/mlas/lib/sgemm.cpp index 0360127ca0..62170a2573 100644 --- a/onnxruntime/core/mlas/lib/sgemm.cpp +++ b/onnxruntime/core/mlas/lib/sgemm.cpp @@ -1554,6 +1554,7 @@ Return Value: } #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) +// Chance of arithmetic overflow could be reduced #pragma warning(disable : 26451) #endif void diff --git a/onnxruntime/core/optimizer/optimizer_execution_frame.cc b/onnxruntime/core/optimizer/optimizer_execution_frame.cc index 828bfdbf87..77161ed6a8 100644 --- a/onnxruntime/core/optimizer/optimizer_execution_frame.cc +++ b/onnxruntime/core/optimizer/optimizer_execution_frame.cc @@ -41,7 +41,7 @@ OptimizerExecutionFrame::Info::Info(const std::vector& nodes, size_t cpu_tensor_length; ORT_RETURN_IF_ERROR(utils::GetSizeInBytesFromTensorProto<0>(tensor_proto, &cpu_tensor_length)); OrtValue ort_value; - std::unique_ptr data(new char[cpu_tensor_length]); + std::unique_ptr data = std::make_unique(cpu_tensor_length); std::unique_ptr p_tensor; ORT_RETURN_IF_ERROR(utils::TensorProtoToMLValue(Env::Default(), model_path.IsEmpty() ? nullptr : model_path.ToPathString().c_str(), @@ -103,8 +103,9 @@ OptimizerExecutionFrame::Info::Info(const std::vector& nodes, std::unique_ptr OptimizerExecutionFrame::Info::CreateKernel(const Node* node) const { std::unique_ptr op_kernel; std::shared_ptr kernel_registry = execution_provider_.GetKernelRegistry(); + FuncManager func; auto status = kernel_registry->TryCreateKernel(*node, execution_provider_, initializers_, - ort_value_name_idx_map_, FuncManager(), data_transfer_mgr_, + ort_value_name_idx_map_, func, data_transfer_mgr_, op_kernel); // Kernel found in the CPU kernel registry diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc index fb1c49e312..b5a90c36a9 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc @@ -28,10 +28,10 @@ void DropQDQNodesRules(SelectorsAndActions& qdq_selectors_and_actions) { MoveToSlot(dq, ArgType::kInput, 0, ArgType::kInput, 0), MoveToSlot(q, ArgType::kOutput, 0, ArgType::kOutput, 0)}; - std::unique_ptr action(new MergeIntoTarget(std::move(moves))); + std::unique_ptr action = std::make_unique(std::move(moves)); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::DropDQDNodesSelector()); + std::unique_ptr selector = std::make_unique(); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"Gather", {}}, {"Reshape", {}}, @@ -49,10 +49,10 @@ void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int // 3 nodes. DQ, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"1DQ"}; - std::unique_ptr action(new QDQ::UnaryReplaceWithQLinear(kMSDomain)); + std::unique_ptr action = std::make_unique(kMSDomain); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::UnarySelector(is_int8_allowed)); + std::unique_ptr selector = std::make_unique(is_int8_allowed); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"AveragePool", {}}}, std::move(selector), @@ -67,10 +67,10 @@ void BinaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { // 4 nodes. 2 x DQ for inputs, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"2DQ"}; - std::unique_ptr action(new QDQ::BinaryReplaceWithQLinear(kMSDomain)); + std::unique_ptr action = std::make_unique(kMSDomain); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::BinarySelector()); + std::unique_ptr selector = std::make_unique(); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"Add", {}}, {"Mul", {}}}, @@ -86,10 +86,10 @@ void VariadicOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { // 0=variadic DQ nodes 2=target, 3=Q // Replace with QLinear version of operator. Delete all original nodes. const std::string action_name{"*DQ"}; - std::unique_ptr action(new QDQ::VariadicReplaceWithQLinear(kMSDomain)); + std::unique_ptr action = std::make_unique(kMSDomain); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::VariadicSelector()); + std::unique_ptr selector = std::make_unique(); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"Concat", {}}}, @@ -107,10 +107,10 @@ void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_a // Replace Conv with QLinearConv // Delete all original nodes const std::string action_name{"Conv"}; - std::unique_ptr action(new QDQ::ConvReplaceWithQLinear()); + std::unique_ptr action = std::make_unique(); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::ConvSelector(is_int8_allowed)); + std::unique_ptr selector = std::make_unique(is_int8_allowed); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"Conv", {}}}, @@ -129,10 +129,10 @@ void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8 // Delete all original nodes. const std::string action_name{"MatMul"}; - std::unique_ptr action(new QDQ::MatMulReplaceWithQLinear()); + std::unique_ptr action = std::make_unique(); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector(new QDQ::MatMulSelector(is_int8_allowed)); + std::unique_ptr selector = std::make_unique(is_int8_allowed); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, SelectorAndAction::OpVersionsMap{{"MatMul", {}}}, std::move(selector), diff --git a/onnxruntime/core/platform/windows/env.cc b/onnxruntime/core/platform/windows/env.cc index 01ad7b1521..6e370fffa2 100644 --- a/onnxruntime/core/platform/windows/env.cc +++ b/onnxruntime/core/platform/windows/env.cc @@ -54,6 +54,11 @@ class WindowsThread : public EnvThread { unsigned (*start_address)(int id, Eigen::ThreadPoolInterface* param); Eigen::ThreadPoolInterface* param; const ThreadOptions& thread_options; + Param(const ORTCHAR_T* name_prefix1, + int index1, + unsigned (*start_address1)(int id, Eigen::ThreadPoolInterface* param), + Eigen::ThreadPoolInterface* param1, + const ThreadOptions& thread_options1) : name_prefix(name_prefix1), index(index1), start_address(start_address1), param(param1), thread_options(thread_options1) {} }; public: @@ -63,15 +68,15 @@ class WindowsThread : public EnvThread { custom_create_thread_fn = thread_options.custom_create_thread_fn; custom_thread_creation_options = thread_options.custom_thread_creation_options; custom_join_thread_fn = thread_options.custom_join_thread_fn; - + std::unique_ptr local_param = std::make_unique(name_prefix, index, start_address, param, thread_options); if (custom_create_thread_fn) { - custom_thread_handle = custom_create_thread_fn(custom_thread_creation_options, (OrtThreadWorkerFn)CustomThreadMain, new Param{name_prefix, index, start_address, param, thread_options}); + custom_thread_handle = custom_create_thread_fn(custom_thread_creation_options, (OrtThreadWorkerFn)CustomThreadMain, local_param.release()); if (!custom_thread_handle) { - ORT_THROW("custom_create_thread_fn returned invalid handle."); + ORT_THROW("custom_create_thread_fn returned invalid handle."); } } else { hThread.reset(reinterpret_cast(_beginthreadex(nullptr, thread_options.stack_size, ThreadMain, - new Param{name_prefix, index, start_address, param, thread_options}, 0, + local_param.release(), 0, &threadID))); } } @@ -142,12 +147,18 @@ class WindowsThread : public EnvThread { class WindowsEnv : public Env { public: +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26409) +#endif EnvThread* CreateThread(_In_opt_z_ const ORTCHAR_T* name_prefix, int index, unsigned (*start_address)(int id, Eigen::ThreadPoolInterface* param), Eigen::ThreadPoolInterface* param, const ThreadOptions& thread_options) { return new WindowsThread(name_prefix, index, start_address, param, thread_options); } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif void SleepForMicroseconds(int64_t micros) const override { Sleep(static_cast(micros) / 1000); } @@ -524,14 +535,32 @@ class WindowsEnv : public Env { } virtual Status LoadDynamicLibrary(const std::string& library_filename, bool /*global_symbols*/, void** handle) const override { + const std::wstring& wlibrary_filename = ToWideString(library_filename); #if WINAPI_FAMILY == WINAPI_FAMILY_PC_APP - *handle = ::LoadPackagedLibrary(ToWideString(library_filename).c_str(), 0); + *handle = ::LoadPackagedLibrary(wlibrary_filename.c_str(), 0); #else - *handle = ::LoadLibraryExA(library_filename.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); + // TODO: in most cases, the path name is a relative path and the behavior of the following line of code is undefined. + *handle = ::LoadLibraryExW(wlibrary_filename.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); #endif if (!*handle) { const auto error_code = GetLastError(); - return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "LoadLibrary failed with error ", error_code, " \"", std::system_category().message(error_code), "\" when trying to load \"", library_filename, "\""); + LPVOID lpMsgBuf; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&lpMsgBuf, + 0, NULL); + std::wostringstream oss; + oss << L"LoadLibrary failed with error " << error_code << L" \"" << (LPWSTR)lpMsgBuf << L"\" when trying to load \"" << wlibrary_filename << L"\""; + std::wstring errmsg = oss.str(); + // TODO: errmsg should be converted to UTF-8 as it will be passed out to the C interface. + common::Status status(common::ONNXRUNTIME, common::FAIL, ToMBString(errmsg)); + LocalFree(lpMsgBuf); + return status; } return Status::OK(); } @@ -548,7 +577,23 @@ class WindowsEnv : public Env { *symbol = ::GetProcAddress(reinterpret_cast(handle), symbol_name.c_str()); if (!*symbol) { const auto error_code = GetLastError(); - return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to find symbol in library, error code: ", error_code, " - ", std::system_category().message(error_code)); + LPVOID lpMsgBuf; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&lpMsgBuf, + 0, NULL); + std::wostringstream oss; + oss << L"Failed to find symbol " << ToWideString(symbol_name) << L" in library, error code: " << error_code << L" \"" << (LPWSTR)lpMsgBuf << L"\""; + std::wstring errmsg = oss.str(); + // TODO: errmsg should be converted to UTF-8 as it will be passed out to the C interface. + common::Status status(common::ONNXRUNTIME, common::FAIL, ToMBString(errmsg)); + LocalFree(lpMsgBuf); + return status; } return Status::OK(); } @@ -576,11 +621,11 @@ class WindowsEnv : public Env { // Create buffer to hold the result std::string buffer(kBufferSize, '\0'); - //The last argument is the size of the buffer pointed to by the lpBuffer parameter, including the null-terminating character, in characters. - //If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer, not including the terminating null character. - //Therefore, If the function succeeds, kBufferSize should be larger than char_count. + // The last argument is the size of the buffer pointed to by the lpBuffer parameter, including the null-terminating character, in characters. + // If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer, not including the terminating null character. + // Therefore, If the function succeeds, kBufferSize should be larger than char_count. auto char_count = GetEnvironmentVariableA(var_name.c_str(), buffer.data(), kBufferSize); - + if (kBufferSize > char_count) { buffer.resize(char_count); return buffer; diff --git a/onnxruntime/core/platform/windows/stacktrace.cc b/onnxruntime/core/platform/windows/stacktrace.cc index 53e403a042..4e159b8edd 100644 --- a/onnxruntime/core/platform/windows/stacktrace.cc +++ b/onnxruntime/core/platform/windows/stacktrace.cc @@ -104,7 +104,7 @@ std::vector CaptureStackTrace::Trace() const { stacktrace.reserve(num_frames); // hide CaptureStackTrace::Trace and GetStackTrace so the output starts with the 'real' location - const int frames_to_skip = 2; + constexpr int frames_to_skip = 2; // we generally want to skip the first two frames, but if something weird is going on (e.g. code coverage is // running) and we only have 1 or 2 frames, output them so there's at least something that may be meaningful diff --git a/onnxruntime/core/providers/common.h b/onnxruntime/core/providers/common.h index 0b9179c0b4..22949ed297 100644 --- a/onnxruntime/core/providers/common.h +++ b/onnxruntime/core/providers/common.h @@ -118,9 +118,9 @@ inline Status ComputePad(const int64_t in_dim, return Status::OK(); } -inline int64_t ComputeOutputShape(const int64_t in_dim, - const int64_t stride, const int64_t kernel, const int64_t dilation, - const int64_t pad_head, const int64_t pad_tail) { +constexpr inline int64_t ComputeOutputShape(const int64_t in_dim, + const int64_t stride, const int64_t kernel, const int64_t dilation, + const int64_t pad_head, const int64_t pad_tail) { const int64_t dkernel = dilation * (kernel - 1) + 1; return static_cast(static_cast(in_dim + pad_head + pad_tail - dkernel) / stride + 1); } diff --git a/onnxruntime/core/providers/cpu/activation/activations.h b/onnxruntime/core/providers/cpu/activation/activations.h index 75a73a818d..9b5fd84929 100644 --- a/onnxruntime/core/providers/cpu/activation/activations.h +++ b/onnxruntime/core/providers/cpu/activation/activations.h @@ -84,6 +84,7 @@ struct Softplus : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes&) { return Status::OK(); } + GSL_SUPPRESS(r .11) ElementWiseRangedTransform* Copy() const { using T1 = typename std::remove_pointer::type; using T2 = typename std::remove_const::type; @@ -106,6 +107,7 @@ struct Relu : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes&) { return Status::OK(); } + GSL_SUPPRESS(r .11) ElementWiseRangedTransform* Copy() const { // replace it with a macro. why this? using T1 = typename std::remove_pointer::type; using T2 = typename std::remove_const::type; //redundant? @@ -128,6 +130,7 @@ struct Sigmoid : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes&) { return Status::OK(); } + GSL_SUPPRESS(r .11) ElementWiseRangedTransform* Copy() const { using T1 = typename std::remove_pointer::type; using T2 = typename std::remove_const::type; @@ -153,6 +156,7 @@ struct Softsign : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes&) { return Status::OK(); } + GSL_SUPPRESS(r .11) ElementWiseRangedTransform* Copy() const { using T1 = typename std::remove_pointer::type; using T2 = typename std::remove_const::type; @@ -175,6 +179,7 @@ struct Tanh : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes&) { return Status::OK(); } + GSL_SUPPRESS(r .11) ElementWiseRangedTransform* Copy() const { using T1 = typename std::remove_pointer::type; using T2 = typename std::remove_const::type; @@ -192,6 +197,7 @@ struct Tanh : public ElementWiseRangedTransform { ym = xm.tanh(); } }; + template <> void Tanh::operator()(std::ptrdiff_t first, std::ptrdiff_t last) const; @@ -226,7 +232,6 @@ struct Selu : public ElementWiseRangedTransform { ym = (T)gamma * (xm.cwiseMax(0.0f) + ((T)alpha * (xm.array().exp() - 1.0f)).cwiseMin(0.0f)); } }; - } // namespace functors DEFINE_ELE_KERNEL(Celu); diff --git a/onnxruntime/core/providers/cpu/controlflow/loop.cc b/onnxruntime/core/providers/cpu/controlflow/loop.cc index b844d79206..fac00d83b0 100644 --- a/onnxruntime/core/providers/cpu/controlflow/loop.cc +++ b/onnxruntime/core/providers/cpu/controlflow/loop.cc @@ -142,7 +142,7 @@ Loop::Info::Info(const onnxruntime::Node& node, const GraphViewer& subgraph_in) const auto& node_input_types = node.InputDefs(); loop_carried_vars_types.reserve(num_subgraph_inputs); for (int i = 0; i < num_loop_carried_vars; ++i) { - loop_carried_vars_types.push_back(node_input_types[i + 2]->TypeAsProto()); + loop_carried_vars_types.push_back(node_input_types[static_cast(i) + 2]->TypeAsProto()); } auto& subgraph_inputs = subgraph.GetInputs(); @@ -280,7 +280,7 @@ common::Status Loop::SetupSubgraphExecutionInfo(const SessionState& session_stat // the Loop inputs are matched to subgraph feeds based on order. // we first need the names of the Loop inputs to determine what device they are available on std::vector feed_names; - feed_names.reserve(info_->num_subgraph_inputs + info_->num_implicit_inputs); + feed_names.reserve(static_cast(info_->num_subgraph_inputs) + info_->num_implicit_inputs); // iter_num and cond subgraph inputs - created by the LoopImpl::Initialize so the name doesn't matter // as we skip them when we call FindDevicesForValues, and default them to always being on CPU. @@ -291,7 +291,7 @@ common::Status Loop::SetupSubgraphExecutionInfo(const SessionState& session_stat const auto& loop_inputs = node.InputDefs(); for (int i = 0; i < info_->num_loop_carried_vars; ++i) { // + 2 to skip 'M' and 'cond' Loop inputs - feed_names.push_back(loop_inputs[i + 2]->Name()); + feed_names.push_back(loop_inputs[static_cast(i) + 2]->Name()); } for (auto& entry : node.ImplicitInputDefs()) { @@ -306,7 +306,7 @@ common::Status Loop::SetupSubgraphExecutionInfo(const SessionState& session_stat // now update the feed names to use the subgraph input names for the loop carried vars so that we can determine // what device the subgraph needs them on - for (int i = 0; i < info_->num_loop_carried_vars; ++i) { + for (ptrdiff_t i = 0; i < info_->num_loop_carried_vars; ++i) { // +2 for both to skip the iter_num and cond values feed_names[i + 2] = info_->subgraph_input_names[i + 2]; } @@ -329,7 +329,7 @@ common::Status Loop::SetupSubgraphExecutionInfo(const SessionState& session_stat // Loop state variables need to be where we can feed them in to the next iteration, so set the fetch location // to match the feed location. - for (int i = 0; i < info_->num_loop_carried_vars; ++i) { + for (ptrdiff_t i = 0; i < info_->num_loop_carried_vars; ++i) { // +2 for both to skip the iter_num and cond input values const auto& alloc_info = utils::FindMemoryInfoForValue(session_state, loop_inputs[i + 2]->Name()); fetch_locations.push_back(&alloc_info); @@ -421,13 +421,13 @@ Status LoopImpl::Initialize() { iter_num_mlvalue_ = MakeScalarMLValue(cpu_allocator, 0, iter_num_rank != 0); condition_mlvalue_ = MakeScalarMLValue(cpu_allocator, condition_, condition_rank != 0); - loop_output_tensors_.resize(info_.num_outputs - info_.num_loop_carried_vars); + loop_output_tensors_.resize(static_cast(info_.num_outputs) - info_.num_loop_carried_vars); return status; } void LoopImpl::CreateInitialFeeds(std::vector& feeds) { - feeds.reserve(info_.num_subgraph_inputs + info_.num_implicit_inputs); + feeds.reserve(static_cast(info_.num_subgraph_inputs) + info_.num_implicit_inputs); // This ordering is the same as used in SetupSubgraphExecutionInfo feeds.push_back(iter_num_mlvalue_); @@ -450,12 +450,12 @@ void LoopImpl::SaveOutputsAndUpdateFeeds(const std::vector& last_outpu // next_input: iter_num, cond, loop_vars. iter_num is re-used // simple copy for cond and loop carried vars. start at 1 to skip iter_num in input - for (int i = 1; i < info_.num_subgraph_inputs; ++i) { + for (ptrdiff_t i = 1; i < info_.num_subgraph_inputs; ++i) { next_inputs[i] = last_outputs[i - 1]; } // save loop outputs as we have to concatenate at the end - for (int j = info_.num_loop_carried_vars; j < info_.num_outputs; ++j) { + for (ptrdiff_t j = info_.num_loop_carried_vars; j < info_.num_outputs; ++j) { ORT_ENFORCE(last_outputs[j + 1].IsTensor(), "All scan outputs MUST be tensors"); loop_output_tensors_[j - info_.num_loop_carried_vars].push_back(last_outputs[j + 1]); // skip 'cond' in output } @@ -570,13 +570,13 @@ Status LoopImpl::Execute(const FeedsFetchesManager& ffm) { if (iter_num_value != 0) { for (int i = 0; i < info_.num_loop_carried_vars; ++i) { // need to allocate Loop output and copy OrtValue from fetches - ORT_RETURN_IF_ERROR(copy_mlvalue_to_output(fetches[i + 1], i, iter_num_value, *info_.loop_carried_vars_types[i])); // skip cond + ORT_RETURN_IF_ERROR(copy_mlvalue_to_output(fetches[static_cast(i) + 1], i, iter_num_value, *info_.loop_carried_vars_types[static_cast(i)])); // skip cond } for (int i = info_.num_loop_carried_vars; i < info_.num_outputs; ++i) { // add last output - auto& per_iteration_outputs = loop_output_tensors_[i - info_.num_loop_carried_vars]; - per_iteration_outputs.push_back(fetches[i + 1]); // skip cond + auto& per_iteration_outputs = loop_output_tensors_[static_cast(i) - info_.num_loop_carried_vars]; + per_iteration_outputs.push_back(fetches[static_cast(i) + 1]); // skip cond ORT_RETURN_IF_ERROR(ConcatenateLoopOutput(per_iteration_outputs, i)); } @@ -584,7 +584,7 @@ Status LoopImpl::Execute(const FeedsFetchesManager& ffm) { // no iterations. // copy input loop carried vars to output. for (int i = 0; i < info_.num_loop_carried_vars; ++i) { - ORT_RETURN_IF_ERROR(copy_mlvalue_to_output(feeds[i + 2], i, iter_num_value, *info_.loop_carried_vars_types[i])); // skip iter# and cond + ORT_RETURN_IF_ERROR(copy_mlvalue_to_output(feeds[static_cast(i) + 2], i, iter_num_value, *info_.loop_carried_vars_types[i])); // skip iter# and cond } // create empty outputs for loop outputs using the subgraph output shapes for the rank @@ -592,11 +592,11 @@ Status LoopImpl::Execute(const FeedsFetchesManager& ffm) { for (int i = info_.num_loop_carried_vars; i < info_.num_outputs; ++i) { // get shape from subgraph output if possible to attempt to have the correct rank - auto* graph_output = graph_outputs.at(i + 1); // + 1 as first subgraph output is condition value + auto* graph_output = graph_outputs.at(static_cast(i) + 1); // + 1 as first subgraph output is condition value auto* graph_output_shape = graph_output->Shape(); std::vector output_dims; - output_dims.reserve((graph_output_shape ? graph_output_shape->dim_size() : 0) + 1); + output_dims.reserve(static_cast(graph_output_shape ? graph_output_shape->dim_size() : 0) + 1); output_dims.push_back(0); // num iterations is first dim if (graph_output_shape) { diff --git a/onnxruntime/core/providers/cpu/controlflow/scan_8.cc b/onnxruntime/core/providers/cpu/controlflow/scan_8.cc index b5765bf5ca..53e7ae0e69 100644 --- a/onnxruntime/core/providers/cpu/controlflow/scan_8.cc +++ b/onnxruntime/core/providers/cpu/controlflow/scan_8.cc @@ -161,7 +161,7 @@ Status Scan<8>::SetupSubgraphExecutionInfo(const SessionState& session_state, const auto& node = Node(); info_ = std::make_unique::Info>(node, subgraph_session_state.GetGraphViewer(), - static_cast(num_scan_inputs_)); + static_cast(num_scan_inputs_)); auto status = scan::detail::CreateFeedsFetchesManager(node, *info_, session_state, subgraph_session_state, /* is_v8 */ true, feeds_fetches_manager_); @@ -396,13 +396,13 @@ Status Scan8Impl::Execute(const FeedsFetchesManager& ffm) { // Setup input OrtValue streams std::vector::Iterator> scan_input_stream_iterators; - scan_input_stream_iterators.reserve(info_.num_variadic_inputs - info_.num_loop_state_variables); + scan_input_stream_iterators.reserve(static_cast(info_.num_variadic_inputs) - info_.num_loop_state_variables); for (int i = info_.num_loop_state_variables, end = info_.num_variadic_inputs; i < end; ++i) { const auto& ort_value = GetSubgraphInputMLValue(context_, i); // forward - if (directions_[i - info_.num_loop_state_variables] == static_cast(ScanDirection::kForward)) { + if (directions_[static_cast(i) - info_.num_loop_state_variables] == static_cast(ScanDirection::kForward)) { // the iterator is self contained, so we don't need to keep the OrtValueTensorSlicer instance around scan_input_stream_iterators.push_back(device_helpers_.create_const_slicer_func(ort_value, 1, b).begin()); } else { // reverse diff --git a/onnxruntime/core/providers/cpu/controlflow/scan_9.cc b/onnxruntime/core/providers/cpu/controlflow/scan_9.cc index 001c2d9ac8..c387a3da4c 100644 --- a/onnxruntime/core/providers/cpu/controlflow/scan_9.cc +++ b/onnxruntime/core/providers/cpu/controlflow/scan_9.cc @@ -205,7 +205,7 @@ Status Scan<9>::SetupSubgraphExecutionInfo(const SessionState& session_state, const auto& node = Node(); info_ = std::make_unique::Info>(node, subgraph_session_state.GetGraphViewer(), - static_cast(num_scan_inputs_)); + static_cast(num_scan_inputs_)); auto status = scan::detail::CreateFeedsFetchesManager(node, *info_, session_state, subgraph_session_state, /* is_v8 */ false, feeds_fetches_manager_); @@ -281,7 +281,7 @@ Status ScanImpl::ValidateSubgraphInput(int start_input, int end_input, " Expected ", min_dims_required, " dimensions or more but input had shape of ", input_shape); - auto seq_len_dim = input_axes_[i - info_.num_loop_state_variables]; + auto seq_len_dim = input_axes_[static_cast(i) - info_.num_loop_state_variables]; auto this_seq_len = input_shape[seq_len_dim]; if (sequence_len_ < 0) { @@ -432,7 +432,7 @@ Status ScanImpl::Execute(const FeedsFetchesManager& ffm) { // Setup input OrtValue streams std::vector::Iterator> scan_input_stream_iterators; - scan_input_stream_iterators.reserve(info_.num_inputs - info_.num_loop_state_variables); + scan_input_stream_iterators.reserve(static_cast(info_.num_inputs) - info_.num_loop_state_variables); for (int i = 0, end = info_.num_scan_inputs; i < end; ++i) { const auto& ort_value = inputs_[i]; diff --git a/onnxruntime/core/providers/cpu/controlflow/scan_utils.cc b/onnxruntime/core/providers/cpu/controlflow/scan_utils.cc index 49a5cb19ec..e5b25b56a4 100644 --- a/onnxruntime/core/providers/cpu/controlflow/scan_utils.cc +++ b/onnxruntime/core/providers/cpu/controlflow/scan_utils.cc @@ -142,7 +142,7 @@ Status CreateFeedsFetchesManager(const Node& node, // we need the names of the Scan inputs to determine what device they are available on, // so first create a list using those value std::vector feed_names; - feed_names.reserve(info.num_variadic_inputs + info.num_implicit_inputs); + feed_names.reserve(static_cast(info.num_variadic_inputs) + info.num_implicit_inputs); const auto& scan_inputs = node.InputDefs(); int start = is_v8 ? 1 : 0; // skip sequence_lens for v8 @@ -217,7 +217,7 @@ Status IterateSequence(OpKernelContextInternal& context, const SessionState& ses feeds[input] = loop_state_variables[input].Input(); } else { // add sliced input - auto& iterator = scan_input_stream_iterators[input - num_loop_state_variables]; + auto& iterator = scan_input_stream_iterators[static_cast(input) - num_loop_state_variables]; feeds[input] = *iterator; ++iterator; diff --git a/onnxruntime/core/providers/cpu/controlflow/scan_utils.h b/onnxruntime/core/providers/cpu/controlflow/scan_utils.h index 6e36fe2f28..4eee03b6f2 100644 --- a/onnxruntime/core/providers/cpu/controlflow/scan_utils.h +++ b/onnxruntime/core/providers/cpu/controlflow/scan_utils.h @@ -52,7 +52,7 @@ class LoopStateVariable { const OrtValue original_value_; OrtValue final_value_; - /* we use original_value and final_value once, + /* we use original_value and final_value once, and alternate between a_ and b_ as input/output for each iteration to avoid copies Iteration Input Output @@ -88,8 +88,8 @@ class OutputIterator { ScanDirection direction = ScanDirection::kForward, bool temporary = false, MLDataType data_type = nullptr) { - iterator.reset(new OutputIterator(context, output_index, is_loop_state_var, is_v8, final_shape, - create_slicer_func, zero_data_func, direction, temporary, data_type)); + iterator = std::make_unique(context, output_index, is_loop_state_var, is_v8, final_shape, + create_slicer_func, zero_data_func, direction, temporary, data_type); return iterator->Initialize(); } @@ -115,8 +115,7 @@ class OutputIterator { ORT_ENFORCE(final_output_mlvalue_, "Attempt to retrieve final output before it was set."); return *final_output_mlvalue_; } - - private: + //std::unique_ptr needs to access this function. OutputIterator(OpKernelContextInternal& context, int output_index, bool is_loop_state_var, @@ -128,6 +127,7 @@ class OutputIterator { bool temporary, MLDataType data_type); + private: Status Initialize(); Status AllocateFinalBuffer(); @@ -201,7 +201,7 @@ void CalculateTransposedShapeForInput(const TensorShape& original_shape, int64_t /** Calculate the transpose permutations and shape by shifting the chosen axis FROM the first dimension. -e.g. if shape is {4, 2, 3} and axis 2 is chosen, dimension 0 will move to dimension 2, +e.g. if shape is {4, 2, 3} and axis 2 is chosen, dimension 0 will move to dimension 2, the permutations will be {1, 2, 0} and output shape will be {2, 3, 4} */ void CalculateTransposedShapeForOutput(const TensorShape& original_shape, int64_t axis, diff --git a/onnxruntime/core/providers/cpu/cpu_provider_factory.cc b/onnxruntime/core/providers/cpu/cpu_provider_factory.cc index a2dff68a39..00222f5642 100644 --- a/onnxruntime/core/providers/cpu/cpu_provider_factory.cc +++ b/onnxruntime/core/providers/cpu/cpu_provider_factory.cc @@ -37,7 +37,9 @@ ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_CPU, _In_ OrtSessio options->provider_factories.push_back(onnxruntime::CreateExecutionProviderFactory_CPU(use_arena)); return nullptr; } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif ORT_API_STATUS_IMPL(OrtApis::CreateCpuMemoryInfo, enum OrtAllocatorType type, enum OrtMemType mem_type, _Outptr_ OrtMemoryInfo** out) { *out = new OrtMemoryInfo(onnxruntime::CPU, type, OrtDevice(), 0, mem_type); diff --git a/onnxruntime/core/providers/cpu/element_wise_ranged_transform.h b/onnxruntime/core/providers/cpu/element_wise_ranged_transform.h index b7fe209203..f6cfc64216 100644 --- a/onnxruntime/core/providers/cpu/element_wise_ranged_transform.h +++ b/onnxruntime/core/providers/cpu/element_wise_ranged_transform.h @@ -56,6 +56,7 @@ ElementWiseRangedTransform::~ElementWiseRangedTransform() { Status Init(const onnxruntime::NodeAttributes& attributes) { \ return (GetFloatParam(#X, attributes, X)); \ } \ + GSL_SUPPRESS(r .11) \ ElementWiseRangedTransform* Copy() const final { \ using T1 = typename std::remove_pointer::type; \ using T2 = typename std::remove_const::type; \ @@ -70,6 +71,7 @@ ElementWiseRangedTransform::~ElementWiseRangedTransform() { ORT_RETURN_IF_ERROR(GetFloatParam(#Y, attributes, Y)); \ return Status::OK(); \ } \ + GSL_SUPPRESS(r .11) \ ElementWiseRangedTransform* Copy() const final { \ using T1 = typename std::remove_pointer::type; \ using T2 = typename std::remove_const::type; \ diff --git a/onnxruntime/core/providers/cpu/generator/range.cc b/onnxruntime/core/providers/cpu/generator/range.cc index 05ef9f508a..97903fd074 100644 --- a/onnxruntime/core/providers/cpu/generator/range.cc +++ b/onnxruntime/core/providers/cpu/generator/range.cc @@ -6,7 +6,10 @@ #include #include "core/providers/op_kernel_type_control.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace op_kernel_type_control { diff --git a/onnxruntime/core/providers/cpu/math/clip.h b/onnxruntime/core/providers/cpu/math/clip.h index cdbe86ee66..938f41f1f2 100644 --- a/onnxruntime/core/providers/cpu/math/clip.h +++ b/onnxruntime/core/providers/cpu/math/clip.h @@ -16,8 +16,8 @@ template class Clip_6Base { public: explicit Clip_6Base(const OpKernelInfo& info) { - auto min_val = std::numeric_limits::lowest(); - auto max_val = std::numeric_limits::max(); + constexpr auto min_val = std::numeric_limits::lowest(); + constexpr auto max_val = std::numeric_limits::max(); info.GetAttrOrDefault("min", &min_, min_val); info.GetAttrOrDefault("max", &max_, max_val); ORT_ENFORCE(min_ <= max_); diff --git a/onnxruntime/core/providers/cpu/math/det.cc b/onnxruntime/core/providers/cpu/math/det.cc index c7b2feffe4..996e8505f0 100644 --- a/onnxruntime/core/providers/cpu/math/det.cc +++ b/onnxruntime/core/providers/cpu/math/det.cc @@ -3,6 +3,11 @@ #include "core/providers/cpu/math/det.h" #include "core/util/math_cpuonly.h" +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif using namespace onnxruntime::common; diff --git a/onnxruntime/core/providers/cpu/math/einsum_utils/einsum_compute_preprocessor.cc b/onnxruntime/core/providers/cpu/math/einsum_utils/einsum_compute_preprocessor.cc index 88ef7738b2..ab6944b011 100644 --- a/onnxruntime/core/providers/cpu/math/einsum_utils/einsum_compute_preprocessor.cc +++ b/onnxruntime/core/providers/cpu/math/einsum_utils/einsum_compute_preprocessor.cc @@ -114,7 +114,7 @@ Status EinsumComputePreprocessor::ProcessSubscripts() { // Example for the following line of code // Subscript "...ij" for an input of rank 6 // num_of_ellipsis_dims = 6 - 5 + 3 = 4 - int64_t current_num_of_ellipsis_dims = rank - subscript.length() + 3; + int64_t current_num_of_ellipsis_dims = static_cast(rank) - subscript.length() + 3; if (current_num_of_ellipsis_dims < 0) { return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Einsum subscripts string contains too many subscript labels when compared to the rank of the input"); diff --git a/onnxruntime/core/providers/cpu/math/element_wise_ops.cc b/onnxruntime/core/providers/cpu/math/element_wise_ops.cc index 3403023608..5224c7fef5 100644 --- a/onnxruntime/core/providers/cpu/math/element_wise_ops.cc +++ b/onnxruntime/core/providers/cpu/math/element_wise_ops.cc @@ -1794,8 +1794,8 @@ void UntypedBroadcastTwo(OpKernelContext& context, const ProcessBroadcastSpanFun concurrency::ThreadPool::TryParallelFor( tp, output_size / span_size, - TensorOpCost{static_cast(input_broadcaster.Input0ElementSize() * span_size), - static_cast(output_tensor.DataType()->Size() * span_size), + TensorOpCost{static_cast(input_broadcaster.Input0ElementSize()) * span_size, + static_cast(output_tensor.DataType()->Size()) * span_size, unit_cost * span_size}, [span_size, &const_input_broadcaster, &output_tensor, &funcs, user_data](std::ptrdiff_t first_span, std::ptrdiff_t last_span) { diff --git a/onnxruntime/core/providers/cpu/math/element_wise_ops.h b/onnxruntime/core/providers/cpu/math/element_wise_ops.h index b95738c878..a94d6b25c3 100644 --- a/onnxruntime/core/providers/cpu/math/element_wise_ops.h +++ b/onnxruntime/core/providers/cpu/math/element_wise_ops.h @@ -10,7 +10,12 @@ namespace onnxruntime { namespace functors { - +// TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +// Do not use raw new/delete. +#pragma warning(disable : 26409) +#endif template struct Log final : public ElementWiseRangedTransform { Status Init(const onnxruntime::NodeAttributes) { @@ -982,4 +987,7 @@ struct TensorAllocator { private: AllocatorPtr allocator_; }; +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/ml/ml_common.h b/onnxruntime/core/providers/cpu/ml/ml_common.h index e2fb9139e1..e40b2a563f 100644 --- a/onnxruntime/core/providers/cpu/ml/ml_common.h +++ b/onnxruntime/core/providers/cpu/ml/ml_common.h @@ -241,7 +241,7 @@ static inline void multiclass_probability(int64_t classcount, } } -static const float ml_sqrt2 = 1.41421356f; +static constexpr float ml_sqrt2 = 1.41421356f; static inline float ComputeLogistic(float val) { float v = 1 / (1 + std::exp(-std::abs(val))); diff --git a/onnxruntime/core/providers/cpu/ml/svmclassifier.cc b/onnxruntime/core/providers/cpu/ml/svmclassifier.cc index e9bd36e846..070d0aec73 100644 --- a/onnxruntime/core/providers/cpu/ml/svmclassifier.cc +++ b/onnxruntime/core/providers/cpu/ml/svmclassifier.cc @@ -3,6 +3,11 @@ #include "core/providers/cpu/ml/svmclassifier.h" #include "core/platform/threadpool.h" +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace ml { diff --git a/onnxruntime/core/providers/cpu/nn/batch_norm.h b/onnxruntime/core/providers/cpu/nn/batch_norm.h index fc109dff76..bb8400094b 100644 --- a/onnxruntime/core/providers/cpu/nn/batch_norm.h +++ b/onnxruntime/core/providers/cpu/nn/batch_norm.h @@ -58,7 +58,10 @@ class BatchNorm : public OpKernel { #endif } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 26451) +#endif Status Compute(OpKernelContext* p_op_kernel_context) const override { const auto* X = p_op_kernel_context->Input(0); const auto* scale = p_op_kernel_context->Input(1); @@ -206,4 +209,7 @@ class BatchNorm : public OpKernel { const bool is_spatial_; int64_t is_train_; }; +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/nn/batch_norm_helper.h b/onnxruntime/core/providers/cpu/nn/batch_norm_helper.h index 85e555ef23..49afe6503c 100644 --- a/onnxruntime/core/providers/cpu/nn/batch_norm_helper.h +++ b/onnxruntime/core/providers/cpu/nn/batch_norm_helper.h @@ -8,7 +8,12 @@ #include "core/framework/tensor.h" #endif #include - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { class BatchNormHelper { public: @@ -124,3 +129,6 @@ class BatchNormHelper { } }; } // namespace onnxruntime +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/onnxruntime/core/providers/cpu/nn/conv_attributes.h b/onnxruntime/core/providers/cpu/nn/conv_attributes.h index 7fff54137d..393a5ea992 100644 --- a/onnxruntime/core/providers/cpu/nn/conv_attributes.h +++ b/onnxruntime/core/providers/cpu/nn/conv_attributes.h @@ -243,7 +243,7 @@ struct ConvAttributes { } post_slicing_needed = true; - slice_axes.push_back(dim + 2); + slice_axes.push_back(static_cast(dim) + 2); slice_starts.push_back(excess_output_head); slice_ends.push_back(excess_output_head + output_dim_size); // we may modify this below output_shape_with_revised_pads.push_back(excess_output_head + output_dim_size); // we may modify this below @@ -273,7 +273,7 @@ struct ConvAttributes { // Head has not been over-padded. Only tail pads need to be modified. post_slicing_needed = true; - slice_axes.push_back(dim + 2); + slice_axes.push_back(static_cast(dim) + 2); slice_starts.push_back(0); slice_ends.push_back(output_dim_size - revised_dim_size); } diff --git a/onnxruntime/core/providers/cpu/nn/conv_transpose.cc b/onnxruntime/core/providers/cpu/nn/conv_transpose.cc index d7e39c16b6..1e2f4f60d3 100644 --- a/onnxruntime/core/providers/cpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/cpu/nn/conv_transpose.cc @@ -76,7 +76,7 @@ Status ConvTranspose::PrePack(const Tensor& tensor, int input_idx, Alloca transposed_filter_ = BufferUniquePtr(packed_filter_data, BufferDeleter(alloc)); for (int64_t group_id = 0; group_id < conv_transpose_attrs_.group; ++group_id) { - MlasTranspose(tensor.Data() + (N * K * group_id), + MlasTranspose(tensor.Data() + (group_id * N * K), ((float*)packed_filter_data) + (group_id * packed_elements_per_group), K, N); } diff --git a/onnxruntime/core/providers/cpu/nn/conv_transpose_attributes.h b/onnxruntime/core/providers/cpu/nn/conv_transpose_attributes.h index 9ded92912f..621a522344 100644 --- a/onnxruntime/core/providers/cpu/nn/conv_transpose_attributes.h +++ b/onnxruntime/core/providers/cpu/nn/conv_transpose_attributes.h @@ -50,7 +50,7 @@ struct ConvTransposeAttributes : public ConvAttributes { const TensorShape& F_Shape = (filter_shape != nullptr) ? *filter_shape : F->Shape(); const Tensor* Pads = dynamic_padding ? context->Input(2) : nullptr; const Tensor* B = has_bias ? (dynamic_padding ? context->Input(3) : context->Input(2)) : nullptr; - const TensorShape& input_shape = X->Shape().Slice(2); + TensorShape input_shape = X->Shape().Slice(2); const int64_t num_input_channels = X->Shape()[1]; const int64_t N = X->Shape()[0]; diff --git a/onnxruntime/core/providers/cpu/nn/lrn.cc b/onnxruntime/core/providers/cpu/nn/lrn.cc index a3d133358f..5111a1479e 100644 --- a/onnxruntime/core/providers/cpu/nn/lrn.cc +++ b/onnxruntime/core/providers/cpu/nn/lrn.cc @@ -21,7 +21,11 @@ #include "core/common/safeint.h" #include "core/util/math.h" #include "core/util/math_cpuonly.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace functors { @@ -74,7 +78,7 @@ Status LRN::Compute(OpKernelContext* context) const { auto* scale_data = static_cast(scale_buffer.get()); math::Set(Xsize, bias_, scale_data, &CPUMathUtil::Instance()); - const size_t padded_square_size = (C + size_ - 1) * H * W; + const size_t padded_square_size = (static_cast(C) + size_ - 1) * H * W; auto psdata = alloc->Alloc(SafeInt(sizeof(float)) * padded_square_size); BufferUniquePtr padded_square_buffer(psdata, BufferDeleter(alloc)); auto* padded_square_data = static_cast(padded_square_buffer.get()); diff --git a/onnxruntime/core/providers/cpu/nn/pool_attributes.h b/onnxruntime/core/providers/cpu/nn/pool_attributes.h index 11c11b6b6c..87f07e55f7 100644 --- a/onnxruntime/core/providers/cpu/nn/pool_attributes.h +++ b/onnxruntime/core/providers/cpu/nn/pool_attributes.h @@ -168,7 +168,11 @@ struct PoolAttributes { *out_size = ComputeOutputSize(in_size, stride, kernel, *pad_head + *pad_tail, dilation); } } - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif int64_t ComputeOutputSize(int64_t in_size, int64_t stride, int64_t kernel, @@ -180,6 +184,9 @@ struct PoolAttributes { return static_cast( std::ceil(static_cast(in_size + pad_needed - dilation * (kernel - 1) - 1) / stride + 1)); } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif }; } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/nn/pool_base.h b/onnxruntime/core/providers/cpu/nn/pool_base.h index d03754eec9..00dd1b1520 100644 --- a/onnxruntime/core/providers/cpu/nn/pool_base.h +++ b/onnxruntime/core/providers/cpu/nn/pool_base.h @@ -36,7 +36,7 @@ class PoolProcessContext { class AveragePool { public: - static float Initialize() { + constexpr static float Initialize() { return 0.0; } @@ -59,7 +59,7 @@ class MaxPool; template <> class MaxPool<1 /*START_VERSION*/> { public: - static float Initialize() { + constexpr static float Initialize() { return std::numeric_limits::lowest(); } @@ -84,7 +84,7 @@ class MaxPool<8 /*START_VERSION*/> { class LpPool { public: - static float Initialize() { + constexpr static float Initialize() { return 0.0f; } diff --git a/onnxruntime/core/providers/cpu/nn/shrink.cc b/onnxruntime/core/providers/cpu/nn/shrink.cc index 6272eb409f..0c336da99e 100644 --- a/onnxruntime/core/providers/cpu/nn/shrink.cc +++ b/onnxruntime/core/providers/cpu/nn/shrink.cc @@ -31,7 +31,10 @@ ONNX_CPU_OPERATOR_KERNEL( BuildKernelDefConstraintsFromTypeList(), BuildKernelDefConstraintsFromTypeList()), Shrink); - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace shrink_internal { template inline T ShrinkCore(const T& val, float bias, float lambd) { diff --git a/onnxruntime/core/providers/cpu/nn/tfidfvectorizer.cc b/onnxruntime/core/providers/cpu/nn/tfidfvectorizer.cc index d6677a482c..464d027202 100644 --- a/onnxruntime/core/providers/cpu/nn/tfidfvectorizer.cc +++ b/onnxruntime/core/providers/cpu/nn/tfidfvectorizer.cc @@ -125,7 +125,7 @@ struct TfIdfVectorizer::Impl { // Contains output indexes // represents ngram_indexes output gsl::span ngram_indexes_; - gsl::span weights_; + gsl::span weights_; // This map contains references to pool_string_ entries // of pool_strings attribute @@ -145,13 +145,13 @@ struct TfIdfVectorizer::Impl { assert(ngram_id != 0); --ngram_id; assert(ngram_id < ngram_indexes_.size()); - auto output_idx = row_num * output_size_ + ngram_indexes_[ngram_id]; + auto output_idx = static_cast(row_num) * output_size_ + ngram_indexes_[ngram_id]; assert(static_cast(output_idx) < frequencies.size()); ++frequencies[output_idx]; } }; -TfIdfVectorizer::TfIdfVectorizer(const OpKernelInfo& info) : OpKernel(info), impl_(new Impl) { +TfIdfVectorizer::TfIdfVectorizer(const OpKernelInfo& info) : OpKernel(info), impl_(std::make_unique()) { std::string mode; Status status = info.GetAttr("mode", &mode); ORT_ENFORCE(status.IsOK(), "mode is required"); diff --git a/onnxruntime/core/providers/cpu/object_detection/non_max_suppression.cc b/onnxruntime/core/providers/cpu/object_detection/non_max_suppression.cc index bc6b7e3543..ddc4432eba 100644 --- a/onnxruntime/core/providers/cpu/object_detection/non_max_suppression.cc +++ b/onnxruntime/core/providers/cpu/object_detection/non_max_suppression.cc @@ -194,7 +194,7 @@ Status NonMaxSuppression::Compute(OpKernelContext* ctx) const { } //for class_index } //for batch_index - const auto last_dim = 3; + constexpr auto last_dim = 3; const auto num_selected = selected_indices.size(); Tensor* output = ctx->Output(0, {static_cast(num_selected), last_dim}); ORT_ENFORCE(output != nullptr); diff --git a/onnxruntime/core/providers/cpu/object_detection/roialign.cc b/onnxruntime/core/providers/cpu/object_detection/roialign.cc index ed9f56d050..f316da7cb6 100644 --- a/onnxruntime/core/providers/cpu/object_detection/roialign.cc +++ b/onnxruntime/core/providers/cpu/object_detection/roialign.cc @@ -49,7 +49,11 @@ struct PreCalc { T w3; T w4; }; - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif template static void PreCalcForBilinearInterpolate(const int64_t height, const int64_t width, const int64_t pooled_height, const int64_t pooled_width, const int64_t iy_upper, const int64_t ix_upper, @@ -235,8 +239,8 @@ void RoiAlignForward(const TensorShape& output_shape, const T* bottom_data, floa } // namespace Status CheckROIAlignValidInput(const Tensor* X_ptr, const Tensor* rois_ptr, const Tensor* batch_indices_ptr) { - const int64_t EXPECTED_NUM_ROI_DIMS = 2; - const int64_t EXPECTED_SECOND_ROI_DIM = 4; + constexpr int64_t EXPECTED_NUM_ROI_DIMS = 2; + constexpr int64_t EXPECTED_SECOND_ROI_DIM = 4; if (!X_ptr) { return Status(common::ONNXRUNTIME, common::INVALID_ARGUMENT, "Null input X ptr"); } diff --git a/onnxruntime/core/providers/cpu/quantization/qlinearconv.cc b/onnxruntime/core/providers/cpu/quantization/qlinearconv.cc index 27b23781b3..2b81637f7f 100644 --- a/onnxruntime/core/providers/cpu/quantization/qlinearconv.cc +++ b/onnxruntime/core/providers/cpu/quantization/qlinearconv.cc @@ -619,7 +619,7 @@ Status QLinearConv::Compute(OpKernelContext* context) const { auto conv_worker = [&](ptrdiff_t batch) { auto work = concurrency::ThreadPool::PartitionWork(batch, thread_count, static_cast(output_image_size)); int64_t output_start = static_cast(work.start); - int64_t output_count = static_cast(work.end - work.start); + int64_t output_count = static_cast(work.end) - work.start; ActType const** worker_indirection_buffer = nullptr; if (indirection_buffer) { diff --git a/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc b/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc index c8af3ffff3..5a8c659c96 100644 --- a/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc +++ b/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc @@ -3,7 +3,10 @@ #include "core/providers/cpu/reduction/reduction_ops.h" #include "core/providers/common.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif using namespace std; namespace onnxruntime { @@ -219,10 +222,6 @@ bool operator!=(FastReduceKind a, FastReduceKind b) { return static_cast(a) != static_cast(b); } -bool IsFastReduceKindAvailable(FastReduceKind scenario, FastReduceKind available) { - return (static_cast(scenario) & static_cast(available)) > 0; -} - bool ResultsNoTransposePrepareForReduce::equal(gsl::span local_input_shape, gsl::span local_reduced_axes) { if (gsl::make_span(input_shape) != local_input_shape) @@ -267,12 +266,6 @@ void ReduceAggregatorBase::FastReduceKRK(const Tensor&, const std::vector(n_row * n_col * element_size), - static_cast(n_row * element_size), - static_cast(n_row * n_col * element_size * n_ops)}; -} - void NoTransposePrepareForReduce(const TensorShape& new_input_shape, gsl::span reduced_axes, ResultsNoTransposePrepareForReduce& results) { diff --git a/onnxruntime/core/providers/cpu/reduction/reduction_ops.h b/onnxruntime/core/providers/cpu/reduction/reduction_ops.h index 9f064fa345..8acce4524d 100644 --- a/onnxruntime/core/providers/cpu/reduction/reduction_ops.h +++ b/onnxruntime/core/providers/cpu/reduction/reduction_ops.h @@ -34,10 +34,15 @@ bool operator==(FastReduceKind a, FastReduceKind b); bool operator!=(FastReduceKind a, FastReduceKind b); -bool IsFastReduceKindAvailable(FastReduceKind scenario, FastReduceKind available); - +constexpr bool IsFastReduceKindAvailable(FastReduceKind scenario, FastReduceKind available) { + return (static_cast(scenario) & static_cast(available)) > 0; +} /* Evaluate the cost of parallelized FastReduce implementations. */ -TensorOpCost ParallelReduceFastCost(int64_t n_row, int64_t n_col, int64_t element_size, int n_ops); +constexpr TensorOpCost ParallelReduceFastCost(int64_t n_row, int64_t n_col, int64_t element_size, int n_ops) { + return TensorOpCost{static_cast(n_row * n_col * element_size), + static_cast(n_row * element_size), + static_cast(n_row * n_col * element_size * n_ops)}; +} /** This only improves reduce function when reduced axes are contiguous: diff --git a/onnxruntime/core/providers/cpu/rnn/deep_cpu_gru.cc b/onnxruntime/core/providers/cpu/rnn/deep_cpu_gru.cc index 8f4f2aaa32..e53dbb4cf0 100644 --- a/onnxruntime/core/providers/cpu/rnn/deep_cpu_gru.cc +++ b/onnxruntime/core/providers/cpu/rnn/deep_cpu_gru.cc @@ -14,7 +14,11 @@ #ifdef _MSC_VER #pragma warning(pop) #endif - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif /* ONNX_OPERATOR_SCHEMA(GRU) .SetDoc(R"DOC( @@ -644,7 +648,7 @@ void UniDirectionalGru::Compute(const gsl::span& inputs_arg, for (int r = 0; r < batch_size_; r++) { const T* p_bias_r = use_bias_ ? SafeRawConstPointer(batched_bias_WRr_local + r * hidden_size_, batched_bias_WRr_local_end, hidden_size_) - : nullptr; + : nullptr; // initialize p_rt with input to calculate rt. outputZRH_ has Xt*(Wr^T) + Ht-1*(Rr^T). T* p_rt = SafeRawPointer(outputZRH_, out_added_offset + r * hidden_size_x3 + hidden_size_, hidden_size_); @@ -738,7 +742,7 @@ void UniDirectionalGru::Compute(const gsl::span& inputs_arg, const T* p_bias_z = use_bias_ ? SafeRawConstPointer(batched_bias_WRz_local, batched_bias_WRz_local_end, hidden_size_) - : nullptr; + : nullptr; // initialize p_zt with Xt*(Wz^T) + Ht-1*(Rz^T), which is most of the input to calculate zt: T* p_zt = SafeRawPointer(outputZRH_, out_added_offset + r * hidden_size_x3, hidden_size_); @@ -788,7 +792,7 @@ void UniDirectionalGru::Compute(const gsl::span& inputs_arg, prev_Ht = output; prev_Ht_end = output_end; } - } // End parallel section + } // End parallel section // copy last output to final_hidden_state for (int i = 0; i < batch_size_; i++) { diff --git a/onnxruntime/core/providers/cpu/rnn/deep_cpu_lstm.cc b/onnxruntime/core/providers/cpu/rnn/deep_cpu_lstm.cc index a711a59bd1..b602adb32e 100644 --- a/onnxruntime/core/providers/cpu/rnn/deep_cpu_lstm.cc +++ b/onnxruntime/core/providers/cpu/rnn/deep_cpu_lstm.cc @@ -185,7 +185,7 @@ Status DeepCpuLstmOp::TryPackWeights(const Tensor& weights, PackedWeights& packe const size_t N = static_cast(shape[1]); const size_t K = static_cast(shape[2]); - if ((shape[0] != num_directions_) || (N != static_cast(hidden_size_ * 4))) { + if ((shape[0] != num_directions_) || (N != static_cast(hidden_size_) * 4)) { return Status::OK(); } diff --git a/onnxruntime/core/providers/cpu/rnn/lstm_base.cc b/onnxruntime/core/providers/cpu/rnn/lstm_base.cc index 44d785b62b..cfabe3fb45 100644 --- a/onnxruntime/core/providers/cpu/rnn/lstm_base.cc +++ b/onnxruntime/core/providers/cpu/rnn/lstm_base.cc @@ -3,7 +3,10 @@ #include "lstm_base.h" #include "uni_directional_lstm.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { using namespace rnn::detail; diff --git a/onnxruntime/core/providers/cpu/rnn/rnn.cc b/onnxruntime/core/providers/cpu/rnn/rnn.cc index 1f0e0610da..a51129ceac 100644 --- a/onnxruntime/core/providers/cpu/rnn/rnn.cc +++ b/onnxruntime/core/providers/cpu/rnn/rnn.cc @@ -9,7 +9,11 @@ #include "core/providers/cpu/rnn/rnn_helpers.h" #include "core/util/math.h" #include "core/util/math_cpuonly.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { ONNX_CPU_OPERATOR_VERSIONED_KERNEL( RNN, diff --git a/onnxruntime/core/providers/cpu/rnn/rnn_helpers.cc b/onnxruntime/core/providers/cpu/rnn/rnn_helpers.cc index a7c20b9ed6..ece449095c 100644 --- a/onnxruntime/core/providers/cpu/rnn/rnn_helpers.cc +++ b/onnxruntime/core/providers/cpu/rnn/rnn_helpers.cc @@ -17,7 +17,10 @@ #include "core/providers/cpu/rnn/rnn_activation_functors.h" #include "core/util/math.h" #include "core/util/math_cpuonly.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace rnn { namespace detail { @@ -311,21 +314,21 @@ void ComputeGemm(const int M, namespace deepcpu { -const float alpha_1 = 4.89352455891786e-03f; -const float alpha_3 = 6.37261928875436e-04f; -const float alpha_5 = 1.48572235717979e-05f; -const float alpha_7 = 5.12229709037114e-08f; -const float alpha_9 = -8.60467152213735e-11f; -const float alpha_11 = 2.00018790482477e-13f; -const float alpha_13 = -2.76076847742355e-16f; +constexpr float alpha_1 = 4.89352455891786e-03f; +constexpr float alpha_3 = 6.37261928875436e-04f; +constexpr float alpha_5 = 1.48572235717979e-05f; +constexpr float alpha_7 = 5.12229709037114e-08f; +constexpr float alpha_9 = -8.60467152213735e-11f; +constexpr float alpha_11 = 2.00018790482477e-13f; +constexpr float alpha_13 = -2.76076847742355e-16f; -const float beta_0 = 4.89352518554385e-03f; -const float beta_2 = 2.26843463243900e-03f; -const float beta_4 = 1.18534705686654e-04f; -const float beta_6 = 1.19825839466702e-06f; +constexpr float beta_0 = 4.89352518554385e-03f; +constexpr float beta_2 = 2.26843463243900e-03f; +constexpr float beta_4 = 1.18534705686654e-04f; +constexpr float beta_6 = 1.19825839466702e-06f; -const float sigmoid_bound = 20.0f; -const float tanh_bound = 10.0f; +constexpr float sigmoid_bound = 20.0f; +constexpr float tanh_bound = 10.0f; #if defined(__GNUC__) && !defined(__wasm__) #define restrict __restrict__ @@ -918,4 +921,3 @@ GruOutputGateFuncPtr GruOutputGateFuncByName(const std::string& func) { } // namespace detail } // namespace rnn } // namespace onnxruntime - diff --git a/onnxruntime/core/providers/cpu/rnn/rnn_helpers.h b/onnxruntime/core/providers/cpu/rnn/rnn_helpers.h index e23d516350..c94cdf14ab 100644 --- a/onnxruntime/core/providers/cpu/rnn/rnn_helpers.h +++ b/onnxruntime/core/providers/cpu/rnn/rnn_helpers.h @@ -110,7 +110,7 @@ void ReverseSequence(gsl::span inputs, for (int i = 0; i < batch_size; i++) { int seq_len = sequence_lengths[i]; - for (int j = 0; j < seq_len; j++) { + for (ptrdiff_t j = 0; j < seq_len; j++) { gsl::span src = inputs.subspan(j * batch_size * input_size + i * input_size, input_size); gsl::span dest = inputs_reverse.subspan(num_directions * (seq_len - j - 1) * batch_size * input_size + i * input_size, input_size); diff --git a/onnxruntime/core/providers/cpu/rnn/uni_directional_lstm.cc b/onnxruntime/core/providers/cpu/rnn/uni_directional_lstm.cc index 715aa931a3..605ebacaee 100644 --- a/onnxruntime/core/providers/cpu/rnn/uni_directional_lstm.cc +++ b/onnxruntime/core/providers/cpu/rnn/uni_directional_lstm.cc @@ -4,7 +4,11 @@ #include "uni_directional_lstm.h" #include "core/platform/threadpool.h" - +//TODO: fix the warnings +#if defined(_MSC_VER) && !defined(__clang__) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { namespace lstm { @@ -82,7 +86,7 @@ UniDirectionalLstm::UniDirectionalLstm( template void UniDirectionalLstm::AllocateBuffers() { // allocate and fill with zeroes - const bool fill = true; + constexpr bool fill = true; hidden0_ = Allocate(allocator_, hidden_size_, hidden0_ptr_, fill); internal_memory_prev_ = Allocate(allocator_, hidden_size_, internal_memory_prev_ptr_, fill); batched_hidden0_ = Allocate(allocator_, batch_size_ * hidden_size_, batched_hidden0_ptr_); diff --git a/onnxruntime/core/providers/cpu/sequence/sequence_ops.cc b/onnxruntime/core/providers/cpu/sequence/sequence_ops.cc index 412c6d6aa0..9645028745 100644 --- a/onnxruntime/core/providers/cpu/sequence/sequence_ops.cc +++ b/onnxruntime/core/providers/cpu/sequence/sequence_ops.cc @@ -69,7 +69,7 @@ static int64_t GetSeqIdx(const Tensor& idx_tensor) { return seq_idx; } -bool ValidateSeqIdx(int64_t input_seq_idx, int64_t seq_size) { +constexpr bool ValidateSeqIdx(int64_t input_seq_idx, int64_t seq_size) { bool retval = false; if (input_seq_idx < 0) { retval = input_seq_idx <= -1 && input_seq_idx >= -seq_size; @@ -536,7 +536,7 @@ Status SplitToSequence::ComputeImpl(OpKernelContext& context, const Tensor& inpu copy_data(src, dst, count); }); - input_offset += split_size * after_dims_excluding_split; // offset by the N data we used in this iteration + input_offset += static_cast(split_size) * after_dims_excluding_split; // offset by the N data we used in this iteration // if keep_dims = 0, reshape the tensor by dropping the dimension corresponding to 'axis' if (use_keep_dims && keepdims_ == 0) { diff --git a/onnxruntime/core/providers/cpu/tensor/expand.cc b/onnxruntime/core/providers/cpu/tensor/expand.cc index 085214f290..466bb83ad1 100644 --- a/onnxruntime/core/providers/cpu/tensor/expand.cc +++ b/onnxruntime/core/providers/cpu/tensor/expand.cc @@ -78,9 +78,9 @@ Status Expand::Compute(OpKernelContext* context) const { return Status::OK(); } - std::unique_ptr input_dim_group{new int64_t[max_dims_size]}; - std::unique_ptr output_dim_group{new int64_t[max_dims_size]}; - std::unique_ptr expand_dim_size{new int64_t[max_dims_size]}; + std::unique_ptr input_dim_group = std::make_unique(max_dims_size); + std::unique_ptr output_dim_group = std::make_unique(max_dims_size); + std::unique_ptr expand_dim_size = std::make_unique(max_dims_size); auto dim_group_start = max_dims_size; for (int64_t input_dims_iter = input_dims_size - 1, diff --git a/onnxruntime/core/providers/cpu/tensor/gather_nd.cc b/onnxruntime/core/providers/cpu/tensor/gather_nd.cc index cec467e066..4e75de493f 100644 --- a/onnxruntime/core/providers/cpu/tensor/gather_nd.cc +++ b/onnxruntime/core/providers/cpu/tensor/gather_nd.cc @@ -100,7 +100,7 @@ Status GatherNDBase::PrepareForCompute(const TensorShape& input_shape, const Ten relative_slice_offset += index * sizes_from_slice_dims[dim_idx]; } - p.slice_offsets[slice_idx] = input_base_offset + relative_slice_offset; + p.slice_offsets[slice_idx] = static_cast(input_base_offset) + relative_slice_offset; }; concurrency::ThreadPool::TryParallelFor( diff --git a/onnxruntime/core/providers/cpu/tensor/nonzero_op.cc b/onnxruntime/core/providers/cpu/tensor/nonzero_op.cc index 0b09f213b6..9fc0aeb2b9 100644 --- a/onnxruntime/core/providers/cpu/tensor/nonzero_op.cc +++ b/onnxruntime/core/providers/cpu/tensor/nonzero_op.cc @@ -77,7 +77,7 @@ Status NonZero::Compute(OpKernelContext* context) const { // as we iterate the entries, increment the coordinate for the current entry // e.g. if shape is {2,2}, we start with 0,0 increment to 0,1 increment to 1,0 and finally 1,1 auto increment_coordinate = [&coordinate, &coordinate_size, &X_shape]() { - for (int64_t idx = coordinate_size - 1; idx >= 0; --idx) { + for (Eigen::Index idx = coordinate_size - 1; idx >= 0; --idx) { int64_t& cur_coord = coordinate[idx]; if (cur_coord != X_shape[idx] - 1) { ++cur_coord; diff --git a/onnxruntime/core/providers/cpu/tensor/onehot.cc b/onnxruntime/core/providers/cpu/tensor/onehot.cc index cd621f968d..42e20284c5 100644 --- a/onnxruntime/core/providers/cpu/tensor/onehot.cc +++ b/onnxruntime/core/providers/cpu/tensor/onehot.cc @@ -94,7 +94,7 @@ Status PrepareOutputShape(const Tensor* indices, const int64_t depth_val, const output_shape = indices_shape.GetDimsAsVector(); // output rank is always 1 more than the input rank as a new dimension is added to the input shape - const auto output_rank = static_cast(indices_num_dims + 1); + const auto output_rank = static_cast(indices_num_dims) + 1; auto true_axis = HandleNegativeAxis(axis, output_rank); diff --git a/onnxruntime/core/providers/cpu/tensor/reverse_sequence.cc b/onnxruntime/core/providers/cpu/tensor/reverse_sequence.cc index 493ff62b1d..a76f82fb39 100644 --- a/onnxruntime/core/providers/cpu/tensor/reverse_sequence.cc +++ b/onnxruntime/core/providers/cpu/tensor/reverse_sequence.cc @@ -79,7 +79,7 @@ Status ReverseSequenceOp::Compute(OpKernelContext* context) const { return status; } -static int64_t TimeMajorInputOffset(const int64_t max_seq_len, +constexpr static int64_t TimeMajorInputOffset(const int64_t max_seq_len, const int64_t batch_size, const int64_t input_size, const int64_t batch_num, @@ -88,7 +88,7 @@ static int64_t TimeMajorInputOffset(const int64_t max_seq_len, return seq_num * batch_size * input_size + batch_num * input_size; } -static int64_t BatchMajorInputOffset(const int64_t max_seq_len, +constexpr static int64_t BatchMajorInputOffset(const int64_t max_seq_len, const int64_t batch_size, const int64_t input_size, const int64_t batch_num, @@ -97,7 +97,7 @@ static int64_t BatchMajorInputOffset(const int64_t max_seq_len, return batch_num * max_seq_len * input_size + seq_num * input_size; } -static int64_t TimeMajorOutputOffset(const int64_t max_seq_len, +constexpr static int64_t TimeMajorOutputOffset(const int64_t max_seq_len, const int64_t batch_size, const int64_t input_size, const int64_t batch_num, @@ -107,7 +107,7 @@ static int64_t TimeMajorOutputOffset(const int64_t max_seq_len, return (seq_len - seq_num - 1) * batch_size * input_size + batch_num * input_size; } -static int64_t BatchMajorOutputOffset(const int64_t max_seq_len, +constexpr static int64_t BatchMajorOutputOffset(const int64_t max_seq_len, const int64_t batch_size, const int64_t input_size, const int64_t batch_num, diff --git a/onnxruntime/core/providers/cpu/tensor/scatter_nd.cc b/onnxruntime/core/providers/cpu/tensor/scatter_nd.cc index b5a19fd44c..3fb3956cdc 100644 --- a/onnxruntime/core/providers/cpu/tensor/scatter_nd.cc +++ b/onnxruntime/core/providers/cpu/tensor/scatter_nd.cc @@ -64,7 +64,7 @@ Status ScatterNDBase::ValidateShapes(const TensorShape& input_shape, // Validate rank of update tensor // Per spec, the rank of the update tensor should be: // (Rank of input tensor) + (Rank of indices tensor) -1 - last_indice_dimension - if (update_rank != (input_rank + indice_rank - 1 - static_cast(last_indice_dimension))) { + if (update_rank != (input_rank + indice_rank - 1 - static_cast(last_indice_dimension))) { return true; } diff --git a/onnxruntime/core/providers/cpu/tensor/space_depth_ops.cc b/onnxruntime/core/providers/cpu/tensor/space_depth_ops.cc index e565c2467b..a62bad2178 100644 --- a/onnxruntime/core/providers/cpu/tensor/space_depth_ops.cc +++ b/onnxruntime/core/providers/cpu/tensor/space_depth_ops.cc @@ -62,7 +62,7 @@ ONNX_CPU_OPERATOR_KERNEL( // intermediate tensor shapes are: // (batch, blocksize, blocksize, input_depth / (blocksize * blocksize), input_height, input_width) for DepthToSpace // (batch, input_depth, input_height / blocksize, blocksize, input_width / blocksize, blocksize) for SpaceToDepth -const int IntermediateTensorRank = 6; +constexpr int IntermediateTensorRank = 6; template using EigenTensorMap = Eigen::TensorMap, Eigen::Aligned>; diff --git a/onnxruntime/core/providers/cpu/tensor/split.cc b/onnxruntime/core/providers/cpu/tensor/split.cc index 74d8be1fce..345c9d2be3 100644 --- a/onnxruntime/core/providers/cpu/tensor/split.cc +++ b/onnxruntime/core/providers/cpu/tensor/split.cc @@ -197,7 +197,7 @@ Status Split::ComputeImpl(OpKernelContext& context, const Tensor& input) const { copy_data(src, dst, count); }); - input_offset += split_size * after_dims_excluding_split; // offset by the N data we used in this iteration + input_offset += static_cast(split_size) * after_dims_excluding_split; // offset by the N data we used in this iteration } return Status::OK(); diff --git a/onnxruntime/core/providers/cpu/tensor/transpose.cc b/onnxruntime/core/providers/cpu/tensor/transpose.cc index 16d0f5c746..de6a1b33cf 100644 --- a/onnxruntime/core/providers/cpu/tensor/transpose.cc +++ b/onnxruntime/core/providers/cpu/tensor/transpose.cc @@ -78,7 +78,7 @@ static void IncrementIndexAndComputeOffsetSetup(MultiIndex& mindex, size_t num_a for (size_t i = 0; i < num_axes; ++i) { if (target_dims[i] == 1) continue; - mindex.InitAxis(naxes, 0, static_cast(target_dims[i]), stride[i] * element_size); + mindex.InitAxis(naxes, 0, static_cast(target_dims[i]), stride[i] * static_cast(element_size)); ++naxes; } ORT_ENFORCE(naxes > 0, "Method IncrementIndexAndComputeOffset assumes this value is strictly positive."); diff --git a/onnxruntime/core/providers/cpu/tensor/upsample.h b/onnxruntime/core/providers/cpu/tensor/upsample.h index 3d998187e8..dd9dc489de 100644 --- a/onnxruntime/core/providers/cpu/tensor/upsample.h +++ b/onnxruntime/core/providers/cpu/tensor/upsample.h @@ -7,7 +7,11 @@ #include "core/framework/op_kernel.h" #endif #include - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +// Chance of arithmetic overflow could be reduced +#pragma warning(disable : 26451) +#endif namespace onnxruntime { constexpr const char* UpsampleModeNN = "nearest"; @@ -16,9 +20,9 @@ constexpr const char* UpsampleModeCubic = "cubic"; // In case of cubic mode the grid used to calculate the interpolation value // is a 4x4 matrix -const size_t CubicModeGridLength = 4; +constexpr size_t CubicModeGridLength = 4; -using GetNearestPixelFunc = int64_t(*)(float, bool); +using GetNearestPixelFunc = int64_t (*)(float, bool); using GetOriginalCoordinateFunc = float (*)(float, float, float, float, float, float); enum UpsampleMode { @@ -375,3 +379,6 @@ class Upsample : public UpsampleBase, public OpKernel { }; } // namespace onnxruntime +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/onnxruntime/core/providers/cuda/cuda_kernel.h b/onnxruntime/core/providers/cuda/cuda_kernel.h index 8268e40292..cb3232ffd5 100644 --- a/onnxruntime/core/providers/cuda/cuda_kernel.h +++ b/onnxruntime/core/providers/cuda/cuda_kernel.h @@ -30,7 +30,7 @@ class CudaKernel : public OpKernel { if (s.IsOK()) { auto err = cudaGetLastError(); if (err != cudaSuccess) { - s = ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "CUDA error ", cudaGetErrorName(err), ":", cudaGetErrorString(err)); + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "CUDA error ", cudaGetErrorName(err), ":", cudaGetErrorString(err)); } } diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp index 02733453f7..04d1e6859f 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp @@ -450,9 +450,9 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel( constantCpuInputCapture, shapeInferrerCapture, defaultAttributesCapture - ](const onnxruntime::OpKernelInfo& info) -> onnxruntime::OpKernel* + ](onnxruntime::FuncManager&, const onnxruntime::OpKernelInfo& info, std::unique_ptr& out) -> onnxruntime::common::Status { - return new AbiOpKernel( + out = std::make_unique( kernelFactoryCapture.Get(), info, requiresInputShapesAtCreation, @@ -461,6 +461,7 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel( constantCpuInputCapture, shapeInferrerCapture.Get(), &defaultAttributesCapture); + return Status::OK(); }; onnxruntime::KernelCreateInfo create_info(builder.Build(), lotusKernelCreateFn); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp index cac81590ed..ba65508d2b 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp @@ -681,9 +681,10 @@ namespace Dml printf("\n"); #endif - auto fused_kernel_func = [partitionNodePropsMap, transferredInitializerMap](const onnxruntime::OpKernelInfo& info) mutable ->onnxruntime::OpKernel* + auto fused_kernel_func = [partitionNodePropsMap, transferredInitializerMap](onnxruntime::FuncManager& func_mgr, const onnxruntime::OpKernelInfo& info, std::unique_ptr& out) mutable ->onnxruntime::Status { - return CreateFusedGraphKernel(info, partitionNodePropsMap, *transferredInitializerMap); + out.reset(CreateFusedGraphKernel(info, partitionNodePropsMap, *transferredInitializerMap)); + return Status::OK(); }; // build the kernel definition on the fly, and register it to the fused_kernel_regisitry. diff --git a/onnxruntime/core/session/IOBinding.h b/onnxruntime/core/session/IOBinding.h index 2b97dbeb22..61f7557f03 100644 --- a/onnxruntime/core/session/IOBinding.h +++ b/onnxruntime/core/session/IOBinding.h @@ -50,30 +50,30 @@ class IOBinding { common::Status BindInput(const std::string& name, const OrtValue& ml_value); /** - * If the BindInput calls are async this function acts as a barrier to ensure all inputs are fully copied - * before you call the Run() method. There is no point calling Run() if you're inputs are not ready at the - * desired location. - * This is a blocking call and is a wrapper over IExecutionProvider::Sync(). - * Call InferenceSession::Run() only after calling this method or else you'll end up wasting cycles inside Run(). - */ + * If the BindInput calls are async this function acts as a barrier to ensure all inputs are fully copied + * before you call the Run() method. There is no point calling Run() if you're inputs are not ready at the + * desired location. + * This is a blocking call and is a wrapper over IExecutionProvider::Sync(). + * Call InferenceSession::Run() only after calling this method or else you'll end up wasting cycles inside Run(). + */ common::Status SynchronizeInputs(); common::Status SynchronizeOutputs(); /** - * Bind an output name to a provided pre-allocated OrtValue. - */ + * Bind an output name to a provided pre-allocated OrtValue. + */ common::Status BindOutput(const std::string& name, const OrtValue& ml_value); /** - * Bind an output name to a device. - * - * @param device Device to allocate the output on. Default is CPU. - */ + * Bind an output name to a device. + * + * @param device Device to allocate the output on. Default is CPU. + */ common::Status BindOutput(const std::string& name, OrtDevice device = {}); /** - * This simply collects the outputs obtained after calling Run() inside the @param outputs. - */ + * This simply collects the outputs obtained after calling Run() inside the @param outputs. + */ const std::vector& GetOutputNames() const; const std::vector& GetOutputs() const; std::vector& GetOutputs(); @@ -82,22 +82,22 @@ class IOBinding { const std::vector& GetInputs() const; /** - * Get a CPU allocator from provider for async copy later if the provider supports that - * If it doesn't support that, return the default allocator from CPU provider - * \return a nonnull pointer - */ + * Get a CPU allocator from provider for async copy later if the provider supports that + * If it doesn't support that, return the default allocator from CPU provider + * \return a nonnull pointer + */ AllocatorPtr GetCPUAllocator(int id, onnxruntime::ProviderType provider_type) const; /** - * clear inputs or outputs. IOBinding is stateful. There are cases we need to reset its state. - */ + * clear inputs or outputs. IOBinding is stateful. There are cases we need to reset its state. + */ void ClearOutputs(); void ClearInputs(); + IOBinding(const SessionState& session_state); private: friend InferenceSession; - IOBinding(const SessionState& session_state); const SessionState& session_state_; std::vector feed_names_; std::vector feeds_; diff --git a/onnxruntime/core/session/abi_session_options.cc b/onnxruntime/core/session/abi_session_options.cc index e5cb9fa176..cb721b65f8 100644 --- a/onnxruntime/core/session/abi_session_options.cc +++ b/onnxruntime/core/session/abi_session_options.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "core/graph/onnx_protobuf.h" +#include "core/common/gsl_suppress.h" #include "core/session/onnxruntime_c_api.h" #include "core/session/ort_apis.h" #include "core/framework/error_code_helper.h" diff --git a/onnxruntime/core/session/allocator_adapters.cc b/onnxruntime/core/session/allocator_adapters.cc index a3a8cb273a..6dd495e578 100644 --- a/onnxruntime/core/session/allocator_adapters.cc +++ b/onnxruntime/core/session/allocator_adapters.cc @@ -47,7 +47,9 @@ void IAllocatorImplWrappingOrtAllocator::Free(void* p) { } } // namespace onnxruntime - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif ORT_API_STATUS_IMPL(OrtApis::CreateAllocator, const OrtSession* sess, const OrtMemoryInfo* mem_info, _Outptr_ OrtAllocator** out) { API_IMPL_BEGIN diff --git a/onnxruntime/core/session/custom_ops.cc b/onnxruntime/core/session/custom_ops.cc index 4d6b8b382b..6510888995 100644 --- a/onnxruntime/core/session/custom_ops.cc +++ b/onnxruntime/core/session/custom_ops.cc @@ -258,8 +258,9 @@ common::Status CreateCustomRegistry(const std::vector& op_do def_builder.Provider(onnxruntime::kCpuExecutionProvider); } - KernelCreateFn kernel_create_fn = [op](const OpKernelInfo& info) -> OpKernel* { - return new CustomOpKernel(info, *op); + KernelCreateFn kernel_create_fn = [op](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { + out = std::make_unique(info, *op); + return Status::OK(); }; KernelCreateInfo create_info(def_builder.Build(), kernel_create_fn); diff --git a/onnxruntime/core/session/environment.cc b/onnxruntime/core/session/environment.cc index 563159ca93..ba479a1b80 100644 --- a/onnxruntime/core/session/environment.cc +++ b/onnxruntime/core/session/environment.cc @@ -50,7 +50,7 @@ Status Environment::Create(std::unique_ptr logging_mana std::unique_ptr& environment, const OrtThreadingOptions* tp_options, bool create_global_thread_pools) { - environment = std::unique_ptr(new Environment()); + environment = std::make_unique(); auto status = environment->Initialize(std::move(logging_manager), tp_options, create_global_thread_pools); return status; } diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index b525224b79..4641e2da89 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -1982,8 +1982,7 @@ common::Status InferenceSession::NewIOBinding(std::unique_ptr* io_bin } } - // private constructor, can't use make_unique - *io_binding = std::unique_ptr(new IOBinding(*session_state_)); + *io_binding = std::make_unique(*session_state_); return Status::OK(); } diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index 74880c7ba3..086c7236f3 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -2131,6 +2131,8 @@ ORT_API_STATUS_IMPL(OrtApis::CreateArenaCfgV2, _In_reads_(num_keys) const char* API_IMPL_END } +//Allow using raw new/delete because this is for C. +GSL_SUPPRESS(r .11) ORT_API(void, OrtApis::ReleaseArenaCfg, _Frees_ptr_opt_ OrtArenaCfg* ptr) { delete ptr; } diff --git a/onnxruntime/core/session/ort_env.cc b/onnxruntime/core/session/ort_env.cc index 834bbbeae9..dd10f0eb68 100644 --- a/onnxruntime/core/session/ort_env.cc +++ b/onnxruntime/core/session/ort_env.cc @@ -16,7 +16,7 @@ using namespace onnxruntime; using namespace onnxruntime::logging; -OrtEnv* OrtEnv::p_instance_ = nullptr; +std::unique_ptr OrtEnv::p_instance_; int OrtEnv::ref_count_ = 0; onnxruntime::OrtMutex OrtEnv::m_; @@ -52,19 +52,19 @@ OrtEnv* OrtEnv::GetInstance(const OrtEnv::LoggingManagerConstructionInfo& lm_inf if (lm_info.logging_function) { std::unique_ptr logger = std::make_unique(lm_info.logging_function, lm_info.logger_param); - lmgr.reset(new LoggingManager(std::move(logger), - static_cast(lm_info.default_warning_level), - false, - LoggingManager::InstanceType::Default, - &name)); + lmgr = std::make_unique(std::move(logger), + static_cast(lm_info.default_warning_level), + false, + LoggingManager::InstanceType::Default, + &name); } else { auto sink = MakePlatformDefaultLogSink(); - lmgr.reset(new LoggingManager(std::move(sink), - static_cast(lm_info.default_warning_level), - false, - LoggingManager::InstanceType::Default, - &name)); + lmgr = std::make_unique(std::move(sink), + static_cast(lm_info.default_warning_level), + false, + LoggingManager::InstanceType::Default, + &name); } std::unique_ptr env; if (!tp_options) { @@ -75,11 +75,11 @@ OrtEnv* OrtEnv::GetInstance(const OrtEnv::LoggingManagerConstructionInfo& lm_inf if (!status.IsOK()) { return nullptr; } - p_instance_ = new OrtEnv(std::move(env)); + p_instance_ = std::make_unique(std::move(env)); } ++ref_count_; - return p_instance_; + return p_instance_.get(); } void OrtEnv::Release(OrtEnv* env_ptr) { @@ -87,11 +87,10 @@ void OrtEnv::Release(OrtEnv* env_ptr) { return; } std::lock_guard lock(m_); - ORT_ENFORCE(env_ptr == p_instance_); // sanity check + ORT_ENFORCE(env_ptr == p_instance_.get()); // sanity check --ref_count_; if (ref_count_ == 0) { - delete p_instance_; - p_instance_ = nullptr; + p_instance_.reset(); } } diff --git a/onnxruntime/core/session/ort_env.h b/onnxruntime/core/session/ort_env.h index 8d85c1a4b3..da852b9425 100644 --- a/onnxruntime/core/session/ort_env.h +++ b/onnxruntime/core/session/ort_env.h @@ -59,30 +59,29 @@ struct OrtEnv { /** * Registers an allocator for sharing between multiple sessions. * Returns an error if an allocator with the same OrtMemoryInfo is already registered. - */ + */ onnxruntime::common::Status RegisterAllocator(onnxruntime::AllocatorPtr allocator); /** * Creates and registers an allocator for sharing between multiple sessions. * Return an error if an allocator with the same OrtMemoryInfo is already registered. - */ + */ onnxruntime::common::Status CreateAndRegisterAllocator(const OrtMemoryInfo& mem_info, const OrtArenaCfg* arena_cfg = nullptr); /** * Removes registered allocator that was previously registered for sharing between multiple sessions. - */ + */ onnxruntime::common::Status UnregisterAllocator(const OrtMemoryInfo& mem_info); + OrtEnv(std::unique_ptr value); + ~OrtEnv(); private: - static OrtEnv* p_instance_; + static std::unique_ptr p_instance_; static onnxruntime::OrtMutex m_; static int ref_count_; std::unique_ptr value_; - OrtEnv(std::unique_ptr value1); - ~OrtEnv(); - ORT_DISALLOW_COPY_AND_ASSIGNMENT(OrtEnv); }; diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index bafb803e11..cb76556779 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -140,7 +140,9 @@ struct Node__EdgeIterator_Impl : Node__EdgeIterator { Node::EdgeConstIterator v_; }; - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif // wrapped = The internal object is exposed as an opaque pointer, so we wrap it in a class that forwards every call to the real calls. No members are ever directly accessed // direct = Same implementation is used for shared providers & core code, but some of the methods need to be routed through here to make the linker happy struct ProviderHostImpl : ProviderHost { diff --git a/onnxruntime/core/util/qmath.h b/onnxruntime/core/util/qmath.h index 9c272cde54..34c68ea4ff 100644 --- a/onnxruntime/core/util/qmath.h +++ b/onnxruntime/core/util/qmath.h @@ -59,12 +59,12 @@ void GetQuantizationParameter(const float* data, int64_t num_of_elements, float& block_size = num_of_elements; } - for (int i = 0; i < num_blocks; i++) { + for (int i = 0; i < num_blocks; i++) { aggregate[i].min = std::numeric_limits::max(); aggregate[i].max = std::numeric_limits::lowest(); } - const TensorOpCost unit_cost{static_cast(block_size * sizeof(float)), 2.0, static_cast(block_size)}; + const TensorOpCost unit_cost{static_cast(block_size) * sizeof(float), 2.0, static_cast(block_size)}; concurrency::ThreadPool::TryParallelFor(thread_pool, num_blocks, unit_cost, [&](std::ptrdiff_t begin, std::ptrdiff_t end) { auto begin_idx = begin * block_size; auto end_idx = std::min(std::ptrdiff_t(num_of_elements), end * block_size); @@ -105,8 +105,8 @@ void GetQuantizationParameter(const float* data, int64_t num_of_elements, float& } /** - * @brief Run MlasQuantizeLinear in parallel, with provided thread pool -*/ + * @brief Run MlasQuantizeLinear in parallel, with provided thread pool + */ template void ParQuantizeLinear(const float* Input, OutputType* Output, diff --git a/onnxruntime/core/util/thread_utils.cc b/onnxruntime/core/util/thread_utils.cc index 4446c2f7a4..312076de28 100644 --- a/onnxruntime/core/util/thread_utils.cc +++ b/onnxruntime/core/util/thread_utils.cc @@ -37,20 +37,23 @@ CreateThreadPoolHelper(Env* env, OrtThreadPoolParams options) { } return std::make_unique(env, to, options.name, options.thread_pool_size, - options.allow_spinning); + options.allow_spinning); } std::unique_ptr CreateThreadPool(Env* env, OrtThreadPoolParams options, ThreadPoolType tpool_type) { -// If openmp is enabled we don't want to create any additional threadpools for sequential execution. -// However, parallel execution relies on the existence of a separate threadpool. Hence we allow eigen threadpools -// to be created for parallel execution. + // If openmp is enabled we don't want to create any additional threadpools for sequential execution. + // However, parallel execution relies on the existence of a separate threadpool. Hence we allow eigen threadpools + // to be created for parallel execution. ORT_UNUSED_PARAMETER(tpool_type); return CreateThreadPoolHelper(env, options); } } // namespace concurrency } // namespace onnxruntime +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif namespace OrtApis { ORT_API_STATUS_IMPL(CreateThreadingOptions, _Outptr_ OrtThreadingOptions** out) { *out = new OrtThreadingOptions(); diff --git a/onnxruntime/python/numpy_helper.h b/onnxruntime/python/numpy_helper.h new file mode 100644 index 0000000000..d9165c3d31 --- /dev/null +++ b/onnxruntime/python/numpy_helper.h @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include +namespace onnxruntime { +namespace python { +constexpr bool IsNumericNumpyType(int npy_type) { + return npy_type < NPY_OBJECT || npy_type == NPY_HALF; +} +} // namespace python +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/python/onnxruntime_pybind_mlvalue.cc b/onnxruntime/python/onnxruntime_pybind_mlvalue.cc index f169d7f67d..480fdcef04 100644 --- a/onnxruntime/python/onnxruntime_pybind_mlvalue.cc +++ b/onnxruntime/python/onnxruntime_pybind_mlvalue.cc @@ -9,6 +9,7 @@ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #define PY_ARRAY_UNIQUE_SYMBOL onnxruntime_python_ARRAY_API #include +#include "python/numpy_helper.h" #include "core/graph/graph.h" #include "core/framework/tensor_shape.h" @@ -41,10 +42,6 @@ bool IsNumpyArray(py::object& obj) { return PyObjectCheck_NumpyArray(obj.ptr()); } -bool IsNumericNumpyType(int npy_type) { - return npy_type < NPY_OBJECT || npy_type == NPY_HALF; -} - int GetNumpyArrayType(const py::object& obj) { return PyArray_TYPE(reinterpret_cast(obj.ptr())); } @@ -253,8 +250,7 @@ MLDataType NumpyTypeToOnnxRuntimeType(int numpy_type) { {NPY_UINT, DataTypeImpl::GetType()}, {NPY_LONGLONG, DataTypeImpl::GetType()}, {NPY_ULONGLONG, DataTypeImpl::GetType()}, - {NPY_OBJECT, DataTypeImpl::GetType()} - }; + {NPY_OBJECT, DataTypeImpl::GetType()}}; const auto it = type_map.find(numpy_type); if (it == type_map.end()) { throw std::runtime_error("No corresponding Numpy type for Tensor Type."); diff --git a/onnxruntime/python/onnxruntime_pybind_mlvalue.h b/onnxruntime/python/onnxruntime_pybind_mlvalue.h index eb1b43a55d..d253dfdcb1 100644 --- a/onnxruntime/python/onnxruntime_pybind_mlvalue.h +++ b/onnxruntime/python/onnxruntime_pybind_mlvalue.h @@ -23,8 +23,6 @@ namespace python { extern const char* PYTHON_ORTVALUE_OBJECT_NAME; extern const char* PYTHON_ORTVALUE_NATIVE_OBJECT_ATTR; -bool IsNumericNumpyType(int npy_type); - bool IsNumericNumpyArray(const pybind11::object& py_object); bool IsNumpyArray(pybind11::object& obj); diff --git a/onnxruntime/python/onnxruntime_pybind_ortvalue.cc b/onnxruntime/python/onnxruntime_pybind_ortvalue.cc index a4e7523ecf..f37539906f 100644 --- a/onnxruntime/python/onnxruntime_pybind_ortvalue.cc +++ b/onnxruntime/python/onnxruntime_pybind_ortvalue.cc @@ -9,6 +9,7 @@ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #define PY_ARRAY_UNIQUE_SYMBOL onnxruntime_python_ARRAY_API #include +#include "python/numpy_helper.h" #include "core/framework/ort_value.h" #include "core/framework/tensor.h" diff --git a/onnxruntime/python/onnxruntime_pybind_sparse_tensor.cc b/onnxruntime/python/onnxruntime_pybind_sparse_tensor.cc index f8f51d257d..5e2839ed5f 100644 --- a/onnxruntime/python/onnxruntime_pybind_sparse_tensor.cc +++ b/onnxruntime/python/onnxruntime_pybind_sparse_tensor.cc @@ -9,6 +9,7 @@ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #define PY_ARRAY_UNIQUE_SYMBOL onnxruntime_python_ARRAY_API #include +#include "python/numpy_helper.h" #include "core/framework/tensor_shape.h" #include "core/framework/tensor.h" diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc index 2ed442df75..2c3a194ede 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.cc +++ b/onnxruntime/python/onnxruntime_pybind_state.cc @@ -202,15 +202,15 @@ py::object GetPyObjectFromSparseTensor(size_t pos, const OrtValue& ort_value, co if (!data_transfer_manager) { LOGS(logger, WARNING) << "Returned OrtValue with sparse tensor at position: " << pos << " is on GPU but no data_transfer_manager provided." << " Returned it will have its data on GPU, you can copy it using numpy_array_to_cpu()"; - py_sparse_tensor.reset(new PySparseTensor(ort_value)); + py_sparse_tensor = std::make_unique(ort_value); } else { auto dst_sparse_tensor = std::make_unique(src_sparse_tensor.DataType(), src_sparse_tensor.DenseShape(), GetAllocator()); auto status = src_sparse_tensor.Copy(*data_transfer_manager, 0, *dst_sparse_tensor); OrtPybindThrowIfError(status); - py_sparse_tensor.reset(new PySparseTensor(std::move(dst_sparse_tensor))); + py_sparse_tensor = std::make_unique(std::move(dst_sparse_tensor)); } } else { - py_sparse_tensor.reset(new PySparseTensor(ort_value)); + py_sparse_tensor = std::make_unique(ort_value); } py::object result = py::cast(py_sparse_tensor.get(), py::return_value_policy::take_ownership); @@ -1301,7 +1301,7 @@ including arg name, arg type (contains both type and shape).)pbdoc") }, "node shape (assuming the node holds a tensor)"); - py::class_(m, "SessionObjectInitializer"); + py::class_ sessionObjectInitializer(m, "SessionObjectInitializer"); py::class_(m, "InferenceSession", R"pbdoc(This is the main class used to run a model.)pbdoc") // In Python3, a Python bytes object will be passed to C++ functions that accept std::string or char* // without any conversion. So this init method can be used for model file path (string) and model content (bytes) @@ -1542,7 +1542,7 @@ void InitializeEnv() { InitArray(); Env::Default().GetTelemetryProvider().SetLanguageProjection(OrtLanguageProjection::ORT_PROJECTION_PYTHON); OrtPybindThrowIfError(Environment::Create(std::make_unique( - std::unique_ptr{new CLogSink{}}, + std::make_unique(), Severity::kWARNING, false, LoggingManager::InstanceType::Default, &SessionObjectInitializer::default_logger_id), session_env)); diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index 0218c2c5f1..db4eda1259 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -379,9 +379,9 @@ class PySparseTensor { std::unique_ptr AsOrtValue() const; private: - // instance_ represents data that comes as input. Thus we depend on numpy - // arrays that own the underlying memory to stay around. We store copies - // of py::objects for those arrays in backing_storage_ as an extra ref-count. + // instance_ represents data that comes as input. Thus we depend on numpy + //arrays that own the underlying memory to stay around. We store copies + //of py::objects for those arrays in backing_storage_ as an extra ref-count. // If we have and are able to copy from the OrtValue returned by run() to CPU, then this owns the data // and backing_storage_ is empty. @@ -393,6 +393,11 @@ class PySparseTensor { }; #endif // !defined(DISABLE_SPARSE_TENSORS) +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +//You can attempt to make 'onnxruntime::python::SessionObjectInitializer::Get' constexpr +#pragma warning(disable : 26497) +#endif class SessionObjectInitializer { public: typedef const PySessionOptions& Arg1; @@ -413,7 +418,9 @@ class SessionObjectInitializer { return SessionObjectInitializer(); } }; - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif Environment& GetEnv(); // Initialize an InferenceSession. diff --git a/onnxruntime/test/contrib_ops/tensor_op_test.cc b/onnxruntime/test/contrib_ops/tensor_op_test.cc index 2d4c836782..a72d2d3d83 100644 --- a/onnxruntime/test/contrib_ops/tensor_op_test.cc +++ b/onnxruntime/test/contrib_ops/tensor_op_test.cc @@ -14,7 +14,7 @@ namespace test { using ExpectResult = OpTester::ExpectResult; TEST(CropContribOpTest, CropBorderOnly) { - const int N = 2, C = 1, H = 3, W = 4; + constexpr int N = 2, C = 1, H = 3, W = 4; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f, 2.0f, 3.0f, 4.0f, 5.0f, 3.0f, 4.0f, 5.0f, 6.0f, @@ -37,7 +37,7 @@ TEST(CropContribOpTest, CropBorderOnly) { } TEST(CropContribOpTest, CropBorderAndScale) { - const int N = 2, C = 1, H = 3, W = 4; + constexpr int N = 2, C = 1, H = 3, W = 4; std::vector X = {1.0f, 2.0f, 3.0f, 4.0f, 2.0f, 3.0f, 4.0f, 5.0f, 3.0f, 4.0f, 5.0f, 6.0f, @@ -65,7 +65,7 @@ TEST(CropContribOpTest, CropBorderAndScale) { } TEST(ImageScalerContribOpTest, ImageScalerTest) { - const int64_t N = 1, C = 2, H = 2, W = 2; + constexpr int64_t N = 1, C = 2, H = 2, W = 2; std::vector X = { 1.0f, 3.0f, 3.0f, 5.0f, @@ -92,9 +92,9 @@ TEST(ImageScalerContribOpTest, ImageScalerTest) { } void MeanVarianceNormalizationAcrossChannels(bool across_channels, bool normalize_variance) { - const int64_t N = 2, C = 2, H = 2, W = 3; - int64_t one = 1; - int64_t zero = 0; + constexpr int64_t N = 2, C = 2, H = 2, W = 3; + constexpr int64_t one = 1; + constexpr int64_t zero = 0; std::vector X = {3.0f, -3.0f, -1.0f, 1.0f, 2.0f, -1.0f, @@ -118,9 +118,9 @@ void MeanVarianceNormalizationAcrossChannels(bool across_channels, bool normaliz } void MeanVarianceNormalizationPerChannel(bool across_channels, bool normalize_variance) { - const int64_t N = 2, C = 2, H = 2, W = 3; - int64_t one = 1; - int64_t zero = 0; + constexpr int64_t N = 2, C = 2, H = 2, W = 3; + constexpr int64_t one = 1; + constexpr int64_t zero = 0; std::vector N1C1 = {3.0f, -3.0f, -1.0f, 1.0f, 2.0f, -1.0f}; diff --git a/onnxruntime/test/eager/ort_invoker_test.cc b/onnxruntime/test/eager/ort_invoker_test.cc index d5b0c02d09..ed2efccd76 100644 --- a/onnxruntime/test/eager/ort_invoker_test.cc +++ b/onnxruntime/test/eager/ort_invoker_test.cc @@ -87,8 +87,9 @@ class TestKernel final : public OpKernel { } }; -OpKernel* CreateTestKernel(const OpKernelInfo& info) { - return new TestKernel(info); +Status CreateTestKernel(FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { + out = std::make_unique(info); + return Status::OK(); } TEST(InvokerTest, CustomOp) { diff --git a/onnxruntime/test/framework/allocation_planner_test.cc b/onnxruntime/test/framework/allocation_planner_test.cc index 379ef1d4e4..78b598dcf1 100644 --- a/onnxruntime/test/framework/allocation_planner_test.cc +++ b/onnxruntime/test/framework/allocation_planner_test.cc @@ -230,13 +230,13 @@ class PlannerTest : public ::testing::Test { ASSERT_NE(ep, nullptr); auto info = std::make_unique( *p_node, kernel_def, *ep, state_->GetInitializedTensors(), state_->GetOrtValueNameIdxMap(), - state_->GetFuncMgr(), state_->GetDataTransferMgr()); + state_->GetDataTransferMgr()); op_kernel_infos_.push_back(std::move(info)); if (!KernelRegistry::HasImplementationOf(*reg, *p_node, onnxruntime::kCpuExecutionProvider)) { auto st = reg->Register( KernelCreateInfo(std::make_unique(kernel_def), - [](const OpKernelInfo& info) -> OpKernel* { return new DummyOpKernel(info); })); + [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique(info); return Status::OK(); })); ORT_ENFORCE(st.IsOK(), st.ErrorMessage()); } @@ -575,7 +575,7 @@ TEST_F(PlannerTest, LocationPlanningForPassThroughExplicitAndImplicitSubgraphInp /* Inputs: iter_num, cond_in, loop carried state variables. iter_num_in cond_in [loop_state_var] (unused) | | - [Identity] [If] + [Identity] [If] | | cond_out loop_state_var_out */ diff --git a/onnxruntime/test/framework/float_16_test.cc b/onnxruntime/test/framework/float_16_test.cc index cf453d099e..f8bdb78660 100644 --- a/onnxruntime/test/framework/float_16_test.cc +++ b/onnxruntime/test/framework/float_16_test.cc @@ -145,7 +145,7 @@ TEST(Float16_Tests, Mul_16_Test) { auto def = MulFP16KernelDef(); //Register a foo kernel which is doing Add, but bind to Mul. - KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) -> OpKernel* { return new MulFP16Kernel(info); }; + KernelCreateFn kernel_create_fn = [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique(info); return Status::OK(); }; EXPECT_TRUE(registry->RegisterCustomKernel(def, kernel_create_fn).IsOK()); EXPECT_TRUE(session_object.Load(MUL_MODEL_URI).IsOK()); diff --git a/onnxruntime/test/framework/kernel_registry_test.cc b/onnxruntime/test/framework/kernel_registry_test.cc index be9dd2a260..e2490b6ff4 100644 --- a/onnxruntime/test/framework/kernel_registry_test.cc +++ b/onnxruntime/test/framework/kernel_registry_test.cc @@ -26,8 +26,9 @@ class FakeKernel final : public OpKernel { } }; -OpKernel* CreateFakeKernel(const OpKernelInfo& info) { - return new FakeKernel(info); +Status CreateFakeKernel(FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { + out = std::make_unique(info); + return Status::OK(); } } // namespace diff --git a/onnxruntime/test/framework/local_kernel_registry_test.cc b/onnxruntime/test/framework/local_kernel_registry_test.cc index 1cfdf97311..67e65fee60 100644 --- a/onnxruntime/test/framework/local_kernel_registry_test.cc +++ b/onnxruntime/test/framework/local_kernel_registry_test.cc @@ -95,8 +95,9 @@ KernelDefBuilder FooKernelDef(const char* schema_name) { return def; } -OpKernel* CreateFooKernel(const OpKernelInfo& kernel_info) { - return new FooKernel(kernel_info); +Status CreateFooKernel(FuncManager&, const OpKernelInfo& kernel_info, std::unique_ptr& out) { + out = std::make_unique>(kernel_info); + return Status::OK(); } // kernel with optional outputs @@ -181,8 +182,9 @@ class OptionalOpKernel : public OpKernel { } }; -OpKernel* CreateOptionalOpKernel(const OpKernelInfo& kernel_info) { - return new OptionalOpKernel(kernel_info); +Status CreateOptionalOpKernel(FuncManager&, const OpKernelInfo& kernel_info, std::unique_ptr& out) { + out = std::make_unique>(kernel_info); + return Status::OK(); } static const std::string MUL_MODEL_URI = "testdata/mul_1.onnx"; diff --git a/onnxruntime/test/framework/opaque_kernels_test.cc b/onnxruntime/test/framework/opaque_kernels_test.cc index 632f68deb0..a65f9a19a8 100644 --- a/onnxruntime/test/framework/opaque_kernels_test.cc +++ b/onnxruntime/test/framework/opaque_kernels_test.cc @@ -291,9 +291,9 @@ TEST_F(OpaqueTypeTests, RunModel) { EXPECT_TRUE(registry->RegisterOpSet(schemas, onnxruntime::kMLDomain, 8, 9).IsOK()); // Register our kernels here auto ctor_def = ConstructSparseTensorDef(); - EXPECT_TRUE(registry->RegisterCustomKernel(ctor_def, [](const OpKernelInfo& info) { return new ConstructSparseTensor(info); }).IsOK()); + EXPECT_TRUE(registry->RegisterCustomKernel(ctor_def, [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }).IsOK()); auto shape_def = ConstructFetchSparseShape(); - EXPECT_TRUE(registry->RegisterCustomKernel(shape_def, [](const OpKernelInfo& info) { return new FetchSparseTensorShape(info); }).IsOK()); + EXPECT_TRUE(registry->RegisterCustomKernel(shape_def, [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }).IsOK()); IOnnxRuntimeOpSchemaRegistryList custom_schema_registries_ = {registry->GetOpschemaRegistry()}; std::unordered_map domain_to_version = {{onnxruntime::kMLDomain, 8}}; diff --git a/onnxruntime/test/framework/parallel_executor_test.cc b/onnxruntime/test/framework/parallel_executor_test.cc index 49c7800c1b..8dcaad10c5 100644 --- a/onnxruntime/test/framework/parallel_executor_test.cc +++ b/onnxruntime/test/framework/parallel_executor_test.cc @@ -82,7 +82,7 @@ TEST(ParallelExecutor, TestStatusPropagation) { std::vector schemas{TestOp::OpSchema()}; Status status; ASSERT_TRUE((status = registry->RegisterOpSet(schemas, TestOp::OpDomain, 10, 11)).IsOK()) << status; - KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename TestOp::OpKernelImpl(info); }; + KernelCreateFn kernel_create_fn = [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }; auto kernel_def = TestOp::KernelDef(); ASSERT_TRUE((status = registry->RegisterCustomKernel(kernel_def, kernel_create_fn)).IsOK()) << status; @@ -125,7 +125,7 @@ TEST_P(ParallelExecutorThreadPoolTest, TestNullInterOpThreadPool) { std::vector schemas{TestOp::OpSchema()}; Status status; ASSERT_TRUE((status = registry->RegisterOpSet(schemas, TestOp::OpDomain, 10, 11)).IsOK()) << status; - KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename TestOp::OpKernelImpl(info); }; + KernelCreateFn kernel_create_fn = [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }; auto kernel_def = TestOp::KernelDef(); ASSERT_TRUE((status = registry->RegisterCustomKernel(kernel_def, kernel_create_fn)).IsOK()) << status; @@ -144,6 +144,6 @@ TEST_P(ParallelExecutorThreadPoolTest, TestNullInterOpThreadPool) { } INSTANTIATE_TEST_SUITE_P(ParallelExecutorThreadPoolTests, ParallelExecutorThreadPoolTest, - testing::Values(1, 0)); + testing::Values(1, 0)); } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/framework/session_state_test.cc b/onnxruntime/test/framework/session_state_test.cc index c6d49e7356..344f563fab 100644 --- a/onnxruntime/test/framework/session_state_test.cc +++ b/onnxruntime/test/framework/session_state_test.cc @@ -76,7 +76,7 @@ TEST_P(SessionStateAddGetKernelTest, AddGetKernelTest) { auto kernel_def = KernelDefBuilder().SetName("Variable").Provider(kCpuExecutionProvider).SinceVersion(1, 10).Build(); OpKernelInfo p_info(node, *kernel_def, *cpu_execution_provider, s.GetConstantInitializedTensors(), - s.GetOrtValueNameIdxMap(), s.GetFuncMgr(), s.GetDataTransferMgr()); + s.GetOrtValueNameIdxMap(), s.GetDataTransferMgr()); unique_ptr p_kernel; p_kernel.reset(new TestOpKernel(p_info)); size_t orig_num_outputs = p_kernel->Node().OutputDefs().size(); @@ -88,7 +88,7 @@ TEST_P(SessionStateAddGetKernelTest, AddGetKernelTest) { node.SetExecutionProviderType(kCpuExecutionProvider); std::shared_ptr kernel_registry = std::make_shared(); ASSERT_STATUS_OK(kernel_registry->Register(KernelCreateInfo( - std::move(kernel_def), [](const OpKernelInfo& info) -> OpKernel* { return new TestOpKernel(info); }))); + std::move(kernel_def), [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique(info); return Status::OK(); }))); kernel_registry_manager.RegisterKernelRegistry(kernel_registry); ASSERT_STATUS_OK(s.FinalizeSessionState(ORT_TSTR(""), kernel_registry_manager)); @@ -511,7 +511,7 @@ TEST_P(SessionStatePrepackingTest, PrePackingTest) { auto kernel_def = KernelDefBuilder().SetName("PrePackingTest").Provider(kCpuExecutionProvider).SinceVersion(1).Build(); ASSERT_STATUS_OK(kernel_registry->Register( KernelCreateInfo(std::move(kernel_def), - [](const OpKernelInfo& info) -> OpKernel* { return new PrePackingTestOpKernel(info); }))); + [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique(info); return Status::OK(); }))); kernel_registry_manager.RegisterKernelRegistry(kernel_registry); PlaceAllNodesToCPUEP(model.MainGraph()); @@ -553,7 +553,7 @@ TEST(SessionStateTest, SharedInitalizersWithPrePackingTest) { auto kernel_def = KernelDefBuilder().SetName("PrePackingTest").Provider(kCpuExecutionProvider).SinceVersion(1).Build(); ASSERT_STATUS_OK(kernel_registry->Register( KernelCreateInfo(std::move(kernel_def), - [](const OpKernelInfo& info) -> OpKernel* { return new PrePackingTestOpKernel(info); }))); + [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { out = std::make_unique(info); return Status::OK(); }))); kernel_registry_manager.RegisterKernelRegistry(kernel_registry); // Part 1: Pre-packing enabled + no shared initializers = no pre-packed weights caching diff --git a/onnxruntime/test/framework/sparse_kernels_test.cc b/onnxruntime/test/framework/sparse_kernels_test.cc index 3bba5d1a9d..30d1232a7b 100644 --- a/onnxruntime/test/framework/sparse_kernels_test.cc +++ b/onnxruntime/test/framework/sparse_kernels_test.cc @@ -95,8 +95,8 @@ This operator constructs a sparse tensor from three tensors that provide a COO } /** - * @brief An implementation of the SparseFromCOO op. - */ + * @brief An implementation of the SparseFromCOO op. + */ class OpKernelImpl final : public OpKernel { public: OpKernelImpl(const OpKernelInfo& info) : OpKernel{info} {} @@ -264,7 +264,7 @@ struct SparseToValues { return schema; } - // A kernel implementation of SparseToValues + // A kernel implementation of SparseToValues class OpKernelImpl final : public OpKernel { public: OpKernelImpl(const OpKernelInfo& info) : OpKernel{info} {} @@ -333,7 +333,7 @@ class SparseTensorTests : public testing::Test { .SetDomain(onnxruntime::kMLDomain) .SinceVersion(10) .Provider(onnxruntime::kCpuExecutionProvider); - KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename Op::OpKernelImpl(info); }; + KernelCreateFn kernel_create_fn = [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }; EXPECT_TRUE(registry2->RegisterCustomKernel(kernel_def_builder, kernel_create_fn).IsOK()); }; register_actions.push_back(register_kernel); @@ -698,9 +698,10 @@ struct InsertIndices { std::vector indices_data; insert_indices_data(indices_1D, values_size, shape_size, indices_data, indices_tp); indices_tp.set_data_type(utils::ToTensorProtoElementType()); - ORT_IF_CONSTEXPR (sizeof(T) == sizeof(int8_t)) { + ORT_IF_CONSTEXPR(sizeof(T) == sizeof(int8_t)) { indices_tp.mutable_raw_data()->assign(reinterpret_cast(indices_data.data()), indices_data.size()); - } else { + } + else { // Conversion on the fly to the target data type std::vector indices(indices_data.cbegin(), indices_data.cend()); indices_tp.mutable_raw_data()->assign(reinterpret_cast(indices.data()), indices.size() * sizeof(T)); @@ -823,8 +824,7 @@ static void TestConversion( TensorProto_DataType_INT8, TensorProto_DataType_INT16, TensorProto_DataType_INT32, - TensorProto_DataType_INT64 - }; + TensorProto_DataType_INT64}; for (auto dt : indices_types) { TestConversion(true, dt, inserter, checker); @@ -1037,7 +1037,7 @@ TensorProto CreateDenseTensor(size_t indices_start, std::vector& expected_values, std::vector& expected_indicies) { TensorProto result; std::vector values = CreateSparseValues(indices_start); - auto ind_start = static_cast(indices_start); + auto ind_start = static_cast(indices_start); expected_indicies = {ind_start, ind_start + 1}; for (const auto& ind : expected_indicies) { expected_values.push_back(values[ind]); @@ -1110,11 +1110,11 @@ void RawSparseDataChecker(gsl::span expected_bfloat, template static void TestDenseToSparseConversionValues(size_t indices_start, - std::function& values, TensorProto& tp)> inserter, - std::function expected, - gsl::span expected_indicies, - const SparseTensorProto& actual)> - checker) { + std::function& values, TensorProto& tp)> inserter, + std::function expected, + gsl::span expected_indicies, + const SparseTensorProto& actual)> + checker) { std::vector expected_values; std::vector expected_indicies; // Path is required for loading external data @@ -1862,7 +1862,7 @@ TEST(SparseTensorConversionTests, BlockSparse) { indices_span.cbegin(), indices_span.cend())); } } -#endif // !defined(DISABLE_SPARSE_TENSORS) +#endif // !defined(DISABLE_SPARSE_TENSORS) } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/mlas/bench/bench_qgemm.cpp b/onnxruntime/test/mlas/bench/bench_qgemm.cpp index d2bf9a57e6..1d21c8732b 100644 --- a/onnxruntime/test/mlas/bench/bench_qgemm.cpp +++ b/onnxruntime/test/mlas/bench/bench_qgemm.cpp @@ -13,9 +13,9 @@ static const std::vector qgemm_arg_names = {"M", "N", "K", "Batch", "Threads"}; void QGEMM(benchmark::State& state, bool pack_b, bool a_is_signed) { - const bool b_is_signed = true; - const uint8_t a_zero_point = 29; - const uint8_t b_zero_point = 179; + constexpr bool b_is_signed = true; + constexpr uint8_t a_zero_point = 29; + constexpr uint8_t b_zero_point = 179; if (state.range(0) <= 0) throw std::invalid_argument("M must greater than 0!"); if (state.range(1) <= 0) throw std::invalid_argument("N must greater than 0!"); diff --git a/onnxruntime/test/mlas/unittest/test_conv2d_nchwc.h b/onnxruntime/test/mlas/unittest/test_conv2d_nchwc.h index 439ebb027e..e516fa8a0b 100644 --- a/onnxruntime/test/mlas/unittest/test_conv2d_nchwc.h +++ b/onnxruntime/test/mlas/unittest/test_conv2d_nchwc.h @@ -31,9 +31,9 @@ class MlasNchwcConv2DTest : public MlasConv2DTest { const float* Filter, const float* Bias, float* Output) override { - int64_t InputShape[] = {int64_t(BatchCount), int64_t(GroupCount * InputChannels), int64_t(InputHeight), int64_t(InputWidth)}; - int64_t FilterShape[] = {int64_t(GroupCount * FilterCount), int64_t(InputChannels), int64_t(KernelHeight), int64_t(KernelWidth)}; - int64_t OutputShape[] = {int64_t(BatchCount), int64_t(GroupCount * FilterCount), int64_t(OutputHeight), int64_t(OutputWidth)}; + int64_t InputShape[] = {int64_t(BatchCount), int64_t(GroupCount) * int64_t(InputChannels), int64_t(InputHeight), int64_t(InputWidth)}; + int64_t FilterShape[] = {int64_t(GroupCount) * int64_t(FilterCount), int64_t(InputChannels), int64_t(KernelHeight), int64_t(KernelWidth)}; + int64_t OutputShape[] = {int64_t(BatchCount), int64_t(GroupCount) * int64_t(FilterCount), int64_t(OutputHeight), int64_t(OutputWidth)}; int64_t KernelShape[] = {int64_t(KernelHeight), int64_t(KernelWidth)}; int64_t DilationShape[] = {int64_t(DilationHeight), int64_t(DilationWidth)}; @@ -149,7 +149,7 @@ class MlasNchwcConv2DTest : public MlasConv2DTest { public: static const char* GetTestSuiteName(void) { - static const std::string suite_name(Threaded? "Conv2dNchwc_Threaded" : "Conv2dNchwc_SingleThread"); + static const std::string suite_name(Threaded ? "Conv2dNchwc_Threaded" : "Conv2dNchwc_SingleThread"); return suite_name.c_str(); } diff --git a/onnxruntime/test/onnx/TestCase.cc b/onnxruntime/test/onnx/TestCase.cc index 0b1b16d301..f4fb214066 100644 --- a/onnxruntime/test/onnx/TestCase.cc +++ b/onnxruntime/test/onnx/TestCase.cc @@ -265,22 +265,22 @@ void LoopDataFile(int test_data_pb_fd, bool is_input, const TestModelInfo& model #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr TestModelInfo::LoadOnnxModel(_In_ const PATH_CHAR_TYPE* model_url) { - return std::unique_ptr(new OnnxModelInfo(model_url)); + return std::make_unique(model_url); } #endif std::unique_ptr TestModelInfo::LoadOrtModel(_In_ const PATH_CHAR_TYPE* model_url) { - return std::unique_ptr(new OnnxModelInfo(model_url, true)); + return std::make_unique(model_url, true); } /** - * test_case_dir must have contents of: - * model.onnx - * ???/input_??.pb - * ???/output_??.pb - * ???/input_??.pb - * ???/output_??.pb - */ + * test_case_dir must have contents of: + * model.onnx + * ???/input_??.pb + * ???/output_??.pb + * ???/input_??.pb + * ???/output_??.pb + */ class OnnxTestCase : public ITestCase { private: std::string test_case_name_; @@ -352,9 +352,9 @@ std::unique_ptr CreateOnnxTestCase(const std::string& test_case_name, std::unique_ptr model, double default_per_sample_tolerance, double default_relative_per_sample_tolerance) { - return std::unique_ptr(new OnnxTestCase(test_case_name, std::move(model), - default_per_sample_tolerance, - default_relative_per_sample_tolerance)); + return std::make_unique(test_case_name, std::move(model), + default_per_sample_tolerance, + default_relative_per_sample_tolerance); } void OnnxTestCase::GetPerSampleTolerance(double* value) const { diff --git a/onnxruntime/test/onnx/dataitem_request.cc b/onnxruntime/test/onnx/dataitem_request.cc index 41e81baa13..abe8111a29 100644 --- a/onnxruntime/test/onnx/dataitem_request.cc +++ b/onnxruntime/test/onnx/dataitem_request.cc @@ -39,7 +39,7 @@ void DataTaskRequestContext::Request(const Callback& cb, concurrency::ThreadPool const ITestCase& c, Ort::Session& session, OrtAllocator* allocator, size_t task_id) { assert(cb); - std::unique_ptr self(new DataTaskRequestContext(cb, c, session, allocator, task_id)); + std::unique_ptr self = std::make_unique(cb, c, session, allocator, task_id); CallableFactory f(self.get()); auto runnable = f.GetCallable<&DataTaskRequestContext::RunAsync>(); onnxruntime::concurrency::ThreadPool::Schedule(tp, [runnable]() { runnable.Invoke(); }); diff --git a/onnxruntime/test/onnx/dataitem_request.h b/onnxruntime/test/onnx/dataitem_request.h index 417b800e5c..96a0e64cd8 100644 --- a/onnxruntime/test/onnx/dataitem_request.h +++ b/onnxruntime/test/onnx/dataitem_request.h @@ -8,7 +8,6 @@ #include "core/common/common.h" #include "core/platform/env_time.h" - class ITestCase; struct OrtAllocator; @@ -40,7 +39,7 @@ class DataTaskRequestContext { /// this task id /// execution result and elapsed time static std::pair Run(const ITestCase& c, ::Ort::Session& session, - OrtAllocator* allocator, size_t task_id); + OrtAllocator* allocator, size_t task_id); /// /// Schedules a data task to run on a threadpool. The function @@ -68,7 +67,6 @@ class DataTaskRequestContext { return spent_time_; } - private: DataTaskRequestContext(const Callback& cb, const ITestCase& test_case, ::Ort::Session& session, OrtAllocator* allocator, size_t task_id) @@ -80,6 +78,7 @@ class DataTaskRequestContext { SetTimeSpecToZero(&spent_time_); } + private: void RunAsync(); std::pair RunImpl(); diff --git a/onnxruntime/test/onnx/microbenchmark/activation.cc b/onnxruntime/test/onnx/microbenchmark/activation.cc index d0b417b84e..d763e89219 100644 --- a/onnxruntime/test/onnx/microbenchmark/activation.cc +++ b/onnxruntime/test/onnx/microbenchmark/activation.cc @@ -69,7 +69,7 @@ struct KernelAndDef { .SetDomain(domain) .TypeConstraint("T", DataTypeImpl::GetTensorType()) .Build(); - OpKernelInfo info(main_node, *out.def, *out.a, {}, {}, {}, {}); + OpKernelInfo info(main_node, *out.def, *out.a, {}, {}, {}); out.kernel = std::make_unique(info); return out; } diff --git a/onnxruntime/test/onnx/tensorprotoutils.cc b/onnxruntime/test/onnx/tensorprotoutils.cc index 4cff3880d5..902ee79d1b 100644 --- a/onnxruntime/test/onnx/tensorprotoutils.cc +++ b/onnxruntime/test/onnx/tensorprotoutils.cc @@ -69,7 +69,7 @@ static void UnpackTensorWithRawData(const void* raw_data, size_t raw_data_length ORT_CXX_API_THROW(MakeString("UnpackTensor: the pre-allocated size does not match the raw data size, expected ", expected_size_in_bytes, ", got ", raw_data_length), OrtErrorCode::ORT_FAIL); - if constexpr(endian::native != endian::little) { + if constexpr (endian::native != endian::little) { ORT_CXX_API_THROW("UnpackTensorWithRawData only handles little-endian native byte order for now.", OrtErrorCode::ORT_NOT_IMPLEMENTED); } @@ -298,7 +298,9 @@ OrtStatus* OrtInitializeBufferForTensor(void* input, size_t input_len, } ORT_API(void, OrtUninitializeBuffer, _In_opt_ void* input, size_t input_len, enum ONNXTensorElementDataType type); - +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(disable : 26409) +#endif static void UnInitTensor(void* param) noexcept { UnInitializeParam* p = reinterpret_cast(param); OrtUninitializeBuffer(p->preallocated, p->preallocated_size, p->ele_type); diff --git a/onnxruntime/test/onnx/testcase_request.cc b/onnxruntime/test/onnx/testcase_request.cc index ccb64e7131..bc6429905b 100644 --- a/onnxruntime/test/onnx/testcase_request.cc +++ b/onnxruntime/test/onnx/testcase_request.cc @@ -85,7 +85,7 @@ void TestCaseRequestContext::Request(const Callback& cb, PThreadPool tpool, concurrent_runs = 1; } - std::unique_ptr self(new TestCaseRequestContext(cb, tpool, c, env, session_opts, test_case_id)); + std::unique_ptr self = std::make_unique(cb, tpool, c, env, session_opts, test_case_id); CallableFactory f(self.get()); auto runnable = f.GetCallable<&TestCaseRequestContext::RunAsync>(); onnxruntime::concurrency::ThreadPool::Schedule(tpool, [runnable, concurrent_runs]() { runnable.Invoke(concurrent_runs); }); diff --git a/onnxruntime/test/onnx/testcase_request.h b/onnxruntime/test/onnx/testcase_request.h index 75d02db3d6..4d53a0867d 100644 --- a/onnxruntime/test/onnx/testcase_request.h +++ b/onnxruntime/test/onnx/testcase_request.h @@ -78,11 +78,10 @@ class TestCaseRequestContext { /// The impact is mitigated by the fact that __Ctor is still private. ~TestCaseRequestContext() = default; - private: - TestCaseRequestContext(const Callback& cb, PThreadPool tp, const ITestCase& test_case, Ort::Env& env, const Ort::SessionOptions& session_opts, size_t test_case_id); + private: bool SetupSession(); std::shared_ptr GetResult() const { @@ -119,6 +118,5 @@ class TestCaseRequestContext { mutable bool finished_ = false; }; -} +} //namespace test } // namespace onnxruntime - diff --git a/onnxruntime/test/optimizer/graph_transform_test.cc b/onnxruntime/test/optimizer/graph_transform_test.cc index af7f5739f7..abc080a31a 100644 --- a/onnxruntime/test/optimizer/graph_transform_test.cc +++ b/onnxruntime/test/optimizer/graph_transform_test.cc @@ -1339,7 +1339,7 @@ TEST_F(GraphTransformationTests, GemmTransposeFusionOutput) { ASSERT_TRUE(new_input_defs[1]->Name() == "A"); } -// ((A')'B')' = BA' +// ((A')'B')' = BA' TEST_F(GraphTransformationTests, GemmTransposeFusionInputOutput) { auto model_uri = MODEL_FOLDER "fusion/gemm_transpose_inputs_output_transposed.onnx"; std::shared_ptr p_model; @@ -1368,7 +1368,7 @@ TEST_F(GraphTransformationTests, GemmTransposeFusionInputOutput) { ASSERT_TRUE(new_input_defs[1]->Name() == "A"); } -// (A'(B'))' = BA +// (A'(B'))' = BA TEST_F(GraphTransformationTests, GemmTransposeFusionInputOutput2) { auto model_uri = MODEL_FOLDER "fusion/gemm_transpose_inputs_output_transposed_2.onnx"; std::shared_ptr p_model; @@ -1497,8 +1497,8 @@ TEST_F(GraphTransformationTests, GemmSumFusionInternalNodes) { ASSERT_EQ(op_to_count["Identity"], 4); ASSERT_EQ(graph.NumberOfNodes(), 5); - for(Node &node : graph.Nodes()) { - if(node.OpType() == "Gemm") { + for (Node& node : graph.Nodes()) { + if (node.OpType() == "Gemm") { ASSERT_FALSE(static_cast(node.GetAttributes().at("transA").i())); ASSERT_FALSE(static_cast(node.GetAttributes().at("transB").i())); ASSERT_EQ(node.GetAttributes().at("alpha").f(), 1.0); @@ -4339,8 +4339,8 @@ TEST_F(GraphTransformationTests, ComputationReductionTransformer_GatherND_E2E) { values_unsqueezed_masked_lm_positions); ASSERT_TRUE(expected_ort_values.size() == actual_ort_values.size()); - const double per_sample_tolerance = 1e-4; - const double relative_per_sample_tolerance = 1e-4; + constexpr double per_sample_tolerance = 1e-4; + constexpr double relative_per_sample_tolerance = 1e-4; for (size_t i = 0; i < expected_ort_values.size(); i++) { auto ret = CompareOrtValue(actual_ort_values[i], expected_ort_values[i], per_sample_tolerance, relative_per_sample_tolerance, false); @@ -4411,7 +4411,7 @@ TEST_F(GraphTransformationTests, MatMulScaleFusionFusableModels) { EXPECT_EQ(transformed_op_counts["com.microsoft.FusedMatMul"], 1); // check combined scale, individual scales should all have the same value - const float scale_value = 3.0f; + constexpr float scale_value = 3.0f; const int num_scales = original_op_counts["Mul"] + original_op_counts["Div"] + original_op_counts["com.microsoft.FusedMatMul"]; @@ -4694,7 +4694,7 @@ TEST_F(GraphTransformationTests, PropagateCastOpsTests) { // Create a temporary directory, which will be deleted automatically, to save/load the transformed models. TemporaryDirectory temp_dir{ORT_TSTR("propagate_casts_test_output_dir")}; for (PropagateCastOpsTestSpecs test_case : test_cases) { - for (auto scenario : test_case.casts_count_map) { + for (const auto& scenario : test_case.casts_count_map) { Strategy strategy = scenario.first.first; int level = scenario.first.second; int expected_casts_count = scenario.second; diff --git a/onnxruntime/test/perftest/TFModelInfo.cc b/onnxruntime/test/perftest/TFModelInfo.cc index 8b161faf90..82f5359545 100644 --- a/onnxruntime/test/perftest/TFModelInfo.cc +++ b/onnxruntime/test/perftest/TFModelInfo.cc @@ -8,8 +8,7 @@ #include std::unique_ptr TFModelInfo::Create(_In_ const PATH_CHAR_TYPE* model_url) { - auto* model_info = new TFModelInfo{}; - std::unique_ptr ret(model_info); + std::unique_ptr model_info = std::make_unique(); model_info->model_url_ = model_url; std::basic_string meta_file_path = model_url; @@ -50,7 +49,7 @@ std::unique_ptr TFModelInfo::Create(_In_ const PATH_CHAR_TYPE* mo } } - return ret; + return model_info; } int TFModelInfo::GetInputCount() const { return static_cast(input_names_.size()); } diff --git a/onnxruntime/test/perftest/TFModelInfo.h b/onnxruntime/test/perftest/TFModelInfo.h index bf7f871a5a..2ca60010e3 100644 --- a/onnxruntime/test/perftest/TFModelInfo.h +++ b/onnxruntime/test/perftest/TFModelInfo.h @@ -22,9 +22,9 @@ class TFModelInfo : public TestModelInfo { ~TFModelInfo() override = default; static std::unique_ptr Create(_In_ const PATH_CHAR_TYPE* model_url); + TFModelInfo() = default; private: - TFModelInfo() = default; std::basic_string model_url_; std::vector input_names_; std::vector output_names_; diff --git a/onnxruntime/test/perftest/performance_runner.cc b/onnxruntime/test/perftest/performance_runner.cc index 8536085611..f789ed5745 100644 --- a/onnxruntime/test/perftest/performance_runner.cc +++ b/onnxruntime/test/perftest/performance_runner.cc @@ -35,7 +35,7 @@ static std::once_flag default_pool_init; Eigen::ThreadPoolInterface* GetDefaultThreadPool(const onnxruntime::Env& env) { std::call_once(default_pool_init, [&env] { int core_num = env.GetNumCpuCores(); - default_pool.reset(new DefaultThreadPoolType(core_num)); + default_pool = std::make_unique(core_num); }); return default_pool.get(); } @@ -258,8 +258,7 @@ static std::unique_ptr CreateSession(Ort::Env& env, std::random_dev const PerformanceTestConfig& performance_test_config_, const TestModelInfo& test_model_info) { if (CompareCString(performance_test_config_.backend.c_str(), ORT_TSTR("ort")) == 0) { - return std::unique_ptr( - new OnnxRuntimeTestSession(env, rd, performance_test_config_, test_model_info)); + return std::make_unique(env, rd, performance_test_config_, test_model_info); } #ifdef HAVE_TENSORFLOW if (CompareCString(performance_test_config_.backend.c_str(), ORT_TSTR("tf")) == 0) { diff --git a/onnxruntime/test/providers/cpu/activation/activation_op_test.cc b/onnxruntime/test/providers/cpu/activation/activation_op_test.cc index fb6ae200ab..a530bbb8c8 100644 --- a/onnxruntime/test/providers/cpu/activation/activation_op_test.cc +++ b/onnxruntime/test/providers/cpu/activation/activation_op_test.cc @@ -105,17 +105,19 @@ TEST_F(ActivationOpTest, Relu) { TestActivationOp("Relu", input_values, [](float x) { return std::max(x, 0.0f); }); - TestActivationOp("Relu", - input_values_double, - [](double x) { return std::max(x, 0.0); }, - {}, - /*is_tensorrt_supported=*/ false); - TestActivationOp("Relu", - input_values_int8, - [](int8_t x) { return std::max(x, static_cast(0)); }, - {}, - /*is_tensorrt_supported=*/ false, - /*opset_version= */ 14); + TestActivationOp( + "Relu", + input_values_double, + [](double x) { return std::max(x, 0.0); }, + {}, + /*is_tensorrt_supported=*/false); + TestActivationOp( + "Relu", + input_values_int8, + [](int8_t x) { return std::max(x, static_cast(0)); }, + {}, + /*is_tensorrt_supported=*/false, + /*opset_version= */ 14); } TEST_F(ActivationOpTest, Elu) { @@ -217,9 +219,9 @@ TEST_F(ActivationOpTest, PRelu_MultiChannel) { std::vector inputs{1.0f, 2.0f, -4.0f, 3.0f, 0.0f, 5.0f, -9.0f, 8.0f}; std::vector slopes{1.0f, -2.0f}; std::vector outputs; - const int64_t num_images = 2; - const int64_t num_channels = 2; - const int64_t num_pixels = 2; + constexpr int64_t num_images = 2; + constexpr int64_t num_channels = 2; + constexpr int64_t num_pixels = 2; for (unsigned i = 0; i < inputs.size(); i++) outputs.push_back(formula(inputs[i], slopes[i / num_pixels % num_channels])); diff --git a/onnxruntime/test/providers/cpu/generator/random_test.cc b/onnxruntime/test/providers/cpu/generator/random_test.cc index e1be1e28f9..a59e19f2f1 100644 --- a/onnxruntime/test/providers/cpu/generator/random_test.cc +++ b/onnxruntime/test/providers/cpu/generator/random_test.cc @@ -15,9 +15,9 @@ TEST(Random, RandomNormal2DDouble) { std::vector dims{20, 50}; - float scale = 10.f; - float mean = 0.f; - float seed = 123.f; + constexpr float scale = 10.f; + constexpr float mean = 0.f; + constexpr float seed = 123.f; test.AddAttribute("scale", scale); test.AddAttribute("mean", mean); @@ -44,9 +44,9 @@ void RunRandomNormalLike3DFloat(bool infer_dtype = false) { std::vector dims{2, 2, 3}; - float scale = 10.f; - float mean = 0.f; - float seed = 123.f; + constexpr float scale = 10.f; + constexpr float mean = 0.f; + constexpr float seed = 123.f; test.AddAttribute("scale", scale); test.AddAttribute("mean", mean); @@ -79,7 +79,7 @@ TEST(Random, RandomNormalLike3DDouble) { } TEST(Random, RandomNormalLikeInferDType) { - const bool infer_dtype = true; + constexpr bool infer_dtype = true; RunRandomNormalLike3DFloat(infer_dtype); } @@ -88,9 +88,9 @@ TEST(Random, RandomUniform1DFloat) { std::vector dims{10}; - float low = 0.f; - float high = 100.f; - float seed = 123.f; + constexpr float low = 0.f; + constexpr float high = 100.f; + constexpr float seed = 123.f; test.AddAttribute("low", low); test.AddAttribute("high", high); @@ -116,9 +116,9 @@ void RunRandomUniformLikeTest(bool infer_dtype = false) { std::vector dims{2, 6}; - float low = 0.f; - float high = 100.f; - float seed = 123.f; + constexpr float low = 0.f; + constexpr float high = 100.f; + constexpr float seed = 123.f; test.AddAttribute("low", low); test.AddAttribute("high", high); @@ -149,12 +149,12 @@ TEST(Random, RandomUniformLike2DDouble) { } TEST(Random, RandomUniformLikeInferDType) { - const bool infer_dtype = true; + constexpr bool infer_dtype = true; RunRandomUniformLikeTest(infer_dtype); } TEST(Random, InvalidDType) { - float seed = 123.f; + constexpr float seed = 123.f; std::vector dims{1, 4}; std::vector input{0, 0, 0, 0}; @@ -179,8 +179,8 @@ TEST(Random, InvalidDType) { { OpTester test("RandomUniform"); - float low = 0.f; - float high = 100.f; + constexpr float low = 0.f; + constexpr float high = 100.f; test.AddAttribute("low", low); test.AddAttribute("high", high); @@ -195,8 +195,8 @@ TEST(Random, InvalidDType) { { OpTester test("RandomNormalLike"); - float scale = 10.f; - float mean = 0.f; + constexpr float scale = 10.f; + constexpr float mean = 0.f; test.AddAttribute("scale", scale); test.AddAttribute("mean", mean); @@ -211,8 +211,8 @@ TEST(Random, InvalidDType) { { OpTester test("RandomUniformLike"); - float low = 0.f; - float high = 100.f; + constexpr float low = 0.f; + constexpr float high = 100.f; test.AddAttribute("low", low); test.AddAttribute("high", high); @@ -234,10 +234,10 @@ for verification. TEST(Random, MultinomialGoodCase) { OpTester test("Multinomial"); - const int64_t num_samples = 10; - const float seed = 1618.f; - const int batch_size = 2; - const int num_classes = 3; + constexpr int64_t num_samples = 10; + constexpr float seed = 1618.f; + constexpr int batch_size = 2; + constexpr int num_classes = 3; const std::vector input_dims{batch_size, num_classes}; std::vector input(TensorShape(input_dims).Size()); @@ -264,9 +264,9 @@ TEST(Random, MultinomialGoodCase) { TEST(Random, MultinomialDefaultDType) { auto run_test = [](int num_run_calls, const std::vector& expected_output) { OpTester test("Multinomial"); - const int64_t num_samples = 10; - const int batch_size = 2; - const float seed = 1618.f; + constexpr int64_t num_samples = 10; + constexpr int batch_size = 2; + constexpr float seed = 1618.f; const std::vector input_dims{2, 3}; std::vector input(TensorShape(input_dims).Size()); @@ -307,10 +307,10 @@ TEST(Random, MultinomialDefaultDType) { TEST(Random, MultinomialInvalidDtype) { OpTester test("Multinomial"); - const int64_t num_samples = 10; - const int batch_size = 2; - const int num_classes = 3; - const float seed = 1618.f; + constexpr int64_t num_samples = 10; + constexpr int batch_size = 2; + constexpr int num_classes = 3; + constexpr float seed = 1618.f; const std::vector input_dims{batch_size, num_classes}; std::vector input(TensorShape(input_dims).Size()); diff --git a/onnxruntime/test/providers/cpu/math/element_wise_ops_test.cc b/onnxruntime/test/providers/cpu/math/element_wise_ops_test.cc index 68c764813f..841e075855 100644 --- a/onnxruntime/test/providers/cpu/math/element_wise_ops_test.cc +++ b/onnxruntime/test/providers/cpu/math/element_wise_ops_test.cc @@ -1572,7 +1572,6 @@ TEST(MathOpTest, Xor) { test.Run(); } - TEST(MathOpTest, Xor_Issue8880) { OpTester test("Xor"); test.AddInput("A", {1}, {true}); @@ -2247,7 +2246,7 @@ TEST(MathOpTest, ErfMoreData) { test.Run(); } -const int ModOp_ver = 10; +constexpr int ModOp_ver = 10; TEST(ModOpTest, Fmod_float_mixed_sign) { OpTester test("Mod", ModOp_ver); diff --git a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc index aa5e103874..0cb078b456 100644 --- a/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc +++ b/onnxruntime/test/providers/cpu/math/quantize_linear_matmul_test.cc @@ -415,8 +415,8 @@ TEST(QuantizeLinearMatmulOpTest, PerColumn_ND_S8S8) { } /** - * @brief Extend QLinearMatMul for verifying prepacking behavior -*/ + * @brief Extend QLinearMatMul for verifying prepacking behavior + */ struct PrePackTestOp { // TODO!! use template and macro to extract a common utility out of this // for grey box kernel testing by extending kernel classes. @@ -487,7 +487,7 @@ TEST(QuantizeLinearMatmulOpTest, QLinearMatMulPrePack) { std::vector schemas{PrePackTestOp::OpSchema()}; Status status; ASSERT_TRUE((status = registry->RegisterOpSet(schemas, PrePackTestOp::OpDomain, 10, 11)).IsOK()) << status; - KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename PrePackTestOp::QLinearMatMulPrePackT(info); }; + KernelCreateFn kernel_create_fn = [](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) { out = std::make_unique(info); return Status::OK(); }; auto kernel_def = PrePackTestOp::KernelDef(); ASSERT_TRUE((status = registry->RegisterCustomKernel(kernel_def, kernel_create_fn)).IsOK()) << status; diff --git a/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc b/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc index 55f516bed7..12e98e41f5 100644 --- a/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc +++ b/onnxruntime/test/providers/cpu/reduction/reduction_ops_test.cc @@ -13,10 +13,10 @@ namespace onnxruntime { namespace test { -const float FLOAT_INF = std::numeric_limits::infinity(); -const float FLOAT_NINF = -std::numeric_limits::infinity(); -const double DOUBLE_INF = std::numeric_limits::infinity(); -const double DOUBLE_NINF = -std::numeric_limits::infinity(); +constexpr float FLOAT_INF = std::numeric_limits::infinity(); +constexpr float FLOAT_NINF = -std::numeric_limits::infinity(); +constexpr double DOUBLE_INF = std::numeric_limits::infinity(); +constexpr double DOUBLE_NINF = -std::numeric_limits::infinity(); // Disable TensorRT on some of the tests because the limit in its parser: axis >=0 && axis < nbDims template @@ -778,7 +778,7 @@ TEST(ReductionOpTest, ReduceMax_int32) { #if defined(OPENVINO_CONFIG_GPU_FP32) || defined(OPENVINO_CONFIG_GPU_FP16) || defined(OPENVINO_CONFIG_MYRIAD) test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider, kOpenVINOExecutionProvider}); // OpenVINO: Disabled temporarily #else - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 #endif } @@ -799,7 +799,7 @@ TEST(ReductionOpTest, ReduceMax_int64) { #if defined(OPENVINO_CONFIG_GPU_FP32) || defined(OPENVINO_CONFIG_GPU_FP16) || defined(OPENVINO_CONFIG_MYRIAD) test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider, kOpenVINOExecutionProvider}); // OpenVINO: Disabled temporarily #else - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 #endif } @@ -820,7 +820,7 @@ TEST(ReductionOpTest, ReduceMax_int8) { #if defined(OPENVINO_CONFIG_MYRIAD) test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider, kOpenVINOExecutionProvider}); // OpenVINO: Disabled temporarily #else - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 #endif } @@ -841,7 +841,7 @@ TEST(ReductionOpTest, ReduceMax_uint8) { #if defined(OPENVINO_CONFIG_MYRIAD) test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider, kOpenVINOExecutionProvider}); // OpenVINO: Disabled temporarily #else - test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT: axis must be 0 #endif } @@ -1049,7 +1049,7 @@ TEST(ReductionOpTest, ReduceMean) { 9.0f, 10.0f, 11.0f, 12.0f}); test.AddOutput("reduced", {1, 2, 1}, {5.5f, 7.5f}); - + test.Run(); } diff --git a/onnxruntime/test/providers/cpu/tensor/copy_test.cc b/onnxruntime/test/providers/cpu/tensor/copy_test.cc index 91c496a8ed..f8a72a5c8f 100644 --- a/onnxruntime/test/providers/cpu/tensor/copy_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/copy_test.cc @@ -51,17 +51,16 @@ TEST_F(CopyTest, Contiguous3D) { TEST_F(CopyTest, Transpose4D) { // Test performing a transpose using a strided copy - int64_t numel = 2 * 3 * 4 * 5; - double* src = new double[numel]; + constexpr int64_t numel = 2 * 3 * 4 * 5; + std::unique_ptr src = std::make_unique(numel); for (int i = 0; i < numel; i++) { src[i] = static_cast(i); } - - double* dst = new double[numel]; + std::unique_ptr dst = std::make_unique(numel); std::vector dst_strides = {60, 5, 15, 1}; std::vector src_strides = {60, 20, 5, 1}; - StridedCopy(tp.get(), dst, dst_strides, {2, 3, 4, 5}, src, src_strides); + StridedCopy(tp.get(), dst.get(), dst_strides, {2, 3, 4, 5}, src.get(), src_strides); // stride to access the dst tensor as if it were contiguous std::vector contig_dst_strides = {60, 15, 5, 1}; @@ -78,18 +77,15 @@ TEST_F(CopyTest, Transpose4D) { } } } - delete[] src; - delete[] dst; } TEST_F(CopyTest, Concat2D) { // test performing a concat using a strided copy - double* src = new double[6 * 2]; + std::unique_ptr src = std::make_unique(6 * 2); for (int i = 0; i < 6 * 2; i++) { src[i] = static_cast(i); } - - double* dst = new double[10 * 5]; + std::unique_ptr dst = std::make_unique(10 * 5); for (int i = 0; i < 10 * 5; i++) { dst[i] = 0; } @@ -97,7 +93,7 @@ TEST_F(CopyTest, Concat2D) { std::vector dst_strides = {5, 1}; std::vector src_strides = {2, 1}; std::ptrdiff_t offset = 3; - StridedCopy(tp.get(), dst + offset, dst_strides, {6, 2}, src, src_strides); + StridedCopy(tp.get(), dst.get() + offset, dst_strides, {6, 2}, src.get(), src_strides); for (int i0 = 0; i0 < 10; i0++) { for (int i1 = 0; i1 < 5; i1++) { @@ -110,8 +106,6 @@ TEST_F(CopyTest, Concat2D) { } } } - delete[] src; - delete[] dst; } TEST_F(CopyTest, CoalesceTensorsTest) { diff --git a/onnxruntime/test/providers/cpu/tensor/split_op_test.cc b/onnxruntime/test/providers/cpu/tensor/split_op_test.cc index b2dc3a44b3..c3b5b25ee7 100644 --- a/onnxruntime/test/providers/cpu/tensor/split_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/split_op_test.cc @@ -50,7 +50,7 @@ void RunTest(int64_t axis, const std::vector split_sizes, const ShapeAn } TEST(SplitOperatorTest, Axis0EqualSplitFloat) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -73,7 +73,7 @@ TEST(SplitOperatorTest, Axis0EqualSplitFloat) { template ::value, T>::type> static void SplitTestInt() { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector> outputs; // input shape and data @@ -107,7 +107,7 @@ TEST(SplitOperatorTest, Axis0EqualSplitInt64) { } TEST(SplitOperatorTest, Axis0EqualSplitString) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -129,7 +129,7 @@ TEST(SplitOperatorTest, Axis0EqualSplitString) { } TEST(SplitOperatorTest, Axis0UnequalSplitFloat) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -152,7 +152,7 @@ TEST(SplitOperatorTest, Axis0UnequalSplitFloat) { } TEST(SplitOperatorTest, Axis0UnequalSplitString) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -175,7 +175,7 @@ TEST(SplitOperatorTest, Axis0UnequalSplitString) { } TEST(SplitOperatorTest, Axis1EqualSplitFloat) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; // input shape and data @@ -195,7 +195,7 @@ TEST(SplitOperatorTest, Axis1EqualSplitFloat) { } TEST(SplitOperatorTest, Axis1EqualSplitString) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; // input shape and data @@ -215,7 +215,7 @@ TEST(SplitOperatorTest, Axis1EqualSplitString) { } TEST(SplitOperatorTest, Axis1UnequalSplitFloat) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; // input shape and data @@ -237,7 +237,7 @@ TEST(SplitOperatorTest, Axis1UnequalSplitFloat) { } TEST(SplitOperatorTest, Axis1UnequalSplitString) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; // input shape and data @@ -271,7 +271,7 @@ ShapeAndData CreateInput(std::vector shape) { } TEST(SplitOperatorTest, Axis2EqualSplit) { - const int64_t axis = 2; + constexpr int64_t axis = 2; std::vector outputs; ShapeAndFloatData input = CreateInput({2, 2, 6}); @@ -301,7 +301,7 @@ TEST(SplitOperatorTest, Axis2EqualSplit) { } TEST(SplitOperatorTest, Axis2UnequalSplit) { - const int64_t axis = 2; + constexpr int64_t axis = 2; std::vector outputs; ShapeAndFloatData input = CreateInput({2, 2, 6}); @@ -333,7 +333,7 @@ TEST(SplitOperatorTest, Axis2UnequalSplit) { } TEST(SplitOperatorTest, ZeroSizeInput) { - const int64_t axis = -1; + constexpr int64_t axis = -1; std::vector outputs{{{0, 1}, {}}, {{0, 1}, {}}}; ShapeAndFloatData input = CreateInput({0, 2}); @@ -343,7 +343,7 @@ TEST(SplitOperatorTest, ZeroSizeInput) { // test a split of a dimension that has leading and trailing dimensions TEST(SplitOperatorTest, Axis1SplitMiddleDimensionEqually) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; ShapeAndFloatData input = CreateInput({2, 4, 4}); @@ -367,7 +367,7 @@ TEST(SplitOperatorTest, Axis1SplitMiddleDimensionEqually) { // test a split of a dimension that has leading and trailing dimensions TEST(SplitOperatorTest, Axis1SplitMiddleDimensionUnequally) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector outputs; ShapeAndFloatData input = CreateInput({2, 4, 4}); @@ -392,7 +392,7 @@ TEST(SplitOperatorTest, Axis1SplitMiddleDimensionUnequally) { } TEST(SplitOperatorTest, NegativeAxis) { - const int64_t axis = -1; // split last axis equally + constexpr int64_t axis = -1; // split last axis equally std::vector outputs; // input shape and data @@ -412,7 +412,7 @@ TEST(SplitOperatorTest, NegativeAxis) { } TEST(SplitOperatorTest, InvalidAxis) { - const int64_t axis = 2; + constexpr int64_t axis = 2; std::vector outputs; // input shape and data @@ -429,7 +429,7 @@ TEST(SplitOperatorTest, InvalidAxis) { // sum of values in splits is too small TEST(SplitOperatorTest, SplitAttributeSumTooSmall) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -448,7 +448,7 @@ TEST(SplitOperatorTest, SplitAttributeSumTooSmall) { } TEST(SplitOperatorTest, InvalidValueInSplitAttribute) { - const int64_t axis = -1; + constexpr int64_t axis = -1; std::vector outputs; // input shape and data @@ -467,7 +467,7 @@ TEST(SplitOperatorTest, InvalidValueInSplitAttribute) { // split as input TEST(SplitOperatorTest, Axis0UnequalSplitInputFloat) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -491,7 +491,7 @@ TEST(SplitOperatorTest, Axis0UnequalSplitInputFloat) { // split as input TEST(SplitOperatorTest, Axis0UnequalSplitInputFloat_not_initializer) { - const int64_t axis = 0; + constexpr int64_t axis = 0; std::vector outputs; // input shape and data @@ -576,7 +576,7 @@ SplitMiddleDimension() // test split for uint8_t data that has leading and trailing dimensions TEST(SplitOperatorTest, Uint8Axis1SplitMiddleDimensionUnequally) { - const int64_t axis = 1; + constexpr int64_t axis = 1; std::vector> outputs; ShapeAndData input = CreateInput({2, 4, 4}); @@ -602,7 +602,7 @@ TEST(SplitOperatorTest, Uint8Axis1SplitMiddleDimensionUnequally) { // test split for uint8_t data on the last axis equally TEST(SplitOperatorTest, Uint8NegativeAxis) { - const int64_t axis = -1; + constexpr int64_t axis = -1; std::vector> outputs; ShapeAndData input = {{2, 4}, @@ -621,7 +621,7 @@ TEST(SplitOperatorTest, Uint8NegativeAxis) { } TEST(SplitOperatorTest, MissingOptionalInputAdded) { - const int64_t axis = 1; // split last axis equally + constexpr int64_t axis = 1; // split last axis equally std::vector outputs; // input shape and data diff --git a/onnxruntime/test/providers/cpu/tensor/tensor_op_test.cc b/onnxruntime/test/providers/cpu/tensor/tensor_op_test.cc index 1a7fada780..f2eeb06640 100644 --- a/onnxruntime/test/providers/cpu/tensor/tensor_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/tensor_op_test.cc @@ -146,7 +146,7 @@ TEST(TensorOpTest, ShapeTest3D) { } void MeanVarianceNormalizationFunctionDefaultPerChannel() { - const int64_t N = 2, C = 2, H = 2, W = 3; + constexpr int64_t N = 2, C = 2, H = 2, W = 3; std::vector N1C1 = {3.0f, -3.0f, -1.0f, 1.0f, 2.0f, -1.0f}; @@ -209,7 +209,7 @@ void MeanVarianceNormalizationFunctionDefaultPerChannel() { } void MeanVarianceNormalizationFunctionAcrossChannels(std::vector axes) { - const int64_t N = 2, C = 2, H = 2, W = 3; + constexpr int64_t N = 2, C = 2, H = 2, W = 3; std::vector X = {3.0f, -3.0f, -1.0f, 1.0f, 2.0f, -1.0f, diff --git a/onnxruntime/test/providers/cpu/tensor/unique_op_test.cc b/onnxruntime/test/providers/cpu/tensor/unique_op_test.cc index a8e43fdc53..c539e59b5d 100644 --- a/onnxruntime/test/providers/cpu/tensor/unique_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/unique_op_test.cc @@ -142,7 +142,7 @@ TEST(Unique, Axis0_Unsorted) { 0.f, 1.f, 1.f, 0.f}; - const int64_t axis = 0; + constexpr int64_t axis = 0; bool sorted = false; const std::vector Y_dims{3, 2}; const std::vector Y{0.f, 1.f, @@ -167,7 +167,7 @@ TEST(Unique, Axis0_Sorted) { 0.f, 1.f, 1.f, 0.f}; - const int64_t axis = 0; + constexpr int64_t axis = 0; bool sorted = true; const std::vector Y_dims{3, 2}; const std::vector Y{0.f, 1.f, @@ -192,7 +192,7 @@ TEST(Unique, Axis0_Unsorted_String) { "0.f", "1.f", "1.f", "0.f"}; - const int64_t axis = 0; + constexpr int64_t axis = 0; bool sorted = false; const std::vector Y_dims{3, 2}; const std::vector Y{"0.f", "1.f", @@ -222,7 +222,7 @@ TEST(Unique, Axis1_Unsorted) { 2, 1, 0, 1}; - const int64_t axis = 1; + constexpr int64_t axis = 1; bool sorted = false; const std::vector Y_dims{2, 3, 2}; const std::vector Y{1, 1, @@ -256,7 +256,7 @@ TEST(Unique, Axis1_Sorted) { 2, 1, 0, 1}; - const int64_t axis = 1; + constexpr int64_t axis = 1; bool sorted = true; const std::vector Y_dims{2, 3, 2}; const std::vector Y{0, 1, @@ -286,7 +286,7 @@ TEST(Unique, Axis2_Unsorted) { 1, 1, 0, 1, 2, 1, 0, 1}; - const int64_t axis = 2; + constexpr int64_t axis = 2; bool sorted = false; const std::vector Y_dims{2, 2, 3}; const std::vector Y{1, 1, 0, @@ -314,7 +314,7 @@ TEST(Unique, Axis2_Sorted) { 1, 1, 0, 1, 2, 1, 0, 1}; - const int64_t axis = 2; + constexpr int64_t axis = 2; bool sorted = true; const std::vector Y_dims{2, 2, 3}; const std::vector Y{0, 1, 1, @@ -335,7 +335,7 @@ TEST(Unique, Axis2_Sorted) { } TEST(Unique, InvalidAxis) { - const int64_t axis = 12; + constexpr int64_t axis = 12; const std::vector X_dims{2, 3}; const std::vector X{1.f, 4.f, 1.f, 2.f, 2.f, 0.f}; const std::vector Y_dims{}; diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc index d59ec0f4bd..0aacbf14ce 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc @@ -49,8 +49,8 @@ TEST(InternalTestingEP, TestSortResultsInSinglePartition) { ASSERT_STATUS_OK(session->Initialize()); - const auto& func_mgr = session->GetSessionState().GetFuncMgr(); - NodeComputeInfo* compute_func = nullptr; + auto& func_mgr = const_cast(session->GetSessionState()).GetMutableFuncMgr(); + const NodeComputeInfo* compute_func = nullptr; int num_partitions{0}, num_other_nodes{0}; @@ -94,8 +94,8 @@ TEST(InternalTestingEP, TestDependenciesCorrectlyHandled) { ASSERT_STATUS_OK(session->Initialize()); // this should fail if we don't process dependencies correctly - const auto& func_mgr = session->GetSessionState().GetFuncMgr(); - NodeComputeInfo* compute_func = nullptr; + auto& func_mgr = const_cast(session->GetSessionState()).GetMutableFuncMgr(); + const NodeComputeInfo* compute_func = nullptr; int num_partitions{0}; int num_other_nodes{0}; @@ -235,8 +235,8 @@ static void TestNnapiPartitioning(const std::string& test_name, const std::strin unsupported_op_str = oss.str(); } - const auto& func_mgr = session->GetSessionState().GetFuncMgr(); - NodeComputeInfo* compute_func = nullptr; + auto& func_mgr = const_cast(session->GetSessionState()).GetMutableFuncMgr(); + const NodeComputeInfo* compute_func = nullptr; stats.num_nodes_not_handled = 0; stats.num_compiled_nodes = 0; diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc b/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc index cdd2eb6445..f456809f0b 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc @@ -174,8 +174,8 @@ TEST(InternalTestingEP, TestLoadOrtModelWithReducedOpCoverage) { // Conv+Add gets fused by level 1 optimizer into single node. The 'Conv'/'Add'/'Relu' nodes should be compiled and // handled by the custom EP. fallback to CPU for MaxPool. ASSERT_EQ(graph.NumberOfNodes(), 6); - const auto& func_mgr = session->GetSessionState().GetFuncMgr(); - NodeComputeInfo* compute_func = nullptr; + auto& func_mgr = const_cast(session->GetSessionState()).GetMutableFuncMgr(); + const NodeComputeInfo* compute_func = nullptr; // the generated op type should have a hash for the model based on the model path const std::string expected_op_type_prefix = "InternalTestingEP_9611636968429821767_"; @@ -197,14 +197,14 @@ TEST(InternalTestingEP, TestLoadOrtModelWithReducedOpCoverage) { // count nodes assigned to the test EP and make sure they all have valid compute funcs static int CountAndValidateAssignedNodes(const Graph& current_graph, const std::unordered_set& supported_ops, - const FuncManager& func_mgr) { + FuncManager& func_mgr) { int count = 0; for (const auto& node : current_graph.Nodes()) { EXPECT_EQ(supported_ops.count(node.OpType()), size_t(0)) << "Nodes with supported op types should have been replaced. Node with type " << node.OpType() << " was not."; if (node.GetExecutionProviderType() == utils::kInternalTestingExecutionProvider) { - NodeComputeInfo* compute_func = nullptr; + const NodeComputeInfo* compute_func = nullptr; EXPECT_STATUS_OK(func_mgr.GetFuncs(node.Name(), compute_func)); EXPECT_NE(compute_func, nullptr); ++count; @@ -232,7 +232,7 @@ TEST(InternalTestingEP, TestModelWithSubgraph) { CreateSession(SessionOptions{}, session, ort_model_path, enable_custom_ep, &supported_ops); const auto& graph = session->GetGraph(); - const auto& func_mgr = session->GetSessionState().GetFuncMgr(); + auto& func_mgr = const_cast(session->GetSessionState()).GetMutableFuncMgr(); int num_replaced_nodes = CountAndValidateAssignedNodes(graph, supported_ops, func_mgr); @@ -317,7 +317,7 @@ TEST(InternalTestingEP, TestOrtModelWithCompileFailure) { ASSERT_STATUS_OK(session.Initialize()); int num_replaced_nodes = CountAndValidateAssignedNodes( - session.GetGraph(), supported_ops, session.GetSessionState().GetFuncMgr()); + session.GetGraph(), supported_ops, const_cast(session.GetSessionState()).GetMutableFuncMgr()); ASSERT_EQ(num_replaced_nodes, 3); } @@ -335,7 +335,7 @@ TEST(InternalTestingEP, TestOrtModelWithCompileFailure) { // 2 Conv nodes shoule be replaced with fused nodes const auto& graph = session.GetGraph(); int num_replaced_nodes = CountAndValidateAssignedNodes( - session.GetGraph(), {"Conv"}, session.GetSessionState().GetFuncMgr()); + session.GetGraph(), {"Conv"}, const_cast(session.GetSessionState()).GetMutableFuncMgr()); ASSERT_EQ(num_replaced_nodes, 2); diff --git a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc index ac053eca95..aca03e7a6b 100644 --- a/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc +++ b/onnxruntime/test/testdata/custom_execution_provider_library/my_allocator.cc @@ -11,6 +11,7 @@ MyEPAllocator::MyEPAllocator(OrtDevice::DeviceId device_id) } #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(disable : 26400) +#pragma warning(disable : 26409) #endif void* MyEPAllocator::Alloc(size_t size) { void* device_address = new (std::nothrow) uint8_t[size]; diff --git a/onnxruntime/test/util/test_allocator.cc b/onnxruntime/test/util/test_allocator.cc index 1383894372..002e759bd0 100644 --- a/onnxruntime/test/util/test_allocator.cc +++ b/onnxruntime/test/util/test_allocator.cc @@ -17,6 +17,7 @@ MockedOrtAllocator::~MockedOrtAllocator() { } #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(disable : 26400) +#pragma warning(disable : 26409) #endif void* MockedOrtAllocator::Alloc(size_t size) { constexpr size_t extra_len = sizeof(size_t); diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 82c984608a..f9c900295f 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -1620,7 +1620,8 @@ def run_onnxruntime_tests(args, source_dir, ctest_path, build_dir, configs): if not args.disable_ml_ops: run_subprocess([sys.executable, 'onnxruntime_test_python_mlops.py'], cwd=cwd, dll_path=dll_path) - if args.enable_training and args.use_cuda: + # The following test has multiple failures on Windows + if args.enable_training and args.use_cuda and not is_windows(): # run basic frontend tests run_training_python_frontend_tests(cwd=cwd) diff --git a/tools/ci_build/github/azure-pipelines/nuget/templates/gpu.yml b/tools/ci_build/github/azure-pipelines/nuget/templates/gpu.yml index 4278039acd..1236a78627 100644 --- a/tools/ci_build/github/azure-pipelines/nuget/templates/gpu.yml +++ b/tools/ci_build/github/azure-pipelines/nuget/templates/gpu.yml @@ -2,7 +2,7 @@ parameters: DoEsrp: 'false' jobs: -- template: ../../templates/win-ci-2019.yml +- template: win-ci-2019.yml parameters: AgentPool : 'onnxruntime-gpu-winbuild' ArtifactName: 'drop-nuget-dml' @@ -25,7 +25,7 @@ jobs: mkdir $(Build.ArtifactStagingDirectory)\testdata copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\custom_op_library.* $(Build.ArtifactStagingDirectory)\testdata -- template: ../../templates/win-ci-2019.yml +- template: win-ci-2019.yml parameters: AgentPool : 'onnxruntime-gpu-winbuild' ArtifactName: 'drop-win-dml-x86-zip' @@ -47,7 +47,7 @@ jobs: mkdir $(Build.ArtifactStagingDirectory)\testdata copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\custom_op_library.* $(Build.ArtifactStagingDirectory)\testdata -- template: ../../templates/win-ci-2019.yml +- template: win-ci-2019.yml parameters: AgentPool : 'onnxruntime-gpu-winbuild' ArtifactName: 'drop-win-dml-arm64-zip' @@ -69,7 +69,7 @@ jobs: mkdir $(Build.ArtifactStagingDirectory)\testdata copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\custom_op_library.* $(Build.ArtifactStagingDirectory)\testdata -- template: ../../templates/win-ci-2019.yml +- template: win-ci-2019.yml parameters: AgentPool : 'onnxruntime-gpu-winbuild' ArtifactName: 'drop-win-dml-arm-zip' diff --git a/tools/ci_build/github/azure-pipelines/templates/win-ci-2019.yml b/tools/ci_build/github/azure-pipelines/nuget/templates/win-ci-2019.yml similarity index 97% rename from tools/ci_build/github/azure-pipelines/templates/win-ci-2019.yml rename to tools/ci_build/github/azure-pipelines/nuget/templates/win-ci-2019.yml index 04e21bcd22..976ae5b921 100644 --- a/tools/ci_build/github/azure-pipelines/templates/win-ci-2019.yml +++ b/tools/ci_build/github/azure-pipelines/nuget/templates/win-ci-2019.yml @@ -197,14 +197,14 @@ jobs: arguments: ${{ parameters.BuildArch }} modifyEnvironment: true # Esrp signing - - template: win-esrp-dll.yml + - template: ../../templates/win-esrp-dll.yml parameters: FolderPath: '$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig)' DisplayName: 'ESRP - Sign Native dlls' DoEsrp: ${{ parameters.DoEsrp }} Pattern: 'onnx_test_runner.exe, onnxruntime_perf_test.exe,*.dll' #keep sync with src/Microsoft.ML.OnnxRuntime/Microsoft.ML.OnnxRuntime.csproj - - template: win-esrp-dll.yml + - template: ../../templates/win-esrp-dll.yml parameters: FolderPath: '$(Build.SourcesDirectory)\csharp\src\Microsoft.ML.OnnxRuntime\bin\$(BuildConfig)' DisplayName: 'ESRP - Sign C# dlls' @@ -238,7 +238,7 @@ jobs: filename: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat' arguments: ${{ parameters.BuildArch }} modifyEnvironment: true - - template: win-esrp-dll.yml + - template: ../../templates/win-esrp-dll.yml parameters: FolderPath: '$(Build.SourcesDirectory)\js\node\bin\napi-v3\win32\x64' DisplayName: 'ESRP - Sign Node.js binding binaries' @@ -267,11 +267,11 @@ jobs: workingDirectory: '$(Build.ArtifactStagingDirectory)' - ${{ if eq(parameters['DoCompliance'], 'true') }}: - - template: compliance.yml + - template: ../../templates/compliance.yml parameters : msbuildPlatform: ${{ parameters.sln_platform }} - - template: component-governance-component-detection-steps.yml + - template: ../../templates/component-governance-component-detection-steps.yml parameters : condition : 'succeeded' diff --git a/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml b/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml index 8189eda2cc..47fc0e388e 100644 --- a/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/win-cpu-ci.yml @@ -173,6 +173,7 @@ jobs: - ${{ if eq(parameters.EnablePython, true) }}: - powershell: | + python3 -m pip uninstall -y ort-nightly-gpu ort-nightly onnxruntime onnxruntime-gpu -qq Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' @@ -196,26 +197,32 @@ jobs: **/*.pdb **/*.dll - - task: PythonScript@0 - displayName: 'Generate cmake config' + #Manually set msBuildCommandline so that we can also set CAExcludePath + #build_dir must be a sub folder of $(Build.SourcesDirectory) + - task: SDLNativeRules@3 + displayName: 'Run the PREfast SDL Native Rules for MSBuild' inputs: - scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' - arguments: '--config RelWithDebInfo --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} --cmake_extra_defines onnxruntime_ENABLE_STATIC_ANALYSIS=ON' - workingDirectory: '$(Build.BinariesDirectory)' + msBuildArchitecture: amd64 + setupCommandlines: 'python $(Build.SourcesDirectory)\tools\ci_build\build.py --config RelWithDebInfo --build_dir $(Build.SourcesDirectory)\b --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} --cmake_extra_defines onnxruntime_ENABLE_STATIC_ANALYSIS=ON' + msBuildCommandline: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\msbuild.exe" "$(Build.SourcesDirectory)\b\RelWithDebInfo\onnxruntime.sln" /p:RunCodeAnalysis=true /p:platform=${{ parameters.msbuildPlatform }} /p:configuration=RelWithDebInfo /p:VisualStudioVersion="16.0" /m /p:PreferredToolArchitecture=x64' + excludedPaths: '$(Build.SourcesDirectory)\b#$(Build.SourcesDirectory)\cmake#C:\program files (x86)' + rulesetName: Custom + customRuleset: $(Build.SourcesDirectory)\cmake\Sdl.ruleset - - - task: VSBuild@1 - displayName: 'Build' + - task: SdtReport@2 + displayName: 'Create Security Analysis Report' inputs: - solution: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\onnxruntime.sln' - platform: ${{ parameters.msbuildPlatform }} - configuration: ${{ parameters.BuildConfig }} - msbuildArgs: /m /p:CAExcludePath="$(Build.BinariesDirectory);$(Build.SourcesDirectory)\cmake;C:\program files (x86)" /p:PreferredToolArchitecture=x64 - msbuildArchitecture: ${{ parameters.buildArch }} - maximumCpuCount: true - logProjectEvents: false - workingFolder: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}' - createLogFile: true + SDLNativeRules: true + + - task: PublishSecurityAnalysisLogs@3 + displayName: 'Publish Security Analysis Logs' + continueOnError: true + + - task: PostAnalysis@2 + displayName: 'Guardian Break' + inputs: + GdnBreakGdnToolSDLNativeRulesSeverity: Warning + GdnBreakGdnToolSDLNativeRules: true - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: diff --git a/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml b/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml index e919400234..e9167d3684 100644 --- a/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/win-gpu-ci.yml @@ -20,6 +20,10 @@ parameters: - name: isX86 type: boolean default: false + +- name: isTraining + type: boolean + default: false - name: EnablePython type: boolean @@ -109,6 +113,13 @@ jobs: workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx' displayName: 'Install ONNX' + - ${{ if eq(parameters.isTraining, true) }}: + - script: | + python -m pip install -r $(Build.SourcesDirectory)\tools\ci_build\github\linux\docker\scripts\training\ortmodule\stage1\requirements_torch1.9.0_cu11.1.txt + python -m pip install -r $(Build.SourcesDirectory)\tools\ci_build\github\linux\docker\scripts\training\requirements.txt + workingDirectory: '$(Build.BinariesDirectory)' + displayName: 'Install python modules' + - task: NuGetToolInstaller@0 displayName: Use Nuget 5.7.0 inputs: @@ -182,6 +193,7 @@ jobs: - ${{ if eq(parameters.EnablePython, true) }}: - powershell: | + python3 -m pip uninstall -y ort-nightly-gpu ort-nightly onnxruntime onnxruntime-gpu -qq Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} workingDirectory: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\${{ parameters.BuildConfig }}' @@ -205,26 +217,35 @@ jobs: **/*.pdb **/*.dll - - task: PythonScript@0 - displayName: 'Generate cmake config' - inputs: - scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' - arguments: '--config Debug --build_dir $(Build.BinariesDirectory) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} onnxruntime_ENABLE_STATIC_ANALYSIS=ON' - workingDirectory: '$(Build.BinariesDirectory)' - - - task: VSBuild@1 - displayName: 'Build' + #Manually set msBuildCommandline so that we can also set CAExcludePath + #build_dir must be a sub folder of $(Build.SourcesDirectory) + #TODO: move this step to a CPU-only machine to save GPU resources. + - task: SDLNativeRules@3 + displayName: 'Run the PREfast SDL Native Rules for MSBuild' inputs: - solution: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}\onnxruntime.sln' - platform: ${{ parameters.msbuildPlatform }} - configuration: ${{ parameters.BuildConfig }} - msbuildArgs: /m /p:CAExcludePath="$(Build.BinariesDirectory);$(Build.SourcesDirectory)\cmake;C:\program files (x86)" /p:PreferredToolArchitecture=x64 - msbuildArchitecture: ${{ parameters.buildArch }} - maximumCpuCount: true - logProjectEvents: false - workingFolder: '$(Build.BinariesDirectory)\${{ parameters.BuildConfig }}' - createLogFile: true + msBuildArchitecture: amd64 + setupCommandlines: 'python $(Build.SourcesDirectory)\tools\ci_build\build.py --config RelWithDebInfo --build_dir $(Build.SourcesDirectory)\b --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_shared_lib --enable_onnx_tests ${{ parameters.additionalBuildFlags }} onnxruntime_ENABLE_STATIC_ANALYSIS=ON' + msBuildCommandline: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\msbuild.exe" "$(Build.SourcesDirectory)\b\RelWithDebInfo\onnxruntime.sln" /p:RunCodeAnalysis=true /p:platform=${{ parameters.msbuildPlatform }} /p:configuration=RelWithDebInfo /p:VisualStudioVersion="16.0" /m /p:PreferredToolArchitecture=x64' + excludedPaths: '$(Build.SourcesDirectory)\b#$(Build.SourcesDirectory)\cmake#C:\program files (x86)' + rulesetName: Custom + customRuleset: $(Build.SourcesDirectory)\cmake\Sdl.ruleset + publishXML: true + + - task: SdtReport@2 + displayName: 'Create Security Analysis Report' + inputs: + SDLNativeRules: true + + - task: PublishSecurityAnalysisLogs@3 + displayName: 'Publish Security Analysis Logs' + continueOnError: true + + - task: PostAnalysis@2 + displayName: 'Guardian Break v2' + inputs: + GdnBreakGdnToolSDLNativeRulesSeverity: Warning + GdnBreakGdnToolSDLNativeRules: true - ${{ if eq(parameters.RunOnnxRuntimeTests, true) }}: diff --git a/tools/ci_build/github/azure-pipelines/win-gpu-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/win-gpu-ci-pipeline.yml index a2d9dc3048..3fd5f46721 100644 --- a/tools/ci_build/github/azure-pipelines/win-gpu-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/win-gpu-ci-pipeline.yml @@ -5,229 +5,54 @@ parameters: default: true stages: -- stage: inference +- stage: cuda dependsOn: [] jobs: - - job: 'build' - pool: 'Win-GPU-2019' - strategy: - matrix: - cuda: - additionalBuildFlags: --build_java --build_nodejs --use_cuda --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52 --gen_doc validate --enable_cuda_profiling - EnvSetupScript: setup_env_cuda_11.bat - ORT_EP_NAME: CUDA - dml: - additionalBuildFlags: --use_dml --cmake_extra_defines CMAKE_SYSTEM_VERSION=10.0.18362.0 --enable_wcos --use_winml - EnvSetupScript: setup_env.bat - ORT_EP_NAME: DML - variables: - OrtPackageId: 'Microsoft.ML.OnnxRuntime.Gpu' - MsbuildArguments: '-maxcpucount' - TESTONGPU: 'ON' - OnnxRuntimeBuildDirectory: '$(Build.BinariesDirectory)' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - setVcvars: true + - template: templates/win-gpu-ci.yml + parameters: BuildConfig: 'RelWithDebInfo' - UseOmp: '' + EnvSetupScript: setup_env_cuda_11.bat buildArch: x64 + additionalBuildFlags: --enable_pybind --build_java --build_nodejs --use_cuda --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --gen_doc validate --enable_cuda_profiling --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52 msbuildPlatform: x64 isX86: false - ALLOW_RELEASED_ONNX_OPSET_ONLY: '0' - DocUpdateNeeded: false - timeoutInMinutes: 180 - workspace: - clean: all - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - addToPath: true - architecture: $(buildArch) + job_name_suffix: x64_RelWithDebInfo + RunOnnxRuntimeTests: ${{ parameters.RunOnnxRuntimeTests }} + RunStaticCodeAnalysis: false + ORT_EP_NAME: CUDA + DocUpdateNeeded: true - - task: NodeTool@0 - inputs: - versionSpec: '12.x' - force32bit: $(isX86) - - - task: JavaToolInstaller@0 - #Our build machine doesn't have java x86 - condition: and(succeeded(), eq(variables['buildArch'], 'x64')) - inputs: - versionSpec: '11' - jdkArchitectureOption: $(buildArch) - jdkSourceOption: 'PreInstalled' - - - task: BatchScript@1 - displayName: 'setup env' - inputs: - filename: '$(Build.SourcesDirectory)\tools\ci_build\github\windows\$(EnvSetupScript)' - modifyEnvironment: true - workingFolder: '$(Build.BinariesDirectory)' - - - script: | - set ORT_DOXY_SRC=$(Build.SourcesDirectory) - set ORT_DOXY_OUT=$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig) - mkdir %ORT_DOXY_SRC% - mkdir %ORT_DOXY_OUT% - "C:\Program Files\doxygen\bin\doxygen.exe" $(Build.SourcesDirectory)\tools\ci_build\github\Doxyfile_csharp.cfg - - workingDirectory: '$(Build.SourcesDirectory)' - displayName: 'API Documentation Check and generate' - - - script: | - python -m pip install -q setuptools wheel numpy - workingDirectory: '$(Build.BinariesDirectory)' - displayName: 'Install python modules' - - - powershell: | - $Env:USE_MSVC_STATIC_RUNTIME=1 - $Env:ONNX_ML=1 - $Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=$(buildArch)-windows-static" - python setup.py bdist_wheel - python -m pip uninstall -y onnx -qq - Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} - workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx' - displayName: 'Install ONNX' - - - task: NuGetToolInstaller@0 - displayName: Use Nuget 5.7.0 - inputs: - versionSpec: 5.7.0 - - - task: NuGetCommand@2 - displayName: 'NuGet restore' - inputs: - command: 'restore' - feedsToUse: 'config' - restoreSolution: '$(Build.SourcesDirectory)\packages.config' - nugetConfigPath: '$(Build.SourcesDirectory)\NuGet.config' - restoreDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)' - - - task: PythonScript@0 - displayName: 'Generate cmake config' - inputs: - scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py' - arguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) $(UseOmp) --skip_submodule_sync --build_shared_lib --update --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests $(additionalBuildFlags)' - workingDirectory: '$(Build.BinariesDirectory)' - - - task: VSBuild@1 - displayName: 'Build' - inputs: - solution: '$(Build.BinariesDirectory)\$(BuildConfig)\onnxruntime.sln' - platform: $(msbuildPlatform) - configuration: $(BuildConfig) - msbuildArgs: $(MsbuildArguments) - msbuildArchitecture: $(buildArch) - maximumCpuCount: true - logProjectEvents: false - workingFolder: '$(Build.BinariesDirectory)\$(BuildConfig)' - createLogFile: true - - - task: PythonScript@0 - displayName: 'Build wheel' - inputs: - scriptPath: '$(Build.SourcesDirectory)\setup.py' - arguments: 'bdist_wheel' - workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig)' - - - task: MSBuild@1 - displayName: 'Restore NuGet Packages' - inputs: - solution: '$(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.sln' - platform: 'Any CPU' - configuration: '$(BuildConfig)' - msbuildArguments: '-t:restore -p:OrtPackageId=$(OrtPackageId)' - workingDirectory: '$(Build.SourcesDirectory)\csharp' - - - task: MSBuild@1 - displayName: 'Build C#' - inputs: - solution: '$(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.sln' - platform: 'Any CPU' - configuration: '$(BuildConfig)' - msbuildArguments: '-p:OnnxRuntimeBuildDirectory="$(Build.BinariesDirectory)" -p:OrtPackageId=$(OrtPackageId) -p:DefineConstants=USE_$(ORT_EP_NAME)' - workingDirectory: '$(Build.SourcesDirectory)\csharp' - - - task: DotNetCoreCLI@2 - displayName: 'Test C#' - condition: and(and(succeeded(), eq(variables['BuildConfig'], 'RelWithDebInfo')),eq('${{ parameters.RunOnnxRuntimeTests}}', true)) - inputs: - command: test - projects: '$(Build.SourcesDirectory)\csharp\test\Microsoft.ML.OnnxRuntime.Tests.NetCoreApp\Microsoft.ML.OnnxRuntime.Tests.NetCoreApp.csproj' - configuration: '$(BuildConfig)' - arguments: '--configuration $(BuildConfig) -p:Platform="Any CPU" -p:OnnxRuntimeBuildDirectory="$(Build.BinariesDirectory)" -p:OrtPackageId=$(OrtPackageId) -p:DefineConstants=USE_$(ORT_EP_NAME)' - workingDirectory: '$(Build.SourcesDirectory)\csharp' - - - powershell: | - Get-ChildItem -Path dist/*.whl | foreach {pip --disable-pip-version-check install --upgrade $_.fullname} - python $(Build.SourcesDirectory)\tools\ci_build\build.py --config $(BuildConfig) --build_dir $(Build.BinariesDirectory) $(UseOmp) --skip_submodule_sync --build_shared_lib --test --cmake_generator "Visual Studio 16 2019" --build_wheel --enable_onnx_tests $(additionalBuildFlags) - workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)\$(BuildConfig)' - condition: and(succeeded(), eq('${{ parameters.RunOnnxRuntimeTests}}', true)) - displayName: 'Run tests' - - # if the validation from --gen_doc failed it sets a variable so we can publish the latest version of the docs - # as an artifact, allowing a developer to download this and replace the current version instead of having to build - # and generate the docs locally themselves. handle each of the two md files separately - simpler than copying - # them to another location and publishing from there in a single task. - - task: PublishBuildArtifacts@1 - condition: and(failed(), eq(variables['DocUpdateNeeded'], 'true')) - inputs: - pathtoPublish: '$(Build.SourcesDirectory)/docs/OperatorKernels.md' - artifactName: 'OperatorKernels.md' - - - task: PublishBuildArtifacts@1 - condition: and(failed(), eq(variables['DocUpdateNeeded'], 'true')) - inputs: - pathtoPublish: '$(Build.SourcesDirectory)/docs/ContribOperators.md' - artifactName: 'ContribOperators.md' - - - - task: PublishSecurityAnalysisLogs@3 - displayName: 'Publish Security Analysis Logs' - condition: and(succeeded(), eq(variables['BuildConfig'], 'RelWithDebInfo')) - inputs: - ArtifactName: CodeAnalysisLogs - - - task: PublishTestResults@2 - displayName: 'Publish unit test results' - inputs: - testResultsFiles: '**/*.results.xml' - searchFolder: '$(Build.BinariesDirectory)' - testRunTitle: 'Unit Test Run' - condition: succeededOrFailed() - - - template: templates/component-governance-component-detection-steps.yml - parameters : - condition : 'succeeded' - stage: training dependsOn: [] jobs: - - template: templates/win-ci-2019.yml - parameters: - AgentPool : 'Win-GPU-2019' - JobName: 'Win_GPU_Training' - # TODO fix test failures and remove --skip_onnx_tests - BuildCommand: >- - --build_dir $(Build.BinariesDirectory) - --build_shared_lib - --cmake_generator "Visual Studio 16 2019" - --enable_onnx_tests - --enable_training - --skip_onnx_tests - --skip_submodule_sync - --use_cuda - --cuda_version 10.2 - --cuda_home "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2" - --cudnn_home "C:\local\cudnn-10.2-windows10-x64-v8.0.3.33\cuda" - --cmake_extra_defines "CMAKE_CUDA_ARCHITECTURES=52" - BuildArch: 'x64' - EnvSetupScript: 'setup_env_cuda.bat' - sln_platform: 'x64' - CudaVersion: '10.2' - OrtPackageId: 'Microsoft.ML.OnnxRuntime.Gpu' - BuildConfigurations: ['RelWithDebInfo'] - # Enable unreleased onnx opsets in CI builds - # This facilitates testing the implementation for the new opsets - AllowReleasedOpsetOnly: '0' - DoCompliance: 'true' \ No newline at end of file + - template: templates/win-gpu-ci.yml + parameters: + BuildConfig: 'RelWithDebInfo' + EnvSetupScript: setup_env_cuda_11.bat + buildArch: x64 + additionalBuildFlags: --enable_pybind --enable_training --use_cuda --cuda_version=11.4 --cuda_home="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4" --cudnn_home="C:\local\cudnn-11.4-windows-x64-v8.2.2.26\cuda" --skip_onnx_tests --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=52 + msbuildPlatform: x64 + isX86: false + job_name_suffix: x64_RelWithDebInfo + RunOnnxRuntimeTests: ${{ parameters.RunOnnxRuntimeTests }} + RunStaticCodeAnalysis: false + ORT_EP_NAME: CUDA + isTraining: true + +- stage: dml + dependsOn: [] + jobs: + - template: templates/win-gpu-ci.yml + parameters: + BuildConfig: 'RelWithDebInfo' + EnvSetupScript: setup_env.bat + buildArch: x64 + additionalBuildFlags: --enable_pybind --use_dml --enable_wcos --use_winml --cmake_extra_defines CMAKE_SYSTEM_VERSION=10.0.18362.0 + msbuildPlatform: x64 + isX86: false + job_name_suffix: x64_RelWithDebInfo + RunOnnxRuntimeTests: ${{ parameters.RunOnnxRuntimeTests }} + RunStaticCodeAnalysis: false + ORT_EP_NAME: DML + From 7a1bdc2052bca1b4073229fee71123976731b866 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Mon, 20 Dec 2021 21:19:29 -0800 Subject: [PATCH 067/113] Don't check cache shape when using dynamic axis (#10090) Co-authored-by: Ubuntu --- .../core/graph/contrib_ops/contrib_defs.cc | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc index 6eb90e969c..cf4e7efd8d 100644 --- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc @@ -550,20 +550,21 @@ void DecoderAttentionTypeAndShapeInference(ONNX_NAMESPACE::InferenceContext& ctx if (cache_dims.size() != 4) { fail_shape_inference("key and value cache shall be 4 dimensions"); } - if (!cache_dims[0].has_dim_value() || - !cache_dims[1].has_dim_value() || - !cache_dims[2].has_dim_value() || - !cache_dims[3].has_dim_value()) { - fail_shape_inference("key and value cache dimensions value shall not be null"); - } - ONNX_NAMESPACE::TensorShapeProto new_cache_shape; - *new_cache_shape.add_dim() = cache_shape.dim(0); - *new_cache_shape.add_dim() = cache_shape.dim(1); - new_cache_shape.add_dim(); - *new_cache_shape.add_dim() = cache_shape.dim(3); + // has_dim_value() will return false if value is dynamic + if (cache_dims[0].has_dim_value() && + cache_dims[1].has_dim_value() && + cache_dims[2].has_dim_value() && + cache_dims[3].has_dim_value()) { - updateOutputShape(ctx, 1, new_cache_shape); - updateOutputShape(ctx, 2, new_cache_shape); + ONNX_NAMESPACE::TensorShapeProto new_cache_shape; + *new_cache_shape.add_dim() = cache_shape.dim(0); + *new_cache_shape.add_dim() = cache_shape.dim(1); + new_cache_shape.add_dim(); + *new_cache_shape.add_dim() = cache_shape.dim(3); + + updateOutputShape(ctx, 1, new_cache_shape); + updateOutputShape(ctx, 2, new_cache_shape); + } } } } @@ -611,7 +612,7 @@ void BeamSearchShapeInference(ONNX_NAMESPACE::InferenceContext& ctx) { if (!(input_ids_dims[0].has_dim_value() && input_ids_dims[1].has_dim_value())) { return; } - + int64_t batch_size = input_ids_dims[0].dim_value(); int64_t sequence_length = input_ids_dims[1].dim_value(); @@ -883,7 +884,7 @@ Some boolean parameters are passed by runtime input for generic purpose .TypeConstraint("B", {"tensor(bool)"}, "Constrain key_padding_mask to bool tensors.") .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { DecoderAttentionTypeAndShapeInference(ctx); - }); + }); static const char* EmbedLayerNormalization_ver1_doc = R"DOC( EmbedLayerNormalization is the fusion of embedding layer in BERT model, with optional mask processing. From ce1a9ca6186c713b8962d1bf7cd6178cab21f64b Mon Sep 17 00:00:00 2001 From: Sheil Kumar Date: Tue, 21 Dec 2021 12:34:03 -0800 Subject: [PATCH 068/113] Fix Microsoft.AI.MachineLearning NuGet App failure with multiple binaries copied to same destination (#10076) * Include onnxruntime binary when not using pacakge referene or uap app. * Remove the lib\uap10.0 build from the nuget package - causing conflicts * Add UWP test * remove build files * remove local change * reset mimalloc and onnx-tensorrt * change username to Microsoft Co-authored-by: Sheil Kumar --- .../Microsoft.AI.MachineLearning.props | 21 --- .../Microsoft.AI.MachineLearning.targets | 28 ++- .../.gitignore | 5 + .../App.xaml | 7 + .../App.xaml.cs | 100 ++++++++++ .../Assets/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Assets/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes .../Assets/StoreLogo.png | Bin 0 -> 1451 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes .../MainPage.xaml | 14 ++ .../MainPage.xaml.cs | 32 ++++ ...rosoft.AI.MachineLearning.Tests.Uwp.csproj | 177 ++++++++++++++++++ ...oft.AI.MachineLearning.Tests.Uwp.csproj.pp | 177 ++++++++++++++++++ ...Microsoft.AI.MachineLearning.Tests.Uwp.sln | 51 +++++ .../NuGet.config.pp | 10 + .../Package.appxmanifest | 49 +++++ .../Properties/AssemblyInfo.cs | 29 +++ .../Properties/Default.rd.xml | 31 +++ .../nuget/templates/windowsai.yml | 75 ++++---- 22 files changed, 752 insertions(+), 54 deletions(-) create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/.gitignore create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml.cs create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/LockScreenLogo.scale-200.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/SplashScreen.scale-200.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square150x150Logo.scale-200.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.scale-200.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/StoreLogo.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Wide310x150Logo.scale-200.png create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/MainPage.xaml create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/MainPage.xaml.cs create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj.pp create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.sln create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/NuGet.config.pp create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Package.appxmanifest create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/AssemblyInfo.cs create mode 100644 csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/Default.rd.xml diff --git a/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.props b/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.props index 96c2dcf6dc..ec7bda8625 100644 --- a/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.props +++ b/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.props @@ -13,27 +13,6 @@ - - x86 - $(Platform) - - - - $(MSBuildThisFileDirectory)..\..\runtimes\win-$(WindowsAI-Platform)\_native - static\ - $(RuntimesDirectory)\$(WindowsAIBinarySubfolder)microsoft.ai.machinelearning.dll - $(MSBuildThisFileDirectory)..\..\winmds\Microsoft.AI.MachineLearning.winmd - $(MSBuildThisFileDirectory)..\..\winmds\Microsoft.AI.MachineLearning.Experimental.winmd - - $([System.IO.Path]::GetFullPath($(WindowsAIBinary))) - $([System.IO.Path]::GetFullPath($(WindowsAIWinMD))) - $([System.IO.Path]::GetFullPath($(WindowsAIExperimentalWinMD))) - - - - $(RuntimesDirectory)\$(WindowsAIBinarySubfolder)onnxruntime.dll - - true diff --git a/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.targets b/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.targets index 61090cac1c..2f100fd75a 100644 --- a/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.targets +++ b/csharp/src/Microsoft.AI.MachineLearning/Microsoft.AI.MachineLearning.targets @@ -1,5 +1,28 @@ + + $(Platform) + x86 + $(Platform) + $(Platform) + + + + $(MSBuildThisFileDirectory)..\..\runtimes\win-$(WindowsAI-Platform)\_native + static\ + $(RuntimesDirectory)\$(WindowsAIBinarySubfolder)microsoft.ai.machinelearning.dll + $(MSBuildThisFileDirectory)..\..\winmds\Microsoft.AI.MachineLearning.winmd + $(MSBuildThisFileDirectory)..\..\winmds\Microsoft.AI.MachineLearning.Experimental.winmd + + $([System.IO.Path]::GetFullPath($(WindowsAIBinary))) + $([System.IO.Path]::GetFullPath($(WindowsAIWinMD))) + $([System.IO.Path]::GetFullPath($(WindowsAIExperimentalWinMD))) + + + + $(RuntimesDirectory)\$(WindowsAIBinarySubfolder)onnxruntime.dll + + $(WindowsAIBinary) @@ -10,6 +33,9 @@ - + + + + diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/.gitignore b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/.gitignore new file mode 100644 index 0000000000..7a45a34077 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/.gitignore @@ -0,0 +1,5 @@ +# build, distribute, and bins (+ python proto bindings) +Debug +x64 +packages +AppPackages \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml new file mode 100644 index 0000000000..d2e98d90a8 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml @@ -0,0 +1,7 @@ + + + diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml.cs b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml.cs new file mode 100644 index 0000000000..e2bc13c3b2 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/App.xaml.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +namespace Microsoft.AI.MachineLearning.Tests.Uwp +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + sealed partial class App : Application + { + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + this.InitializeComponent(); + this.Suspending += OnSuspending; + } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific file. + /// + /// Details about the launch request and process. + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + Frame rootFrame = Window.Current.Content as Frame; + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == null) + { + // Create a Frame to act as the navigation context and navigate to the first page + rootFrame = new Frame(); + + rootFrame.NavigationFailed += OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //TODO: Load state from previously suspended application + } + + // Place the frame in the current Window + Window.Current.Content = rootFrame; + } + + if (e.PrelaunchActivated == false) + { + if (rootFrame.Content == null) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame.Navigate(typeof(MainPage), e.Arguments); + } + // Ensure the current window is active + Window.Current.Activate(); + } + } + + /// + /// Invoked when Navigation to a certain page fails + /// + /// The Frame which failed navigation + /// Details about the navigation failure + void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + + /// + /// Invoked when application execution is being suspended. Application state is saved + /// without knowing whether the application will be terminated or resumed with the contents + /// of memory still intact. + /// + /// The source of the suspend request. + /// Details about the suspend request. + private void OnSuspending(object sender, SuspendingEventArgs e) + { + var deferral = e.SuspendingOperation.GetDeferral(); + //TODO: Save application state and stop any background activity + deferral.Complete(); + } + } +} diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/LockScreenLogo.scale-200.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..735f57adb5dfc01886d137b4e493d7e97cf13af3 GIT binary patch literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/SplashScreen.scale-200.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..023e7f1feda78d5100569825acedfd213a0d84e9 GIT binary patch literal 7700 zcmeHLYj~4Yw%(;oxoEH#Kxq-eR|+VkP17b#Vk;?4QwkI+A{L04G+#<<(x#Un1#+h5>eArRq zTw$)ZvTWW_Y?bDho0nPVTh08+s`sp!j74rJTTtXIDww0SILedFv?sZ?yb@@}GN;#8 znk_b~Q(A0YR#uV4ef!osoV1M3;vQ8N$O|fStfgf$S5;ddUNv`tWtGjM;koG#N;7M< zP*84lnx(bn_KF&9Z5Ai$)#Cs3a|$OFw>WKCT$of*L7_CqQEinflT|W{JT+aKp-E0v zsxmYg)1(T>DROm+LN1eQw8}KCTp=C!$H7`PU!t9_Hw@TsTI2`udRZv*!a5`#A9hK6Y95L(CDUX&_@QxKV z_feX{UhA#ZWlvgpL$#w^D#lq`_A4AzDqd|Zv6y9PX&DNcN|l}_D^{q@GG&H^Pg583 z8FI6N8^H7b5WjGp;urW)d7F+_lcp%KsLX0viCmE(OHH+=%ZfD_=`voUuoUxFO^L;- z;!;2{g-YiiO6m4bs89OuF9!p{FGtH-f%8<2gY!h9s)4ciN%{Kh1+`}{^}M~+TDH9N z^Z5PlgVXMC&2&k*Hw^Lb9gny#ro$MOIxIt{+r)EA10$VR3 zanN8D{TUkl+v0CQ_>ZoHP<M-x#8@8ZiT#$Kh`(uRaX1g$Bg|qy$<#7 zSSAi{Nb8Y=lvNVeio+UGLCAtoLBfL`iOv`)yoJMDJBN>4IH@(l7YRF;61@>qq1iM9 zr@b#OC~SAxSle?5Pp8Z78{VO0YFr1x7kZU64Z23eLf2T2#6J_t;-E}DkB?NufZ0Ug zi?J&byXeaB-uTNVhuiM!UVQw}bZrJ3GtAETYp->!{q#zfN7D3AS9@Q7*V^85jGx#R z(QxYV(wW#F0XF9^^s>>H8pPlVJ>)3Oz z&_X8Sf@~?cH_O*cgi$U#`v`RRfv#y3m(ZpKk^5uLup+lVs$~}FZU$r_+}#hl%?g5m z-u-}-666ssp-xWQak~>PPy$mRc|~?pVSs1_@mBEXpPVfLF6(Ktf1S* zPPh@QZ=tFMs?LM2(5P3L2;l_6XX6s&cYsP1ip#eg0`ZEP0HGYh{UmS@o`MihLLvkU zgyAG0G`b1|qjxxh1(ODKFE%AP}Dq=3vK$P7TXP4GrM1kQ72!GUVMDl`rDC&2;TA}*nF z8$nQD&6ys_nc1*E7$*1S@R8$ymy(sQV}imGSedB@{!QR5P&N_H=-^o!?LsWs+2|mH z-e=)T^SvI)=_JIm7}j4;@*Z17=(#}m=~YF~z~CLI+vdAGlJDcdF$TM?CVI1%LhUrN zaa6DJ=Yh$)$k&Oz{-~8yw^GM^8prYxSxo zvI4k#ibryMa%%*8oI-5m61Koa_A_xg=(fwp0aBX{;X4Q;NXUhtaoJDo1>TqhWtn=_ zd5~chq#&6~c%8JZK#t_&J(9EVUU&upYeIovLt1>vaHe}UUq>#RGQj!EN#5+0@T`(@ z^g~>*c`VGRiSt;!$_4+0hk^I!@O3``5=sZ8IwlxWW7km1B&_t&E*u0_9UBa#VqwY* zz>nxv?FAsVnRaD(Bui=6i==BFUw0k4n$>`umU`F2l?7CYTD^)c2X+d9X&ddS9|gj? zM?knGkGCX&W8offw8aLC2$D{PjC3nVZwd4k?eZH8*mZ)U@3Qk8RDFOz_#WUA#vnzy zyP>KrCfKwSXea7}jgJjBc}PGY+4#6%lbZyjhy`5sZd_Vy6Wz;ixa?czkN}J9It1K6 zY!eu>|AwF^fwZlLAYyQI*lM@^>O>Iu6Vf6i>Q$?v!SeUS<{>UYMwz$*%Aq?w^`j{h z!$GZbhu=^D{&ET8;))LL%ZBDZkQqRd2;u~!d9bHGmLRhLDctNgYyjsuvoSZ#iVdoB z2!f--UUA#U;<{je#?cYt^{PIyKa%hW>}uepWMyAI{{Zo7?2>?$c9;whJae%oN|I-kpTQSx_C$Z&;f zi2i)qmEn=y4U0uvk)$m;zKfjPK@oc?I`}1Jzl$Q~aoKBd3kt7L#7gyt|A_qgz6ai< z=X%D1i!d2h?rHR^R8SUj&G||dkC?DT>{o#Yau<@uqVT{Xef&XG}5*E4aPk{}~ zplx&XhaV)&1EfI3Em;Bw#O5SV^c;{twb-1Rw)+=0!e_BLbd7tYmXCH0wrlOSS+~`7He8Iqx0{CN+DVit9;*6L~JAN zD&cyT)2?h}xnYmL?^)<7YyzZ3$FHU^Eg;DLqAV{#wv#Wj7S`Jdl1pX&{3(uZ?!uh} zDc$ZTNV*7le_W6}Hju~GMTxZQ1aWCeUc%!jv3MHAzt>Y-nQK%zfT*3ebDQA5b?iGn; zBjv3B+GhLTexd_(CzZDP4|#n5^~scvB6#Pk%Ho!kQ>yYw((Dv{6=$g3jT1!u6gORW zx5#`7Wy-ZHRa~IxGHdrp(bm%lf>2%J660nj$fCqN(epv@y!l9s7@k6EvxS{AMP>WY zX4$@F8^kayphIx-RGO$+LYl9YdoI5d|4#q9##`_F5Xnx`&GPzp2fB{-{P@ATw=X@~ z_|&^UMWAKD;jjBKTK(~o?cUFRK8EX=6>cXpfzg4ZpMB>*w_^8GSiT-Jp|xBOnzM+j z*09-@-~qJ(eqWq5@R4i^u4^{McCP(!3}C|v_WsTR*bIUxN(Nx`u##3B4{sE`Z`v8w zAwIG`?1~PkID~W{uDzmqH98Pew_1(;x2%8r^vY{)_&J2K)cN{W+h5+g)ZcjP&Ci#O zgy|8K@4kyMfwilHd&6TDlhb%++Pk!>9HRld6HT7gwyZGrxS$}CsD6`>6!!2K1@Mjf z(P0WYB7V_OFZyeWrbOFb>O54BNXf~K&?}3=^v;v_wT{DKr?jN^DtN&DXwX%u?s*c6`%8>WFz z7}YW^tp0bp^NriE)AB6M2l<7rn7fzePtR*omOevpfm9n?}2V*+0iW;S)C zhg`NAjL?D=W#k*$aR{>pGf~lD-rVtD;5jW1_*Jn1j1=es@Kcx4ySM_bwcQCT=d+DV z>Sz~L=Hj@(X%31nK$mWI@7d>}ORB`K(p=+`UD)+99YUGQc7y^bHZ1F(8|tL0 zdK*DT0kSXG_{BKTpP2*2PecdKV9;dq$^ZZDP;Nyq1kp-&GI5eAyZsK!e3V zK@rPy*{(`KIfo+lc878mDKk^V#`VT05}64kBtk%DgwLrOvLMj5-;*GNKv6c6pzMuL z6EP%ob|_0IW}lLRXCP2!9wWhEw3LA7iF#1O1mIZ@Z=6&bz41F;@S_GvYAG-#CW3z{ zP3+6vHhvP&A3$##Vo9$dT^#MoGg^|MDm=Bt1d2RRwSZ<;ZHICpLBv5Xs!D?BH^(9_ z7`H=N&^v|Z-%mP}wNzG{aiFCsRgwzwq!N6obW9+7(R; z(SZ=23`|`>qil!LMGG{_Heq!BD>(Y-zV9wD)}hz25JA37YR%39;kI4y9pgtcUass6 zP24}ZY$vvYeI`zy&)A_X#nY3017ap*0&jx|mVwyGhg3;!keU53a}Uhm3BZI$N$6Se zLWlAmy1S0xKJm4G_U@sN_Tm=`$xWJSEwKU98rZ&)1R^*$$1vA3oG#&*%SMxY_~oGP zP&PFJatFLM-Ps%84IV-+Ow)T{C7cqUAvauy4C z(FRz&?6$Rypj{xO!`y=*J5o4@U8Q-(y5(*=YoKeZ+-1YdljXxkA#B)zo=FeQH#?Le zycNUmEEHWO9a=X^pb#&cOq7-`7UA87#|S22)<7RUtZo|(zibX=w;K3qur9vy#`MNV z6UUcf9ZwEnKCCp+OoBnF@OdbvH)ANXO0o~Pi9l8=x3))}L<#vO0-~O4!~--Ket?d} zJaqsj<@CD1%S2cTW%rOP{Vto%0sGW~1RMa_j^)5nil0Yw- z0EE#bP+l4#P^%PQ+N*oxu1Zq05xZ!bXfYTg>9c{(Iw*lnjR^>kz%lAN^zFce7rppy zY8zA~3GD=A6d*hze&l4D_wA~+O!56)BZTe_rEu}Ezi<4!kG|W#amBZ5{&XS2@6R~H z{9o^y*BkH4$~yX9U&@CgbOzX1bn9xqF|zh$Dh0Y5y*E0e90*$!ObrHY3Ok0`2=O~r zCuke6KrP9KOf?V(YDsM<6pX2nVoN%M$LT^q#FmtaF?1^27F*IcNX~XRB(|hCFvdcc zc)$=S-)acdk$g4?_>jRqxpI6M3vHZk?0c^3=byamYDNf;uB{3NlKW5IhnOS3DNkMV z?tK8?kJ}pmvp%&&eTVOVjHP`q34hN1@!aK}H(K!vI`~gf|Gv+FNEQD5Yd<~yX7k_l h&G-K)@HZb3BABY{)U1?^%I#E6`MGoTtustd{~yM6srvu` literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square150x150Logo.scale-200.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..af49fec1a5484db1d52a7f9b5ec90a27c7030186 GIT binary patch literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.scale-200.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..ce342a2ec8a61291ba76c54604aea7e9d20af11b GIT binary patch literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c02ce97e0a802b85f6021e822c89f8bf57d5cd GIT binary patch literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/StoreLogo.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Wide310x150Logo.scale-200.png b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..288995b397fdbef1fb7e85afd71445d5de1952c5 GIT binary patch literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA + + + + + diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/MainPage.xaml.cs b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/MainPage.xaml.cs new file mode 100644 index 0000000000..2cd0c888f1 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/MainPage.xaml.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 + +namespace Microsoft.AI.MachineLearning.Tests.Uwp +{ + ///

+ /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPage : Page + { + public MainPage() + { + this.InitializeComponent(); + var model = Windows.ApplicationModel.Package.Current.InstalledPath + "\\squeezenet.onnx"; + Microsoft.AI.MachineLearning.LearningModel.LoadFromFilePath(model); + } + } +} diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj new file mode 100644 index 0000000000..dc12806a98 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj @@ -0,0 +1,177 @@ + + + + + Debug + x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609} + AppContainerExe + Properties + Microsoft.AI.MachineLearning.Tests.Uwp + Microsoft.AI.MachineLearning.Tests.Uwp + en-US + UAP + 10.0.22000.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + false + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + MainPage.xaml + + + + + + Designer + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + 1.9.1 + + + 6.2.12 + + + + + Always + true + + + + 14.0 + + + + \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj.pp b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj.pp new file mode 100644 index 0000000000..bd445b41f6 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.csproj.pp @@ -0,0 +1,177 @@ + + + + + Debug + x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609} + AppContainerExe + Properties + Microsoft.AI.MachineLearning.Tests.Uwp + Microsoft.AI.MachineLearning.Tests.Uwp + en-US + UAP + 10.0.22000.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + false + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + MainPage.xaml + + + + + + Designer + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + [PackageVersion] + + + 6.2.12 + + + + + Always + true + + + + 14.0 + + + + \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.sln b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.sln new file mode 100644 index 0000000000..5585634e02 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Microsoft.AI.MachineLearning.Tests.Uwp.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31911.196 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AI.MachineLearning.Tests.Uwp", "Microsoft.AI.MachineLearning.Tests.Uwp.csproj", "{F8060B61-2BBC-4516-8C4E-AB969766B609}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM.ActiveCfg = Debug|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM.Build.0 = Debug|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM.Deploy.0 = Debug|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM64.Build.0 = Debug|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x64.ActiveCfg = Debug|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x64.Build.0 = Debug|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x64.Deploy.0 = Debug|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x86.ActiveCfg = Debug|x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x86.Build.0 = Debug|x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Debug|x86.Deploy.0 = Debug|x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM.ActiveCfg = Release|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM.Build.0 = Release|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM.Deploy.0 = Release|ARM + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM64.ActiveCfg = Release|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM64.Build.0 = Release|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|ARM64.Deploy.0 = Release|ARM64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x64.ActiveCfg = Release|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x64.Build.0 = Release|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x64.Deploy.0 = Release|x64 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x86.ActiveCfg = Release|x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x86.Build.0 = Release|x86 + {F8060B61-2BBC-4516-8C4E-AB969766B609}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {61039EFE-27CB-40D3-9CAB-BDE4B2ED9A94} + EndGlobalSection +EndGlobal diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/NuGet.config.pp b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/NuGet.config.pp new file mode 100644 index 0000000000..7597671d5b --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/NuGet.config.pp @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Package.appxmanifest b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Package.appxmanifest new file mode 100644 index 0000000000..cfb78a6c5c --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + Microsoft.AI.MachineLearning.Tests.Uwp + sheil + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/AssemblyInfo.cs b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..56062dba16 --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Microsoft.AI.MachineLearning.Tests.Uwp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Microsoft.AI.MachineLearning.Tests.Uwp")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/Default.rd.xml b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/Default.rd.xml new file mode 100644 index 0000000000..af00722cdf --- /dev/null +++ b/csharp/test/Microsoft.AI.MachineLearning.Tests.Uwp/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/ci_build/github/azure-pipelines/nuget/templates/windowsai.yml b/tools/ci_build/github/azure-pipelines/nuget/templates/windowsai.yml index 292b75f442..70c26ef9ea 100644 --- a/tools/ci_build/github/azure-pipelines/nuget/templates/windowsai.yml +++ b/tools/ci_build/github/azure-pipelines/nuget/templates/windowsai.yml @@ -218,41 +218,29 @@ jobs: $arm_static_runtime_nupkg_unzipped_directory = [System.IO.Path]::Combine($arm_static_runtime_nupkg_unzipped_directory_root, 'binaries', [System.IO.Path]::GetFileNameWithoutExtension($arm_static_runtime_nuget_package)) [System.IO.Compression.ZipFile]::ExtractToDirectory($arm_static_runtime_nuget_package, $arm_static_runtime_nupkg_unzipped_directory) - $x64_store_runtime_path_old = [System.IO.Path]::Combine($x64_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-x64', '_native') - $x64_store_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-x64', 'lib\\uap10.0') $x64_static_runtime_path_old = [System.IO.Path]::Combine($x64_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-x64', '_native') $x64_static_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-x64', '_native', 'static') $x86_runtime_path_old = [System.IO.Path]::Combine($x86_nupkg_unzipped_directory, 'runtimes', 'win-x86', '_native') $x86_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-x86', '_native') - $x86_store_runtime_path_old = [System.IO.Path]::Combine($x86_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-x86', '_native') - $x86_store_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-x86', 'lib\\uap10.0') $x86_static_runtime_path_old = [System.IO.Path]::Combine($x86_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-x86', '_native') $x86_static_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-x86', '_native', 'static') $arm64_runtime_path_old = [System.IO.Path]::Combine($arm64_nupkg_unzipped_directory, 'runtimes', 'win-arm64', '_native') $arm64_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm64', '_native') - $arm64_store_runtime_path_old = [System.IO.Path]::Combine($arm64_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-arm64', '_native') - $arm64_store_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm64', 'lib\\uap10.0') $arm64_static_runtime_path_old = [System.IO.Path]::Combine($arm64_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-arm64', '_native') $arm64_static_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm64', '_native', 'static') $arm_runtime_path_old = [System.IO.Path]::Combine($arm_nupkg_unzipped_directory, 'runtimes', 'win-arm', '_native') $arm_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm', '_native') - $arm_store_runtime_path_old = [System.IO.Path]::Combine($arm_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-arm', '_native') - $arm_store_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm', 'lib\\uap10.0') $arm_static_runtime_path_old = [System.IO.Path]::Combine($arm_static_runtime_nupkg_unzipped_directory, 'runtimes', 'win-arm', '_native') $arm_static_runtime_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'runtimes', 'win-arm', '_native', 'static') $uap_build_path_old = [System.IO.Path]::Combine($x64_static_runtime_nupkg_unzipped_directory, 'build', 'native') $uap_build_path_new = [System.IO.Path]::Combine($x64_nupkg_unzipped_directory, 'build', 'uap10.0') - New-Item -Path $x64_store_runtime_path_new -ItemType Directory New-Item -Path $x64_static_runtime_path_new -ItemType Directory New-Item -Path $x86_runtime_path_new -ItemType Directory - New-Item -Path $x86_store_runtime_path_new -ItemType Directory New-Item -Path $x86_static_runtime_path_new -ItemType Directory New-Item -Path $arm64_runtime_path_new -ItemType Directory - New-Item -Path $arm64_store_runtime_path_new -ItemType Directory New-Item -Path $arm64_static_runtime_path_new -ItemType Directory New-Item -Path $arm_runtime_path_new -ItemType Directory - New-Item -Path $arm_store_runtime_path_new -ItemType Directory New-Item -Path $arm_static_runtime_path_new -ItemType Directory Copy-Item ([System.IO.Path]::Combine($x86_runtime_path_old, 'onnxruntime.dll')) $x86_runtime_path_new @@ -270,26 +258,6 @@ jobs: Copy-Item ([System.IO.Path]::Combine($arm_runtime_path_old, 'microsoft.ai.machinelearning.dll')) $arm_runtime_path_new Copy-Item ([System.IO.Path]::Combine($arm_runtime_path_old, 'microsoft.ai.machinelearning.lib')) $arm_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x64_store_runtime_path_old, 'onnxruntime.dll')) $x64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x64_store_runtime_path_old, 'onnxruntime.lib')) $x64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x64_store_runtime_path_old, 'microsoft.ai.machinelearning.dll')) $x64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x64_store_runtime_path_old, 'microsoft.ai.machinelearning.lib')) $x64_store_runtime_path_new - - Copy-Item ([System.IO.Path]::Combine($x86_store_runtime_path_old, 'onnxruntime.dll')) $x86_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x86_store_runtime_path_old, 'onnxruntime.lib')) $x86_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x86_store_runtime_path_old, 'microsoft.ai.machinelearning.dll')) $x86_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x86_store_runtime_path_old, 'microsoft.ai.machinelearning.lib')) $x86_store_runtime_path_new - - Copy-Item ([System.IO.Path]::Combine($arm64_store_runtime_path_old, 'onnxruntime.dll')) $arm64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm64_store_runtime_path_old, 'onnxruntime.lib')) $arm64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm64_store_runtime_path_old, 'microsoft.ai.machinelearning.dll')) $arm64_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm64_store_runtime_path_old, 'microsoft.ai.machinelearning.lib')) $arm64_store_runtime_path_new - - Copy-Item ([System.IO.Path]::Combine($arm_store_runtime_path_old, 'onnxruntime.dll')) $arm_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm_store_runtime_path_old, 'onnxruntime.lib')) $arm_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm_store_runtime_path_old, 'microsoft.ai.machinelearning.dll')) $arm_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($arm_store_runtime_path_old, 'microsoft.ai.machinelearning.lib')) $arm_store_runtime_path_new - Copy-Item ([System.IO.Path]::Combine($x64_static_runtime_path_old, 'onnxruntime.dll')) ([System.IO.Path]::Combine($x64_static_runtime_path_new, 'onnxruntime.dll')) Copy-Item ([System.IO.Path]::Combine($x64_static_runtime_path_old, 'onnxruntime.lib')) ([System.IO.Path]::Combine($x64_static_runtime_path_new, 'onnxruntime.lib')) Copy-Item ([System.IO.Path]::Combine($x64_static_runtime_path_old, 'microsoft.ai.machinelearning.dll')) ([System.IO.Path]::Combine($x64_static_runtime_path_new, 'microsoft.ai.machinelearning.dll')) @@ -511,6 +479,49 @@ jobs: msbuild Microsoft.AI.MachineLearning.Tests.DotNet5_0.csproj /p:Platform=AnyCpu workingDirectory: $(Build.SourcesDirectory)\csharp\test\Microsoft.AI.MachineLearning.Tests.DotNet5_0 + + - task: PowerShell@2 + displayName: 'NuGet Tests: Fix Nuget Package references (C# UWP)' + inputs: + targetType: 'inline' + script: | + Add-Type -AssemblyName "System.IO.Compression.FileSystem" + $src_root_dir = $Env:BUILD_SOURCESDIRECTORY; + $artifacts_staging_dir = $Env:BUILD_ARTIFACTSTAGINGDIRECTORY; + $merged_nuget_path = [System.IO.Path]::Combine($artifacts_staging_dir, 'merged') + $nupkgs = (Get-ChildItem -Filter Microsoft.AI.MachineLearning*) + $merged_nuget_package = $nupkgs[0] + $merged_nuget_package_name = $merged_nuget_package.Name + $matched_name = ($merged_nuget_package_name -match "Microsoft.AI.MachineLearning.(?.*).nupkg") + $package_version = $matches['version'] + $src_dir = [System.IO.Path]::Combine($src_root_dir, 'csharp', 'test', 'Microsoft.AI.MachineLearning.Tests.Uwp') + $input_csproj = [System.IO.Path]::Combine($src_dir, 'Microsoft.AI.MachineLearning.Tests.Uwp.csproj.pp') + $csproj = [System.IO.Path]::Combine($src_dir, 'Microsoft.AI.MachineLearning.Tests.Uwp.csproj') + $input_csproj_content = Get-Content -Path $input_csproj + $csproj_content = $input_csproj_content -replace '\[PackageVersion\]', $package_version + Set-Content -Path $csproj -Value $csproj_content + $input_nuget_config = [System.IO.Path]::Combine($src_dir, 'NuGet.config.pp') + $nuget_config = [System.IO.Path]::Combine($src_dir, 'NuGet.config') + $input_nuget_config_content = Get-Content -Path $input_nuget_config + $nuget_config_content = $input_nuget_config_content -replace '\[BuildPackageSource\]', $merged_nuget_path + Set-Content -Path $nuget_config -Value $nuget_config_content + workingDirectory: $(Build.ArtifactStagingDirectory)\merged + + - task: PowerShell@2 + displayName: 'NuGet Tests: Build Tests (C# UWP)' + inputs: + targetType: 'inline' + script: | + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=x64 /t:Restore + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=x64 + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=x86 /t:Restore + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=x86 + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=ARM /t:Restore + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=ARM + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=ARM64 /t:Restore + msbuild Microsoft.AI.MachineLearning.Tests.Uwp.csproj /p:Platform=ARM64 + workingDirectory: $(Build.SourcesDirectory)\csharp\test\Microsoft.AI.MachineLearning.Tests.Uwp + - task: PowerShell@2 displayName: 'NuGet Tests: Run Tests' continueOnError: true From 05d20343ee04990a7082ccb162faab9dd9a8305c Mon Sep 17 00:00:00 2001 From: stevenlix <38092805+stevenlix@users.noreply.github.com> Date: Wed, 22 Dec 2021 12:19:56 -0800 Subject: [PATCH 069/113] Remove duplicated constant initializer copies for TensorRT nodes (#10105) * add new field constant_initializers in metadef and remove constant initializers from trt node inputs * remove redundancy * use GetConstantInitializer() to get constant initializers * add ORT_ENFORCE check Co-authored-by: Ubuntu --- include/onnxruntime/core/graph/indexed_sub_graph.h | 1 + onnxruntime/core/graph/function.cc | 10 ++++++++++ .../providers/shared_library/provider_interfaces.h | 1 + .../shared_library/provider_wrappedtypes.h | 2 ++ .../tensorrt/tensorrt_execution_provider.cc | 13 +++++++++++++ onnxruntime/core/session/provider_bridge_ort.cc | 1 + 6 files changed, 28 insertions(+) diff --git a/include/onnxruntime/core/graph/indexed_sub_graph.h b/include/onnxruntime/core/graph/indexed_sub_graph.h index 43275cebe1..0ec595399e 100644 --- a/include/onnxruntime/core/graph/indexed_sub_graph.h +++ b/include/onnxruntime/core/graph/indexed_sub_graph.h @@ -39,6 +39,7 @@ struct IndexedSubGraph { std::vector inputs; ///< Inputs of customized SubGraph/FunctionProto. std::vector outputs; ///< Outputs of customized SubGraph/FunctionProto. + std::vector constant_initializers; ///< Constant initializers of customized SubGraph/FunctionProto. NodeAttributes attributes; ///< Attributes of customized SubGraph/FunctionProto. std::string doc_string; ///< Doc string of customized SubGraph/FunctionProto. diff --git a/onnxruntime/core/graph/function.cc b/onnxruntime/core/graph/function.cc index 43a1638354..613915934e 100644 --- a/onnxruntime/core/graph/function.cc +++ b/onnxruntime/core/graph/function.cc @@ -457,6 +457,16 @@ FunctionImpl::FunctionImpl(const onnxruntime::Graph& graph, } } + for (const auto& constant_initializer : meta_def->constant_initializers) { + const ONNX_NAMESPACE::TensorProto* initializer = graph.GetConstantInitializer(constant_initializer, true); + ORT_ENFORCE(initializer != nullptr, "Initializer " + constant_initializer + " is not found or is not constant initializer."); + // meta_def->constant_initializers could have duplicates so make sure we only add once + const ONNX_NAMESPACE::TensorProto* subgraph_initializer = nullptr; + if (!function_body_graph.GetInitializedTensor(constant_initializer, subgraph_initializer)) { + function_body_graph.AddInitializedTensor(*initializer); + } + } + //TODO: if we reuse the nodes in parent graph, maybe we don't need to resolve it. auto status = function_body_graph.Resolve(); ORT_ENFORCE(status.IsOK(), status.ErrorMessage()); diff --git a/onnxruntime/core/providers/shared_library/provider_interfaces.h b/onnxruntime/core/providers/shared_library/provider_interfaces.h index bd0c7a581c..37ce00a4e8 100644 --- a/onnxruntime/core/providers/shared_library/provider_interfaces.h +++ b/onnxruntime/core/providers/shared_library/provider_interfaces.h @@ -429,6 +429,7 @@ struct ProviderHost { virtual ONNX_NAMESPACE::OperatorStatus& IndexedSubGraph_MetaDef__status(IndexedSubGraph_MetaDef* p) = 0; virtual std::vector& IndexedSubGraph_MetaDef__inputs(IndexedSubGraph_MetaDef* p) = 0; virtual std::vector& IndexedSubGraph_MetaDef__outputs(IndexedSubGraph_MetaDef* p) = 0; + virtual std::vector& IndexedSubGraph_MetaDef__constant_initializers(IndexedSubGraph_MetaDef* p) = 0; virtual NodeAttributes& IndexedSubGraph_MetaDef__attributes(IndexedSubGraph_MetaDef* p) = 0; virtual std::string& IndexedSubGraph_MetaDef__doc_string(IndexedSubGraph_MetaDef* p) = 0; diff --git a/onnxruntime/core/providers/shared_library/provider_wrappedtypes.h b/onnxruntime/core/providers/shared_library/provider_wrappedtypes.h index bf93e2c415..572f6f7ca1 100644 --- a/onnxruntime/core/providers/shared_library/provider_wrappedtypes.h +++ b/onnxruntime/core/providers/shared_library/provider_wrappedtypes.h @@ -348,6 +348,8 @@ struct IndexedSubGraph_MetaDef final { const std::vector& inputs() const { return g_host->IndexedSubGraph_MetaDef__inputs(const_cast(this)); } std::vector& inputs() { return g_host->IndexedSubGraph_MetaDef__inputs(this); } const std::vector& outputs() const { return g_host->IndexedSubGraph_MetaDef__outputs(const_cast(this)); } + const std::vector& constant_initializers() const { return g_host->IndexedSubGraph_MetaDef__constant_initializers(const_cast(this)); } + std::vector& constant_initializers() { return g_host->IndexedSubGraph_MetaDef__constant_initializers(this); } std::vector& outputs() { return g_host->IndexedSubGraph_MetaDef__outputs(this); } NodeAttributes& attributes() { return g_host->IndexedSubGraph_MetaDef__attributes(this); } diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc index 3f0751151f..7deec5ca6d 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc @@ -714,10 +714,15 @@ std::unique_ptr TensorrtExecutionProvider::GetSubGraph(SubGraph int input_order = 0; int output_order = 0; + std::vector initializers; for (const auto& index : graph_nodes_index.first) { sub_graph->Nodes().push_back(node_index[index]); const auto& node = graph.GetNode(node_index[index]); for (const auto& input : node->InputDefs()) { + if (graph.IsConstantInitializer(input->Name(), true)) { + initializers.push_back(input->Name()); + continue; + } const auto& it = fused_outputs.find(input); if (it != fused_outputs.end()) { fused_outputs.erase(it); @@ -729,6 +734,10 @@ std::unique_ptr TensorrtExecutionProvider::GetSubGraph(SubGraph } for (const auto& input : node->ImplicitInputDefs()) { + if (graph.IsConstantInitializer(input->Name(), true)) { + initializers.push_back(input->Name()); + continue; + } const auto& it = fused_outputs.find(input); if (it != fused_outputs.end()) { fused_outputs.erase(it); @@ -810,6 +819,10 @@ std::unique_ptr TensorrtExecutionProvider::GetSubGraph(SubGraph } } + for (const auto& initializer : initializers) { + meta_def->constant_initializers().push_back(initializer); + } + for (const auto& output : outputs) { if (output.second->Exists()) { meta_def->outputs().push_back(output.second->Name()); diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index cb76556779..bec88849df 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -509,6 +509,7 @@ struct ProviderHostImpl : ProviderHost { ONNX_NAMESPACE::OperatorStatus& IndexedSubGraph_MetaDef__status(IndexedSubGraph_MetaDef* p) override { return p->status; } std::vector& IndexedSubGraph_MetaDef__inputs(IndexedSubGraph_MetaDef* p) override { return p->inputs; } std::vector& IndexedSubGraph_MetaDef__outputs(IndexedSubGraph_MetaDef* p) override { return p->outputs; } + std::vector& IndexedSubGraph_MetaDef__constant_initializers(IndexedSubGraph_MetaDef* p) override { return p->constant_initializers; } NodeAttributes& IndexedSubGraph_MetaDef__attributes(IndexedSubGraph_MetaDef* p) override { return p->attributes; } std::string& IndexedSubGraph_MetaDef__doc_string(IndexedSubGraph_MetaDef* p) override { return p->doc_string; } From f780f06240ef407a838d7ea6d11a24cfcc436733 Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Fri, 24 Dec 2021 10:02:52 +0800 Subject: [PATCH 070/113] ConcatGrad for OpSet13 (#10109) --- .../core/graph/gradient_builder.cc | 96 ++++++++----------- .../test/gradient/gradient_ops_test.cc | 2 + 2 files changed, 44 insertions(+), 54 deletions(-) diff --git a/orttraining/orttraining/core/graph/gradient_builder.cc b/orttraining/orttraining/core/graph/gradient_builder.cc index 10987beb0d..55b521e13a 100755 --- a/orttraining/orttraining/core/graph/gradient_builder.cc +++ b/orttraining/orttraining/core/graph/gradient_builder.cc @@ -510,72 +510,60 @@ IMPLEMENT_GRADIENT_BUILDER(GetConcatGradient) { ORT_ENFORCE(attributes.at("axis").has_i()); auto axis = attributes.at("axis").i(); - std::vector split_attribute(GetSrcNodeInputSize()); - std::vector outputs; - for (int i = 0; i < GetSrcNodeInputSize(); ++i) { - std::vector data_shape; - ORT_ENFORCE(GetShape(I(i), data_shape).IsOK()); - int64_t axis_index = axis < 0 ? static_cast(data_shape.size()) + axis : axis; - if (axis_index >= 0 && axis_index < static_cast(data_shape.size()) && data_shape[axis_index].has_dim_value()) { - split_attribute[i] = data_shape[axis_index].dim_value(); - } else { - ORT_THROW("Error: can't infer split attribute value for ConcatGrad"); - } - outputs.push_back(GI(i)); - } - + std::vector node_outputs; std::vector new_attributes; new_attributes.push_back(MakeAttribute("axis", axis)); - new_attributes.push_back(MakeAttribute("split", split_attribute)); - return std::vector{ - NodeDef("Split", - {GO(0)}, - outputs, - new_attributes)}; + // Split Op before OpSet13 has "split" as attribute, but as input since OpSet13. + if (SrcNodeOpsetVersion() < 13) { + std::vector split_attribute(GetSrcNodeInputSize()); + for (int i = 0; i < GetSrcNodeInputSize(); ++i) { + std::vector data_shape; + ORT_ENFORCE(GetShape(I(i), data_shape).IsOK()); + int64_t axis_index = axis < 0 ? static_cast(data_shape.size()) + axis : axis; + if (axis_index >= 0 && axis_index < static_cast(data_shape.size()) && + data_shape[axis_index].has_dim_value()) { + split_attribute[i] = data_shape[axis_index].dim_value(); + } else { + ORT_THROW("Error: can't infer split attribute value for ConcatGrad"); + } + node_outputs.push_back(GI(i)); + } + + new_attributes.push_back(MakeAttribute("split", split_attribute)); + return std::vector{NodeDef("Split", {GO(0)}, node_outputs, new_attributes)}; + } + + std::vector output; + NodeDef axis_const_node = ConstantScalarNode(axis, {1}, Name(std::to_string(axis) + "_int64")); + ArgDef axis_arg_def = axis_const_node.output_args[0]; + output.emplace_back(axis_const_node); + std::vector split_sizes; + for (int i = 0; i < GetSrcNodeInputSize(); ++i) { + ArgDef shape_arg_def = IA("shape_" + std::to_string(i)); + ArgDef split_size_arg_def = IA("split_size_" + std::to_string(i)); + output.emplace_back(NodeDef("Shape", {I(i)}, {shape_arg_def})); + output.emplace_back( + NodeDef("Gather", {shape_arg_def, axis_arg_def}, {split_size_arg_def}, {MakeAttribute("axis", int64_t(0))})); + split_sizes.emplace_back(split_size_arg_def); + node_outputs.emplace_back(GI(i)); + } + output.emplace_back(NodeDef("Concat", split_sizes, {IA("split_sizes")}, {MakeAttribute("axis", int64_t(0))})); + output.emplace_back(NodeDef("Split", {GO(0), IA("split_sizes")}, node_outputs, new_attributes)); + return output; } IMPLEMENT_GRADIENT_BUILDER(GetConcatTrainingGradient) { auto attributes = SrcNodeAttributes(); ORT_ENFORCE(utils::HasInt(attributes.at("axis"))); auto axis = attributes.at("axis").i(); - - std::vector split_attribute(GetSrcNodeInputSize()); - std::vector outputs; - bool known_shapes = true; - for (int i = 0; i < GetSrcNodeInputSize(); ++i) { - std::vector data_shape; - if (GetShape(I(i), data_shape).IsOK()) { - int64_t rank = static_cast(data_shape.size()); - int64_t axis_index = HandleNegativeAxis(axis, rank); - if (data_shape[axis_index].has_dim_value()) { - split_attribute[i] = data_shape[axis_index].dim_value(); - } else { - known_shapes = false; - } - } else { - known_shapes = false; - } - - outputs.push_back(GI(i)); - } - std::vector new_attributes; new_attributes.push_back(MakeAttribute("axis", axis)); - if (known_shapes) { - new_attributes.push_back(MakeAttribute("split", split_attribute)); - return std::vector{ - NodeDef("Split", - {GO(0)}, - outputs, - new_attributes)}; - } else { - return std::vector{ - NodeDef(OpDef{"SplitTraining", kMSDomain, 1}, - {GO(0), O(1)}, - outputs, - new_attributes)}; + std::vector outputs; + for (int i = 0; i < GetSrcNodeInputSize(); ++i) { + outputs.push_back(GI(i)); } + return std::vector{NodeDef(OpDef{"SplitTraining", kMSDomain, 1}, {GO(0), O(1)}, outputs, new_attributes)}; } IMPLEMENT_GRADIENT_BUILDER(GetGatherNDGradient) { diff --git a/orttraining/orttraining/test/gradient/gradient_ops_test.cc b/orttraining/orttraining/test/gradient/gradient_ops_test.cc index 9b95925410..4511336435 100644 --- a/orttraining/orttraining/test/gradient/gradient_ops_test.cc +++ b/orttraining/orttraining/test/gradient/gradient_ops_test.cc @@ -1126,7 +1126,9 @@ static void TestConcatOpGrad(const std::string& op_type, } TEST(GradientCheckerTest, ConcatGrad) { + // Concat's gradient uses Split, and Split Op move "split" attribute to input since OpSet13. TestConcatOpGrad("Concat"); + TestConcatOpGrad("Concat", kOnnxDomain, 13); } TEST(GradientCheckerTest, ConcatTrainingGrad) { /*also test w/o shape inferencing */ From ceb17f82ffc9f72acb64f28629d7db93d98e5ba9 Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Mon, 27 Dec 2021 10:49:46 +0800 Subject: [PATCH 071/113] Use FusedMatMul When Transpose is Between First Dim and Contiguous Batch Dims (#9734) * fusedmatmul support transpose batches * fix win build * fix contrib op md * more comments --- docs/ContribOperators.md | 4 + .../core/graph/contrib_ops/contrib_defs.cc | 58 +++--- .../core/optimizer/matmul_transpose_fusion.cc | 132 +++++++++---- onnxruntime/core/providers/cpu/math/matmul.cc | 6 +- onnxruntime/core/providers/cpu/math/matmul.h | 10 +- .../core/providers/cpu/math/matmul_helper.h | 121 +++++++++--- .../core/providers/cuda/math/matmul.cc | 34 ++-- onnxruntime/core/providers/cuda/math/matmul.h | 7 +- .../core/providers/rocm/math/matmul.cc | 34 ++-- .../test/contrib_ops/fused_matmul_op_test.cc | 147 ++++++++++---- .../test/optimizer/graph_transform_test.cc | 70 +++++++ .../transform/fusion/transpose_matmul_gen.py | 187 ++++++++++++++++++ .../transpose_matmul_trans_batch_fusion1.onnx | Bin 0 -> 343 bytes .../transpose_matmul_trans_batch_fusion2.onnx | Bin 0 -> 322 bytes .../transpose_matmul_trans_batch_fusion3.onnx | Bin 0 -> 373 bytes ...tmul_trans_batch_fusion_invalid_case1.onnx | Bin 0 -> 281 bytes ...tmul_trans_batch_fusion_invalid_case2.onnx | Bin 0 -> 322 bytes ...tmul_trans_batch_fusion_invalid_case3.onnx | Bin 0 -> 357 bytes 18 files changed, 642 insertions(+), 168 deletions(-) create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion1.onnx create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion2.onnx create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion3.onnx create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case1.onnx create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case2.onnx create mode 100644 onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case3.onnx diff --git a/docs/ContribOperators.md b/docs/ContribOperators.md index a982999f0a..d8630076c1 100644 --- a/docs/ContribOperators.md +++ b/docs/ContribOperators.md @@ -1272,6 +1272,10 @@ This version of the operator has been available since version 1 of the 'com.micr
Whether A should be transposed on the last two dimensions before doing multiplication
transB : int
Whether B should be transposed on the last two dimensions before doing multiplication
+
transBatchA : int
+
Whether A should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before doing multiplication
+
transBatchB : int
+
Whether B should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before doing multiplication
#### Inputs diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc index cf4e7efd8d..502244fa4b 100644 --- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc @@ -282,6 +282,10 @@ void FusedMatMulShapeInference(ONNX_NAMESPACE::InferenceContext& ctx) { bool transa = transAAttr ? static_cast(transAAttr->i()) != 0 : false; auto transBAttr = ctx.getAttribute("transB"); bool transb = transBAttr ? static_cast(transBAttr->i()) != 0 : false; + auto trans_batch_a_attr = ctx.getAttribute("transBatchA"); + bool trans_batch_a = trans_batch_a_attr ? static_cast(trans_batch_a_attr->i()) != 0 : false; + auto trans_batch_b_attr = ctx.getAttribute("transBatchB"); + bool trans_batch_b = trans_batch_b_attr ? static_cast(trans_batch_b_attr->i()) != 0 : false; int input1Idx = 0; int input2Idx = 1; if (!hasInputShape(ctx, input1Idx) || !hasInputShape(ctx, input2Idx)) { @@ -309,11 +313,13 @@ void FusedMatMulShapeInference(ONNX_NAMESPACE::InferenceContext& ctx) { // for vector input, transa does not make impact on the dim. shape0 = shape0_raw; } else { - for (int i = 0; i < rank0 - 2; ++i) { + int start = trans_batch_a ? 1 : 0; + int end = trans_batch_a ? rank0 - 1 : rank0 - 2; + for (int i = start; i < end; ++i) { *shape0.add_dim() = shape0_raw.dim(i); } - *shape0.add_dim() = shape0_raw.dim(transa ? rank0 - 1 : rank0 - 2); - *shape0.add_dim() = shape0_raw.dim(transa ? rank0 - 2 : rank0 - 1); + *shape0.add_dim() = shape0_raw.dim(transa ? rank0 - 1 : (trans_batch_a ? 0 : rank0 - 2)); + *shape0.add_dim() = shape0_raw.dim(transa ? (trans_batch_a ? 0 : rank0 - 2) : rank0 - 1); } auto rank1 = shape1_raw.dim_size(); @@ -321,11 +327,13 @@ void FusedMatMulShapeInference(ONNX_NAMESPACE::InferenceContext& ctx) { // for vector input, transb does not make impact on the dim. shape1 = shape1_raw; } else { - for (int i = 0; i < rank1 - 2; ++i) { + int start = trans_batch_b ? 1 : 0; + int end = trans_batch_b ? rank1 - 1 : rank1 - 2; + for (int i = start; i < end; ++i) { *shape1.add_dim() = shape1_raw.dim(i); } - *shape1.add_dim() = shape1_raw.dim(transb ? rank1 - 1 : rank1 - 2); - *shape1.add_dim() = shape1_raw.dim(transb ? rank1 - 2 : rank1 - 1); + *shape1.add_dim() = shape1_raw.dim(transb ? rank1 - 1 : (trans_batch_b ? 0 : rank1 - 2)); + *shape1.add_dim() = shape1_raw.dim(transb ? (trans_batch_b ? 0 : rank1 - 2) : rank1 - 1); } ONNX_NAMESPACE::TensorShapeProto shapeL, shapeR; @@ -2138,30 +2146,24 @@ Matrix product that behaves like numpy.matmul: https://docs.scipy.org/doc/numpy- .SinceVersion(1) .Input(0, "A", "N-dimensional matrix A", "T") .Input(1, "B", "N-dimensional matrix B", "T") - .Attr( - "alpha", - "Scalar multiplier for the product of the input tensors.", - AttributeProto::FLOAT, - 1.0f) - .Attr( - "transA", - "Whether A should be transposed on the last two dimensions before doing multiplication", - AttributeProto::INT, - static_cast(0)) - .Attr( - "transB", - "Whether B should be transposed on the last two dimensions before doing multiplication", - AttributeProto::INT, - static_cast(0)) + .Attr("alpha", "Scalar multiplier for the product of the input tensors.", AttributeProto::FLOAT, 1.0f) + .Attr("transA", "Whether A should be transposed on the last two dimensions before doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transB", "Whether B should be transposed on the last two dimensions before doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transBatchA", + "Whether A should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before " + "doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transBatchB", + "Whether B should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before " + "doing multiplication", + AttributeProto::INT, static_cast(0)) .Output(0, "Y", "Matrix multiply results", "T") - .TypeConstraint( - "T", - {"tensor(float16)", "tensor(float)", "tensor(double)", "tensor(bfloat16)"}, - "Constrain input and output types to float tensors.") + .TypeConstraint("T", {"tensor(float16)", "tensor(float)", "tensor(double)", "tensor(bfloat16)"}, + "Constrain input and output types to float tensors.") .SetDoc(FusedMatMul_doc) - .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { - FusedMatMulShapeInference(ctx); - }); + .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { FusedMatMulShapeInference(ctx); }); ONNX_CONTRIB_OPERATOR_SCHEMA(SparseToDenseMatMul) .SetDomain(kMSDomain) diff --git a/onnxruntime/core/optimizer/matmul_transpose_fusion.cc b/onnxruntime/core/optimizer/matmul_transpose_fusion.cc index 1f6e546e84..25ce5ba150 100644 --- a/onnxruntime/core/optimizer/matmul_transpose_fusion.cc +++ b/onnxruntime/core/optimizer/matmul_transpose_fusion.cc @@ -32,14 +32,25 @@ static bool GetTransposePerms(const Node& transpose_node, std::vector& return true; } -static Node* GetTransposeNodeFromOutput(Graph& graph, NodeArg& node_arg) { - Node* trans_node = graph.GetMutableProducerNode(node_arg.Name()); - if (trans_node == nullptr || trans_node->OpType() != "Transpose") { - return nullptr; - } +// is_trans is whether to transpose the 2 dims used to MatMul. +// is_trans_batch is whether to transpose 1st dim and batch dims. +// Batch here has the same meaning in CUDA's GemmStridedBatched (other than the training batch concept), +// i.e., all dims except the 2 dims used to MatMul, including from dim[0] to dim[rank-3]. +// For example (take lhs input as example): +// is_trans=False, is_trans_batch=False: +// the input tensor is in shape [b0,...,bn,M,K], no Transpose (no fuse for this case) +// is_trans=False, is_trans_batch=True: +// the input tensor is in shape [M,b0,...,bn,K], Transpose perm=[1,...,rank-2,0,rank-1] +// is_trans=True , is_trans_batch=False: +// the input tensor is in shape [b0,...,bn,K,M], Transpose perm=[0,...,rank-3,rank-1,rank-2] +// is_trans=True , is_trans_batch=True: +// the input tensor is in shape [K,b0,...,bn,M], Transpose perm=[1,...,rank-2,rank-1,0] +static Node* GetTransposeNodeFromOutput(Graph& graph, NodeArg& node_arg, bool& is_trans, bool& is_trans_batch) { + is_trans = is_trans_batch = false; - // if the node has Graph output, skip it too - if (graph.NodeProducesGraphOutput(*trans_node)) { + // Skip if not a Transpose node or it has graph output. + Node* trans_node = graph.GetMutableProducerNode(node_arg.Name()); + if (trans_node == nullptr || trans_node->OpType() != "Transpose" || graph.NodeProducesGraphOutput(*trans_node)) { return nullptr; } @@ -48,28 +59,34 @@ static Node* GetTransposeNodeFromOutput(Graph& graph, NodeArg& node_arg) { return nullptr; } - int64_t rank = perms.size(); + size_t rank = perms.size(); if (rank < 2) { return nullptr; } - bool is_trans_on_last_two_dims = true; - for (int64_t i = 0; i < rank - 2; i++) { - if (perms[static_cast(i)] != i) { - is_trans_on_last_two_dims = false; - break; - } - } - - if (is_trans_on_last_two_dims) { - // rank is atleast 2 (checked above) and so it is safe to cast (rank - 2) and (rank - 1) to size_t - is_trans_on_last_two_dims = perms[static_cast(rank - 2)] == rank - 1 && perms[static_cast(rank - 1)] == rank - 2; - } - - if (!is_trans_on_last_two_dims) { + // We can fuse the Transpose node only when the last axis of original tensor is within the last two dims after transpose. + int64_t last_axis = static_cast(rank) - 1; + size_t last_axis_index = perms[rank - 1] == last_axis ? rank - 1 : perms[rank - 2] == last_axis ? rank - 2 : rank; + if (last_axis_index == rank) { return nullptr; } + // Transpose node can be fused to MatMul when the batch dims keep same relative orders before and after transpose. + // But if they are not contiguous, after the fusion, we can only use GemmBatched instead of GemmStridedBatched, + // which may have perf issue. To keep it simple, we will fuse only when batch dimensions are contiguous. + if (rank >= 3) { + if (perms[0] != 0 && perms[0] != 1) { + return nullptr; + } + for (size_t i = 0; i < rank - 3; ++i) { + if (perms[i] + 1 != perms[i + 1]) { + return nullptr; + } + } + } + + is_trans = last_axis_index == rank - 2; + is_trans_batch = rank >= 3 && perms[0] == 1; return trans_node; } @@ -118,9 +135,10 @@ static size_t UpdateConsumerCount(Graph& graph, NodeArg* target, std::unordered_ */ static Node* ReorderCastAndTranspose(Graph& graph, Node* cast, std::unordered_map& consumer_count, - std::deque& removed_nodes) { + std::deque& removed_nodes, + bool& is_trans, bool& is_trans_batch) { ORT_ENFORCE(cast != nullptr); - auto transpose = GetTransposeNodeFromOutput(graph, *cast->MutableInputDefs()[0]); + auto transpose = GetTransposeNodeFromOutput(graph, *cast->MutableInputDefs()[0], is_trans, is_trans_batch); if (transpose == nullptr) { return nullptr; } @@ -290,26 +308,58 @@ Status MatmulTransposeFusion::ApplyImpl(Graph& graph, bool& modified, int graph_ if (!IsAllowedFusedMatMulDataType(static_cast(left_type))) { continue; } - auto left = GetTransposeNodeFromOutput(graph, *left_input); + + bool is_trans_left = false; + bool is_trans_batch_left = false; + Node* left = nullptr; + // If it's already a FusedMatMul with transBatchA is true, don't fuse it. + if (node.OpType() != "FusedMatMul" || node.GetAttributes().at("transBatchA").i() == 0) { + left = GetTransposeNodeFromOutput(graph, *left_input, is_trans_left, is_trans_batch_left); + if (!left) { + Node* left_node = graph.GetMutableProducerNode(left_input->Name()); + if (left_node && left_node->OpType() == "Cast") { + left = ReorderCastAndTranspose(graph, left_node, consumer_count, removed_nodes, is_trans_left, + is_trans_batch_left); + } + } + } NodeArg* right_input = node.MutableInputDefs()[1]; auto right_type = right_input->TypeAsProto()->tensor_type().elem_type(); if (!IsAllowedFusedMatMulDataType(static_cast(right_type))) { continue; } - auto right = GetTransposeNodeFromOutput(graph, *right_input); - if (!left) { - Node* left_node = graph.GetMutableProducerNode(left_input->Name()); - if (left_node && left_node->OpType() == "Cast") { - left = ReorderCastAndTranspose(graph, left_node, consumer_count, removed_nodes); + bool is_trans_right = false; + bool is_trans_batch_right = false; + Node* right = nullptr; + // If it's already a FusedMatMul with transBatchB is true, don't fuse it. + if (node.OpType() != "FusedMatMul" || node.GetAttributes().at("transBatchB").i() == 0) { + right = GetTransposeNodeFromOutput(graph, *right_input, is_trans_right, is_trans_batch_right); + if (!right) { + Node* right_node = graph.GetMutableProducerNode(right_input->Name()); + if (right_node && right_node->OpType() == "Cast") { + right = ReorderCastAndTranspose(graph, right_node, consumer_count, removed_nodes, is_trans_right, + is_trans_batch_right); + } } } - if (!right) { - Node* right_node = graph.GetMutableProducerNode(right_input->Name()); - if (right_node && right_node->OpType() == "Cast") { - right = ReorderCastAndTranspose(graph, right_node, consumer_count, removed_nodes); + // When the rank of two inputs are not equal, we need to pad 1 to one of them for MutMul. + // For example, if padding 1 is the "M" dim for left input, set is_trans_batch to true is not correct logically. + // To keep it simple, if any side of is_trans_batch is true, we require both side has same rank. + if (is_trans_batch_left || is_trans_batch_right) { + auto shape_left = left_input->Shape(); + auto shape_right = right_input->Shape(); + if (!shape_left || !shape_right || shape_left->dim_size() != shape_right->dim_size()) { + if (is_trans_batch_left) { + is_trans_left = is_trans_batch_left = false; + left = nullptr; + } + if (is_trans_batch_right) { + is_trans_right = is_trans_batch_right = false; + right= nullptr; + } } } @@ -339,16 +389,18 @@ Status MatmulTransposeFusion::ApplyImpl(Graph& graph, bool& modified, int graph_ "fused MatMul and Transpose ", input_defs, output_defs, {}, kMSDomain); - bool transpose_left = (left != nullptr); - bool transpose_right = (right != nullptr); float alpha = 1.0f; if (node.OpType() == "FusedMatMul") { - transpose_left ^= static_cast(node.GetAttributes().at("transA").i()); - transpose_right ^= static_cast(node.GetAttributes().at("transB").i()); + is_trans_left ^= static_cast(node.GetAttributes().at("transA").i()); + is_trans_right ^= static_cast(node.GetAttributes().at("transB").i()); + is_trans_batch_left ^= static_cast(node.GetAttributes().at("transBatchA").i()); + is_trans_batch_right ^= static_cast(node.GetAttributes().at("transBatchB").i()); alpha = node.GetAttributes().at("alpha").f(); } - matmul_node.AddAttribute("transA", static_cast(transpose_left)); - matmul_node.AddAttribute("transB", static_cast(transpose_right)); + matmul_node.AddAttribute("transA", static_cast(is_trans_left)); + matmul_node.AddAttribute("transB", static_cast(is_trans_right)); + matmul_node.AddAttribute("transBatchA", static_cast(is_trans_batch_left)); + matmul_node.AddAttribute("transBatchB", static_cast(is_trans_batch_right)); matmul_node.AddAttribute("alpha", alpha); // Assign provider to this new node. Provider should be same as the provider for old node. matmul_node.SetExecutionProviderType(node.GetExecutionProviderType()); diff --git a/onnxruntime/core/providers/cpu/math/matmul.cc b/onnxruntime/core/providers/cpu/math/matmul.cc index ad9e34cc67..ec395cf018 100644 --- a/onnxruntime/core/providers/cpu/math/matmul.cc +++ b/onnxruntime/core/providers/cpu/math/matmul.cc @@ -169,7 +169,7 @@ Status MatMul::Compute(OpKernelContext* ctx) const { const bool trans_b = trans_b_attr_ && b_shape.NumDimensions() != 1; MatMulComputeHelper helper; - ORT_RETURN_IF_ERROR(helper.Compute(a->Shape(), b_shape, trans_a, trans_b)); + ORT_RETURN_IF_ERROR(helper.Compute(a->Shape(), b_shape, trans_a, trans_b, trans_batch_a_, trans_batch_b_)); Tensor* y = ctx->Output(0, helper.OutputShape()); // Bail out early if the output is going to be empty @@ -184,8 +184,8 @@ Status MatMul::Compute(OpKernelContext* ctx) const { const size_t M = static_cast(helper.M()); const size_t N = static_cast(helper.N()); const size_t K = static_cast(helper.K()); - const size_t lda = static_cast(trans_a ? M : K); - const size_t ldb = static_cast(trans_b ? K : N); + const size_t lda = helper.Lda(trans_a); + const size_t ldb = helper.Ldb(trans_b); std::vector data(max_len); for (size_t i = 0; i < max_len; i++) { diff --git a/onnxruntime/core/providers/cpu/math/matmul.h b/onnxruntime/core/providers/cpu/math/matmul.h index 4f312855f9..96e461673b 100644 --- a/onnxruntime/core/providers/cpu/math/matmul.h +++ b/onnxruntime/core/providers/cpu/math/matmul.h @@ -22,14 +22,18 @@ class MatMul final : public OpKernel { info.GetAttrOrDefault("transA", &trans_a_attr_, 0); info.GetAttrOrDefault("transB", &trans_b_attr_, 0); info.GetAttrOrDefault("alpha", &alpha_attr_, 1.0); + int64_t trans_batch_a_attr, trans_batch_b_attr; + info.GetAttrOrDefault("transBatchA", &trans_batch_a_attr, 0); + info.GetAttrOrDefault("transBatchB", &trans_batch_b_attr, 0); + trans_batch_a_ = trans_batch_a_attr != 0; + trans_batch_b_ = trans_batch_b_attr != 0; } Status PrePack(const Tensor& tensor, int input_idx, AllocatorPtr alloc, /*out*/ bool& is_packed, /*out*/ PrePackedWeights* prepacked_weights) override; - Status UseSharedPrePackedBuffers(std::vector& prepacked_buffers, - int input_idx, + Status UseSharedPrePackedBuffers(std::vector& prepacked_buffers, int input_idx, /*out*/ bool& used_shared_buffers) override; Status Compute(OpKernelContext* context) const override; @@ -42,6 +46,8 @@ class MatMul final : public OpKernel { float alpha_attr_; int64_t trans_a_attr_; int64_t trans_b_attr_; + bool trans_batch_a_; + bool trans_batch_b_; }; } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cpu/math/matmul_helper.h b/onnxruntime/core/providers/cpu/math/matmul_helper.h index 2ba1e2a234..6988225ccd 100644 --- a/onnxruntime/core/providers/cpu/math/matmul_helper.h +++ b/onnxruntime/core/providers/cpu/math/matmul_helper.h @@ -22,8 +22,12 @@ inline void TensorShapeCopyDims(const TensorShape& shape, int64_t* dims, size_t class MatMulComputeHelper { public: - Status Compute(const TensorShape& left_shape, const TensorShape& right_shape, - bool transa = false, bool transb = false) { + // fill_offsets is to control if to fill offsets here. + // For CUDA/ROCM kernel when we can use GemmStridedBatched, we don't need to fill the offsets. + Status Compute(const TensorShape& orig_left_shape, const TensorShape& orig_right_shape, + bool transa = false, bool transb = false, + bool trans_batch_a = false, bool trans_batch_b = false, + bool fill_offsets = true) { // Following numpy.matmul for shape inference: // https://docs.scipy.org/doc/numpy/reference/generated/numpy.matmul.html // The behavior depends on the arguments in the following way. @@ -32,8 +36,8 @@ class MatMulComputeHelper { // * If the first argument is 1 - D, it is promoted to a matrix by prepending a 1 to its dimensions.After matrix multiplication the prepended 1 is removed. // * If the second argument is 1 - D, it is promoted to a matrix by appending a 1 to its dimensions.After matrix multiplication the appended 1 is removed. - size_t left_num_dims = left_shape.NumDimensions(); - size_t right_num_dims = right_shape.NumDimensions(); + size_t left_num_dims = orig_left_shape.NumDimensions(); + size_t right_num_dims = orig_right_shape.NumDimensions(); ORT_RETURN_IF_NOT(left_num_dims >= 1 && right_num_dims >= 1, "left_num_dims and right_num_dims must be >= 1"); // Special cases below for right_shape being 2D and left_shape > 2D by flattening left_shape to 2D @@ -42,22 +46,59 @@ class MatMulComputeHelper { // A: [M1, M2, ... K], B: [N, K]^T // A: [M1, M2, ... K], B: [1, ..., 1, K, N] // A: [M1, M2, ... K], B: [1, ..., 1, N, K]^T - if (!transa && left_num_dims >= 2 && right_num_dims >= 2 && left_num_dims >= right_num_dims && - right_shape.SizeToDimension(right_num_dims - 1) == right_shape[right_num_dims - 2]) { - M_ = static_cast(left_shape.SizeToDimension(left_num_dims - 1)); - K_ = static_cast(left_shape[left_num_dims - 1]); - N_ = static_cast(transb ? right_shape[right_num_dims - 2] : right_shape[right_num_dims - 1]); - output_shape_ = left_shape; + if (!transa && !trans_batch_a && !trans_batch_b && left_num_dims >= 2 && right_num_dims >= 2 && left_num_dims >= right_num_dims && + orig_right_shape.SizeToDimension(right_num_dims - 1) == orig_right_shape[right_num_dims - 2]) { + M_ = static_cast(orig_left_shape.SizeToDimension(left_num_dims - 1)); + K_ = static_cast(orig_left_shape[left_num_dims - 1]); + N_ = static_cast(transb ? orig_right_shape[right_num_dims - 2] : orig_right_shape[right_num_dims - 1]); + output_shape_ = orig_left_shape; output_shape_[left_num_dims - 1] = N_; output_offsets_ = {0}; left_offsets_ = {0}; right_offsets_ = {0}; - ORT_RETURN_IF_NOT(K_ == right_shape[right_num_dims - 2] || - (transb && K_ == right_shape[right_num_dims - 1]), + ORT_RETURN_IF_NOT((!transb && K_ == orig_right_shape[right_num_dims - 2]) || + (transb && K_ == orig_right_shape[right_num_dims - 1]), "MatMul dimension mismatch"); return Status::OK(); } + std::vector dims_left(left_num_dims); + std::vector dims_right(right_num_dims); + orig_left_shape.CopyDims(&dims_left[0], left_num_dims); + orig_right_shape.CopyDims(&dims_right[0], right_num_dims); + left_stride_factor_ = right_stride_factor_ = 1; + left_ld_factor_ = right_ld_factor_ = 1; + + if (trans_batch_a || trans_batch_b) { + ORT_ENFORCE(left_num_dims > 2 && left_num_dims == right_num_dims, + "Two inputs should have same rank and rank >= 3 if transBatchA or transBatchB is true"); + // trans_batch_a means the input tensor is either [M,b0,...,bn,K] or [K,b0,...,bn,M]. + // Switch the dim[0] and batch dims here. + if (trans_batch_a) { + int64_t leading_dim = dims_left[0]; + for (size_t i = 0; i < left_num_dims - 2; ++i) { + dims_left[i] = dims_left[i + 1]; + left_ld_factor_ *= static_cast(dims_left[i]); + } + dims_left[left_num_dims - 2] = leading_dim; + left_stride_factor_ = static_cast(leading_dim); + } + // trans_batch_b means the input tensor is either [K,b0,...,bn,N] or [N,b0,...,bn,K]. + // Switch the dim[0] and batch dims here. + if (trans_batch_b) { + int64_t leading_dim = dims_right[0]; + for (size_t i = 0; i < right_num_dims - 2; ++i) { + dims_right[i] = dims_right[i + 1]; + right_ld_factor_ *= static_cast(dims_right[i]); + } + dims_right[right_num_dims - 2] = leading_dim; + right_stride_factor_ = static_cast(leading_dim); + } + } + + TensorShape left_shape(dims_left); + TensorShape right_shape(dims_right); + bool has_1D_input = (left_num_dims == 1 || right_num_dims == 1); size_t num_input_dims = std::max(left_num_dims, right_num_dims); @@ -146,7 +187,7 @@ class MatMulComputeHelper { output_shape_ = TensorShape(output_dims); // compute broadcast offsets - ComputeBroadcastOffsets(); + ComputeBroadcastOffsets(fill_offsets); return Status::OK(); } @@ -178,21 +219,8 @@ class MatMulComputeHelper { return Status::OK(); } - private: - void ComputeBroadcastOffsets() { - num_broadcasted_dims_ = left_padded_dims_.size() - 2; - - if (num_broadcasted_dims_ == 0) { - left_offsets_ = {0}; - right_offsets_ = {0}; - output_offsets_ = {0}; - return; - } - - left_mat_size_ = M_ * K_; - right_mat_size_ = K_ * N_; - output_mat_size_ = M_ * N_; - + // Move this piece of code to public so that we don't need to call this if we can use GemmStridedBatched. + void FillOffsets() { // stride in mats and dims for broadcasting left_padded_strides_.resize(num_broadcasted_dims_); right_padded_strides_.resize(num_broadcasted_dims_); @@ -214,6 +242,26 @@ class MatMulComputeHelper { RecursiveFill(0, 0, 0, 0); } + private: + void ComputeBroadcastOffsets(bool fill_offsets) { + num_broadcasted_dims_ = left_padded_dims_.size() - 2; + + if (num_broadcasted_dims_ == 0) { + left_offsets_ = {0}; + right_offsets_ = {0}; + output_offsets_ = {0}; + return; + } + + left_mat_size_ = M_ * K_ / left_stride_factor_; + right_mat_size_ = K_ * N_ / right_stride_factor_; + output_mat_size_ = M_ * N_; + + if (fill_offsets) { + FillOffsets(); + } + } + void RecursiveFill(size_t idx_dim, size_t idx_left, size_t idx_right, size_t idx_out) { if (idx_dim == num_broadcasted_dims_) { left_offsets_[idx_out] = idx_left * left_mat_size_; @@ -260,6 +308,11 @@ class MatMulComputeHelper { std::vector right_zp_offsets_; std::vector right_scale_offsets_; + size_t left_stride_factor_ = 1; + size_t right_stride_factor_ = 1; + int left_ld_factor_ = 1; + int right_ld_factor_ = 1; + public: // output shape const TensorShape& OutputShape() const { @@ -281,6 +334,18 @@ class MatMulComputeHelper { return K_; } + int Lda(bool is_trans) const { + return (is_trans ? static_cast(M_) : static_cast(K_)) * left_ld_factor_; + } + + int Ldb(bool is_trans) const { + return (is_trans ? static_cast(K_) : static_cast(N_)) * right_ld_factor_; + } + + int Ldc() const { + return static_cast(N_); + } + // Batched Gemm offsets in left matrices const std::vector& LeftOffsets() const { return left_offsets_; diff --git a/onnxruntime/core/providers/cuda/math/matmul.cc b/onnxruntime/core/providers/cuda/math/matmul.cc index 1a233aec96..c7632dcdc5 100644 --- a/onnxruntime/core/providers/cuda/math/matmul.cc +++ b/onnxruntime/core/providers/cuda/math/matmul.cc @@ -48,7 +48,7 @@ REGISTER_KERNEL_TYPED(BFloat16) // StridedBatchedGemm can be used for the following GEMM computation // C[pnm] = A[pnk]*B[km] or C[pnm] = A[pnk]*B[pkm] static bool CanUseStridedBatchedGemm(const TensorShape& left_shape, const TensorShape& right_shape, - bool transa, bool transb, + bool transa, bool transb, bool trans_batch_a, bool trans_batch_b, int64_t& stride_A, int64_t& stride_B, int64_t& stride_C, int64_t& batch_count) { size_t left_num_dims = left_shape.NumDimensions(); size_t right_num_dims = right_shape.NumDimensions(); @@ -57,25 +57,33 @@ static bool CanUseStridedBatchedGemm(const TensorShape& left_shape, const Tensor return false; } + size_t left_leading_axis = trans_batch_a ? 0 : left_num_dims - 2; + size_t right_leading_axis = trans_batch_b ? 0 : right_num_dims - 2; int64_t left_p = left_shape.SizeToDimension(left_num_dims - 2); - int64_t left_k = transa ? left_shape[left_num_dims - 2] : left_shape[left_num_dims - 1]; + if (trans_batch_a) { + left_p = left_p * left_shape[left_num_dims - 2] / left_shape[0]; + } + int64_t left_k = transa ? left_shape[left_leading_axis] : left_shape[left_num_dims - 1]; if (right_num_dims >= 3) { int64_t right_p = right_shape.SizeToDimension(right_num_dims - 2); + if (trans_batch_b) { + right_p = right_p * right_shape[right_num_dims - 2] / right_shape[0]; + } if (left_p != right_p) { return false; } } - int64_t right_k = transb ? right_shape[right_num_dims - 1] : right_shape[right_num_dims - 2]; + int64_t right_k = transb ? right_shape[right_num_dims - 1] : right_shape[right_leading_axis]; if (left_k != right_k) { return false; } - int64_t n = transa ? left_shape[left_num_dims - 1] : left_shape[left_num_dims - 2]; - int64_t m = transb ? right_shape[right_num_dims - 2] : right_shape[right_num_dims - 1]; - stride_A = n * left_k; - stride_B = right_num_dims == 2 ? 0 : right_k * m; + int64_t n = transa ? left_shape[left_num_dims - 1] : left_shape[left_leading_axis]; + int64_t m = transb ? right_shape[right_leading_axis] : right_shape[right_num_dims - 1]; + stride_A = n * left_k / (trans_batch_a ? left_shape[0] : 1); + stride_B = right_num_dims == 2 ? 0 : right_k * m / (trans_batch_b ? right_shape[0] : 1); stride_C = n * m; batch_count = left_p; return true; @@ -100,7 +108,7 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { } MatMulComputeHelper helper; - ORT_RETURN_IF_ERROR(helper.Compute(left_X->Shape(), right_X->Shape(), transa, transb)); + ORT_RETURN_IF_ERROR(helper.Compute(left_X->Shape(), right_X->Shape(), transa, transb, trans_batch_a_, trans_batch_b_, false)); Tensor* Y = ctx->Output(0, helper.OutputShape()); @@ -113,9 +121,9 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { cublasOperation_t transA = transa ? CUBLAS_OP_T : CUBLAS_OP_N; cublasOperation_t transB = transb ? CUBLAS_OP_T : CUBLAS_OP_N; - const int lda = transa ? static_cast(helper.M()) : static_cast(helper.K()); - const int ldb = transb ? static_cast(helper.K()) : static_cast(helper.N()); - const int ldc = static_cast(helper.N()); + const int lda = helper.Lda(transa); + const int ldb = helper.Ldb(transb); + const int ldc = helper.Ldc(); int64_t stride_A, stride_B, stride_C, batch_count; auto& device_prop = GetDeviceProp(); if (helper.OutputOffsets().size() == 1) { @@ -137,7 +145,7 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { device_prop)); return Status::OK(); } else if (CanUseStridedBatchedGemm(left_X->Shape(), right_X->Shape(), - transa, transb, stride_A, stride_B, stride_C, batch_count)) { + transa, transb, trans_batch_a_, trans_batch_b_, stride_A, stride_B, stride_C, batch_count)) { CUBLAS_RETURN_IF_ERROR(cublasGemmStridedBatchedHelper(Base::CublasHandle(), transB, transA, @@ -161,6 +169,8 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { return Status::OK(); } + // Fill offsets when needed. + helper.FillOffsets(); CudaAsyncBuffer left_arrays(this, helper.LeftOffsets().size()); CudaAsyncBuffer right_arrays(this, helper.RightOffsets().size()); CudaAsyncBuffer output_arrays(this, helper.OutputOffsets().size()); diff --git a/onnxruntime/core/providers/cuda/math/matmul.h b/onnxruntime/core/providers/cuda/math/matmul.h index ac3d863e44..f857fa1ee2 100644 --- a/onnxruntime/core/providers/cuda/math/matmul.h +++ b/onnxruntime/core/providers/cuda/math/matmul.h @@ -16,8 +16,9 @@ class MatMul final : public CudaKernel { : CudaKernel(info), alpha_{info.GetAttrOrDefault("alpha", 1.0f)}, trans_A_{info.GetAttrOrDefault("transA", 0) != 0}, - trans_B_{info.GetAttrOrDefault("transB", 0) != 0} { - } + trans_B_{info.GetAttrOrDefault("transB", 0) != 0}, + trans_batch_a_{info.GetAttrOrDefault("transBatchA", 0) != 0}, + trans_batch_b_{info.GetAttrOrDefault("transBatchB", 0) != 0} {} Status ComputeInternal(OpKernelContext* context) const override; @@ -25,6 +26,8 @@ class MatMul final : public CudaKernel { const float alpha_; const bool trans_A_; const bool trans_B_; + const bool trans_batch_a_; + const bool trans_batch_b_; }; } // namespace cuda } // namespace onnxruntime diff --git a/onnxruntime/core/providers/rocm/math/matmul.cc b/onnxruntime/core/providers/rocm/math/matmul.cc index 0329917f3d..4e6e8a125d 100644 --- a/onnxruntime/core/providers/rocm/math/matmul.cc +++ b/onnxruntime/core/providers/rocm/math/matmul.cc @@ -45,7 +45,7 @@ REGISTER_KERNEL_TYPED(MLFloat16) // StridedBatchedGemm can be used for the following GEMM computation // C[pnm] = A[pnk]*B[km] or C[pnm] = A[pnk]*B[pkm] static bool CanUseStridedBatchedGemm(const TensorShape& left_shape, const TensorShape& right_shape, - bool transa, bool transb, + bool transa, bool transb, bool trans_batch_a, bool trans_batch_b, int64_t& stride_A, int64_t& stride_B, int64_t& stride_C, int64_t& batch_count) { size_t left_num_dims = left_shape.NumDimensions(); size_t right_num_dims = right_shape.NumDimensions(); @@ -54,25 +54,33 @@ static bool CanUseStridedBatchedGemm(const TensorShape& left_shape, const Tensor return false; } + size_t left_leading_axis = trans_batch_a ? 0 : left_num_dims - 2; + size_t right_leading_axis = trans_batch_b ? 0 : right_num_dims - 2; int64_t left_p = left_shape.SizeToDimension(left_num_dims - 2); - int64_t left_k = transa ? left_shape[left_num_dims - 2] : left_shape[left_num_dims - 1]; + if (trans_batch_a) { + left_p = left_p * left_shape[left_num_dims - 2] / left_shape[0]; + } + int64_t left_k = transa ? left_shape[left_leading_axis] : left_shape[left_num_dims - 1]; if (right_num_dims >= 3) { int64_t right_p = right_shape.SizeToDimension(right_num_dims - 2); + if (trans_batch_b) { + right_p = right_p * right_shape[right_num_dims - 2] / right_shape[0]; + } if (left_p != right_p) { return false; } } - int64_t right_k = transb ? right_shape[right_num_dims - 1] : right_shape[right_num_dims - 2]; + int64_t right_k = transb ? right_shape[right_num_dims - 1] : right_shape[right_leading_axis]; if (left_k != right_k) { return false; } - int64_t n = transa ? left_shape[left_num_dims - 1] : left_shape[left_num_dims - 2]; - int64_t m = transb ? right_shape[right_num_dims - 2] : right_shape[right_num_dims - 1]; - stride_A = n * left_k; - stride_B = right_num_dims == 2 ? 0 : right_k * m; + int64_t n = transa ? left_shape[left_num_dims - 1] : left_shape[left_leading_axis]; + int64_t m = transb ? right_shape[right_leading_axis] : right_shape[right_num_dims - 1]; + stride_A = n * left_k / (trans_batch_a ? left_shape[0] : 1); + stride_B = right_num_dims == 2 ? 0 : right_k * m / (trans_batch_b ? right_shape[0] : 1); stride_C = n * m; batch_count = left_p; return true; @@ -97,7 +105,7 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { } MatMulComputeHelper helper; - ORT_RETURN_IF_ERROR(helper.Compute(left_X->Shape(), right_X->Shape(), transa, transb)); + ORT_RETURN_IF_ERROR(helper.Compute(left_X->Shape(), right_X->Shape(), transa, transb, trans_batch_a_, trans_batch_b_, false)); Tensor* Y = ctx->Output(0, helper.OutputShape()); @@ -110,9 +118,9 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { rocblas_operation transA = transa ? rocblas_operation_transpose : rocblas_operation_none; rocblas_operation transB = transb ? rocblas_operation_transpose : rocblas_operation_none; - const int lda = transa ? static_cast(helper.M()) : static_cast(helper.K()); - const int ldb = transb ? static_cast(helper.K()) : static_cast(helper.N()); - const int ldc = static_cast(helper.N()); + const int lda = helper.Lda(transa); + const int ldb = helper.Ldb(transb); + const int ldc = helper.Ldc(); int64_t stride_A, stride_B, stride_C, batch_count; if (helper.OutputOffsets().size() == 1) { @@ -133,7 +141,7 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { ldc)); return Status::OK(); } else if (CanUseStridedBatchedGemm(left_X->Shape(), right_X->Shape(), - transa, transb, stride_A, stride_B, stride_C, batch_count)) { + transa, transb, trans_batch_a_, trans_batch_b_, stride_A, stride_B, stride_C, batch_count)) { ROCBLAS_RETURN_IF_ERROR(rocblasGemmStridedBatchedHelper(Base::RocblasHandle(), transB, transA, @@ -155,6 +163,8 @@ Status MatMul::ComputeInternal(OpKernelContext* ctx) const { return Status::OK(); } + // Fill offsets when needed. + helper.FillOffsets(); RocmAsyncBuffer left_arrays(this, helper.LeftOffsets().size()); RocmAsyncBuffer right_arrays(this, helper.RightOffsets().size()); RocmAsyncBuffer output_arrays(this, helper.OutputOffsets().size()); diff --git a/onnxruntime/test/contrib_ops/fused_matmul_op_test.cc b/onnxruntime/test/contrib_ops/fused_matmul_op_test.cc index 7bf3fc676d..c1c7a75a18 100644 --- a/onnxruntime/test/contrib_ops/fused_matmul_op_test.cc +++ b/onnxruntime/test/contrib_ops/fused_matmul_op_test.cc @@ -91,71 +91,121 @@ std::vector> GenerateSimpleTestCases() { {0, 4}, {}}); + test_cases.push_back( + {"test 4D", + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 3, 6, 11, 46, 55, 66, 79, 154, 171, 190, 211, 326, 351, 378, 407}}); + + test_cases.push_back( + {"test 4D and broadcast", + {1, 2, 3, 2}, + {3, 2, 2, 1}, + {3, 2, 3, 1}, + {1, 3, 5, 33, 43, 53, 5, 23, 41, 85, 111, 137, 9, 43, 77, 137, 179, 221}}); + return test_cases; } -/* Transpose the last two dimentions */ +// [batch,N,M]->[batch,M,N] template -static void Transpose(const std::vector& src, std::vector& dst, const int64_t batch, const int64_t N, const int64_t M) { - for (int64_t b = 0; b < batch; b++) { - for (int64_t n = 0; n < N * M; n++) { - int64_t i = n / N; - int64_t j = n % N; - dst[b * N * M + n] = src[b * N * M + M * j + i]; +static void Transpose(const std::vector& src, std::vector& dst, size_t batch, size_t N, size_t M) { + for (size_t b = 0; b < batch; b++) { + for (size_t n = 0; n < N * M; n++) { + dst[b * N * M + n] = src[b * N * M + M * (n % N) + n / N]; + } + } +} + +// [batch,N,M]->[N,batch,M] +template +static void TransposeBatch(const std::vector& src, std::vector& dst, size_t batch, size_t N, size_t M) { + for (size_t i = 0; i < batch * N; ++i) { + size_t src_pos = ((i % batch) * N + i / batch) * M; + size_t dst_pos = i * M; + for (size_t j = 0; j < M; j++) { + dst[dst_pos + j] = src[src_pos + j]; } } } template -void ProcessInputs(const std::vector& input_dims, const std::vector& common_input_vals, bool trans_flag, - std::vector& modified_input_dims, std::vector& input_vals) { - auto rank = input_dims.size(); - ORT_ENFORCE(rank >= 1); - int64_t size0 = TensorShape::FromExistingBuffer(input_dims).SizeHelper(0, rank); - std::vector input_vals_raw(common_input_vals.cbegin(), common_input_vals.cbegin() + size0); - input_vals.resize(size0); - - // transpose on 1-d does not take any effect. - if (rank == 1) { - trans_flag = false; +static void TransposeInput(const std::vector& src, std::vector& dst, const std::vector& dims, + std::vector& new_dims, bool is_trans, bool is_trans_batch) { + if (dims.size() < 2 || (!is_trans && !is_trans_batch)) return; + ORT_ENFORCE(!is_trans_batch || dims.size() >= 3); + size_t batch = 1; + size_t size = dims.size(); + new_dims.resize(size); + for (size_t i = 0; i < size - 2; ++i) { + batch *= static_cast(dims[i]); + new_dims[i + (is_trans_batch ? 1 : 0)] = dims[i]; } - - if (trans_flag) { - modified_input_dims[rank - 1] = input_dims[rank - 2]; - modified_input_dims[rank - 2] = input_dims[rank - 1]; - auto batch_size = TensorShape::FromExistingBuffer(input_dims).SizeHelper(0, rank - 2); - Transpose(input_vals_raw, input_vals, batch_size, input_dims[rank - 2], input_dims[rank - 1]); + size_t N = static_cast(dims[size - 2]); + size_t M = static_cast(dims[size - 1]); + if (is_trans && !is_trans_batch) { + new_dims[size - 1] = dims[size - 2]; + new_dims[size - 2] = dims[size - 1]; + Transpose(src, dst, batch, N, M); + } else if (!is_trans && is_trans_batch) { + new_dims[0] = dims[size - 2]; + TransposeBatch(src, dst, batch, N, M); } else { - input_vals = input_vals_raw; + new_dims[size - 1] = dims[size - 2]; + new_dims[0] = dims[size - 1]; + std::vector intermediate(src.size()); + Transpose(src, intermediate, batch, N, M); // [batch,N,M]->[batch,M,N] + TransposeBatch(intermediate, dst, batch, M, N); // [batch,M,N]->[M,batch,N] } } template -void RunFusedMatMulTest(const char* op_name, int32_t opset_version = 7, bool transa = false, bool transb = false, float alpha = 1.0f, bool is_b_constant = false) { - std::vector common_input_vals{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +void ProcessInputs(const std::vector& input_dims, const std::vector& common_input_vals, bool is_trans, + bool is_trans_batch, std::vector& modified_input_dims, std::vector& input_vals) { + auto rank = input_dims.size(); + ORT_ENFORCE(rank >= 1); + int64_t size0 = TensorShape::FromExistingBuffer(input_dims).SizeHelper(0, rank); + std::vector input_vals_raw(common_input_vals.cbegin(), common_input_vals.cbegin() + size0); + input_vals = input_vals_raw; + TransposeInput(input_vals_raw, input_vals, input_dims, modified_input_dims, is_trans, is_trans_batch); +} + +template +void RunFusedMatMulTest(const char* op_name, int32_t opset_version = 7, bool transa = false, bool transb = false, + bool is_trans_batch_a = false, bool is_trans_batch_b = false, float alpha = 1.0f, + bool is_b_constant = false) { + std::vector common_input_vals{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; for (auto t : GenerateSimpleTestCases()) { + // is_trans_batch requires dim_size >= 3 and same dim size in both sides. + if (is_trans_batch_a || is_trans_batch_b) { + if (t.input0_dims.size() < 3 || t.input0_dims.size() != t.input1_dims.size()) { + continue; + } + } + OpTester test(op_name, opset_version, onnxruntime::kMSDomain); std::vector input0_dims(t.input0_dims); std::vector input0_vals; - ProcessInputs(t.input0_dims, common_input_vals, transa, input0_dims, input0_vals); + ProcessInputs(t.input0_dims, common_input_vals, transa, is_trans_batch_a, input0_dims, input0_vals); std::vector input1_dims(t.input1_dims); std::vector input1_vals; - ProcessInputs(t.input1_dims, common_input_vals, transb, input1_dims, input1_vals); + ProcessInputs(t.input1_dims, common_input_vals, transb, is_trans_batch_b, input1_dims, input1_vals); test.AddInput("A", input0_dims, input0_vals); - test.AddInput("B", input1_dims, input1_vals, is_b_constant); test.AddAttribute("transA", (int64_t)transa); test.AddAttribute("transB", (int64_t)transb); + test.AddAttribute("transBatchA", (int64_t)is_trans_batch_a); + test.AddAttribute("transBatchB", (int64_t)is_trans_batch_b); test.AddAttribute("alpha", alpha); if (alpha != 1.0f) { - std::transform( - t.expected_vals.begin(), t.expected_vals.end(), t.expected_vals.begin(), - [alpha](const T& val) -> T { return alpha * val; }); + std::transform(t.expected_vals.begin(), t.expected_vals.end(), t.expected_vals.begin(), + [alpha](const T& val) -> T { return alpha * val; }); } test.AddOutput("Y", t.expected_dims, t.expected_vals); @@ -183,25 +233,40 @@ TEST(FusedMatMulOpTest, FloatTypeTransposeA) { TEST(FusedMatMulOpTest, FloatTypeTransposeB) { RunFusedMatMulTest("FusedMatMul", 1, false, true); // b is constant. This tests weight packing logic - RunFusedMatMulTest("FusedMatMul", 1, false, true, 1.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, false, true, false, false, 1.0f, true); } TEST(FusedMatMulOpTest, FloatTypeTransposeAB) { RunFusedMatMulTest("FusedMatMul", 1, true, true); // b is constant. This tests weight packing logic - RunFusedMatMulTest("FusedMatMul", 1, true, true, 1.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, true, true, false, false, 1.0f, true); } TEST(FusedMatMulOpTest, FloatTypeScale) { - RunFusedMatMulTest("FusedMatMul", 1, false, false, 0.5f); - RunFusedMatMulTest("FusedMatMul", 1, true, false, 2.0f); - RunFusedMatMulTest("FusedMatMul", 1, true, true, 4.0f); + RunFusedMatMulTest("FusedMatMul", 1, false, false, false, false, 0.5f); + RunFusedMatMulTest("FusedMatMul", 1, true, false, false, false, 2.0f); + RunFusedMatMulTest("FusedMatMul", 1, true, true, false, false, 4.0f); // now run tests with b constant. - RunFusedMatMulTest("FusedMatMul", 1, false, false, 0.5f, true); - RunFusedMatMulTest("FusedMatMul", 1, true, false, 2.0f, true); - RunFusedMatMulTest("FusedMatMul", 1, true, true, 4.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, false, false, false, false, 0.5f, true); + RunFusedMatMulTest("FusedMatMul", 1, true, false, false, false, 2.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, true, true, false, false, 4.0f, true); +} + +TEST(FusedMatMulOpTest, FloatTypeTransposeBatch) { + RunFusedMatMulTest("FusedMatMul", 1, false, false, true, false); + RunFusedMatMulTest("FusedMatMul", 1, false, false, false, true); + RunFusedMatMulTest("FusedMatMul", 1, false, false, true, true, 0.5f); + RunFusedMatMulTest("FusedMatMul", 1, true, false, true, false); + RunFusedMatMulTest("FusedMatMul", 1, true, false, false, true); + RunFusedMatMulTest("FusedMatMul", 1, true, false, true, true); + RunFusedMatMulTest("FusedMatMul", 1, false, true, true, false); + RunFusedMatMulTest("FusedMatMul", 1, false, true, false, true, 1.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, false, true, true, true); + RunFusedMatMulTest("FusedMatMul", 1, true, true, true, false, 2.0f, true); + RunFusedMatMulTest("FusedMatMul", 1, true, true, false, true); + RunFusedMatMulTest("FusedMatMul", 1, true, true, true, true); } } // namespace transpose_matmul diff --git a/onnxruntime/test/optimizer/graph_transform_test.cc b/onnxruntime/test/optimizer/graph_transform_test.cc index abc080a31a..34920c043c 100644 --- a/onnxruntime/test/optimizer/graph_transform_test.cc +++ b/onnxruntime/test/optimizer/graph_transform_test.cc @@ -1178,6 +1178,76 @@ TEST_F(GraphTransformationTests, TransposeMatmulFusionWithPreservedTranspose) { ASSERT_FALSE(graph.GraphResolveNeeded()); } +TEST_F(GraphTransformationTests, TransposeMatmulTransBatchFusion) { + const std::vector model_uris = { + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion1.onnx", + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion2.onnx", + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion3.onnx", + }; + const std::vector> trans_batch_attrs = { + {1, 0}, + {1, 1}, + {1, 1}, + }; + size_t index = 0; + for (const auto& model_uri : model_uris) { + std::shared_ptr p_model; + ASSERT_STATUS_OK(Model::Load(model_uri, p_model, nullptr, *logger_)); + Graph& graph = p_model->MainGraph(); + + onnxruntime::GraphTransformerManager graph_transformation_mgr{5}; + ASSERT_STATUS_OK(graph_transformation_mgr.Register( + std::make_unique(), TransformerLevel::Level1)); + ASSERT_STATUS_OK(graph_transformation_mgr.ApplyTransformers(graph, TransformerLevel::Level1, *logger_)); + + std::map op_to_count = CountOpsInGraph(graph); + ASSERT_EQ(op_to_count["Transpose"], 0); + ASSERT_EQ(op_to_count["MatMul"], 0); + ASSERT_EQ(op_to_count["com.microsoft.FusedMatMul"], 1); + for (auto& node : graph.Nodes()) { + if (node.OpType() == "FusedMatMul") { + auto attrs = node.GetAttributes(); + int64_t trans_batch_a = 0; + if (attrs.find("transBatchA") != attrs.end()) { + trans_batch_a = attrs.at("transBatchA").i(); + } + int64_t trans_batch_b = 0; + if (attrs.find("transBatchB") != attrs.end()) { + trans_batch_b = attrs.at("transBatchB").i(); + } + ASSERT_EQ(trans_batch_a, trans_batch_attrs[index].first); + ASSERT_EQ(trans_batch_b, trans_batch_attrs[index].second); + break; + } + } + ++index; + } +} + +TEST_F(GraphTransformationTests, TransposeMatmulTransBatchNoFusion) { + const std::vector model_uris = { + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion_invalid_case1.onnx", + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion_invalid_case2.onnx", + MODEL_FOLDER "fusion/transpose_matmul_trans_batch_fusion_invalid_case3.onnx", + }; + for (const auto& model_uri : model_uris) { + std::shared_ptr p_model; + ASSERT_STATUS_OK(Model::Load(model_uri, p_model, nullptr, *logger_)); + Graph& graph = p_model->MainGraph(); + std::map orig_op_to_count = CountOpsInGraph(graph); + + onnxruntime::GraphTransformerManager graph_transformation_mgr{5}; + ASSERT_STATUS_OK(graph_transformation_mgr.Register( + std::make_unique(), TransformerLevel::Level1)); + ASSERT_STATUS_OK(graph_transformation_mgr.ApplyTransformers(graph, TransformerLevel::Level1, *logger_)); + + std::map op_to_count = CountOpsInGraph(graph); + ASSERT_EQ(op_to_count["Transpose"], orig_op_to_count["Transpose"]); + ASSERT_EQ(op_to_count["MatMul"], orig_op_to_count["MatMul"]); + ASSERT_EQ(op_to_count["com.microsoft.FusedMatMul"], orig_op_to_count["com.microsoft.FusedMatMul"]); + } +} + TEST_F(GraphTransformationTests, Gemm_LeakyRelu_Fusion) { auto model_uri = MODEL_FOLDER "gemm_activation_fusion/gemm_activation_fusion.onnx"; diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_gen.py b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_gen.py index 1f2bc05551..2904a618bb 100644 --- a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_gen.py +++ b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_gen.py @@ -252,3 +252,190 @@ def gen_transpose_fusion_invalid_datatype(model_path, datatype): gen_transpose_fusion_invalid_datatype("transpose_matmul_4d_fusion_invalid_datatype_int32.onnx", TensorProto.INT32) gen_transpose_fusion_invalid_datatype("transpose_matmul_4d_fusion_invalid_datatype_int64.onnx", TensorProto.INT64) + + +def gen_transpose_matmul_trans_batch_fusion(model_path): + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [1, 2, 0]), + helper.make_node( + "Transpose", + ["input_1"], + ["transposed_input_1"], + perm = [0, 2, 1]), + helper.make_node( + "MatMul", + ["transposed_input_0", "transposed_input_1"], + ["output"]) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, ['K', 3, 'M']), + helper.make_tensor_value_info( + "input_1", TensorProto.FLOAT, [3, 'N', 'K']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [3, 'M', 'N']) + ] + + save(model_path + "1.onnx", nodes, inputs, outputs, []) + + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [1, 2, 0, 3]), + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_1"], + perm = [1, 2, 3, 0]), + helper.make_node( + "MatMul", + ["transposed_input_0", "transposed_input_1"], + ["output"]) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, ['M', 2, 3, 'K']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [2, 3, 'M', 'M']) + ] + + save(model_path + "2.onnx", nodes, inputs, outputs, []) + + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [1, 2, 3, 0]), + helper.make_node( + "FusedMatMul", + ["transposed_input_0", "input_1"], + ["output"], + "FusedMatMul", + "", + msdomain.domain, + alpha=3.0, transA=1, transBatchB=1) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, ['M', 2, 3, 'K']), + helper.make_tensor_value_info( + "input_1", TensorProto.FLOAT, ['K', 2, 3, 'N']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [2, 3, 'M', 'M']) + ] + + save(model_path + "3.onnx", nodes, inputs, outputs, []) + + +gen_transpose_matmul_trans_batch_fusion( + "transpose_matmul_trans_batch_fusion") + + +def gen_transpose_matmul_trans_batch_fusion_invalid_cases(model_path): + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [1, 2, 0]), + helper.make_node( + "MatMul", + ["transposed_input_0", "input_1"], + ["output"]) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, ['K', 3, 'M']), + helper.make_tensor_value_info( + "input_1", TensorProto.FLOAT, [2, 3, 'K', 'N']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [2, 3, 'M', 'N']) + ] + + save(model_path + "1.onnx", nodes, inputs, outputs, []) + + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [0, 2, 1, 3]), + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_1"], + perm = [0, 2, 3, 1]), + helper.make_node( + "MatMul", + ["transposed_input_0", "transposed_input_1"], + ["output"]) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, [2, 'M', 3, 'K']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [2, 3, 'M', 'M']) + ] + + save(model_path + "2.onnx", nodes, inputs, outputs, []) + + nodes = [ + helper.make_node( + "Transpose", + ["input_0"], + ["transposed_input_0"], + perm = [1, 2, 3, 0]), + helper.make_node( + "FusedMatMul", + ["transposed_input_0", "input_1"], + ["output"], + "FusedMatMul", + "", + msdomain.domain, + alpha=3.0, transBatchA=1) + ] + + inputs = [ + helper.make_tensor_value_info( + "input_0", TensorProto.FLOAT, ['K', 'M', 2, 3]), + helper.make_tensor_value_info( + "input_1", TensorProto.FLOAT, [2, 3, 'K', 'N']), + ] + + outputs = [ + helper.make_tensor_value_info( + "output", TensorProto.FLOAT, [2, 3, 'M', 'M']) + ] + + save(model_path + "3.onnx", nodes, inputs, outputs, []) + + +gen_transpose_matmul_trans_batch_fusion_invalid_cases( + "transpose_matmul_trans_batch_fusion_invalid_case") diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion1.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion1.onnx new file mode 100644 index 0000000000000000000000000000000000000000..ff11d6f26368624090773f3b226d56d48a1e2f37 GIT binary patch literal 343 zcmd;J7ZS+N%d03V%`3^wP1P+)EiSQI&ctQO#h#g0P+AgiAS6^$l$cjskYAjd5)Tzq z;tYX_Y4LNh6r>jAIxspgIWR0>WJhQ<#G=&@n^p#(Rz{Fk3oa~{VG%PFV#_Zr0Xk2K z%{Q^cw=_pc815j5KnTzuQSt~+h;RvUFbeT;F$*zzb1`u+gBZRD1%^T}1yDIZu*xJk mE~rK5^1dK>KPMJ01_2%?K`!3p{9L`<%;ci{;{3D{0Y(5{fLr|l literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion2.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion2.onnx new file mode 100644 index 0000000000000000000000000000000000000000..1266ca28fdb9a3e2188a090c9723699dc4976673 GIT binary patch literal 322 zcmd;J7ZS+N%d03V%`3^wP1P+)EiSQ|#KdLI#h#g0P+AgiAS6^$l$cjskYAjd5)Tzq z;tYX_X$f+%6r>jAIxspgIWRadFJNTHuh|fnW@ZNlkY)=mEEZxBGZbRWFD(H&QHjkr zvBbADM@Sg%D2PA^&@WNS2#-i`iE%Ir32`wCG5T^baWDZfGl=7zq{Ia^O9-Y0N!k~z e!HI>7L4e0ekc&4tKUXg|Gr1_gI6tjKfDr(CELa-= literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion3.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion3.onnx new file mode 100644 index 0000000000000000000000000000000000000000..741c73cced82c4adf6fa517936ad6d886851f24e GIT binary patch literal 373 zcmZvXK~IA~5QUkg7M$8h$7mXlcq7rY*Lqnwcxmv|lb2>iOi9Wvf!V~fzl1;I{}QoO zOgzlty}bG6jqg!lw0^Iw=Df&mIjec~DexY>T$h%&3nH$Ru1iyAuiJwco^EXLPAVQZQLE(#b+;6e| g4K0VE^)U4G65`>DV`jieI%+&ZCpe2|__tXAUjV*d!vFvP literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case1.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case1.onnx new file mode 100644 index 0000000000000000000000000000000000000000..65f31f641afa183a18a30afec1020a64516d26b4 GIT binary patch literal 281 zcmd;J7ZS+N%d03V%`3^wP1P+)EiSQo$;f5N#h#g0P+AgiAS6^$l$cjskYAjd5)Tzq z;tYX_Y4LNh6r>jAIxspgIWR0>WarZ5!lDCaoS_g~erXBNU?n!+#1h}q93f%2Q4oO; zpbMhpVd@QpM7V@F7=`$_n1vXGlDNr?+; j88$V(U^PxGTnqv{PJ&##$@#f@xtYmD`NjEZB?629s@Fy6 literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case2.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case2.onnx new file mode 100644 index 0000000000000000000000000000000000000000..a2ea9b758a20943081b8848370c98dac0a87149b GIT binary patch literal 322 zcmd;J7ZS+N%d03V%`3^wP1P+)EiSQ|#KdLI#h#g0P+AgiAS6^$l$cjskYAjd5)Tzq z;tYX_X$f+%6r>jAIxsjeIWRgfFJNTHuh|fnW@ZOQkY)=mEEZxBGZbRWFD(H&QHjkr zvBbADM@Sg%D2PA^&@WNS2#-i`iE%Ir32`xTFmW*pG5P`-%pit$k`foxEFokyP-$PV eVkZ_Z1_2%?K`!3p{9L`<%;ci{;{3D{0Y(6L+*lg` literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case3.onnx b/onnxruntime/test/testdata/transform/fusion/transpose_matmul_trans_batch_fusion_invalid_case3.onnx new file mode 100644 index 0000000000000000000000000000000000000000..76e09a048d1e59cf12b332cd89173eca2eaaeb32 GIT binary patch literal 357 zcmd;J7ZS+N%d03V%`3^wP1P+)EiSRz%EV>O#h#g0P+AgiAS6^$l$cjskYAjd5)Tzq z;tYX_X$f+%6r>jAIxspgIWRjgEMR2kD(1qX2WFt55LBxg8EFfL$Zvf@q7&(+J#OfJeV&QB{5 z5{5eoVqyr;CsE2UTMdLHxWqUZg@m}6g&4g-gfABp2NMu8BNQ3J6+xxoiv5z5xS-C) Wrp6a+pc4xhg8+|{AQ!631Q-DbSX(v# literal 0 HcmV?d00001 From 3d6786c92e0abc672d23a8b17171c14c11521902 Mon Sep 17 00:00:00 2001 From: George Wu Date: Mon, 27 Dec 2021 15:43:27 -0800 Subject: [PATCH 072/113] update tensorrt multi gpu pipeline to tensorrt 8.2 (#10141) --- .../github/linux/docker/Dockerfile.ubuntu_tensorrt | 8 ++++---- tools/ci_build/github/linux/run_dockerbuild.sh | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_tensorrt b/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_tensorrt index e8d057878e..b3d1d8c81b 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_tensorrt +++ b/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_tensorrt @@ -1,8 +1,8 @@ -# Tag: nvcr.io/nvidia/tensorrt:21.07-py3 -# Label: com.nvidia.cuda.version: 11.4.0 -# Label: com.nvidia.cudnn.version: 8.2.2.26 +# Tag: nvcr.io/nvidia/tensorrt:21.12-py3 +# Label: com.nvidia.cuda.version: 11.5.0 +# Label: com.nvidia.cudnn.version: 8.3.1.22 # Ubuntu 20.04 -FROM nvcr.io/nvidia/tensorrt:21.07-py3 +FROM nvcr.io/nvidia/tensorrt:21.12-py3 ARG PYTHON_VERSION=3.8 ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/ci_build/github/linux/run_dockerbuild.sh b/tools/ci_build/github/linux/run_dockerbuild.sh index 5e76e435c0..d0748e96ae 100755 --- a/tools/ci_build/github/linux/run_dockerbuild.sh +++ b/tools/ci_build/github/linux/run_dockerbuild.sh @@ -100,8 +100,8 @@ elif [[ $BUILD_DEVICE = "tensorrt"* ]]; then IMAGE="$BUILD_OS-cuda11.0-cudnn8.0-tensorrt7.1" DOCKER_FILE=Dockerfile.ubuntu_tensorrt7_1 else - # TensorRT container release 21.07 - IMAGE="$BUILD_OS-cuda11.4-cudnn8.2-tensorrt8.0" + # TensorRT container release 21.12 + IMAGE="$BUILD_OS-cuda11.5-cudnn8.3-tensorrt8.2" DOCKER_FILE=Dockerfile.ubuntu_tensorrt fi $GET_DOCKER_IMAGE_CMD --repository "onnxruntime-$IMAGE" \ From a367f0664d831d4fb2557e8d63fc09d67d7386fe Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Tue, 28 Dec 2021 16:10:26 +1000 Subject: [PATCH 073/113] From Python 3.8 and on you need to explicitly add the current directory for libraries to be loaded from it. Update onnxruntime_test_python.py with that handling. (#10129) --- .../test/python/onnxruntime_test_python.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/onnxruntime/test/python/onnxruntime_test_python.py b/onnxruntime/test/python/onnxruntime_test_python.py index 8618431ec7..2e28b49b4d 100644 --- a/onnxruntime/test/python/onnxruntime_test_python.py +++ b/onnxruntime/test/python/onnxruntime_test_python.py @@ -2,17 +2,23 @@ # Licensed under the MIT License. # -*- coding: UTF-8 -*- -import unittest -import os -import numpy as np import gc - +import numpy as np import onnxruntime as onnxrt -import threading +import os +import platform import sys +import threading +import unittest + from helper import get_name from onnxruntime.capi.onnxruntime_pybind11_state import Fail +# handle change from python 3.8 and on where loading a dll from the current directory needs to be explicitly allowed. +if platform.system() == 'Windows' and sys.version_info.major >= 3 and sys.version_info.minor >= 8: + os.add_dll_directory(os.getcwd()) + + class TestInferenceSession(unittest.TestCase): def run_model(self, session_object, run_options): @@ -887,7 +893,7 @@ class TestInferenceSession(unittest.TestCase): def testOrtValue_ghIssue9799(self): if 'CUDAExecutionProvider' in onnxrt.get_available_providers(): - session = onnxrt.InferenceSession(get_name("identity_9799.onnx"), + session = onnxrt.InferenceSession(get_name("identity_9799.onnx"), providers=onnxrt.get_available_providers()) for seq_length in range(40, 200): @@ -1105,7 +1111,7 @@ class TestInferenceSession(unittest.TestCase): else: shared_library = './libtest_execution_provider.so' - + if not os.path.exists(shared_library): raise FileNotFoundError("Unable to find '{0}'".format(shared_library)) @@ -1116,9 +1122,9 @@ class TestInferenceSession(unittest.TestCase): session_options = C.get_default_session_options() sess = C.InferenceSession(session_options, custom_op_model, True, True) - sess.initialize_session(['my_ep'], + sess.initialize_session(['my_ep'], [{'shared_lib_path': shared_library, - 'device_id':'1', 'some_config':'val'}], + 'device_id':'1', 'some_config':'val'}], set()) print("Create session with customize execution provider successfully!") From 3bc91c2151823830df83dbdc4a5d0a36df932b4e Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Tue, 28 Dec 2021 19:04:20 -0800 Subject: [PATCH 074/113] Move reduced ops files into build directory (#10030) In a reduced ops build, some source files get updated. This change moves the updated files into the build directory. This way, it is easier to simultaneously manage different build directories (with possibly different reduced ops configurations) based on a single source directory. --- .gitignore | 8 -- cmake/CMakeLists.txt | 4 - cmake/onnxruntime_providers.cmake | 78 +++++++++++-- docs/Reduced_Operator_Kernel_build.md | 16 ++- .../contrib_ops/cpu/cpu_contrib_kernels.cc | 12 -- .../contrib_ops/cuda/cuda_contrib_kernels.cc | 12 -- .../providers/cpu/cpu_execution_provider.cc | 12 -- .../providers/cuda/cuda_execution_provider.cc | 12 -- .../core/providers/op_kernel_type_control.h | 13 --- .../internal_testing_partitioning_tests.cc | 4 + .../internal_testing_tests.cc | 4 + .../training_ops/cpu/cpu_training_kernels.cc | 12 -- .../cuda/cuda_training_kernels.cc | 12 -- tools/ci_build/build.py | 23 ++-- .../linux-cpu-minimal-build-ci-pipeline.yml | 20 ---- .../build_full_ort_and_create_ort_files.sh | 4 +- tools/ci_build/reduce_op_kernels.py | 110 +++++++++++------- 17 files changed, 173 insertions(+), 183 deletions(-) diff --git a/.gitignore b/.gitignore index 418e30eed1..be2375d256 100644 --- a/.gitignore +++ b/.gitignore @@ -60,11 +60,3 @@ onnxruntime/python/version_info.py .envrc .psenvrc *.csproj.user -# exclude generated reduced kernel registration and type control -onnxruntime/contrib_ops/cpu/cpu_contrib_kernels_reduced_ops.cc -onnxruntime/core/providers/cpu/cpu_execution_provider_reduced_ops.cc -orttraining/orttraining/training_ops/cpu/cpu_training_kernels_reduced_ops.cc -onnxruntime/contrib_ops/cuda/cuda_contrib_kernels_reduced_ops.cc -onnxruntime/core/providers/cuda/cuda_execution_provider_reduced_ops.cc -orttraining/orttraining/training_ops/cuda/cuda_training_kernels_reduced_ops.cc -onnxruntime/core/providers/op_kernel_type_control_overrides_reduced_types.inc diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index adfaa4c11f..3c471ed49e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -118,7 +118,6 @@ cmake_dependent_option(onnxruntime_DISABLE_EXCEPTIONS "Disable exception handlin option(onnxruntime_EXTENDED_MINIMAL_BUILD "onnxruntime_MINIMAL_BUILD with support for execution providers that compile kernels." OFF) option(onnxruntime_MINIMAL_BUILD_CUSTOM_OPS "Add custom operator kernels support to a minimal build." OFF) option(onnxruntime_REDUCED_OPS_BUILD "Reduced set of kernels are registered in build via modification of the kernel registration source files." OFF) -option(onnxruntime_REDUCED_OP_TYPE_SUPPORT "Limit the types individual operators support where possible to further reduce the build size." OFF) option(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS "Don't allow models to load external data" OFF) cmake_dependent_option(onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION "Enable runtime graph optimization of ORT format models. Warning: Not yet ready for general use." @@ -390,9 +389,6 @@ endif() if (onnxruntime_REDUCED_OPS_BUILD) add_compile_definitions(REDUCED_OPS_BUILD) - if (onnxruntime_REDUCED_OP_TYPE_SUPPORT) - add_compile_definitions(REDUCED_OP_TYPE_SUPPORT) - endif() endif() if (onnxruntime_DISABLE_EXTERNAL_INITIALIZERS) diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index 90240c5f68..8fba42e3e8 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -1,6 +1,64 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +# Reduced ops build helpers + +# In a reduced ops build, the reduction is performed by updating source files. +# Rather than modifying the source files directly, updated versions will be +# saved to another location in the build directory: ${op_reduction_root}. +set(op_reduction_root "${CMAKE_BINARY_DIR}/op_reduction.generated") + +# This helper function replaces the relevant original source files with their +# updated, reduced ops versions in `all_srcs`. +function(substitute_op_reduction_srcs all_srcs) + # files that are potentially updated in a reduced ops build + set(original_srcs + "${ONNXRUNTIME_ROOT}/contrib_ops/cpu/cpu_contrib_kernels.cc" + "${ONNXRUNTIME_ROOT}/contrib_ops/cuda/cuda_contrib_kernels.cc" + "${ONNXRUNTIME_ROOT}/core/providers/cpu/cpu_execution_provider.cc" + "${ONNXRUNTIME_ROOT}/core/providers/cuda/cuda_execution_provider.cc" + "${ONNXRUNTIME_ROOT}/core/providers/op_kernel_type_control_overrides.inc" + "${ORTTRAINING_SOURCE_DIR}/training_ops/cpu/cpu_training_kernels.cc" + "${ORTTRAINING_SOURCE_DIR}/training_ops/cuda/cuda_training_kernels.cc" + ) + + set(replacement_srcs) + + foreach(original_src ${original_srcs}) + string(FIND "${${all_srcs}}" "${original_src}" idx) + if(idx EQUAL "-1") + continue() + endif() + + file(RELATIVE_PATH src_relative_path "${REPO_ROOT}" "${original_src}") + set(replacement_src "${op_reduction_root}/${src_relative_path}") + + message("File '${original_src}' substituted with reduced op version '${replacement_src}'.") + + string(REPLACE "${original_src}" "${replacement_src}" ${all_srcs} "${${all_srcs}}") + + list(APPEND replacement_srcs "${replacement_src}") + endforeach() + + if(replacement_srcs) + source_group(TREE "${op_reduction_root}" PREFIX "op_reduction.generated" FILES ${replacement_srcs}) + endif() + + set(${all_srcs} "${${all_srcs}}" PARENT_SCOPE) +endfunction() + +# This helper function adds reduced ops build-specific include directories to +# `target`. +function(add_op_reduction_include_dirs target) + set(op_reduction_include_dirs "${op_reduction_root}/onnxruntime") + if (onnxruntime_ENABLE_TRAINING OR onnxruntime_ENABLE_TRAINING_OPS) + list(APPEND op_reduction_include_dirs "${op_reduction_root}/orttraining") + endif() + # add include directories BEFORE so they are searched first, giving op reduction file paths precedence + target_include_directories(${target} BEFORE PRIVATE ${op_reduction_include_dirs}) +endfunction() + + file(GLOB_RECURSE onnxruntime_providers_srcs CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/cpu/*.h" "${ONNXRUNTIME_ROOT}/core/providers/cpu/*.cc" @@ -45,16 +103,10 @@ file(GLOB_RECURSE onnxruntime_rocm_generated_contrib_ops_cu_srcs CONFIGURE_DEPEN "${CMAKE_CURRENT_BINARY_DIR}/amdgpu/onnxruntime/contrib_ops/rocm/*.cuh" ) - file(GLOB onnxruntime_providers_common_srcs CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/*.h" "${ONNXRUNTIME_ROOT}/core/providers/*.cc" - # If we are building with reduced number of kernel registration and types, - # "core/providers/op_kernel_type_control_overrides_reduced_types.inc" - # will be generated with type specifications code. - # For simplicity, we inlcude both .inc files, - # see onnxruntime/core/providers/op_kernel_type_control.h - "${ONNXRUNTIME_ROOT}/core/providers/op_kernel_type_control_overrides*.inc" + "${ONNXRUNTIME_ROOT}/core/providers/op_kernel_type_control_overrides.inc" ) if(onnxruntime_USE_NUPHAR) @@ -176,7 +228,13 @@ if (onnxruntime_ENABLE_TRAINING) list(APPEND onnxruntime_providers_src ${onnxruntime_providers_dlpack_srcs}) endif() +if (onnxruntime_REDUCED_OPS_BUILD) + substitute_op_reduction_srcs(onnxruntime_providers_src) +endif() onnxruntime_add_static_library(onnxruntime_providers ${onnxruntime_providers_src}) +if (onnxruntime_REDUCED_OPS_BUILD) + add_op_reduction_include_dirs(onnxruntime_providers) +endif() if (MSVC) target_compile_options(onnxruntime_providers PRIVATE "/bigobj") @@ -323,7 +381,13 @@ if (onnxruntime_USE_CUDA) list(APPEND onnxruntime_providers_cuda_src ${onnxruntime_cuda_training_ops_cc_srcs} ${onnxruntime_cuda_training_ops_cu_srcs}) endif() + if (onnxruntime_REDUCED_OPS_BUILD) + substitute_op_reduction_srcs(onnxruntime_providers_cuda_src) + endif() onnxruntime_add_shared_library_module(onnxruntime_providers_cuda ${onnxruntime_providers_cuda_src}) + if (onnxruntime_REDUCED_OPS_BUILD) + add_op_reduction_include_dirs(onnxruntime_providers_cuda) + endif() #target_compile_options(onnxruntime_providers_cuda PRIVATE "$<$:SHELL:-Xcompiler \"/analyze:stacksize 131072\">") if (HAS_GUARD_CF) diff --git a/docs/Reduced_Operator_Kernel_build.md b/docs/Reduced_Operator_Kernel_build.md index 02e761e5c6..e25f7d0478 100644 --- a/docs/Reduced_Operator_Kernel_build.md +++ b/docs/Reduced_Operator_Kernel_build.md @@ -4,17 +4,23 @@ In order to reduce the compiled binary size of ONNX Runtime (ORT), the operator A configuration file must be created with details of the kernels that are required. -Following that, ORT must be manually built, providing the configuration file in the `--include_ops_by_config` parameter. The build process will update the ORT kernel registration source files to exclude the unused kernels. +Following that, ORT must be manually built, providing the configuration file in the [build.py](../tools/ci_build/build.py) `--include_ops_by_config` argument. See the [build instructions](https://www.onnxruntime.ai/docs/how-to/build.html#build-instructions) for more details on building ORT. -When building ORT with a reduced set of kernel registrations, `--skip_tests` **MUST** be specified as the kernel reduction will render many of the unit tests invalid. +The build process will generate updated ORT kernel registration and type reduction source files to exclude unused kernel implementations. +The generated files will be under the build directory and the original source files that they are based on are not directly modified. +When building, the generated files will be used instead of the original files. -NOTE: The operator exclusion logic when building with an operator reduction configuration file will only disable kernel registrations each time it runs. It will NOT re-enable previously disabled kernels. If you wish to change the list of kernels included, it is best to revert the repository to a clean state (e.g. via `git reset --hard`) before building ORT again. +The operator exclusion logic only runs during the build file generation (or "update") phase of the build process, i.e., when invoking build.py with no build phase arguments or explicitly with `--update`. + +Note: It is also possible to run the operator exclusion logic independently with [reduce_op_kernels.py](../tools/ci_build/reduce_op_kernels.py). This may be useful when building ORT without using build.py. +As the generated files will go into a build directory, the build directory must be provided with the reduce_op_kernels.py `--cmake_build_dir` argument. +Note that this argument is slightly different from the build.py `--build_dir` argument - build.py will append an additional directory for the build configuration to its `--build_dir` value to get the equivalent of `--cmake_build_dir`. ## Creating a configuration file with the required kernels -The script in `/tools/python/create_reduced_build_config.py` should be used to create the configuration file. This file can be manually edited as needed. The configuration can be created from either ONNX or ORT format models. +The [create_reduced_build_config.py](../tools/python/create_reduced_build_config.py) script should be used to create the configuration file. This file can be manually edited as needed. The configuration can be created from either ONNX or ORT format models. ``` create_reduced_build_config.py --help @@ -35,7 +41,7 @@ optional arguments: ### Type reduction -If the configuration file is created using ORT format models, the input/output types that individual operators require can be tracked if `--enable_type_reduction` is specified. This can be used to further reduce the build size if `--enable_reduced_operator_type_support` is specified when building ORT. +If the configuration file is created using ORT format models, the input/output types that individual operators require can be tracked if the `--enable_type_reduction` argument is specified. This can be used to further reduce the build size if the build.py `--enable_reduced_operator_type_support` argument is specified when building ORT. ONNX format models are not guaranteed to include the required per-node type information, so cannot be used with this option. diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc index 1f0ee6d17e..e9d22000b0 100644 --- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "contrib_ops/cpu/cpu_contrib_kernels.h" #include "core/graph/constants.h" #include "core/mlas/inc/mlas.h" @@ -278,5 +268,3 @@ Status RegisterCpuContribKernels(KernelRegistry& kernel_registry) { } // namespace contrib } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc b/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc index e2be2b8ab4..19b226858a 100644 --- a/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc +++ b/onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_common.h" @@ -214,5 +204,3 @@ Status RegisterCudaContribKernels(KernelRegistry& kernel_registry) { } // namespace cuda } // namespace contrib } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index 1732170145..f015b53941 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "core/providers/cpu/cpu_execution_provider.h" #include "core/framework/op_kernel.h" #include "core/framework/kernel_registry.h" @@ -2074,5 +2064,3 @@ std::unique_ptr CPUExecutionProvider::GetDataTransfer() const { return std::make_unique(); } } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/cuda/cuda_execution_provider.cc b/onnxruntime/core/providers/cuda/cuda_execution_provider.cc index c676ff43a2..cd5e7ad6b9 100755 --- a/onnxruntime/core/providers/cuda/cuda_execution_provider.cc +++ b/onnxruntime/core/providers/cuda/cuda_execution_provider.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_execution_provider.h" #include "core/providers/cuda/cuda_common.h" @@ -2363,5 +2353,3 @@ void CUDAExecutionProvider::RegisterAllocator(std::shared_ptr } } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/onnxruntime/core/providers/op_kernel_type_control.h b/onnxruntime/core/providers/op_kernel_type_control.h index 5d491d9dc9..446666eaa7 100644 --- a/onnxruntime/core/providers/op_kernel_type_control.h +++ b/onnxruntime/core/providers/op_kernel_type_control.h @@ -469,17 +469,4 @@ struct EnabledTypes { #include "core/framework/data_types.h" // for types that might be used in type specifications // all allowed type specifications should be contained in the following file - -// If we are building with reduced number of kernel registration and types -// will be copied to -// , -// where the type specifications code will be inserted, -// This will prevent, -// 1. Accidental commit of the modified -// 2. If the required ops and types config has changed, user has to revert the changes to -// -#ifndef REDUCED_OP_TYPE_SUPPORT #include "core/providers/op_kernel_type_control_overrides.inc" -#else -#include "core/providers/op_kernel_type_control_overrides_reduced_types.inc" -#endif diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc index 0aacbf14ce..a0acb9518e 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_partitioning_tests.cc @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#if !defined(REDUCED_OPS_BUILD) // may not work with excluded op kernel implementations + #include "core/common/logging/logging.h" #include "core/framework/compute_capability.h" #include "core/framework/utils.h" @@ -342,3 +344,5 @@ TEST(InternalTestingEP, DISABLED_TestNnapiPartitioningMlPerfModels) { } // namespace test } // namespace onnxruntime + +#endif // !defined(REDUCED_OPS_BUILD) diff --git a/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc b/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc index f456809f0b..71032d560c 100644 --- a/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc +++ b/onnxruntime/test/providers/internal_testing/internal_testing_tests.cc @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#if !defined(REDUCED_OPS_BUILD) // may not work with excluded op kernel implementations + #include "core/common/logging/logging.h" #include "core/framework/utils.h" #include "core/session/inference_session.h" @@ -354,3 +356,5 @@ TEST(InternalTestingEP, TestOrtModelWithCompileFailure) { } } // namespace test } // namespace onnxruntime + +#endif // !defined(REDUCED_OPS_BUILD) diff --git a/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc b/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc index 8754305d95..800fd48221 100644 --- a/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc +++ b/orttraining/orttraining/training_ops/cpu/cpu_training_kernels.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "orttraining/training_ops/cpu/cpu_training_kernels.h" #include "core/graph/constants.h" @@ -244,5 +234,3 @@ Status RegisterCpuTrainingKernels(KernelRegistry& kernel_registry) { } // namespace contrib } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc b/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc index 7d84cb3f30..8d0882f2ee 100644 --- a/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc +++ b/orttraining/orttraining/training_ops/cuda/cuda_training_kernels.cc @@ -1,16 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// If we are building with reduced number of kernel registration, -// this file will be copied to _reduced_ops.cc, -// where the unused kernel registration will be commented out -// and the "#ifndef REDUCED_OPS_BUILD" be replaced with "#ifdef REDUCED_OPS_BUILD" -// This will prevent, -// 1. Accidental commit of the reduced kernel registration files -// 2. If the required ops config has changed, user has to revert the changes to -// the kernel registration files -#ifndef REDUCED_OPS_BUILD - #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_fwd.h" #include "core/providers/cuda/cuda_pch.h" @@ -468,5 +458,3 @@ Status RegisterCudaTrainingKernels(KernelRegistry& kernel_registry) { } // namespace cuda } // namespace onnxruntime - -#endif // #ifndef REDUCED_OPS_BUILD diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index f9c900295f..edb2433d7e 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -791,9 +791,6 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home args.minimal_build or args.use_extensions)) else "OFF"), "-Donnxruntime_REDUCED_OPS_BUILD=" + ("ON" if is_reduced_ops_build(args) else "OFF"), - "-Donnxruntime_REDUCED_OP_TYPE_SUPPORT=" + ( - "ON" if is_reduced_ops_build(args) and args.enable_reduced_operator_type_support - else "OFF"), "-Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=" + ("ON" if args.enable_language_interop_ops else "OFF"), "-Donnxruntime_USE_DML=" + ("ON" if args.use_dml else "OFF"), "-Donnxruntime_USE_WINML=" + ("ON" if args.use_winml else "OFF"), @@ -2035,13 +2032,6 @@ def main(): if args.skip_tests: args.test = False - if is_reduced_ops_build(args) and args.update: - from reduce_op_kernels import reduce_ops - reduce_ops( - config_path=args.include_ops_by_config, - enable_type_reduction=args.enable_reduced_operator_type_support, - use_cuda=args.use_cuda) - if args.use_tensorrt: args.use_cuda = True @@ -2127,10 +2117,21 @@ def main(): rocm_home = setup_rocm_build(args, configs) if args.update or args.build: - os.makedirs(build_dir, exist_ok=True) + for config in configs: + os.makedirs(get_config_build_dir(build_dir, config), exist_ok=True) log.info("Build started") + if args.update: + if is_reduced_ops_build(args): + from reduce_op_kernels import reduce_ops + for config in configs: + reduce_ops( + config_path=args.include_ops_by_config, + build_dir=get_config_build_dir(build_dir, config), + enable_type_reduction=args.enable_reduced_operator_type_support, + use_cuda=args.use_cuda) + cmake_extra_args = [] path_to_protoc_exe = args.path_to_protoc_exe if not args.skip_submodule_sync: diff --git a/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml index f53e688df3..a273c590b6 100644 --- a/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml @@ -110,10 +110,6 @@ jobs: --enable-custom-ops workingDirectory: $(Build.SourcesDirectory) - - script: git checkout -- . - displayName: Discard local changes to Git repository files - workingDirectory: $(Build.SourcesDirectory) - - task: CmdLine@2 displayName: 3b. Build minimal onnxruntime [exceptions ENABLED, type reduction ENABLED] and run tests inputs: @@ -132,10 +128,6 @@ jobs: --enable-type-reduction workingDirectory: $(Build.SourcesDirectory) - - script: git checkout -- . - displayName: Discard local changes to Git repository files - workingDirectory: $(Build.SourcesDirectory) - - task: CmdLine@2 displayName: 4. Build minimal onnxruntime [exceptions ENABLED, type reduction ENABLED (globally allowed types)] and run tests inputs: @@ -159,10 +151,6 @@ jobs: --skip-model-tests workingDirectory: $(Build.SourcesDirectory) - - script: git checkout -- . - displayName: Discard local changes to Git repository files - workingDirectory: $(Build.SourcesDirectory) - - task: CmdLine@2 displayName: 5. Build onnxruntime minimal baseline for Android arm64-v8a and report binary size inputs: @@ -207,10 +195,6 @@ jobs: --build_id=$(Build.BuildId) workingDirectory: '$(Build.BinariesDirectory)' - - script: git checkout -- . - displayName: Discard local changes to Git repository files - workingDirectory: $(Build.SourcesDirectory) - - task: CmdLine@2 displayName: 6a. Build full onnxruntime with runtime optimizations enabled inputs: @@ -252,10 +236,6 @@ jobs: --cmake_extra_defines onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION=ON workingDirectory: $(Build.SourcesDirectory) - - script: git checkout -- . - displayName: Discard local changes to Git repository files - workingDirectory: $(Build.SourcesDirectory) - - task: CmdLine@2 displayName: 7a. Regular build with python and all optional features disabled. inputs: diff --git a/tools/ci_build/github/linux/ort_minimal/build_full_ort_and_create_ort_files.sh b/tools/ci_build/github/linux/ort_minimal/build_full_ort_and_create_ort_files.sh index 3664d8c114..0f91f1ae0d 100755 --- a/tools/ci_build/github/linux/ort_minimal/build_full_ort_and_create_ort_files.sh +++ b/tools/ci_build/github/linux/ort_minimal/build_full_ort_and_create_ort_files.sh @@ -17,7 +17,7 @@ python3 /onnxruntime_src/tools/ci_build/op_registration_validator.py # Run a full build of ORT. # We need the ORT python package to generate the ORT format files and the required ops config files. # We do not run tests in this command since those are covered by other CIs. -# We run two full builds here. One for enabling nnapi and the other for enabling coreml. +# Both the NNAPI and CoreML EPs are enabled. python3 /onnxruntime_src/tools/ci_build/build.py \ --build_dir ${BUILD_DIR} --cmake_generator Ninja \ --config Debug \ @@ -27,7 +27,7 @@ python3 /onnxruntime_src/tools/ci_build/build.py \ --skip_tests \ --enable_training_ops \ --enable_pybind --cmake_extra_defines PYTHON_INCLUDE_DIR=/opt/python/cp37-cp37m/include/python3.7m PYTHON_LIBRARY=/usr/lib64/librt.so \ - --use_nnapi\ + --use_nnapi \ --use_coreml # Run kernel def hash verification test diff --git a/tools/ci_build/reduce_op_kernels.py b/tools/ci_build/reduce_op_kernels.py index ae98907a46..dc5d578c21 100755 --- a/tools/ci_build/reduce_op_kernels.py +++ b/tools/ci_build/reduce_op_kernels.py @@ -4,7 +4,6 @@ import argparse import op_registration_utils -import os import shutil import sys import typing @@ -12,14 +11,13 @@ import typing from logger import get_logger from pathlib import Path -REDUCED_KERNEL_DEF_SUFFIX = '_reduced_ops' -REDUCED_TYPE_CONTROL_SUFFIX = '_reduced_types' +# directory containing the reduced op files, relative to the build directory +OP_REDUCTION_DIR = "op_reduction.generated" # add the path to /tools/python so we can import the config parsing and type reduction processing -script_path = os.path.dirname(os.path.realpath(__file__)) -ort_root = os.path.abspath(os.path.join(script_path, '..', '..', )) -ort_tools_py_path = os.path.abspath(os.path.join(ort_root, 'tools', 'python')) -sys.path.append(ort_tools_py_path) +SCRIPT_DIR = Path(__file__).parent.resolve() +ORT_ROOT = SCRIPT_DIR.parents[1] +sys.path.append(str(ORT_ROOT / 'tools' / 'python')) from util import parse_config # noqa from util.ort_format_model.operator_type_usage_processors import OpTypeImplFilterInterface # noqa @@ -96,24 +94,37 @@ class _ExcludingRegistrationProcessor(op_registration_utils.RegistrationProcesso return True -def _process_provider_registrations( - ort_root: str, use_cuda: bool, +def _get_op_reduction_file_path(ort_root: Path, build_dir: Path, original_path: typing.Optional[Path] = None): + ''' + Return the op reduction file path corresponding to `original_path` or the op reduction file root if unspecified. + Op reduction files are in a subdirectory of `build_dir` but otherwise share the same components of `original_path` + relative to `ort_root`. + ''' + op_reduction_root = Path(build_dir, OP_REDUCTION_DIR) + return (op_reduction_root / original_path.relative_to(ort_root)) if original_path is not None \ + else op_reduction_root + + +def _generate_provider_registrations( + ort_root: Path, build_dir: Path, use_cuda: bool, required_ops: typing.Optional[dict], op_type_impl_filter: typing.Optional[OpTypeImplFilterInterface]): - '''Rewrite provider registration files.''' - kernel_registration_files = op_registration_utils.get_kernel_registration_files(ort_root, use_cuda) + '''Generate provider registration files.''' + kernel_registration_files = [Path(f) for f in + op_registration_utils.get_kernel_registration_files(str(ort_root), use_cuda)] for kernel_registration_file in kernel_registration_files: - if not os.path.isfile(kernel_registration_file): - raise ValueError('Kernel registration file {} does not exist'.format(kernel_registration_file)) + if not kernel_registration_file.is_file(): + raise ValueError(f'Kernel registration file does not exist: {kernel_registration_file}') log.info("Processing {}".format(kernel_registration_file)) - old_path = Path(kernel_registration_file) - reduced_path = Path(old_path.parent, f'{old_path.stem}{REDUCED_KERNEL_DEF_SUFFIX}{old_path.suffix}') + reduced_path = _get_op_reduction_file_path(ort_root, build_dir, kernel_registration_file) - # read from original and create the reduced kernel def file (*_reduced_ops.cc), - # with commented out lines for any kernels that are not required + reduced_path.parent.mkdir(parents=True, exist_ok=True) + + # read from original and create the reduced kernel def file with commented out lines for any kernels that are + # not required with open(reduced_path, 'w') as file_to_write: processor = _ExcludingRegistrationProcessor(required_ops, op_type_impl_filter, file_to_write) @@ -123,29 +134,24 @@ def _process_provider_registrations( # error should have already been logged so just exit sys.exit(-1) - # enable the contents in the *_reduced_ops.cc - with open(reduced_path, 'r+') as file: - file_content = file.read().replace(r'#ifndef REDUCED_OPS_BUILD', r'#ifdef REDUCED_OPS_BUILD') - with open(reduced_path, "w") as file_to_write: - file_to_write.write(file_content) - - -def _insert_type_control_cpp_code(ort_root: str, cpp_lines: typing.Sequence[str]): +def _generate_type_control_overrides(ort_root: Path, build_dir: Path, cpp_lines: typing.Sequence[str]): ''' - Insert the C++ code to specify operator type requirements. + Generate type control overrides. Insert applicable C++ code to specify operator type requirements. :param ort_root: Root of the ONNX Runtime repository + :param build_dir: Path to the build directory :param cpp_lines: The C++ code to insert ''' - src = os.path.join(ort_root, 'onnxruntime', 'core', 'providers', 'op_kernel_type_control_overrides.inc') - if not os.path.exists(src) or not os.path.isfile(src): - log.warning('Could not find {}. Skipping generation of C++ code to reduce the types supported by operators.' - .format(src)) - return + src = Path(ort_root, 'onnxruntime', 'core', 'providers', 'op_kernel_type_control_overrides.inc') + + if not src.is_file(): + raise ValueError(f"Op kernel type control overrides file does not exist: {src}") + + # create a copy of op_kernel_type_control_overrides.inc + target = _get_op_reduction_file_path(ort_root, build_dir, src) + + target.parent.mkdir(parents=True, exist_ok=True) - # create a copy of the op_kernel_type_control_overrides.inc even the cpp_lines is empty - src_path = Path(src) - target = Path(src_path.parent, f'{src_path.stem}{REDUCED_TYPE_CONTROL_SUFFIX}{src_path.suffix}') shutil.copyfile(src, target) if cpp_lines: @@ -173,20 +179,29 @@ def _insert_type_control_cpp_code(ort_root: str, cpp_lines: typing.Sequence[str] raise RuntimeError('Insertion point was not found in {}'.format(target)) -def reduce_ops(config_path: str, enable_type_reduction: bool = False, use_cuda: bool = True): +def reduce_ops(config_path: str, build_dir: str, enable_type_reduction: bool = False, use_cuda: bool = True): ''' Reduce op kernel implementations. :param config_path: Path to configuration file that specifies the ops to include + :param build_dir: Path to the build directory. The op reduction files will be generated under the build directory. :param enable_type_reduction: Whether per operator type reduction is enabled :param use_cuda: Whether to reduce op kernels for the CUDA provider ''' + build_dir = Path(build_dir).resolve() + build_dir.mkdir(parents=True, exist_ok=True) + required_ops, op_type_impl_filter = parse_config(config_path, enable_type_reduction) - _process_provider_registrations(ort_root, use_cuda, required_ops, op_type_impl_filter) + # delete any existing generated files first + op_reduction_root = _get_op_reduction_file_path(ORT_ROOT, build_dir) + if op_reduction_root.is_dir(): + log.info(f"Deleting existing op reduction file root directory: {op_reduction_root}") + shutil.rmtree(op_reduction_root) - if enable_type_reduction: - type_control_cpp_code = op_type_impl_filter.get_cpp_entries() if op_type_impl_filter is not None else [] - _insert_type_control_cpp_code(ort_root, type_control_cpp_code) + _generate_provider_registrations(ORT_ROOT, build_dir, use_cuda, required_ops, op_type_impl_filter) + + type_control_cpp_code = op_type_impl_filter.get_cpp_entries() if op_type_impl_filter is not None else [] + _generate_type_control_overrides(ORT_ROOT, build_dir, type_control_cpp_code) if __name__ == "__main__": @@ -199,6 +214,19 @@ if __name__ == "__main__": "Create with /tools/python/create_reduced_build_config.py and edit if needed. " "See /docs/ONNX_Runtime_Format_Model_Usage.md for more information.") + parser.add_argument("--cmake_build_dir", type=str, required=True, + help="Path to the build directory. " + "The op reduction files will be generated under the build directory.") + + parser.add_argument("--enable_type_reduction", action="store_true", + help="Whether per operator type reduction is enabled.") + + parser.add_argument("--use_cuda", action="store_true", + help="Whether to reduce op kernels for the CUDA provider.") + args = parser.parse_args() - config_path = os.path.abspath(args.config_path) - reduce_ops(config_path, enable_type_reduction=True, use_cuda=True) + + reduce_ops(config_path=args.config_path, + build_dir=args.cmake_build_dir, + enable_type_reduction=args.enable_type_reduction, + use_cuda=args.use_cuda) From d5742f3a431bebc139318087ca126e1eb68fcaae Mon Sep 17 00:00:00 2001 From: Abhishek Jindal Date: Wed, 29 Dec 2021 19:35:10 -0800 Subject: [PATCH 075/113] moving from torch nightly build to stable build (#10150) * moving from torch nightly build to stable build * using torch cpu version * using torch cpu version from link --- .../ortmodule/stage1/requirements_torch_eager_cpu.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_eager_cpu.txt b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_eager_cpu.txt index 8ffd732ece..487bfdbecf 100644 --- a/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_eager_cpu.txt +++ b/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_eager_cpu.txt @@ -1,10 +1,9 @@ --pre --f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html -torch>=1.9.0 +-f https://download.pytorch.org/whl/cpu/torch_stable.html +torch>=1.10.0 setuptools>=41.4.0 cerberus h5py sklearn numpy pandas - From 28ce2a5a785804d6244d78274c6fbbda06f48b57 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Mon, 3 Jan 2022 10:24:49 -0800 Subject: [PATCH 076/113] Re-work hierarchy, fix virtual method overload/hiding (#10160) Re-work hierarchy, fix virtual method overload/hiding Use std::optional with a clear comment on the member thread-safety. --- .../core/providers/cuda/generator/random.cc | 67 ++++++++--- .../core/providers/cuda/generator/random.h | 105 +++++++++--------- 2 files changed, 102 insertions(+), 70 deletions(-) diff --git a/onnxruntime/core/providers/cuda/generator/random.cc b/onnxruntime/core/providers/cuda/generator/random.cc index 643da1579d..e5560b5acc 100644 --- a/onnxruntime/core/providers/cuda/generator/random.cc +++ b/onnxruntime/core/providers/cuda/generator/random.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "core/providers/cuda/generator/random.h" +#include "core/providers/cuda/generator/random_impl.h" namespace onnxruntime { namespace cuda { @@ -28,50 +29,80 @@ ONNX_OPERATOR_KERNEL_EX(RandomUniformLike, kOnnxDomain, 1, kCudaExecutionProvide .TypeConstraint("T2", DataTypeImpl::AllIEEEFloatTensorTypes()), RandomUniformLike); -Status RandomNormalBase::Compute(OpKernelContext* p_ctx, const TensorShape& shape, int dtype) const { - Tensor& Y = *p_ctx->Output(0, shape); +#define RANDOM_COMPUTE_IMPL(name) \ + template \ + struct name##ComputeImpl { \ + void operator()(const cudaDeviceProp& prop, cudaStream_t stream, const int64_t N, const float alpha, \ + const float beta, PhiloxGenerator& generator, Tensor& Y) const { \ + typedef typename ToCudaType::MappedType CudaT; \ + CudaT* Y_data = reinterpret_cast(Y.template MutableData()); \ + name##KernelImpl(prop, stream, N, alpha, beta, generator, Y_data); \ + } \ + }; + +RANDOM_COMPUTE_IMPL(RandomNormal) +RANDOM_COMPUTE_IMPL(RandomUniform) + +#undef RANDOM_COMPUTE_IMPL + +Status RandomNormalBase::ComputeNormal(const CudaKernel& cuda_kernel, OpKernelContext& ctx, const TensorShape& shape, int dtype) const { + Tensor& Y = *ctx.Output(0, shape); const int64_t N = shape.Size(); - PhiloxGenerator& generator = generator_ ? *generator_ : PhiloxGenerator::Default(); + PhiloxGenerator& generator = GetPhiloxGenerator(); utils::MLTypeCallDispatcher t_disp(dtype); - t_disp.Invoke(GetDeviceProp(), Stream(), N, scale_, mean_, generator, Y); + t_disp.Invoke(cuda_kernel.GetDeviceProp(), cuda_kernel.Stream(), N, scale_, mean_, generator, Y); return Status::OK(); } -Status RandomNormal::ComputeInternal(OpKernelContext* p_ctx) const { return Compute(p_ctx, shape_, dtype_); } - Status RandomNormalLike::ComputeInternal(OpKernelContext* p_ctx) const { const Tensor* p_X = p_ctx->Input(0); - if (!p_X) return Status(common::ONNXRUNTIME, common::FAIL, "X Input is not available."); - if (dtype_ == TensorProto_DataType_UNDEFINED && !p_X->IsDataType() && !p_X->IsDataType() && + + if (!p_X) { + return Status(common::ONNXRUNTIME, common::FAIL, "X Input is not available."); + } + + int dtype = GetDType(); + if (dtype == TensorProto_DataType_UNDEFINED && !p_X->IsDataType() && !p_X->IsDataType() && !p_X->IsDataType()) { return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Output data type is required to be one of float types, but got incompatible data type ", p_X->DataType(), " from input tensor."); } - return Compute(p_ctx, p_X->Shape(), dtype_ != TensorProto_DataType_UNDEFINED ? dtype_ : p_X->GetElementType()); + + if (dtype == TensorProto_DataType_UNDEFINED) + dtype = p_X->GetElementType(); + + return ComputeNormal(*this, *p_ctx, p_X->Shape(), dtype); } -Status RandomUniformBase::Compute(OpKernelContext* p_ctx, const TensorShape& shape, int dtype) const { - Tensor& Y = *p_ctx->Output(0, shape); +Status RandomUniformBase::ComputeUniform(const CudaKernel& cuda_kernel, OpKernelContext& ctx, const TensorShape& shape, int dtype) const { + Tensor& Y = *ctx.Output(0, shape); const int64_t N = shape.Size(); - PhiloxGenerator& generator = generator_ ? *generator_ : PhiloxGenerator::Default(); + PhiloxGenerator& generator = GetPhiloxGenerator(); utils::MLTypeCallDispatcher t_disp(dtype); - t_disp.Invoke(GetDeviceProp(), Stream(), N, range_, from_, generator, Y); + t_disp.Invoke(cuda_kernel.GetDeviceProp(), cuda_kernel.Stream(), N, range_, from_, generator, Y); return Status::OK(); } -Status RandomUniform::ComputeInternal(OpKernelContext* p_ctx) const { return Compute(p_ctx, shape_, dtype_); } - Status RandomUniformLike::ComputeInternal(OpKernelContext* p_ctx) const { const Tensor* p_X = p_ctx->Input(0); - if (!p_X) return Status(common::ONNXRUNTIME, common::FAIL, "X Input is not available."); - if (dtype_ == TensorProto_DataType_UNDEFINED && !p_X->IsDataType() && !p_X->IsDataType() && + + if (!p_X) { + return Status(common::ONNXRUNTIME, common::FAIL, "X Input is not available."); + } + + int dtype = GetDType(); + if (dtype == TensorProto_DataType_UNDEFINED && !p_X->IsDataType() && !p_X->IsDataType() && !p_X->IsDataType()) { return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Output data type is required to be one of float types, but got incompatible data type ", p_X->DataType(), " from input tensor."); } - return Compute(p_ctx, p_X->Shape(), dtype_ != TensorProto_DataType_UNDEFINED ? dtype_ : p_X->GetElementType()); + + if (dtype == TensorProto_DataType_UNDEFINED) + dtype = p_X->GetElementType(); + + return ComputeUniform(*this, *p_ctx, p_X->Shape(), dtype); } } // namespace cuda diff --git a/onnxruntime/core/providers/cuda/generator/random.h b/onnxruntime/core/providers/cuda/generator/random.h index f1b58b1636..3b7fcb58ca 100644 --- a/onnxruntime/core/providers/cuda/generator/random.h +++ b/onnxruntime/core/providers/cuda/generator/random.h @@ -3,126 +3,127 @@ #pragma once +#include "core/framework/random_generator.h" #include "core/providers/cuda/cuda_kernel.h" - -#include "core/providers/cuda/generator/random_impl.h" +#include namespace onnxruntime { namespace cuda { -#define RANDOM_COMPUTE_IMPL(name) \ - template \ - struct name##ComputeImpl { \ - void operator()(const cudaDeviceProp& prop, cudaStream_t stream, const int64_t N, const float alpha, \ - const float beta, PhiloxGenerator& generator, Tensor& Y) const { \ - typedef typename ToCudaType::MappedType CudaT; \ - CudaT* Y_data = reinterpret_cast(Y.template MutableData()); \ - name##KernelImpl(prop, stream, N, alpha, beta, generator, Y_data); \ - } \ - }; - -RANDOM_COMPUTE_IMPL(RandomNormal) -RANDOM_COMPUTE_IMPL(RandomUniform) - -#undef RANDOM_COMPUTE_IMPL - -class RandomBase : public CudaKernel { +class RandomBase { protected: - RandomBase(const OpKernelInfo& info) : CudaKernel(info) { + explicit RandomBase(const OpKernelInfo& info) { float seed = 0.f; if (info.GetAttr("seed", &seed).IsOK()) { - generator_ = std::make_unique(static_cast(seed)); + generator_.emplace(static_cast(seed)); } int64_t dtype; if (info.GetAttr("dtype", &dtype).IsOK()) { + ORT_ENFORCE(ONNX_NAMESPACE::TensorProto::DataType_IsValid(gsl::narrow(dtype)) && + dtype != ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED, + "Invalid dtype of ", dtype); dtype_ = static_cast(dtype); - ORT_ENFORCE(ONNX_NAMESPACE::TensorProto::DataType_IsValid(dtype_) && - dtype_ != ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED, - "Invalid dtype of ", dtype_); } } protected: - std::unique_ptr generator_; + + void SetDTypeIfUndefined(ONNX_NAMESPACE::TensorProto::DataType dtype) noexcept { + if (dtype_ == ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED) { + dtype_ = dtype; + } + } + + ONNX_NAMESPACE::TensorProto::DataType GetDType() const noexcept { return dtype_; } + + PhiloxGenerator& GetPhiloxGenerator() const { + return (generator_.has_value()) ? *generator_ : PhiloxGenerator::Default(); + } + + private: + ONNX_NAMESPACE::TensorProto::DataType dtype_ = ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED; // optional and may be inferred + + // This member is thread-safe, ensuring proper synchronization + mutable std::optional generator_; }; class RandomNormalBase : public RandomBase { protected: RandomNormalBase(const OpKernelInfo& info) : RandomBase(info) { - ORT_ENFORCE(info.GetAttr("scale", &scale_).IsOK()); - ORT_ENFORCE(info.GetAttr("mean", &mean_).IsOK()); + ORT_THROW_IF_ERROR(info.GetAttr("scale", &scale_)); + ORT_THROW_IF_ERROR(info.GetAttr("mean", &mean_)); } - Status Compute(OpKernelContext* p_ctx, const TensorShape& shape, int dtype) const; + Status ComputeNormal(const CudaKernel& cuda_kernel, OpKernelContext& ctx, const TensorShape& shape, int dtype) const; - protected: + private: float scale_; float mean_; }; -class RandomNormal final : public RandomNormalBase { +class RandomNormal final : public CudaKernel, protected RandomNormalBase { public: - explicit RandomNormal(const OpKernelInfo& info) : RandomNormalBase(info) { - if (dtype_ == ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED) { - dtype_ = ONNX_NAMESPACE::TensorProto_DataType_FLOAT; - } + explicit RandomNormal(const OpKernelInfo& info) : CudaKernel(info), RandomNormalBase(info) { + SetDTypeIfUndefined(ONNX_NAMESPACE::TensorProto_DataType_FLOAT); std::vector shape; - ORT_ENFORCE(info.GetAttrs("shape", shape).IsOK()); + ORT_THROW_IF_ERROR(info.GetAttrs("shape", shape)); shape_ = TensorShape(shape); } - Status ComputeInternal(OpKernelContext* p_ctx) const override; + Status ComputeInternal(OpKernelContext* p_ctx) const override { + return ComputeNormal(*this, *p_ctx, shape_, GetDType()); + } private: TensorShape shape_; }; -class RandomNormalLike final : public RandomNormalBase { +class RandomNormalLike final : public CudaKernel, protected RandomNormalBase { public: - explicit RandomNormalLike(const OpKernelInfo& info) : RandomNormalBase(info) {} + explicit RandomNormalLike(const OpKernelInfo& info) : CudaKernel(info), RandomNormalBase(info) {} Status ComputeInternal(OpKernelContext* p_ctx) const override; }; class RandomUniformBase : public RandomBase { protected: - RandomUniformBase(const OpKernelInfo& info) : RandomBase(info) { + explicit RandomUniformBase(const OpKernelInfo& info) : RandomBase(info) { float low, high; - ORT_ENFORCE(info.GetAttr("low", &low).IsOK()); - ORT_ENFORCE(info.GetAttr("high", &high).IsOK()); + ORT_THROW_IF_ERROR(info.GetAttr("low", &low)); + ORT_THROW_IF_ERROR(info.GetAttr("high", &high)); from_ = low; range_ = high - low; } - Status Compute(OpKernelContext* p_ctx, const TensorShape& shape, int dtype) const; + Status ComputeUniform(const CudaKernel& cuda_kernel, OpKernelContext& ctx, const TensorShape& shape, int dtype) const; - protected: + private: float range_; float from_; }; -class RandomUniform final : public RandomUniformBase { +class RandomUniform final : public CudaKernel, protected RandomUniformBase { public: - explicit RandomUniform(const OpKernelInfo& info) : RandomUniformBase(info) { - if (dtype_ == ONNX_NAMESPACE::TensorProto_DataType_UNDEFINED) { - dtype_ = ONNX_NAMESPACE::TensorProto_DataType_FLOAT; - } + explicit RandomUniform(const OpKernelInfo& info) : CudaKernel(info), RandomUniformBase(info) { + SetDTypeIfUndefined(ONNX_NAMESPACE::TensorProto_DataType_FLOAT); std::vector shape; - ORT_ENFORCE(info.GetAttrs("shape", shape).IsOK()); + ORT_THROW_IF_ERROR(info.GetAttrs("shape", shape)); shape_ = TensorShape(shape); } - Status ComputeInternal(OpKernelContext* p_ctx) const override; + Status ComputeInternal(OpKernelContext* p_ctx) const override { + return ComputeUniform(*this, *p_ctx, shape_, GetDType()); + } private: TensorShape shape_; }; -class RandomUniformLike final : public RandomUniformBase { +class RandomUniformLike final : public CudaKernel, protected RandomUniformBase { public: - explicit RandomUniformLike(const OpKernelInfo& info) : RandomUniformBase(info) {} + explicit RandomUniformLike(const OpKernelInfo& info) : CudaKernel(info), RandomUniformBase(info) {} Status ComputeInternal(OpKernelContext* p_ctx) const override; }; From 7208fcbe1c855c12d1f42aadb4093ab9ff3ead7e Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Mon, 3 Jan 2022 10:55:08 -0800 Subject: [PATCH 077/113] use wasmscalar as default kernel (#9988) * use wasmscalar as default kernel --- cmake/onnxruntime_mlas.cmake | 13 ++++++++----- .../SconvDepthwiseKernelScalar.cpp} | 2 +- .../SgemmKernelScalar.cpp} | 4 ++-- .../SgemvKernelScalar.cpp} | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) rename onnxruntime/core/mlas/lib/{wasm/SconvDepthwiseKernelWasmScalar.cpp => scalar/SconvDepthwiseKernelScalar.cpp} (99%) rename onnxruntime/core/mlas/lib/{wasm/SgemmKernelWasmScalar.cpp => scalar/SgemmKernelScalar.cpp} (99%) rename onnxruntime/core/mlas/lib/{wasm/SgemvKernelWasmScalar.cpp => scalar/SgemvKernelScalar.cpp} (99%) diff --git a/cmake/onnxruntime_mlas.cmake b/cmake/onnxruntime_mlas.cmake index d1ddc06301..2fe9bd4e28 100644 --- a/cmake/onnxruntime_mlas.cmake +++ b/cmake/onnxruntime_mlas.cmake @@ -176,7 +176,7 @@ if (onnxruntime_BUILD_WEBASSEMBLY) ) else() file(GLOB_RECURSE mlas_platform_srcs - "${MLAS_SRC_DIR}/wasm/*.cpp" + "${MLAS_SRC_DIR}/scalar/*.cpp" ) endif() target_sources(onnxruntime_mlas PRIVATE ${mlas_platform_srcs}) @@ -336,7 +336,7 @@ else() ${mlas_platform_srcs_power10} ) endif() - endif() + endif() if(NOT ONNXRUNTIME_MLAS_MULTI_ARCH) set(MLAS_SOURCE_IS_NOT_SET 0) endif() @@ -367,7 +367,7 @@ else() ${mlas_platform_srcs} ${MLAS_SRC_DIR}/x86/x86.get_pc_thunk.S ) - endif() + endif() if(NOT ONNXRUNTIME_MLAS_MULTI_ARCH) set(MLAS_SOURCE_IS_NOT_SET 0) @@ -462,9 +462,12 @@ else() list(APPEND ONNXRUNTIME_MLAS_LIBS onnxruntime_mlas_x86_64) set(mlas_platform_srcs ) else() - set(MLAS_SOURCE_IS_NOT_SET 1) + set(MLAS_SOURCE_IS_NOT_SET 0) endif() - + endif() + if(NOT ONNXRUNTIME_MLAS_MULTI_ARCH AND MLAS_SOURCE_IS_NOT_SET) + file(GLOB_RECURSE mlas_platform_srcs + "${MLAS_SRC_DIR}/scalar/*.cpp") endif() target_sources(onnxruntime_mlas PRIVATE ${mlas_platform_srcs}) endif() diff --git a/onnxruntime/core/mlas/lib/wasm/SconvDepthwiseKernelWasmScalar.cpp b/onnxruntime/core/mlas/lib/scalar/SconvDepthwiseKernelScalar.cpp similarity index 99% rename from onnxruntime/core/mlas/lib/wasm/SconvDepthwiseKernelWasmScalar.cpp rename to onnxruntime/core/mlas/lib/scalar/SconvDepthwiseKernelScalar.cpp index ad243777b3..a805f98fef 100644 --- a/onnxruntime/core/mlas/lib/wasm/SconvDepthwiseKernelWasmScalar.cpp +++ b/onnxruntime/core/mlas/lib/scalar/SconvDepthwiseKernelScalar.cpp @@ -6,7 +6,7 @@ Licensed under the MIT License. Module Name: - SconvDepthwiseKernelWasmScalar.cpp + SconvDepthwiseKernelScalar.cpp Abstract: diff --git a/onnxruntime/core/mlas/lib/wasm/SgemmKernelWasmScalar.cpp b/onnxruntime/core/mlas/lib/scalar/SgemmKernelScalar.cpp similarity index 99% rename from onnxruntime/core/mlas/lib/wasm/SgemmKernelWasmScalar.cpp rename to onnxruntime/core/mlas/lib/scalar/SgemmKernelScalar.cpp index 38e873adb0..62729256da 100644 --- a/onnxruntime/core/mlas/lib/wasm/SgemmKernelWasmScalar.cpp +++ b/onnxruntime/core/mlas/lib/scalar/SgemmKernelScalar.cpp @@ -6,7 +6,7 @@ Licensed under the MIT License. Module Name: - SgemmKernelWasmScalar.cpp + SgemmKernelScalar.cpp Abstract: @@ -41,7 +41,7 @@ Arguments: A - Supplies the address of matrix A. B - Supplies the address of matrix B. The matrix data has been packed using - MlasSgemmCopyPackB or MlasSgemmTransposePackB. Note that in WASM scalar, + MlasSgemmCopyPackB or MlasSgemmTransposePackB. Note that in scalar, the packing wide is 4. C - Supplies the address of matrix C. diff --git a/onnxruntime/core/mlas/lib/wasm/SgemvKernelWasmScalar.cpp b/onnxruntime/core/mlas/lib/scalar/SgemvKernelScalar.cpp similarity index 99% rename from onnxruntime/core/mlas/lib/wasm/SgemvKernelWasmScalar.cpp rename to onnxruntime/core/mlas/lib/scalar/SgemvKernelScalar.cpp index bd74c04b40..609a6f251e 100644 --- a/onnxruntime/core/mlas/lib/wasm/SgemvKernelWasmScalar.cpp +++ b/onnxruntime/core/mlas/lib/scalar/SgemvKernelScalar.cpp @@ -6,7 +6,7 @@ Licensed under the MIT License. Module Name: - SgemvKernelWasmScalar.cpp + SgemvKernelScalar.cpp Abstract: From 1d3b34cc923a58fd138e32a110acb16aa564cbb9 Mon Sep 17 00:00:00 2001 From: Tongliang Liao Date: Sat, 25 Dec 2021 23:10:56 +0800 Subject: [PATCH 078/113] Add `.git` suffix to github URL. Although github works with both, this is more precise. Having an extension also makes it easy to match with regex, when we want to inject code to reroute traffic to our own git mirror. --- .gitmodules | 8 ++++---- cmake/CMakeLists.txt | 2 +- cmake/external/dnnl.cmake | 2 +- cmake/external/zlib.cmake | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitmodules b/.gitmodules index b8ecf47269..3cb897233e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,7 +9,7 @@ url = https://github.com/google/benchmark.git [submodule "cmake/external/onnx"] path = cmake/external/onnx - url = https://github.com/onnx/onnx + url = https://github.com/onnx/onnx.git [submodule "cmake/external/tvm"] path = cmake/external/tvm url = https://github.com/microsoft/onnxruntime-tvm.git @@ -18,7 +18,7 @@ url = https://github.com/HowardHinnant/date.git [submodule "cmake/external/nsync"] path = cmake/external/nsync - url = https://github.com/google/nsync + url = https://github.com/google/nsync.git [submodule "cmake/external/re2"] path = cmake/external/re2 url = https://github.com/google/re2.git @@ -39,10 +39,10 @@ url = https://github.com/NVlabs/cub.git [submodule "cmake/external/wil"] path = cmake/external/wil - url = https://github.com/microsoft/wil + url = https://github.com/microsoft/wil.git [submodule "cmake/external/json"] path = cmake/external/json - url = https://github.com/nlohmann/json + url = https://github.com/nlohmann/json.git [submodule "server/external/spdlog"] path = server/external/spdlog url = https://github.com/gabime/spdlog.git diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 3c471ed49e..5328333e48 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -284,7 +284,7 @@ if (onnxruntime_BUILD_CSHARP) endif() if (NOT WIN32) - #TODO: On Linux we may try https://github.com/microsoft/TraceLogging + #TODO: On Linux we may try https://github.com/microsoft/TraceLogging.git if (onnxruntime_ENABLE_INSTRUMENT) message(WARNING "Instrument is only supported on Windows now") set(onnxruntime_ENABLE_INSTRUMENT OFF) diff --git a/cmake/external/dnnl.cmake b/cmake/external/dnnl.cmake index 953bcfaee7..6770e66a29 100644 --- a/cmake/external/dnnl.cmake +++ b/cmake/external/dnnl.cmake @@ -1,6 +1,6 @@ include (ExternalProject) -set(DNNL_URL https://github.com/oneapi-src/onednn) +set(DNNL_URL https://github.com/oneapi-src/onednn.git) # If DNNL_TAG is updated, check if MKLML_VERSION and platform.cmake.patch need to be updated. set(DNNL_TAG v2.4.4) diff --git a/cmake/external/zlib.cmake b/cmake/external/zlib.cmake index 0201417015..b7fcd22c7d 100644 --- a/cmake/external/zlib.cmake +++ b/cmake/external/zlib.cmake @@ -1,7 +1,7 @@ include (ExternalProject) set(zlib_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/zlib_archive) -set(ZLIB_URL https://github.com/madler/zlib) +set(ZLIB_URL https://github.com/madler/zlib.git) set(ZLIB_BUILD ${CMAKE_CURRENT_BINARY_DIR}/zlib/src/zlib) set(ZLIB_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/zlib/install) set(ZLIB_TAG 50893291621658f355bc5b4d450a8d06a563053d) From 230f32360051bca8c376bd842e4387a5c29177ce Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Mon, 3 Jan 2022 14:48:49 -0800 Subject: [PATCH 079/113] add qdq support for LeakyRelu (#10077) * add qdq support for LeakyRelu --- .../qdq_selector_action_transformer.cc | 10 +- .../selectors_actions/qdq_selectors.cc | 11 +- .../selectors_actions/qdq_selectors.h | 5 - .../test/optimizer/qdq_transformer_test.cc | 108 ++++++++++++++---- 4 files changed, 98 insertions(+), 36 deletions(-) diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc index b5a90c36a9..b49c13d1b4 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc @@ -45,20 +45,20 @@ void DropQDQNodesRules(SelectorsAndActions& qdq_selectors_and_actions) { #endif } -void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { +void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { // 3 nodes. DQ, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"1DQ"}; std::unique_ptr action = std::make_unique(kMSDomain); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector = std::make_unique(is_int8_allowed); + std::unique_ptr selector = std::make_unique(); qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"AveragePool", {}}}, + SelectorAndAction::OpVersionsMap{{"AveragePool", {}}, + {"LeakyRelu", {}}}, std::move(selector), std::move(action)); #else - ORT_UNUSED_PARAMETER(is_int8_allowed); qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); #endif } @@ -148,7 +148,7 @@ SelectorsAndActions CreateSelectorsAndActions(bool is_int8_allowed) { SelectorsAndActions qdq_selectors_and_actions; DropQDQNodesRules(qdq_selectors_and_actions); - UnaryOpQDQRules(qdq_selectors_and_actions, is_int8_allowed); + UnaryOpQDQRules(qdq_selectors_and_actions); BinaryOpQDQRules(qdq_selectors_and_actions); VariadicOpQDQRules(qdq_selectors_and_actions); ConvQDQRules(qdq_selectors_and_actions, is_int8_allowed); diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc index ef5ca43840..6acb4478bb 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc @@ -114,8 +114,7 @@ bool UnarySelector::Check(const GraphViewer& graph_viewer, const Node& node, int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - return dt_input == dt_output && - (int8_allowed_ || dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_UINT8); + return dt_input == dt_output; } bool BinarySelector::Check(const GraphViewer& graph_viewer, @@ -173,8 +172,8 @@ bool ConvSelector::Check(const GraphViewer& graph_viewer, return false; } - if(dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { - if(!int8_allowed_ || dt_weight != dt_input) { + if (dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { + if (!int8_allowed_ || dt_weight != dt_input) { return false; } } @@ -202,8 +201,8 @@ bool MatMulSelector::Check(const GraphViewer& graph_viewer, int32_t dt_input = dq_nodes[0]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); int32_t dt_weight = dq_nodes[1]->InputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); - if(dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { - if(!int8_allowed_ || dt_weight != dt_input) { + if (dt_input == ONNX_NAMESPACE::TensorProto_DataType::TensorProto_DataType_INT8) { + if (!int8_allowed_ || dt_weight != dt_input) { return false; } } diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h index 83b8b41b52..ecd2ea602b 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h @@ -63,15 +63,10 @@ class DropDQDNodesSelector : public BaseSelector { // single input. default is to only support uint8. class UnarySelector : public BaseSelector { - public: - UnarySelector(bool int8_allowed = false) : int8_allowed_{int8_allowed} {} - - private: bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; - bool int8_allowed_; }; // 2 DQ nodes providing input -> node -> Q diff --git a/onnxruntime/test/optimizer/qdq_transformer_test.cc b/onnxruntime/test/optimizer/qdq_transformer_test.cc index 9b2bf8eacc..d517c58a32 100644 --- a/onnxruntime/test/optimizer/qdq_transformer_test.cc +++ b/onnxruntime/test/optimizer/qdq_transformer_test.cc @@ -99,10 +99,10 @@ void QDQTransformerConvTests() { auto check_conv_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); - if (std::is_same::value && - std::is_same::value && - (std::is_same::value || - QDQIsInt8Allowed() && std::is_same::value)) { + if constexpr (std::is_same::value && + std::is_same::value && + (std::is_same::value || + QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["QLinearConv"], 1); EXPECT_EQ(op_to_count["QuantizeLinear"], 1); EXPECT_EQ(op_to_count["DequantizeLinear"], 1); @@ -158,7 +158,7 @@ TEST(QDQTransformerTests, Conv_S8X8U8) { TEST(QDQTransformerTests, Conv_S8X8S8) { // input not uint8_t and output not uint8_t QDQTransformerConvTests(); - QDQTransformerConvTests(); + QDQTransformerConvTests(); } TEST(QDQTransformerTests, ConvMaxPoolReshape_UInt8) { @@ -248,7 +248,7 @@ TEST(QDQTransformerTests, ConvMaxPoolReshape_Int8) { builder.AddNode("Reshape", {dq_reshape_output, reshape_shape}, {reshape_output}); // add Q - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(reshape_output, .0039f, 7, output_arg); } else { builder.AddQuantizeLinearNode(reshape_output, .0039f, 135, output_arg); @@ -301,8 +301,7 @@ void QDQTransformerAveragePoolTests() { auto check_binary_op_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); - if (std::is_same::value && - (QDQIsInt8Allowed() || std::is_same::value)) { + if constexpr (std::is_same::value) { EXPECT_EQ(op_to_count["com.microsoft.QLinearAveragePool"], 1); EXPECT_EQ(op_to_count["AveragePool"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 1); @@ -512,9 +511,9 @@ void QDQTransformerMatMulTests(bool has_output_q) { auto check_binary_op_graph = [&](InferenceSessionWrapper& session) { auto op_to_count = CountOpsInGraph(session.GetGraph()); if (has_output_q) { - if (std::is_same::value && - (std::is_same::value || - QDQIsInt8Allowed() && std::is_same::value)) { + if constexpr (std::is_same::value && + (std::is_same::value || + QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["QLinearMatMul"], 1); EXPECT_EQ(op_to_count["MatMul"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 2); @@ -526,8 +525,8 @@ void QDQTransformerMatMulTests(bool has_output_q) { EXPECT_EQ(op_to_count["DequantizeLinear"], 3); } } else { - if (std::is_same::value || - (QDQIsInt8Allowed() && std::is_same::value)) { + if constexpr (std::is_same::value || + (QDQIsInt8Allowed() && std::is_same::value)) { EXPECT_EQ(op_to_count["com.microsoft.MatMulIntegerToFloat"], 1); EXPECT_EQ(op_to_count["MatMul"], 0); EXPECT_EQ(op_to_count["QuantizeLinear"], 2); @@ -1101,7 +1100,7 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8) { // add Q auto* q_output = builder.MakeIntermediate(); - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { @@ -1165,14 +1164,13 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8_Fail) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - if(QDQIsInt8Allowed()){ + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { builder.AddQuantizeLinearNode(reshape_output, .0035f, 135, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 135, output_arg); } - }; auto check_mp_reshape_graph = [&](InferenceSessionWrapper& session) { @@ -1199,6 +1197,76 @@ TEST(QDQTransformerTests, ConvAveragePoolReshape_Int8_Fail) { test_case({1, 22, 11, 13, 15}, {30, 22, 5, 3, 3}); } +template +void QDQTransformerLeakyReluTests() { + auto test_case = [&](const std::vector& input_shape) { + auto build_test_case = [&](ModelTestBuilder& builder) { + auto* input_arg = builder.MakeInput(input_shape, -1.f, 1.f); + auto* output_arg = builder.MakeOutput(); + // add QDQ + LeakyRelu + auto* dq_output = AddQDQNodePair(builder, input_arg, .0035f, 7); + auto* leakyrelu_output = builder.MakeIntermediate(); + Node& leakyrelu_node = builder.AddNode("LeakyRelu", {dq_output}, {leakyrelu_output}); + leakyrelu_node.AddAttribute("alpha", 0.2f); + + // add QDQ output + auto* q_output = builder.MakeIntermediate(); + builder.AddQuantizeLinearNode(leakyrelu_output, + .0038f, + std::numeric_limits::max() / 2, + q_output); + builder.AddDequantizeLinearNode(q_output, + .0039f, + std::numeric_limits::max() / 2, + output_arg); + }; + + auto check_binary_op_graph = [&](InferenceSessionWrapper& session) { + auto op_to_count = CountOpsInGraph(session.GetGraph()); + if constexpr (std::is_same::value) { + EXPECT_EQ(op_to_count["com.microsoft.QLinearLeakyRelu"], 1); + EXPECT_EQ(op_to_count["LeakyRelu"], 0); + EXPECT_EQ(op_to_count["QuantizeLinear"], 1); + EXPECT_EQ(op_to_count["DequantizeLinear"], 1); + } else { + EXPECT_EQ(op_to_count["com.microsoft.QLinearLeakyRelu"], 0); + EXPECT_EQ(op_to_count["LeakyRelu"], 1); + EXPECT_EQ(op_to_count["QuantizeLinear"], 2); + EXPECT_EQ(op_to_count["DequantizeLinear"], 2); + } + }; + + TransformerTester(build_test_case, + check_binary_op_graph, + TransformerLevel::Level1, + TransformerLevel::Level2, + 12 /*opset_version*/, + 0.01 /*per_sample_tolerance*/, + 0.01 /*relative_per_sample_tolerance*/, + std::make_unique()); + }; + + test_case({1, 12, 37}); + test_case({1, 23, 13, 13}); + test_case({1, 22, 11, 13, 15}); +} + +TEST(QDQTransformerTests, LeakyRelu_S8S8) { + QDQTransformerLeakyReluTests(); +} + +TEST(QDQTransformerTests, LeakyRelu_U8U8) { + QDQTransformerLeakyReluTests(); +} + +TEST(QDQTransformerTests, LeakyRelu_S8U8) { + QDQTransformerLeakyReluTests(); +} + +TEST(QDQTransformerTests, LeakyRelu_U8S8) { + QDQTransformerLeakyReluTests(); +} + TEST(QDQTransformerTests, ConvTranspose_QBackward) { auto test_case = [&](const std::vector& input_shape, const std::vector& weights_shape, const std::vector& perms) { auto build_test_case = [&](ModelTestBuilder& builder) { @@ -1220,7 +1288,7 @@ TEST(QDQTransformerTests, ConvTranspose_QBackward) { // add Q auto* q_output = builder.MakeIntermediate(); - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(transpose_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { @@ -1280,7 +1348,7 @@ TEST(QDQTransformerTests, QBackward_MutilpleSteps) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(transpose_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { @@ -1331,7 +1399,7 @@ TEST(QDQTransformerTests, ConvTranspose_DQForward) { // add Q auto* q_output = builder.MakeIntermediate(); - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(conv_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { @@ -1391,7 +1459,7 @@ TEST(QDQTransformerTests, DQForward_MutilpleSteps) { // add Q + DQ auto* q_output = builder.MakeIntermediate(); - if (QDQIsInt8Allowed()) { + if constexpr (QDQIsInt8Allowed()) { builder.AddQuantizeLinearNode(reshape_output, .0035f, 7, q_output); builder.AddDequantizeLinearNode(q_output, .0035f, 7, output_arg); } else { From 0c517112c419627643fa4ba711f20cb0b783bdb5 Mon Sep 17 00:00:00 2001 From: "Nat Kershaw (MSFT)" Date: Mon, 3 Jan 2022 18:22:22 -0800 Subject: [PATCH 080/113] Automate Python API docs generation (#10116) --- .github/workflows/publish-python-apidocs.yml | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/publish-python-apidocs.yml diff --git a/.github/workflows/publish-python-apidocs.yml b/.github/workflows/publish-python-apidocs.yml new file mode 100644 index 0000000000..b2da6ed5f1 --- /dev/null +++ b/.github/workflows/publish-python-apidocs.yml @@ -0,0 +1,49 @@ +name: Update Python API Docs +on: + workflow_dispatch + +jobs: + publish: + name: Generate Python API docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: | + sudo apt update + sudo apt-get install pip + sudo apt-get install graphviz + - name: Install dependencies + run: | + cd docs/python + pip install -r requirements.txt + pip install flatbuffers protobuf==3.19.1 + pip install -i https://test.pypi.org/simple/ ort-nightly + pip list + - name: Generate Python docs with Sphinx + run: | + cd tools/doc + ./builddoc.sh /usr/bin ../.. ../../build + - name: Set vars + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + - name: Check outputs + run: echo ${{ steps.vars.outputs.sha_short }} + - uses: actions/checkout@v2 + with: + ref: gh-pages + clean: false + - name: Move API docs into target area + run: | + rm -rf docs/api/python + mv build/docs/inference/html docs/api/python + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + branch: gh-pages-pr-python-docs + base: gh-pages + title: '[Automated]: Update Python API docs' + commit-message: 'Update Python API docs to commit ${{ steps.vars.outputs.sha_short }}' + add-paths: docs/api/python + + \ No newline at end of file From c29397ad4f3549666b6fe35b1e8b972bec41d46d Mon Sep 17 00:00:00 2001 From: Chi Lo <54722500+chilo-ms@users.noreply.github.com> Date: Mon, 3 Jan 2022 19:13:37 -0800 Subject: [PATCH 081/113] Modify the code to get correct ragne for symmetric quantization (#10170) --- .../python/tools/quantization/onnx_quantizer.py | 2 +- onnxruntime/python/tools/quantization/quant_utils.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/onnxruntime/python/tools/quantization/onnx_quantizer.py b/onnxruntime/python/tools/quantization/onnx_quantizer.py index 38e3c5e30e..ed99ee1560 100644 --- a/onnxruntime/python/tools/quantization/onnx_quantizer.py +++ b/onnxruntime/python/tools/quantization/onnx_quantizer.py @@ -860,7 +860,7 @@ class ONNXQuantizer: quantization_params = {} for tensor_name in self.tensors_range.keys(): rmin, rmax = self.tensors_range[tensor_name] - qmin, qmax = get_qmin_qmax_for_qType(self.input_qType) + qmin, qmax = get_qmin_qmax_for_qType(self.input_qType, symmetric=self.is_activation_symmetric) quantization_params[tensor_name] = compute_scale_zp(rmin, rmax, qmin, qmax, diff --git a/onnxruntime/python/tools/quantization/quant_utils.py b/onnxruntime/python/tools/quantization/quant_utils.py index 73dd7fdbf7..81d1aefeea 100644 --- a/onnxruntime/python/tools/quantization/quant_utils.py +++ b/onnxruntime/python/tools/quantization/quant_utils.py @@ -176,7 +176,7 @@ def quantize_data(data, qType, symmetric, reduce_range=False): if len(data): rmin = min(data) rmax = max(data) - qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, for_weight=True) + qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, symmetric=symmetric) zero_point, scale = compute_scale_zp(rmin, rmax, qmin, qmax, symmetric) @@ -184,7 +184,7 @@ def quantize_data(data, qType, symmetric, reduce_range=False): return rmin, rmax, zero_point, scale, quantized_data -def get_qmin_qmax_for_qType(qType, reduce_range=False, for_weight=False): +def get_qmin_qmax_for_qType(qType, reduce_range=False, symmetric=False): ''' Return qmin and qmax, the minimum and maximum value representable by the given qType :parameter qType: onnx.onnx_pb.TensorProto.UINT8 or onnx.onnx_pb.TensorProto.UINT8 @@ -193,7 +193,7 @@ def get_qmin_qmax_for_qType(qType, reduce_range=False, for_weight=False): if qType == onnx_proto.TensorProto.UINT8: (qmin, qmax) = (0,127) if reduce_range else (0,255) elif qType == onnx_proto.TensorProto.INT8: - if for_weight: + if symmetric: (qmin, qmax) = (-64,64) if reduce_range else (-127,127) else: (qmin, qmax) = (-64,64) if reduce_range else (-128,127) @@ -201,13 +201,13 @@ def get_qmin_qmax_for_qType(qType, reduce_range=False, for_weight=False): raise ValueError("Unexpected data type {} requested. Only INT8 and UINT8 are supported.".format(qType)) return qmin, qmax -def get_qrange_for_qType(qType, reduce_range=False, for_weight=False): +def get_qrange_for_qType(qType, reduce_range=False, symmetric=False): ''' Helper function to get the quantization range for a type. parameter qType: quantization type. return: quantization range. ''' - qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, for_weight=for_weight) + qmin, qmax = get_qmin_qmax_for_qType(qType, reduce_range, symmetric=symmetric) return qmax - qmin class QuantizedInitializer: From 91f85dfdada60e41a9d850e968fd9c58ae58facb Mon Sep 17 00:00:00 2001 From: George Wu Date: Mon, 3 Jan 2022 20:38:37 -0800 Subject: [PATCH 082/113] update Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 to TensorRT 8.2.2.1 (#10167) --- .../docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 index 92dbd25f56..3ac8adaea3 100644 --- a/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 +++ b/tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_4_tensorrt8_2 @@ -182,9 +182,9 @@ CMD ["/bin/bash"] #Build manylinux2014 docker image end -#Install TensorRT 8.2.1.8 +#Install TensorRT 8.2.2.1 #RUN yum install -y wget -RUN v="8.2.1-1.cuda11.4" &&\ +RUN v="8.2.2-1.cuda11.4" &&\ yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo &&\ yum -y install libnvinfer8-${v} libnvparsers8-${v} libnvonnxparsers8-${v} libnvinfer-plugin8-${v} \ libnvinfer-devel-${v} libnvparsers-devel-${v} libnvonnxparsers-devel-${v} libnvinfer-plugin-devel-${v} From 97659495d982982a06eee6a4e3560923b988ff7e Mon Sep 17 00:00:00 2001 From: "Tang, Cheng" Date: Tue, 4 Jan 2022 08:29:30 -0800 Subject: [PATCH 083/113] fix aten view op (#10050) * fix aten view op * add test case * fix signature * fix the build Co-authored-by: Cheng Tang --- orttraining/orttraining/eager/ort_aten.cpp | 5 +++-- orttraining/orttraining/eager/ort_aten.h | 5 +++-- orttraining/orttraining/eager/ort_ops.cpp | 21 +++++++++++++++++++ orttraining/orttraining/eager/ort_ops.h | 16 +++++++------- orttraining/orttraining/eager/ort_util.h | 17 ++++++++------- .../orttraining/eager/test/ort_tensor.py | 6 ++++++ 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index ca33b09d12..d62e783805 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -89,7 +89,7 @@ OrtValue create_ort_value( {}, &ort_val); auto* ort_tensor = ort_val.GetMutable(); - CopyVectorToTensor(invoker, {val}, *ort_tensor); + CopyVectorToTensor(invoker, &val, 1, *ort_tensor); return ort_val; } @@ -369,7 +369,8 @@ at::Tensor& zero_(at::Tensor& self){ CreateMLValue(invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), element_type, {}, &flag_val); auto* ort_flag_tensor = flag_val.GetMutable(); - CopyVectorToTensor(invoker, {1}, *ort_flag_tensor); + int64_t one = 1; + CopyVectorToTensor(invoker, &one, 1, *ort_flag_tensor); std::vector ort_out = {ort_in_self}; diff --git a/orttraining/orttraining/eager/ort_aten.h b/orttraining/orttraining/eager/ort_aten.h index a63f914b30..fc560914e2 100644 --- a/orttraining/orttraining/eager/ort_aten.h +++ b/orttraining/orttraining/eager/ort_aten.h @@ -46,7 +46,7 @@ OrtValue create_ort_value( {1,}, &ort_val); auto* ort_tensor = ort_val.GetMutable(); - CopyVectorToTensor(invoker, {val}, *ort_tensor); + CopyVectorToTensor(invoker, &val, 1, *ort_tensor); return ort_val; } @@ -69,7 +69,8 @@ OrtValue create_ort_value( &ort_value); CopyVectorToTensor( invoker, - values, + values.data(), + values.size(), *ort_value.GetMutable()); return ort_value; } diff --git a/orttraining/orttraining/eager/ort_ops.cpp b/orttraining/orttraining/eager/ort_ops.cpp index 2cc98b356b..9b5f2e8f50 100644 --- a/orttraining/orttraining/eager/ort_ops.cpp +++ b/orttraining/orttraining/eager/ort_ops.cpp @@ -19,5 +19,26 @@ void copy(onnxruntime::ORTInvoker& invoker, ORT_THROW_IF_ERROR(ort_ep.GetDataTransfer()->CopyTensor(src_tensor, *dst_tensor)); } +template class V> +void createInplaceOutputValue(OrtValue& input, V shape, OrtValue* p_mlvalue){ + auto* input_ort_tensor = input.GetMutable(); + auto element_type = onnxruntime::DataTypeImpl::GetType(); + // the ort TensorShape class only accept std::vector, so have to conversion. + std::vector new_shape; + new_shape.assign(shape.begin(), shape.end()); + CreateMLValue(input_ort_tensor->MutableDataRaw(), + element_type, new_shape, p_mlvalue); +} + +template <> +void createInplaceOutputValue(OrtValue& input, std::vector shape, OrtValue* p_mlvalue){ + auto* input_ort_tensor = input.GetMutable(); + auto element_type = onnxruntime::DataTypeImpl::GetType(); + CreateMLValue(input_ort_tensor->MutableDataRaw(), + element_type, shape, p_mlvalue); +} + +template void createInplaceOutputValue(OrtValue& input, c10::ArrayRef shape, OrtValue* p_mlvalue); + } // namespace eager } // namespace torch_ort \ No newline at end of file diff --git a/orttraining/orttraining/eager/ort_ops.h b/orttraining/orttraining/eager/ort_ops.h index b949c329a2..f8c5564a20 100644 --- a/orttraining/orttraining/eager/ort_ops.h +++ b/orttraining/orttraining/eager/ort_ops.h @@ -10,27 +10,27 @@ namespace torch_ort { namespace eager { +template class V> +void createInplaceOutputValue(OrtValue& input, V shape, OrtValue* p_mlvalue); + template class V> OrtValue reshape_invoke( onnxruntime::ORTInvoker& invoker, OrtValue& input, V shape, bool in_place) { - // TODO: actual reshape on buffer - const onnxruntime::Tensor& input_tensor = input.Get(); - auto new_shape = at::infer_size(shape, input_tensor.Shape().Size()); + // the ort reshape kernel already handle the -1 in target shape + // don't need to invoke at::infer_size here. OrtValue shape_tensor; //todo: avoid the copy on this small shape vector; auto element_type = onnxruntime::DataTypeImpl::GetType(); CreateMLValue(invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), - element_type, {(int64_t)new_shape.size(),}, &shape_tensor); + element_type, {(int64_t)shape.size(),}, &shape_tensor); auto* ort_shape_tensor = shape_tensor.GetMutable(); - CopyVectorToTensor(invoker, new_shape, *ort_shape_tensor); + CopyVectorToTensor(invoker, shape.data(), shape.size(), *ort_shape_tensor); std::vector result(1); if (in_place){ - auto* input_ort_tensor = input.GetMutable(); - CreateMLValue(input_ort_tensor->MutableDataRaw(), - element_type, new_shape, &result[0]); + createInplaceOutputValue(input, shape, &result[0]); } ORT_THROW_IF_ERROR(invoker.Invoke("Reshape", {input, shape_tensor}, result, nullptr)); return result[0]; diff --git a/orttraining/orttraining/eager/ort_util.h b/orttraining/orttraining/eager/ort_util.h index 4b467ee000..cf82b47183 100644 --- a/orttraining/orttraining/eager/ort_util.h +++ b/orttraining/orttraining/eager/ort_util.h @@ -19,19 +19,19 @@ void CreateMLValue(void* data_ptr, onnxruntime::MLDataType element_type, const s template inline void CopyVectorToTensor(onnxruntime::ORTInvoker& invoker, - const std::vector& value, + const T* value_ptr, + int64_t size, onnxruntime::Tensor& tensor) { const auto& execution_provider = invoker.GetCurrentExecutionProvider(); OrtValue* ort_value; - int64_t shape = value.size(); OrtMemoryInfo cpuMemoryInfo; Ort::ThrowOnError(Ort::GetApi().CreateTensorWithDataAsOrtValue( &cpuMemoryInfo, - const_cast(reinterpret_cast(value.data())), - value.size() * sizeof(T), - &shape, + const_cast(reinterpret_cast(value_ptr)), + size * sizeof(T), + &size, 1, Ort::TypeToTensorType::type, &ort_value)); @@ -44,11 +44,12 @@ inline void CopyVectorToTensor(onnxruntime::ORTInvoker& invoker, // vector is specialized so we need to handle it separately template <> inline void CopyVectorToTensor(onnxruntime::ORTInvoker& /*invoker*/, - const std::vector& value, + const bool* value_ptr, + int64_t size, onnxruntime::Tensor& tensor) { auto output_span = tensor.MutableDataAsSpan(); - for (size_t i = 0, end = value.size(); i < end; ++i) { - output_span[i] = value[i]; + for (size_t i = 0, end = size; i < end; ++i) { + output_span[i] = value_ptr[i]; } } diff --git a/orttraining/orttraining/eager/test/ort_tensor.py b/orttraining/orttraining/eager/test/ort_tensor.py index 772c26287a..b821a9179a 100644 --- a/orttraining/orttraining/eager/test/ort_tensor.py +++ b/orttraining/orttraining/eager/test/ort_tensor.py @@ -26,6 +26,12 @@ class OrtTensorTests(unittest.TestCase): y = ort_ones.reshape(-1) assert len(y.size()) == 1 assert y.size()[0] == 100 + + def test_view(self): + cpu_ones = torch.ones(2048) + ort_ones = cpu_ones.to('ort') + y = ort_ones.view(4, 512) + assert y.size() == (4, 512) if __name__ == '__main__': unittest.main() \ No newline at end of file From 792db33f0140cf8c43a32d7cad7e8c8110a1fe49 Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Tue, 4 Jan 2022 12:09:07 -0800 Subject: [PATCH 084/113] Enable loading of ORT format model graph runtime optimizations (#9901) Initial implementation of load/replay of runtime optimizations in an ORT format model. --- cmake/CMakeLists.txt | 14 +- cmake/onnxruntime_optimizer.cmake | 13 +- cmake/onnxruntime_unittests.cmake | 7 +- include/onnxruntime/core/graph/graph.h | 40 ++- .../core/optimizer/graph_transformer_utils.h | 25 +- .../onnxruntime_session_options_config_keys.h | 4 +- onnxruntime/core/framework/session_state.cc | 49 ++- onnxruntime/core/framework/session_state.h | 4 +- onnxruntime/core/graph/graph.cc | 19 +- onnxruntime/core/graph/graph_viewer.cc | 5 - .../core/graph/runtime_optimization_record.h | 13 + .../runtime_optimization_record_container.cc | 42 ++- .../runtime_optimization_record_container.h | 18 +- .../core/optimizer/graph_transformer_utils.cc | 66 ++-- .../ort_format_runtime_optimization/utils.cc | 16 - .../ort_format_runtime_optimization/utils.h | 18 - .../selectors_actions/qdq_actions.cc | 2 +- .../selectors_actions/qdq_actions.h | 2 +- .../qdq_selector_action_transformer.cc | 108 +++--- .../qdq_selector_action_transformer.h | 2 +- .../optimizer/selectors_actions/actions.cc | 2 +- .../optimizer/selectors_actions/actions.h | 9 +- .../runtime_optimization_save_context.h | 16 - .../selector_action_transformer.cc | 320 +++++++++++------- .../selector_action_transformer.h | 147 ++++---- ...lector_action_transformer_apply_contexts.h | 40 +++ onnxruntime/core/session/inference_session.cc | 79 +++-- onnxruntime/test/framework/test_utils.cc | 6 +- onnxruntime/test/framework/test_utils.h | 4 +- .../test/optimizer/qdq_transformer_test.cc | 2 +- .../graph_runtime_optimization_test.cc | 133 ++++++-- .../test/testdata/qdq_conv_model_basic.onnx | Bin 575 -> 0 bytes onnxruntime/test/testdata/qdq_conv_test.py | 45 --- .../test/testdata/transform/qdq_conv.onnx | Bin 0 -> 631 bytes .../test/testdata/transform/qdq_conv_gen.py | 55 +++ .../runtime_optimization/qdq_convs.onnx | Bin 0 -> 1847 bytes .../qdq_convs.runtime_optimizations.ort | Bin 0 -> 10536 bytes .../linux-cpu-minimal-build-ci-pipeline.yml | 73 ++-- 38 files changed, 862 insertions(+), 536 deletions(-) delete mode 100644 onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.cc delete mode 100644 onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.h delete mode 100644 onnxruntime/core/optimizer/selectors_actions/runtime_optimization_save_context.h create mode 100644 onnxruntime/core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h rename onnxruntime/test/optimizer/{ => runtime_optimization}/graph_runtime_optimization_test.cc (56%) delete mode 100644 onnxruntime/test/testdata/qdq_conv_model_basic.onnx delete mode 100644 onnxruntime/test/testdata/qdq_conv_test.py create mode 100644 onnxruntime/test/testdata/transform/qdq_conv.onnx create mode 100644 onnxruntime/test/testdata/transform/qdq_conv_gen.py create mode 100644 onnxruntime/test/testdata/transform/runtime_optimization/qdq_convs.onnx create mode 100644 onnxruntime/test/testdata/transform/runtime_optimization/qdq_convs.runtime_optimizations.ort diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5328333e48..e1b4c053c1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -119,9 +119,9 @@ option(onnxruntime_EXTENDED_MINIMAL_BUILD "onnxruntime_MINIMAL_BUILD with suppor option(onnxruntime_MINIMAL_BUILD_CUSTOM_OPS "Add custom operator kernels support to a minimal build." OFF) option(onnxruntime_REDUCED_OPS_BUILD "Reduced set of kernels are registered in build via modification of the kernel registration source files." OFF) option(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS "Don't allow models to load external data" OFF) -cmake_dependent_option(onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION - "Enable runtime graph optimization of ORT format models. Warning: Not yet ready for general use." - OFF "NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_EXTENDED_MINIMAL_BUILD" OFF) +cmake_dependent_option(onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD + "Enable runtime graph optimization replay for ORT format models in an extended minimal build." + OFF "onnxruntime_EXTENDED_MINIMAL_BUILD" OFF) #A special option just for debugging and sanitize check. Please do not enable in option in retail builds. #The option has no effect on Windows. @@ -340,6 +340,10 @@ if (onnxruntime_MINIMAL_BUILD) if (onnxruntime_EXTENDED_MINIMAL_BUILD) # enable EPs that compile kernels at runtime add_compile_definitions(ORT_EXTENDED_MINIMAL_BUILD) + + if (onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + add_compile_definitions(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + endif() endif() if (onnxruntime_MINIMAL_BUILD_CUSTOM_OPS) @@ -372,10 +376,6 @@ if (onnxruntime_MINIMAL_BUILD) endif() endif() -if (onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) - add_compile_definitions(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) -endif() - if (onnxruntime_ENABLE_LTO) include(CheckIPOSupported) check_ipo_supported(RESULT ipo_enabled OUTPUT ipo_output) diff --git a/cmake/onnxruntime_optimizer.cmake b/cmake/onnxruntime_optimizer.cmake index 9afa2c2e48..6350b8a0a7 100644 --- a/cmake/onnxruntime_optimizer.cmake +++ b/cmake/onnxruntime_optimizer.cmake @@ -11,10 +11,10 @@ if (onnxruntime_MINIMAL_BUILD) "${ONNXRUNTIME_ROOT}/core/optimizer/graph_transformer.cc" ) - if (onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) + if (onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) list(APPEND onnxruntime_optimizer_src_patterns - "${ONNXRUNTIME_ROOT}/core/optimizer/ort_format_runtime_optimization/utils.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/ort_format_runtime_optimization/utils.cc" + "${ONNXRUNTIME_INCLUDE_DIR}/core/optimizer/graph_transformer_utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/graph_transformer_utils.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.h" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/*.h" @@ -37,13 +37,6 @@ else() "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/*.h" "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/*.cc" ) - - if (onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) - list(APPEND onnxruntime_optimizer_src_patterns - "${ONNXRUNTIME_ROOT}/core/optimizer/ort_format_runtime_optimization/utils.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/ort_format_runtime_optimization/utils.cc" - ) - endif() endif() if (onnxruntime_ENABLE_TRAINING) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index ee3c33dea2..11c94655e3 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -233,6 +233,11 @@ else() # minimal and/or reduced ops build endif() endif() +if(NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + list(APPEND onnxruntime_test_optimizer_src + "${TEST_SRC_DIR}/optimizer/runtime_optimization/graph_runtime_optimization_test.cc") +endif() + file(GLOB onnxruntime_test_training_src "${ORTTRAINING_SOURCE_DIR}/test/model/*.cc" "${ORTTRAINING_SOURCE_DIR}/test/gradient/*.cc" @@ -687,7 +692,7 @@ AddTest( if (MSVC) # The warning means the type of two integral values around a binary operator is narrow than their result. # If we promote the two input values first, it could be more tolerant to integer overflow. - # However, this is test code. We are less concerned. + # However, this is test code. We are less concerned. target_compile_options(onnxruntime_test_all PRIVATE "/wd26451") else() target_compile_options(onnxruntime_test_all PRIVATE "-Wno-parentheses") diff --git a/include/onnxruntime/core/graph/graph.h b/include/onnxruntime/core/graph/graph.h index 3fe38fa7ef..49204b54ba 100644 --- a/include/onnxruntime/core/graph/graph.h +++ b/include/onnxruntime/core/graph/graph.h @@ -10,6 +10,12 @@ #include #include +#ifdef _WIN32 +#pragma warning(push) +// disable some warnings from protobuf to pass Windows build +#pragma warning(disable : 4244) +#endif + #if !defined(ORT_MINIMAL_BUILD) #include "onnx/defs/schema.h" #else @@ -18,6 +24,10 @@ #include "onnx/onnx_pb.h" #include "onnx/onnx-operators_pb.h" +#ifdef _WIN32 +#pragma warning(pop) +#endif + #include "gsl/gsl" #include "core/common/common.h" @@ -43,7 +53,7 @@ struct IndexedSubGraph; class Model; class OpSignature; -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) class RuntimeOptimizationRecordContainer; #endif @@ -778,7 +788,9 @@ class Graph { return ConstGraphNodes(nodes_, std::move(filter_func)); } - /** Gets the maximum NodeIndex value used in the Graph. */ + /** Gets the maximum NodeIndex value used in the Graph. + WARNING: This actually returns the max index value used + 1. + */ int MaxNodeIndex() const noexcept { return static_cast(nodes_.size()); } //assume the casting won't overflow /** Gets the number of valid Nodes in the Graph. @@ -977,7 +989,7 @@ class Graph { @remarks As a new Graph instance for the fused nodes is not created, a GraphViewer can be constructed with the IndexedSubGraph information to provide a view of the subgraph. The original nodes are left in place while this is in use. - Call FinalizeFuseSubGraph to remove them once the fused replacement node is fully created. + Call FinalizeFuseSubGraph to remove them once the fused replacement node is fully created. */ Node& BeginFuseSubGraph(const IndexedSubGraph& sub_graph, const std::string& fused_node_name); @@ -1189,7 +1201,7 @@ class Graph { Graph& parent_graph, const Node& parent_node, const logging::Logger& logger, std::unique_ptr& graph); -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) const RuntimeOptimizationRecordContainer& RuntimeOptimizations() const { return runtime_optimizations_; } @@ -1197,7 +1209,21 @@ class Graph { RuntimeOptimizationRecordContainer& MutableRuntimeOptimizations() { return runtime_optimizations_; } -#endif + + // Stores information collected during the replay of loaded runtime optimizations + struct RuntimeOptimizationReplayContext { + std::unordered_map produced_node_index_to_kernel_def_hash{}; + size_t num_replayed_optimizations{}; + }; + + const RuntimeOptimizationReplayContext& RuntimeOptimizationReplayCtx() const { + return runtime_optimization_replay_context_; + } + + RuntimeOptimizationReplayContext& MutableRuntimeOptimizationReplayCtx() { + return runtime_optimization_replay_context_; + } +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) // This friendship relationship should only be used to call Graph::Graph and // Graph::LoadGraph All other access should be via the public API. @@ -1414,11 +1440,13 @@ class Graph { std::hash, std::equal_to> sparse_tensor_names_; -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) // Runtime optimization storage. // Note: runtime_optimizations_ == *runtime_optimizations_ptr_ and must be initialized std::unique_ptr runtime_optimizations_ptr_; RuntimeOptimizationRecordContainer& runtime_optimizations_; + + RuntimeOptimizationReplayContext runtime_optimization_replay_context_; #endif #if !defined(ORT_MINIMAL_BUILD) diff --git a/include/onnxruntime/core/optimizer/graph_transformer_utils.h b/include/onnxruntime/core/optimizer/graph_transformer_utils.h index c340ae1f29..1c8628fd8f 100644 --- a/include/onnxruntime/core/optimizer/graph_transformer_utils.h +++ b/include/onnxruntime/core/optimizer/graph_transformer_utils.h @@ -3,19 +3,29 @@ #pragma once -#include +#include +#include +#include +#include "core/framework/session_options.h" #include "core/optimizer/graph_transformer.h" + +#if !defined(ORT_MINIMAL_BUILD) #include "core/optimizer/rule_based_graph_transformer.h" #include "core/optimizer/rewrite_rule.h" +#endif + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) +#include "core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" +#endif namespace onnxruntime { -struct FreeDimensionOverride; class IExecutionProvider; -struct RuntimeOptimizationSaveContext; namespace optimizer_utils { +#if !defined(ORT_MINIMAL_BUILD) + /** Generates all predefined rules for this level. If rules_to_enable is not empty, it returns the intersection of predefined rules and rules_to_enable. TODO: This is visible for testing at the moment, but we should rather make it private. */ @@ -40,6 +50,10 @@ std::vector> GenerateTransformers( const IExecutionProvider& execution_provider /*required by constant folding*/, const std::unordered_set& rules_and_transformers_to_disable = {}); +#endif // !defined(ORT_MINIMAL_BUILD) + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + /** Generates all predefined transformers which support runtime optimizations for this level. Any transformers or rewrite rules named in rules_and_transformers_to_disable will be excluded. @@ -48,8 +62,11 @@ std::vector> GenerateTransformers( - The set of transformers which support runtime optimizations is different. */ std::vector> GenerateTransformersForRuntimeOptimizations( TransformerLevel level, - const RuntimeOptimizationSaveContext& runtime_optimization_save_context, + const SessionOptions& session_options, + const SatApplyContextVariant& apply_context, const std::unordered_set& rules_and_transformers_to_disable = {}); +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + } // namespace optimizer_utils } // namespace onnxruntime diff --git a/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h b/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h index 52343b3f6b..853a3ad09d 100644 --- a/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h +++ b/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h @@ -72,8 +72,8 @@ static const char* const kOrtSessionOptionsConfigUseORTModelBytesDirectly = "ses // Save information for replaying graph optimizations later instead of applying them directly. // // When an ONNX model is loaded, ORT can perform various optimizations on the graph. -// However, when an ORT format model is loaded, these optimizations are typically not available - this scenario must -// be supported by minimal builds. +// However, when an ORT format model is loaded, the logic to perform these optimizations may not be available because +// this scenario must be supported by minimal builds. // When loading an ONNX model, ORT can optionally save the effects of some optimizations for later replay in an ORT // format model. These are known as "runtime optimizations" - in an ORT format model, they happen at runtime. // diff --git a/onnxruntime/core/framework/session_state.cc b/onnxruntime/core/framework/session_state.cc index f93b912618..eaf9f901fe 100644 --- a/onnxruntime/core/framework/session_state.cc +++ b/onnxruntime/core/framework/session_state.cc @@ -980,14 +980,22 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat // kernel hashes for model are in top level SessionState const auto& compiled_kernel_hashes = GetCompiledKernelHashes(); + const bool original_nodes_should_exist = + compiled_kernel_hashes.empty() +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + && graph_.RuntimeOptimizationReplayCtx().num_replayed_optimizations == 0 +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + ; + // process the nodes that existed when the model was created for (FbsSessionStateViewer::Index i = 0, end = fbs_session_state_viewer.GetNumNodeKernelInfos(); i < end; ++i) { const auto node_kernel_info = fbs_session_state_viewer.GetNodeKernelInfo(i); Node* const node = graph_.GetNode(node_kernel_info.node_index); if (node == nullptr) { - // this is OK if we have compiled kernels and the original node was replaced. if not the model is invalid. - ORT_RETURN_IF(compiled_kernel_hashes.empty(), + // this is OK if we have compiled kernels/replayed runtime optimizations and the original node was replaced. + // if not the model is invalid. + ORT_RETURN_IF(original_nodes_should_exist, "Can't find node with index ", node_kernel_info.node_index, ". Invalid ORT format model."); continue; } @@ -995,6 +1003,18 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat ORT_RETURN_IF_ERROR(add_kernel_by_hash(*node, node_kernel_info.kernel_def_hash)); } +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + // process the nodes that were added by replaying any loaded runtime optimizations + for (const auto& [node_index, kernel_def_hash] : + graph_.RuntimeOptimizationReplayCtx().produced_node_index_to_kernel_def_hash) { + const auto* node = graph_.GetNode(node_index); + ORT_RETURN_IF(node == nullptr, + "Can't find runtime optimization produced node with index ", node_index); + + ORT_RETURN_IF_ERROR(add_kernel_by_hash(*node, kernel_def_hash)); + } +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + // lookup the hashes for any nodes we compiled. the nodes indexes for compiled nodes are not in node_indices // as they were created at runtime. if (!compiled_kernel_hashes.empty()) { @@ -1051,7 +1071,7 @@ static void ComputeConstantInitializerUseCount(const Graph& graph, std::unordere } Status SessionState::FinalizeSessionState(const std::basic_string& graph_location, - KernelRegistryManager& kernel_registry_manager, + const KernelRegistryManager& kernel_registry_manager, const SessionOptions& session_options, const onnxruntime::fbs::SessionState* serialized_session_state, bool remove_initializers, @@ -1208,7 +1228,7 @@ static void AccumulateAllNestedSubgraphsInfo( } Status SessionState::FinalizeSessionStateImpl(const std::basic_string& graph_location, - KernelRegistryManager& kernel_registry_manager, + const KernelRegistryManager& kernel_registry_manager, _In_opt_ const Node* parent_node, const SessionOptions& session_options, bool remove_initializers, @@ -1219,6 +1239,27 @@ Status SessionState::FinalizeSessionStateImpl(const std::basic_string unused_initializer_names; + for (const auto& [name, tensor_proto] : graph_.GetAllInitializedTensors()) { + ORT_UNUSED_PARAMETER(tensor_proto); + int idx; + if (!ort_value_name_idx_map_.GetIdx(name, idx).IsOK()) { + unused_initializer_names.push_back(name); + } + } + + for (const auto& name : unused_initializer_names) { + graph_.RemoveInitializedTensor(name); + } + } +#endif // defined(ORT_MINIMAL_BUILD) && defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + // ignore any outer scope args we don't know about. this can happen if a node contains multiple subgraphs. std::vector valid_outer_scope_node_args; if (parent_node) { diff --git a/onnxruntime/core/framework/session_state.h b/onnxruntime/core/framework/session_state.h index b8ec5cb4f8..45443b6612 100644 --- a/onnxruntime/core/framework/session_state.h +++ b/onnxruntime/core/framework/session_state.h @@ -300,7 +300,7 @@ class SessionState { const KernelRegistryManager& kernel_registry_manager); Status FinalizeSessionState(const std::basic_string& graph_loc, - KernelRegistryManager& kernel_registry_manager, + const KernelRegistryManager& kernel_registry_manager, const SessionOptions& session_options = {}, const onnxruntime::fbs::SessionState* serialized_session_state = nullptr, bool remove_initializers = true, @@ -370,7 +370,7 @@ class SessionState { #endif Status FinalizeSessionStateImpl(const std::basic_string& graph_loc, - KernelRegistryManager& kernel_registry_manager, + const KernelRegistryManager& kernel_registry_manager, _In_opt_ const Node* parent_node, const SessionOptions& session_options, bool remove_initializers, diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index f854839abe..54dfca8217 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -1,10 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#ifdef _WIN32 -// disable some warnings from protobuf to pass Windows build -#pragma warning(disable : 4244) -#endif +#include "core/graph/graph.h" #include #include @@ -1104,7 +1101,7 @@ Graph::Graph(const Model& owning_model, const logging::Logger& logger) : owning_model_(owning_model), graph_proto_(graph_proto), -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) runtime_optimizations_ptr_(std::make_unique()), runtime_optimizations_(*runtime_optimizations_ptr_), #endif @@ -2867,7 +2864,7 @@ static void RemoveRepeatedFieldEntry(T& repeated_field, const TIter& entry_to_re // we do this so we don't have to move all the entries past the one being deleted down one. auto slot = entry_to_remove - repeated_field.begin(); auto last_entry = repeated_field.end() - 1; - repeated_field.SwapElements(slot, num_entries - 1); + repeated_field.SwapElements(gsl::narrow(slot), gsl::narrow(num_entries - 1)); repeated_field.erase(last_entry); } else { repeated_field.erase(entry_to_remove); @@ -3176,7 +3173,7 @@ common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder, auto nodes = builder.CreateVector(nodes_vec); auto node_edges = builder.CreateVector(node_edges_vec); -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) auto runtime_optimizations = flatbuffers::Offset{}; // null value if (!RuntimeOptimizations().IsEmpty()) { flatbuffers::Offset @@ -3197,7 +3194,7 @@ common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder, #if !defined(DISABLE_SPARSE_TENSORS) gb.add_sparse_initializers(sparse_initializers); #endif -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) gb.add_runtime_optimizations(runtime_optimizations); #endif fbs_graph = gb.Finish(); @@ -4259,7 +4256,7 @@ Graph::Graph(const Model& owning_model, const logging::Logger& logger) : owning_model_(owning_model), graph_proto_(&deserialized_proto_data_), -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) runtime_optimizations_ptr_(std::make_unique()), runtime_optimizations_(*runtime_optimizations_ptr_), #endif @@ -4406,14 +4403,14 @@ common::Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph ORT_RETURN_IF_ERROR(add_node_args(fbs_graph.outputs(), graph_outputs_)); -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) // runtime optimizations if (const auto* fbs_runtime_optimizations = fbs_graph.runtime_optimizations()) { if (const auto* fbs_runtime_optimization_records = fbs_runtime_optimizations->records()) { ORT_RETURN_IF_ERROR(MutableRuntimeOptimizations().LoadFromOrtFormat(*fbs_runtime_optimization_records)); } } -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) return Status::OK(); } diff --git a/onnxruntime/core/graph/graph_viewer.cc b/onnxruntime/core/graph/graph_viewer.cc index c841d857c5..bf50574b4f 100644 --- a/onnxruntime/core/graph/graph_viewer.cc +++ b/onnxruntime/core/graph/graph_viewer.cc @@ -1,11 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#ifdef _WIN32 -// disable some warnings from protobuf to pass Windows build -#pragma warning(disable : 4244) -#endif - #include "core/graph/graph_viewer.h" #include "core/graph/indexed_sub_graph.h" diff --git a/onnxruntime/core/graph/runtime_optimization_record.h b/onnxruntime/core/graph/runtime_optimization_record.h index 9ed086113a..bf9177c6aa 100644 --- a/onnxruntime/core/graph/runtime_optimization_record.h +++ b/onnxruntime/core/graph/runtime_optimization_record.h @@ -6,6 +6,7 @@ #include #include #include +#include // for std::tie #include "core/graph/basic_types.h" @@ -60,6 +61,18 @@ an ORT format model. This also means that non-empty node indices here must be in int num_variadic_inputs; /** The number of variadic output values of the target node. */ int num_variadic_outputs; + + friend bool operator==(const NodesToOptimizeIndices& a, const NodesToOptimizeIndices& b) { + const auto tied = [](const NodesToOptimizeIndices& n) { + return std::tie(n.nodes, n.num_inputs, n.num_outputs, n.variadic_input, n.variadic_output, + n.num_variadic_inputs, n.num_variadic_outputs); + }; + return tied(a) == tied(b); + } + + friend bool operator!=(const NodesToOptimizeIndices& a, const NodesToOptimizeIndices& b) { + return !(a == b); + } }; struct NodeIndexAndKernelDefHash { diff --git a/onnxruntime/core/graph/runtime_optimization_record_container.cc b/onnxruntime/core/graph/runtime_optimization_record_container.cc index 03ebf9b3bf..1a0223292b 100644 --- a/onnxruntime/core/graph/runtime_optimization_record_container.cc +++ b/onnxruntime/core/graph/runtime_optimization_record_container.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) #include "core/graph/runtime_optimization_record_container.h" @@ -15,13 +15,37 @@ namespace onnxruntime { #if defined(ORT_ENABLE_ADDING_RUNTIME_OPTIMIZATION_RECORDS) -void RuntimeOptimizationRecordContainer::AddRecord(const std::string& optimizer_key, +bool RuntimeOptimizationRecordContainer::RecordExists(const std::string& optimizer_name, + const std::string& action_id, + const NodesToOptimizeIndices& nodes_to_optimize_indices) const { + const auto it = optimizer_name_to_records_.find(optimizer_name); + if (it == optimizer_name_to_records_.end()) return false; + + const auto& records = it->second; + return std::find_if(records.begin(), records.end(), + [&](const RuntimeOptimizationRecord& record) { + return record.action_id == action_id && + record.nodes_to_optimize_indices == nodes_to_optimize_indices; + }) != records.end(); +} + +void RuntimeOptimizationRecordContainer::AddRecord(const std::string& optimizer_name, RuntimeOptimizationRecord&& runtime_optimization_record) { - auto& optimizations = sat_to_optimizations_[optimizer_key]; + auto& optimizations = optimizer_name_to_records_[optimizer_name]; optimizations.emplace_back(std::move(runtime_optimization_record)); } #endif +std::vector RuntimeOptimizationRecordContainer::RemoveRecordsForOptimizer( + const std::string& optimizer_name) { + std::vector records{}; + if (auto it = optimizer_name_to_records_.find(optimizer_name); it != optimizer_name_to_records_.end()) { + records = std::move(it->second); + optimizer_name_to_records_.erase(it); + } + return records; +} + static Status SaveRuntimeOptimizationRecordToOrtFormat( flatbuffers::FlatBufferBuilder& builder, const RuntimeOptimizationRecord& runtime_optimization_record, @@ -64,8 +88,8 @@ Status RuntimeOptimizationRecordContainer::SaveToOrtFormat( flatbuffers::FlatBufferBuilder& builder, flatbuffers::Offset& fbs_runtime_optimizations) const { std::vector> fbs_runtime_optimizations_vector; - fbs_runtime_optimizations_vector.reserve(sat_to_optimizations_.size()); - for (const auto& [optimizer_name, records] : sat_to_optimizations_) { + fbs_runtime_optimizations_vector.reserve(optimizer_name_to_records_.size()); + for (const auto& [optimizer_name, records] : optimizer_name_to_records_) { std::vector> fbs_records_vector; fbs_records_vector.reserve(records.size()); for (const auto& record : records) { @@ -129,7 +153,7 @@ static Status LoadRuntimeOptimizationRecordFromOrtFormat( Status RuntimeOptimizationRecordContainer::LoadFromOrtFormat( const FbsRuntimeOptimizationRecordContainer& fbs_runtime_optimizations) { - SatToOptimizationRecordsMap sat_to_optimizations; + OptimizerNameToRecordsMap optimizer_name_to_records; for (const auto* fbs_runtime_optimization : fbs_runtime_optimizations) { if (!fbs_runtime_optimization) continue; @@ -149,14 +173,14 @@ Status RuntimeOptimizationRecordContainer::LoadFromOrtFormat( } } - ORT_RETURN_IF_NOT(sat_to_optimizations.emplace(optimizer_name, std::move(records)).second, + ORT_RETURN_IF_NOT(optimizer_name_to_records.emplace(optimizer_name, std::move(records)).second, "Attempting to load runtime optimization records for a previously loaded optimizer: ", optimizer_name); } - sat_to_optimizations_ = std::move(sat_to_optimizations); + optimizer_name_to_records_ = std::move(optimizer_name_to_records); return Status::OK(); } } // namespace onnxruntime -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) diff --git a/onnxruntime/core/graph/runtime_optimization_record_container.h b/onnxruntime/core/graph/runtime_optimization_record_container.h index 1e27d2ba6b..3b0866e72c 100644 --- a/onnxruntime/core/graph/runtime_optimization_record_container.h +++ b/onnxruntime/core/graph/runtime_optimization_record_container.h @@ -3,7 +3,7 @@ #pragma once -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) #include #include @@ -32,13 +32,17 @@ struct RuntimeOptimizationRecordContainerEntry; class RuntimeOptimizationRecordContainer { public: - bool IsEmpty() const { return sat_to_optimizations_.empty(); } + bool IsEmpty() const { return optimizer_name_to_records_.empty(); } #if defined(ORT_ENABLE_ADDING_RUNTIME_OPTIMIZATION_RECORDS) - void AddRecord(const std::string& optimizer_key, RuntimeOptimizationRecord&& runtime_optimization_record); + bool RecordExists(const std::string& optimizer_name, + const std::string& action_id, + const NodesToOptimizeIndices& nodes_to_optimize_indices) const; + + void AddRecord(const std::string& optimizer_name, RuntimeOptimizationRecord&& runtime_optimization_record); #endif - // TODO add a way to access and remove them + std::vector RemoveRecordsForOptimizer(const std::string& optimizer_name); using FbsRuntimeOptimizationRecordContainer = flatbuffers::Vector>; - SatToOptimizationRecordsMap sat_to_optimizations_; + using OptimizerNameToRecordsMap = std::unordered_map>; + OptimizerNameToRecordsMap optimizer_name_to_records_; }; } // namespace onnxruntime -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) diff --git a/onnxruntime/core/optimizer/graph_transformer_utils.cc b/onnxruntime/core/optimizer/graph_transformer_utils.cc index f3f5500f8f..d4c4fa61fb 100644 --- a/onnxruntime/core/optimizer/graph_transformer_utils.cc +++ b/onnxruntime/core/optimizer/graph_transformer_utils.cc @@ -3,6 +3,13 @@ #include "core/optimizer/graph_transformer_utils.h" +#include + +#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" +#include "core/session/onnxruntime_session_options_config_keys.h" + +#if !defined(ORT_MINIMAL_BUILD) + #include "core/mlas/inc/mlas.h" #include "core/optimizer/attention_fusion.h" #include "core/optimizer/bias_dropout_fusion.h" @@ -40,7 +47,6 @@ #include "core/optimizer/qdq_transformer/qdq_propagation.h" #include "core/optimizer/qdq_transformer/qdq_s8_to_u8.h" #include "core/optimizer/qdq_transformer/relu_quantizelinear.h" -#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" #include "core/optimizer/relu_clip_fusion.h" #include "core/optimizer/reshape_fusion.h" #include "core/optimizer/rule_based_graph_transformer.h" @@ -48,13 +54,25 @@ #include "core/optimizer/slice_elimination.h" #include "core/optimizer/transpose_optimizer/ort_transpose_optimizer.h" #include "core/optimizer/unsqueeze_elimination.h" -#include "core/session/onnxruntime_session_options_config_keys.h" +#endif // !defined(ORT_MINIMAL_BUILD) -namespace onnxruntime { -class IExecutionProvider; +namespace onnxruntime::optimizer_utils { -namespace optimizer_utils { +static void FilterTransformers(std::vector>& transformers, + const std::unordered_set& transformers_to_disable) { + if (transformers_to_disable.empty()) return; + + transformers.erase( + std::remove_if(transformers.begin(), transformers.end(), + [&](const std::unique_ptr& transformer) { + return !transformer || + transformers_to_disable.find(transformer->Name()) != transformers_to_disable.end(); + }), + transformers.end()); +} + +#if !defined(ORT_MINIMAL_BUILD) std::string GenerateRuleBasedTransformerName(TransformerLevel level) { return "Level" + std::to_string(static_cast(level)) + "_RuleBasedTransformer"; @@ -92,7 +110,7 @@ std::vector> GenerateRewriteRules( break; default: - ORT_ENFORCE(false, "Unsupported level" + std::to_string(static_cast(level))); + ORT_THROW("Unsupported optimization level: ", static_cast(level)); } if (rules_to_disable.empty()) { @@ -130,29 +148,16 @@ std::unique_ptr GenerateRuleBasedGraphTransformer( return rule_transformer; } -static void FilterTransformers(std::vector>& transformers, - const std::unordered_set& transformers_to_disable) { - if (transformers_to_disable.empty()) return; - - transformers.erase( - std::remove_if(transformers.begin(), transformers.end(), - [&](const std::unique_ptr& transformer) { - return !transformer || - transformers_to_disable.find(transformer->Name()) != transformers_to_disable.end(); - }), - transformers.end()); -} - std::vector> GenerateTransformers( TransformerLevel level, const SessionOptions& session_options, const IExecutionProvider& cpu_execution_provider, /*required by constant folding*/ const std::unordered_set& rules_and_transformers_to_disable) { std::vector> transformers; - bool disable_quant_qdq = + const bool disable_quant_qdq = session_options.config_options.GetConfigOrDefault(kOrtSessionOptionsDisableQuantQDQ, "0") == "1"; #ifndef DISABLE_CONTRIB_OPS - bool enable_gelu_approximation = + const bool enable_gelu_approximation = session_options.config_options.GetConfigOrDefault(kOrtSessionOptionsEnableGeluApproximation, "0") == "1"; #endif @@ -252,17 +257,27 @@ std::vector> GenerateTransformers( return transformers; } +#endif // !defined(ORT_MINIMAL_BUILD) + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + std::vector> GenerateTransformersForRuntimeOptimizations( TransformerLevel level, - const RuntimeOptimizationSaveContext& runtime_optimization_save_context, + const SessionOptions& session_options, + const SatApplyContextVariant& apply_context, const std::unordered_set& rules_and_transformers_to_disable) { + const bool disable_quant_qdq = + session_options.config_options.GetConfigOrDefault(kOrtSessionOptionsDisableQuantQDQ, "0") == "1"; + std::vector> transformers; switch (level) { case TransformerLevel::Level1: break; case TransformerLevel::Level2: - transformers.emplace_back(std::make_unique(runtime_optimization_save_context)); + if (!disable_quant_qdq) { + transformers.emplace_back(std::make_unique(apply_context)); + } break; case TransformerLevel::Level3: break; @@ -275,5 +290,6 @@ std::vector> GenerateTransformersForRuntimeOpt return transformers; } -} // namespace optimizer_utils -} // namespace onnxruntime +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + +} // namespace onnxruntime::optimizer_utils diff --git a/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.cc b/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.cc deleted file mode 100644 index 385478ff6e..0000000000 --- a/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "core/optimizer/ort_format_runtime_optimization/utils.h" - -#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" - -namespace onnxruntime::optimizer_utils { - -std::vector> GenerateOrtFormatRuntimeTransformers() { - std::vector> transformers{}; - transformers.emplace_back(std::make_unique()); - return transformers; -} - -} // namespace onnxruntime::optimizer_utils diff --git a/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.h b/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.h deleted file mode 100644 index b9692dd118..0000000000 --- a/onnxruntime/core/optimizer/ort_format_runtime_optimization/utils.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include -#include - -#include "core/optimizer/graph_transformer.h" - -namespace onnxruntime::optimizer_utils { - -/** - * Generates the ORT format model runtime graph optimization transformers. - */ -std::vector> GenerateOrtFormatRuntimeTransformers(); - -} // namespace onnxruntime::optimizer_utils diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.cc index 8c3f92b5cc..b9fa6b100f 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.cc @@ -172,7 +172,7 @@ Status QDQReplaceWithNew::Run(Graph& graph, const NodesToOptimize& selected_node #if !defined(ORT_MINIMAL_BUILD) Status QDQReplaceWithNew::RunForSave(Graph& graph, const NodesToOptimize& selected_nodes, - const RuntimeOptimizationSaveContext& save_context, + const SatRuntimeOptimizationSaveContext& save_context, SavedState& saved_state, bool& graph_modified) const { SetOptionalZeroPoint::UpdateNodes(graph, selected_nodes); graph_modified = true; diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h index 2a3b94b430..2fa72a19c0 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h @@ -23,7 +23,7 @@ struct QDQReplaceWithNew : public ReplaceWithNew { #if !defined(ORT_MINIMAL_BUILD) Status RunForSave(Graph& graph, const NodesToOptimize& selected_nodes, - const RuntimeOptimizationSaveContext& save_context, + const SatRuntimeOptimizationSaveContext& save_context, SavedState& saved_state, bool& graph_modified) const override; #endif // !defined(ORT_MINIMAL_BUILD) }; diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc index b49c13d1b4..f3eb9ce39d 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc @@ -16,7 +16,7 @@ namespace { using NTO = onnxruntime::NodesToOptimize; // create rules for ops that don't change the data -void DropQDQNodesRules(SelectorsAndActions& qdq_selectors_and_actions) { +void DropQDQNodesRules(SelectorActionRegistry& qdq_selector_action_registry) { // 3 nodes. DQ, target, Q. Merge into target and remove DQ and Q. const std::string action_name{"drop"}; NTO::NodeLocation dq{NTO::NodeType::kInput, 0}; @@ -32,20 +32,20 @@ void DropQDQNodesRules(SelectorsAndActions& qdq_selectors_and_actions) { #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"Gather", {}}, - {"Reshape", {}}, - {"Transpose", {}}, - {"MaxPool", {12}}, - {"Resize", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"Gather", {}}, + {"Reshape", {}}, + {"Transpose", {}}, + {"MaxPool", {12}}, + {"Resize", {}}}, + std::move(selector), + std::move(action)); #else - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void UnaryOpQDQRules(SelectorActionRegistry& qdq_selector_action_registry) { // 3 nodes. DQ, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"1DQ"}; @@ -53,17 +53,17 @@ void UnaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"AveragePool", {}}, - {"LeakyRelu", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"AveragePool", {}}, + {"LeakyRelu", {}}}, + std::move(selector), + std::move(action)); #else - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -void BinaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void BinaryOpQDQRules(SelectorActionRegistry& qdq_selector_action_registry) { // 4 nodes. 2 x DQ for inputs, target, Q // Replace with internal QLinear version of operator. Delete all original nodes. const std::string action_name{"2DQ"}; @@ -71,18 +71,18 @@ void BinaryOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"Add", {}}, - {"Mul", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"Add", {}}, + {"Mul", {}}}, + std::move(selector), + std::move(action)); #else - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -void VariadicOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { +void VariadicOpQDQRules(SelectorActionRegistry& qdq_selector_action_registry) { // 0=variadic DQ nodes 2=target, 3=Q // Replace with QLinear version of operator. Delete all original nodes. const std::string action_name{"*DQ"}; @@ -91,17 +91,17 @@ void VariadicOpQDQRules(SelectorsAndActions& qdq_selectors_and_actions) { #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"Concat", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"Concat", {}}}, + std::move(selector), + std::move(action)); #else - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { +void ConvQDQRules(SelectorActionRegistry& qdq_selector_action_registry, bool is_int8_allowed = false) { // 4 or 5 Nodes. 0=DQ X, 1=DQ W, 2=DQ B (optional), 3=Conv, 4=Q // Handle the DQ input for the Bias being optional. // Replace Conv with QLinearConv @@ -112,18 +112,18 @@ void ConvQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_a #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(is_int8_allowed); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"Conv", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"Conv", {}}}, + std::move(selector), + std::move(action)); #else ORT_UNUSED_PARAMETER(is_int8_allowed); - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8_allowed = false) { +void MatMulQDQRules(SelectorActionRegistry& qdq_selector_action_registry, bool is_int8_allowed = false) { // 3 or 4 nodes. 2 x DQ for inputs, target, optional Q // Replace with QLinearMatMul if Q found, or MatMulIntegerToFloat if not. // Delete all original nodes. @@ -133,37 +133,37 @@ void MatMulQDQRules(SelectorsAndActions& qdq_selectors_and_actions, bool is_int8 #if !defined(ORT_MINIMAL_BUILD) std::unique_ptr selector = std::make_unique(is_int8_allowed); - qdq_selectors_and_actions.RegisterSelectorAndAction(action_name, - SelectorAndAction::OpVersionsMap{{"MatMul", {}}}, - std::move(selector), - std::move(action)); + qdq_selector_action_registry.RegisterSelectorAndAction(action_name, + {{"MatMul", {}}}, + std::move(selector), + std::move(action)); #else ORT_UNUSED_PARAMETER(is_int8_allowed); - qdq_selectors_and_actions.RegisterAction(action_name, std::move(action)); + qdq_selector_action_registry.RegisterAction(action_name, std::move(action)); #endif } -SelectorsAndActions CreateSelectorsAndActions(bool is_int8_allowed) { - SelectorsAndActions qdq_selectors_and_actions; +SelectorActionRegistry CreateSelectorActionRegistry(bool is_int8_allowed) { + SelectorActionRegistry qdq_selector_action_registry; - DropQDQNodesRules(qdq_selectors_and_actions); - UnaryOpQDQRules(qdq_selectors_and_actions); - BinaryOpQDQRules(qdq_selectors_and_actions); - VariadicOpQDQRules(qdq_selectors_and_actions); - ConvQDQRules(qdq_selectors_and_actions, is_int8_allowed); - MatMulQDQRules(qdq_selectors_and_actions, is_int8_allowed); + DropQDQNodesRules(qdq_selector_action_registry); + UnaryOpQDQRules(qdq_selector_action_registry); + BinaryOpQDQRules(qdq_selector_action_registry); + VariadicOpQDQRules(qdq_selector_action_registry); + ConvQDQRules(qdq_selector_action_registry, is_int8_allowed); + MatMulQDQRules(qdq_selector_action_registry, is_int8_allowed); - return qdq_selectors_and_actions; + return qdq_selector_action_registry; } } // namespace -QDQSelectorActionTransformer::QDQSelectorActionTransformer(std::optional save_context) +QDQSelectorActionTransformer::QDQSelectorActionTransformer(const SatApplyContextVariant& apply_context) : SelectorActionTransformer{ "QDQSelectorActionTransformer", - CreateSelectorsAndActions(QDQIsInt8Allowed()), - std::move(save_context)} { + CreateSelectorActionRegistry(QDQIsInt8Allowed()), + apply_context} { } } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h index 1ddd4fe560..b324f3962d 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h @@ -22,7 +22,7 @@ Transformer that fuses QDQ and fp32 ops into quantized ops. */ class QDQSelectorActionTransformer : public SelectorActionTransformer { public: - QDQSelectorActionTransformer(std::optional save_context = std::nullopt); + QDQSelectorActionTransformer(const SatApplyContextVariant& apply_context = SatApplyContextVariant{}); }; } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/actions.cc b/onnxruntime/core/optimizer/selectors_actions/actions.cc index c2e7601e34..3dddb0c766 100644 --- a/onnxruntime/core/optimizer/selectors_actions/actions.cc +++ b/onnxruntime/core/optimizer/selectors_actions/actions.cc @@ -105,7 +105,7 @@ Status ReplaceWithNew::Run(Graph& graph, const NodesToOptimize& selected_nodes) #if !defined(ORT_MINIMAL_BUILD) Status ReplaceWithNew::RunForSave(Graph& graph, const NodesToOptimize& selected_nodes, - const RuntimeOptimizationSaveContext& save_context, + const SatRuntimeOptimizationSaveContext& save_context, SavedState& saved_state, bool& graph_modified) const { // make temporary node, use it to look up kernel def hash, remove temporary node const auto op_type = OpType(selected_nodes); diff --git a/onnxruntime/core/optimizer/selectors_actions/actions.h b/onnxruntime/core/optimizer/selectors_actions/actions.h index 5632aaaf7a..e3daf23a38 100644 --- a/onnxruntime/core/optimizer/selectors_actions/actions.h +++ b/onnxruntime/core/optimizer/selectors_actions/actions.h @@ -9,7 +9,7 @@ #include "core/graph/graph_utils.h" // TODO: Minimize usage of this given we want to use Actions in a minimal build #include "core/graph/runtime_optimization_record.h" #include "core/optimizer/selectors_actions/helpers.h" -#include "core/optimizer/selectors_actions/runtime_optimization_save_context.h" +#include "core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" namespace onnxruntime { @@ -23,13 +23,14 @@ struct Action { virtual Status Run(Graph& graph, const NodesToOptimize& selected_nodes) const = 0; #if !defined(ORT_MINIMAL_BUILD) + // per-action saved state struct SavedState { std::vector produced_nodes; }; // saving interface virtual Status RunForSave(Graph& /*graph*/, const NodesToOptimize& /*selected_nodes*/, - const RuntimeOptimizationSaveContext& /*save_context*/, + const SatRuntimeOptimizationSaveContext& /*save_context*/, SavedState& /*saved_state*/, bool& /*graph_modified*/) const { // do nothing by default return Status::OK(); @@ -54,7 +55,7 @@ struct MultiAction : public Action { #if !defined(ORT_MINIMAL_BUILD) Status RunForSave(Graph& graph, const NodesToOptimize& selected_nodes, - const RuntimeOptimizationSaveContext& save_context, + const SatRuntimeOptimizationSaveContext& save_context, SavedState& saved_state, bool& graph_modified) const override { for (const auto& action : actions_) { ORT_RETURN_IF_ERROR(action->RunForSave(graph, selected_nodes, save_context, saved_state, graph_modified)); @@ -109,7 +110,7 @@ struct ReplaceWithNew : public Action { #if !defined(ORT_MINIMAL_BUILD) Status RunForSave(Graph& graph, const NodesToOptimize& selected_nodes, - const RuntimeOptimizationSaveContext& save_context, + const SatRuntimeOptimizationSaveContext& save_context, SavedState& saved_state, bool& graph_modified) const override; #endif // !defined(ORT_MINIMAL_BUILD) diff --git a/onnxruntime/core/optimizer/selectors_actions/runtime_optimization_save_context.h b/onnxruntime/core/optimizer/selectors_actions/runtime_optimization_save_context.h deleted file mode 100644 index 96d93da523..0000000000 --- a/onnxruntime/core/optimizer/selectors_actions/runtime_optimization_save_context.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include - -#include "core/framework/kernel_registry_manager.h" - -namespace onnxruntime { - -struct RuntimeOptimizationSaveContext { - std::reference_wrapper kernel_registry_manager; -}; - -} // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc index f2a7792cc9..892ac73853 100644 --- a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc @@ -3,58 +3,89 @@ #include "core/optimizer/selectors_actions/selector_action_transformer.h" +#include + #include "core/graph/runtime_optimization_record_container.h" namespace onnxruntime { #if !defined(ORT_MINIMAL_BUILD) -SelectorActionTransformer::SelectorActionTransformer(const std::string& name, - SelectorsAndActions&& selectors_and_actions, - std::optional save_context) - : GraphTransformer{name}, - selectors_and_actions_{std::move(selectors_and_actions)}, - runtime_optimization_save_context_{std::move(save_context)} { - // setup a map so we lookup by operator type efficiently - for (const auto& map_entry : selectors_and_actions_.SelectorsAndActionsMap()) { - for (const auto& op_info : map_entry.second->ops_and_versions) { - bool inserted = op_type_to_selector_and_action_.insert({op_info.first, &*map_entry.second}).second; - ORT_ENFORCE(inserted, "Multiple entries for operator is not supported. OpType=", op_info.first); - } - } -} -#else -SelectorActionTransformer::SelectorActionTransformer(const std::string& name, - SelectorsAndActions&& selectors_and_actions, - std::optional save_context) - : GraphTransformer{name}, - selectors_and_actions_{std::move(selectors_and_actions)} { - ORT_ENFORCE(!save_context.has_value(), "Saving runtime optimizations is not supported in a minimal build."); -} -#endif - -#if !defined(ORT_MINIMAL_BUILD) -void SelectorsAndActions::RegisterSelectorAndAction(const std::string& name, - const SelectorAndAction::OpVersionsMap& ops_and_versions_in, - std::unique_ptr selector_in, - std::unique_ptr action_in) { +void SelectorActionRegistry::RegisterSelectorAndAction(const std::string& name, + const OpVersionsMap& ops_and_versions_in, + std::unique_ptr selector_in, + std::unique_ptr action_in) { // currently all registrations are done from internal code with no external inputs, // so throw for invalid usage as it should only happen during development. - ORT_ENFORCE(selectors_and_actions_map_.find(name) == selectors_and_actions_map_.cend(), - "Existing registration with name ", name); + const auto [name_to_entry_it, inserted_in_name_to_entry] = + name_to_entry_.emplace(name, + Entry{name, + ops_and_versions_in, + std::move(selector_in), + std::move(action_in)}); + ORT_ENFORCE(inserted_in_name_to_entry, "Existing registration with name ", name); - auto entry = std::make_unique(name, - ops_and_versions_in, - std::move(selector_in), - std::move(action_in)); - - ORT_IGNORE_RETURN_VALUE(selectors_and_actions_map_.emplace(name, std::move(entry))); + const Entry& entry = name_to_entry_it->second; + for (const auto& [op_type, versions] : entry.ops_and_versions) { + ORT_UNUSED_PARAMETER(versions); + const bool inserted_in_op_type_to_entry = op_type_to_entry_.emplace(op_type, &entry).second; + ORT_ENFORCE(inserted_in_op_type_to_entry, + "Multiple entries for operator is not supported. OpType=", op_type); + } } -Status SelectorActionTransformer::MatchAndProcess(Graph& graph, const GraphViewer& graph_viewer, - Node& node, bool& modified, - const logging::Logger& logger) const { +#else // !defined(ORT_MINIMAL_BUILD) + +void SelectorActionRegistry::RegisterAction(const std::string& name, + std::unique_ptr action) { + // currently all registrations are done from internal code with no external inputs, + // so throw for invalid usage as it should only happen during development. + const bool inserted_in_name_to_entry = name_to_entry_.emplace(name, Entry{name, std::move(action)}).second; + ORT_ENFORCE(inserted_in_name_to_entry, "Existing registration with name ", name); +} + +#endif // !defined(ORT_MINIMAL_BUILD) + +const SelectorActionRegistry::Entry* SelectorActionRegistry::LookUp(const std::string& name) const { + if (const auto it = name_to_entry_.find(name); it != name_to_entry_.end()) { + return &it->second; + } + return nullptr; +} + +#if !defined(ORT_MINIMAL_BUILD) +const SelectorActionRegistry::Entry* SelectorActionRegistry::LookUpByOpType(const std::string& op_type) const { + if (const auto it = op_type_to_entry_.find(op_type); it != op_type_to_entry_.end()) { + return it->second; + } + return nullptr; +} +#endif // !defined(ORT_MINIMAL_BUILD) + +SelectorActionTransformer::SelectorActionTransformer(const std::string& name, + SelectorActionRegistry&& selector_action_registry, + const SatApplyContextVariant& apply_context) + : GraphTransformer{name}, + selector_action_registry_{std::move(selector_action_registry)}, + apply_context_{apply_context} {} + +#if !defined(ORT_MINIMAL_BUILD) + +// check if the node matches any of the registered operators. +// if it does, run the Selector. +// if that selects nodes, run or save the Action. +// +// Some part of the MatchAndProcess use a GraphViewer of the given graph, +// we choose to supply both the graph and the graph_viewer to avoid expensive +// and repeatedly construction of the graph_viewer. +// NOTE, the graph must be the same as the graph_viewer's underlying graph +static Status MatchAndProcess( + Graph& graph, const GraphViewer& graph_viewer, Node& node, bool& modified, const logging::Logger& logger, + const std::string& transformer_name, + const SelectorActionRegistry& selector_action_registry, + const SatRuntimeOptimizationSaveContext* save_context) { Status status = Status::OK(); + do { // TODO: for now this just needs to support ONNX ops. If we ever had a transformer that was going to // target non-ONNX ops we'd need to rework a few things to include the op domain in the matches @@ -62,22 +93,21 @@ Status SelectorActionTransformer::MatchAndProcess(Graph& graph, const GraphViewe break; } - auto op_rule = op_type_to_selector_and_action_.find(node.OpType()); - if (op_rule == op_type_to_selector_and_action_.cend()) { + const auto* selector_action_entry = selector_action_registry.LookUpByOpType(node.OpType()); + + if (!selector_action_entry) { break; } - const auto& selector_and_action = *op_rule->second; - // check the supported versions if specified - const auto& versions = selector_and_action.ops_and_versions.find(node.OpType())->second; + const auto& versions = selector_action_entry->ops_and_versions.find(node.OpType())->second; if (!versions.empty()) { if (std::find(versions.cbegin(), versions.cend(), node.SinceVersion()) == versions.cend()) { break; } } - const auto node_selection_opt = selector_and_action.selector->Select(graph_viewer, node); + const auto node_selection_opt = selector_action_entry->selector->Select(graph_viewer, node); if (!node_selection_opt.has_value()) { break; } @@ -85,31 +115,30 @@ Status SelectorActionTransformer::MatchAndProcess(Graph& graph, const GraphViewe LOGS(logger, VERBOSE) << "Matched " << node.OpType(); + const auto& action = *selector_action_entry->action; NodesToOptimize node_group(graph, node_selection); - if (runtime_optimization_save_context_.has_value()) { -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) - const auto& action = *selector_and_action.action; + if (save_context) { + // don't save a runtime optimization again if it already exists + // this might happen if the transformer is run multiple times, e.g., from a graph transformer manager which may + // run its transformers in multiple passes + if (graph.RuntimeOptimizations().RecordExists(transformer_name, selector_action_entry->name, node_selection)) { + break; + } Action::SavedState action_saved_state{}; - status = action.RunForSave(graph, node_group, *runtime_optimization_save_context_, action_saved_state, - modified); + status = action.RunForSave(graph, node_group, *save_context, action_saved_state, modified); if (!status.IsOK()) { break; } graph.MutableRuntimeOptimizations().AddRecord( - Name(), - RuntimeOptimizationRecord{selector_and_action.name, + transformer_name, + RuntimeOptimizationRecord{selector_action_entry->name, node_selection, action_saved_state.produced_nodes}); -#else - status = ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, - "Saving runtime optimizations is not enabled in this build."); - break; -#endif } else { - status = selector_and_action.action->Run(graph, node_group); + status = action.Run(graph, node_group); if (!status.IsOK()) { break; } @@ -120,65 +149,11 @@ Status SelectorActionTransformer::MatchAndProcess(Graph& graph, const GraphViewe return status; } -#else -void SelectorsAndActions::RegisterAction(const std::string& name, - std::unique_ptr action) { - ORT_ENFORCE(actions_map_.find(name) == actions_map_.cend(), "Existing registration with name ", name); - ORT_IGNORE_RETURN_VALUE(actions_map_.emplace(name, std::move(action))); -} - -// TODO: The implementation here is purely an example to give an idea of how it might be done. -// -// The optimization info would be most conveniently stored in the Graph instance under the transformer name -// as that makes de/serialization to ORT format simple (done as part of Graph de/serialization) -// as well as handling subgraphs (values are stored in the current graph, be that the main graph or the subgraph). -struct ActionReplay { - const std::string action_name; - std::vector node_groups; -}; - -Status SelectorActionTransformer::ApplySaved(Graph& graph, bool& modified, const logging::Logger& /*logger*/) const { - auto fake_get_saved_actions = [](const std::string& /*transfomer_name*/) { - return std::vector(); - }; - - // retrieve any actions saved by this transformer in the Graph - // TODO - setup infra for this to come from the Graph instance. could also have a 'clear all' method to free - // all the saved actions once we're done replaying them. - const std::vector& saved_actions = fake_get_saved_actions(Name()); // = graph.GetSavedActions(Name()); - - const auto& actions_map = selectors_and_actions_.ActionsMap(); - const auto actions_map_end = actions_map.cend(); - - for (const auto& entry : saved_actions) { - auto action_iter = actions_map.find(entry.action_name); - if (action_iter == actions_map_end) { - return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Missing action ", entry.action_name, " for transformer ", Name()); - } - - const std::unique_ptr& action = action_iter->second; - - for (const NodesToOptimizeIndices& node_group : entry.node_groups) { - NodesToOptimize nodes_to_optimize{graph, node_group}; - - // all nodes in the group are still available if IsValid returns true - if (nodes_to_optimize.IsValid()) { - ORT_RETURN_IF_ERROR(action->Run(graph, nodes_to_optimize)); - modified = true; - } - } - } - - return Status::OK(); -} - -#endif - -Status SelectorActionTransformer::ApplyImpl(Graph& graph, bool& modified, int graph_level, - const logging::Logger& logger) const { - // TODO: Is there any reason to create a new GraphViewer? Do we need the different topological sort or can we - // just use graph.GetNodesInTopologicalOrder() and avoid the overhead of re-sorting. +Status SelectorActionTransformer::ApplySelectorsAndActions( + Graph& graph, bool& modified, int graph_level, + const logging::Logger& logger, + const SatRuntimeOptimizationSaveContext* save_context) const { GraphViewer graph_viewer(graph); for (auto index : graph_viewer.GetNodesInTopologicalOrder()) { @@ -189,17 +164,118 @@ Status SelectorActionTransformer::ApplyImpl(Graph& graph, bool& modified, int gr ORT_RETURN_IF_ERROR(Recurse(*node, modified, graph_level, logger)); -#if !defined(ORT_MINIMAL_BUILD) // TODO: use GraphTransformer::GetCompatibleExecutionProviders if we need something more flexible if (node->GetExecutionProviderType() == kCpuExecutionProvider) { - ORT_RETURN_IF_ERROR(MatchAndProcess(graph, graph_viewer, *node, modified, logger)); + ORT_RETURN_IF_ERROR(MatchAndProcess(graph, graph_viewer, *node, modified, logger, + Name(), selector_action_registry_, save_context)); } -#else - ORT_RETURN_IF_ERROR(ApplySaved(graph, modified, logger)); -#endif } return Status::OK(); } +#endif // !defined(ORT_MINIMAL_BUILD) + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + +static Status RegisterProducedNodesWithGraph(NodeIndex pre_action_max_num_nodes, NodeIndex post_action_max_num_nodes, + const RuntimeOptimizationRecord& record, + Graph& graph) { + assert(post_action_max_num_nodes >= pre_action_max_num_nodes); + + const auto num_new_node_indices = post_action_max_num_nodes - pre_action_max_num_nodes; + + auto produced_node_it = record.produced_nodes.begin(); + const auto produced_nodes_end = record.produced_nodes.end(); + + std::unordered_map node_index_to_kernel_def_hash{}; + + for (NodeIndex i = 0; i < num_new_node_indices; ++i) { + const NodeIndex new_node_idx = pre_action_max_num_nodes + i; + const auto* new_node = graph.GetNode(new_node_idx); + + // only account for new nodes that still exist + // an action could add a temporary node and then remove it + if (!new_node) { + continue; + } + + ORT_RETURN_IF(produced_node_it == produced_nodes_end, + "Not enough produced nodes in the runtime optimization record."); + + node_index_to_kernel_def_hash.emplace(new_node_idx, produced_node_it->kernel_def_hash); + + ++produced_node_it; + } + + ORT_RETURN_IF(produced_node_it != produced_nodes_end, "Too many produced nodes in the runtime optimization record."); + + graph.MutableRuntimeOptimizationReplayCtx().produced_node_index_to_kernel_def_hash.merge( + node_index_to_kernel_def_hash); + + return Status::OK(); +} + +Status SelectorActionTransformer::ApplySavedRuntimeOptimizations( + Graph& graph, bool& modified, int graph_level, const logging::Logger& logger) const { + for (auto& node : graph.Nodes()) { + ORT_RETURN_IF_ERROR(Recurse(node, modified, graph_level, logger)); + } + + const auto records = graph.MutableRuntimeOptimizations().RemoveRecordsForOptimizer(Name()); + for (const auto& record : records) { + const auto* selector_action_entry = selector_action_registry_.LookUp(record.action_id); + if (!selector_action_entry) { + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Missing action ", record.action_id, " for transformer ", Name()); + } + + NodesToOptimize nodes_to_optimize{graph, record.nodes_to_optimize_indices}; + + if (!nodes_to_optimize.IsValid()) { + continue; + } + + // all nodes in the group are still available if IsValid returns true + + const NodeIndex pre_action_max_index = graph.MaxNodeIndex(); + + ORT_RETURN_IF_ERROR(selector_action_entry->action->Run(graph, nodes_to_optimize)); + modified = true; + + const NodeIndex post_action_max_index = graph.MaxNodeIndex(); + + ORT_RETURN_IF_ERROR(RegisterProducedNodesWithGraph(pre_action_max_index, post_action_max_index, + record, graph)); + + ++graph.MutableRuntimeOptimizationReplayCtx().num_replayed_optimizations; + } + + return Status::OK(); +} + +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + +Status SelectorActionTransformer::ApplyImpl(Graph& graph, bool& modified, int graph_level, + const logging::Logger& logger) const { + if (std::holds_alternative(apply_context_)) { +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + return ApplySavedRuntimeOptimizations(graph, modified, graph_level, logger); +#else // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, + "Loading runtime optimizations is not enabled in this build."); +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + } + + assert(std::holds_alternative(apply_context_) || + std::holds_alternative(apply_context_)); + +#if !defined(ORT_MINIMAL_BUILD) + const auto* save_context = std::get_if(&apply_context_); + return ApplySelectorsAndActions(graph, modified, graph_level, logger, save_context); +#else // !defined(ORT_MINIMAL_BUILD) + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, + "Running both selectors and actions is not enabled in this build."); +#endif // !defined(ORT_MINIMAL_BUILD) +} + } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h index 82a4108884..3ac9c80551 100644 --- a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h +++ b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h @@ -4,12 +4,14 @@ #pragma once #include +#if !defined(ORT_MINIMAL_BUILD) #include +#endif // !defined(ORT_MINIMAL_BUILD) #include "core/framework/kernel_registry_manager.h" #include "core/optimizer/graph_transformer.h" #include "core/optimizer/selectors_actions/actions.h" -#include "core/optimizer/selectors_actions/runtime_optimization_save_context.h" +#include "core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" namespace onnxruntime { @@ -31,71 +33,78 @@ struct NodeSelector { NodeSelector() = default; }; -struct SelectorAndAction { +#endif // !defined(ORT_MINIMAL_BUILD) + +// class to manage a set of selector and associated actions +class SelectorActionRegistry { + public: using OpVersionsMap = std::unordered_map>; - // ctor so we can use make_unique to construct this class - SelectorAndAction(const std::string& name_in, - const OpVersionsMap& ops_and_versions_in, - std::unique_ptr selector_in, - std::unique_ptr action_in) - : name{name_in}, - ops_and_versions{ops_and_versions_in}, - selector{std::move(selector_in)}, - action{std::move(action_in)} {} + struct Entry { + Entry(const std::string& name_in, +#if !defined(ORT_MINIMAL_BUILD) + const OpVersionsMap& ops_and_versions_in, + std::unique_ptr selector_in, +#endif // !defined(ORT_MINIMAL_BUILD) + std::unique_ptr action_in) + : name{name_in}, +#if !defined(ORT_MINIMAL_BUILD) + ops_and_versions{ops_and_versions_in}, + selector{std::move(selector_in)}, +#endif // !defined(ORT_MINIMAL_BUILD) + action{std::move(action_in)} { + } - const std::string name; - OpVersionsMap ops_and_versions; - std::unique_ptr selector; - std::unique_ptr action; - - // can't copy/assign our unique_ptr members - ORT_DISALLOW_COPY_AND_ASSIGNMENT(SelectorAndAction); -}; -#endif - -// class to manage a set of selector and associated actions in a full build, -// or just the set of actions in a minimal build. -class SelectorsAndActions { - public: - SelectorsAndActions() = default; + std::string name; + +#if !defined(ORT_MINIMAL_BUILD) + OpVersionsMap ops_and_versions; + std::unique_ptr selector; +#endif // !defined(ORT_MINIMAL_BUILD) + + std::unique_ptr action; + }; + + SelectorActionRegistry() noexcept = default; + + SelectorActionRegistry(SelectorActionRegistry&&) noexcept = default; + SelectorActionRegistry& operator=(SelectorActionRegistry&&) noexcept = default; + + ORT_DISALLOW_COPY_AND_ASSIGNMENT(SelectorActionRegistry); #if !defined(ORT_MINIMAL_BUILD) - SelectorsAndActions(SelectorsAndActions&& rhs) noexcept - : selectors_and_actions_map_{std::move(rhs.selectors_and_actions_map_)} {} // register a selector and action for the specified ops. // the name used in the registration is for matching the action when replaying the optimizations in a minimal build. - // as it's stored in the ORT format model a shorter name is better. the name is scoped to this SelectorsAndActions + // as it's stored in the ORT format model a shorter name is better. the name is scoped to this SelectorActionRegistry // instance (which is scoped to a single SelectorActionTransformer instance). void RegisterSelectorAndAction(const std::string& name, - const SelectorAndAction::OpVersionsMap& ops_and_versions_in, - std::unique_ptr selector_in, - std::unique_ptr action_in); + const OpVersionsMap& ops_and_versions, + std::unique_ptr selector, + std::unique_ptr action); - const std::unordered_map>& SelectorsAndActionsMap() const { - return selectors_and_actions_map_; - } - -#else - SelectorsAndActions(SelectorsAndActions&& rhs) noexcept - : actions_map_{std::move(rhs.actions_map_)} {} +#else // !defined(ORT_MINIMAL_BUILD) + // register an action void RegisterAction(const std::string& name, std::unique_ptr action); - const std::unordered_map>& ActionsMap() const { - return actions_map_; - } -#endif +#endif // !defined(ORT_MINIMAL_BUILD) - ORT_DISALLOW_COPY_AND_ASSIGNMENT(SelectorsAndActions); + // return registered Entry or nullptr if not found + const Entry* LookUp(const std::string& name) const; + +#if !defined(ORT_MINIMAL_BUILD) + // return registered Entry or nullptr if not found + const Entry* LookUpByOpType(const std::string& op_type) const; +#endif // !defined(ORT_MINIMAL_BUILD) private: + std::unordered_map name_to_entry_; + #if !defined(ORT_MINIMAL_BUILD) - std::unordered_map> selectors_and_actions_map_; -#else - std::unordered_map> actions_map_; -#endif + // auxiliary mapping to enable lookup by op type + std::unordered_map op_type_to_entry_; +#endif // !defined(ORT_MINIMAL_BUILD) }; /** @@ -104,40 +113,32 @@ This setup allows optimizations to be captured and applied at runtime in a minim */ class SelectorActionTransformer : public GraphTransformer { protected: - // Set `save_context` to find matching node groups and save them for later replay. - // If `save_context` is provided, the matching Action for the Selector will not be directly applied to the Graph - // nodes, but saved as a runtime optimization instead. - SelectorActionTransformer(const std::string& name, SelectorsAndActions&& selectors_and_actions, - std::optional save_context); + SelectorActionTransformer(const std::string& name, SelectorActionRegistry&& selector_action_registry, + const SatApplyContextVariant& apply_context); - // can't copy/assign selectors_and_actions_ + // can't copy/assign selector_action_registry_ ORT_DISALLOW_COPY_AND_ASSIGNMENT(SelectorActionTransformer); private: Status ApplyImpl(Graph& graph, bool& modified, int graph_level, const logging::Logger& logger) const override; - SelectorsAndActions selectors_and_actions_; - #if !defined(ORT_MINIMAL_BUILD) - // check if the node matches any of the registered operators. - // if it does, run the Selector. - // if that selects nodes, run the Action. - // - // Some part of the MatchAndProcess use a GraphViewer of the given graph, - // we choose to supply both the graph and the graph_viewer to avoid expensive - // and repeatedly construction of the graph_viewer. - // NOTE, the graph must be the same as the graph_viewer's underlying graph - Status MatchAndProcess(Graph& graph, const GraphViewer& graph_viewer, Node& node, - bool& modified, const logging::Logger& logger) const; + // apply optimizations by selecting nodes from graph and running or saving the associated actions + Status ApplySelectorsAndActions(Graph& graph, bool& modified, int graph_level, const logging::Logger& logger, + const SatRuntimeOptimizationSaveContext* save_context) const; - std::unordered_map op_type_to_selector_and_action_; - // If set, save runtime optimization to graph. Otherwise, apply optimization to graph nodes. - std::optional runtime_optimization_save_context_; -#else - // apply any saved optimizations - Status ApplySaved(Graph& graph, bool& modified, const logging::Logger& logger) const; -#endif +#endif // !defined(ORT_MINIMAL_BUILD) + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + // apply optimizations by replaying saved runtime optimizations + Status ApplySavedRuntimeOptimizations(Graph& graph, bool& modified, int graph_level, + const logging::Logger& logger) const; +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + + SelectorActionRegistry selector_action_registry_; + + SatApplyContextVariant apply_context_; }; } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h new file mode 100644 index 0000000000..51062e7ebd --- /dev/null +++ b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include +#include + +#include "core/framework/kernel_registry_manager.h" + +namespace onnxruntime { + +// Application context objects for various Selector Action Transformer (SAT) modes of operation: +// - SatDirectApplicationContext: Directly apply transformations to the graph. +// Run Selectors and Actions. +// - SatRuntimeOptimizationSaveContext: Save runtime optimizations separately in the graph for later replay. +// Run Selectors and save Actions. +// - SatRuntimeOptimizationLoadContext: Load runtime optimizations from the graph and replay them if applicable. +// Run Actions. + +// Context to directly apply optimizations. +struct SatDirectApplicationContext { +}; + +// Context to save runtime optimizations for later replay. +struct SatRuntimeOptimizationSaveContext { + std::reference_wrapper kernel_registry_manager; +}; + +// Context to load runtime optimizations and replay them. +struct SatRuntimeOptimizationLoadContext { +}; + +// Union of SAT application contexts for various modes of operation. +// The default mode is direct application. +using SatApplyContextVariant = std::variant; + +} // namespace onnxruntime diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 4641e2da89..f7b95e6d85 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -38,7 +38,7 @@ #include "core/optimizer/graph_transformer.h" #include "core/optimizer/insert_cast_transformer.h" #include "core/optimizer/rule_based_graph_transformer.h" -#include "core/optimizer/selectors_actions/runtime_optimization_save_context.h" +#include "core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" #include "core/optimizer/transformer_memcpy.h" #include "core/platform/Barrier.h" #include "core/platform/ort_mutex.h" @@ -62,10 +62,6 @@ #include "core/session/custom_ops.h" #endif -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) -#include "core/optimizer/ort_format_runtime_optimization/utils.h" -#endif - using namespace ONNX_NAMESPACE; using namespace onnxruntime::common; @@ -1148,19 +1144,25 @@ Status PartitionOrtFormatModel(onnxruntime::Graph& graph, return Status::OK(); } -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) -Status TransformGraphForOrtFormatModel(onnxruntime::Graph& graph, const logging::Logger& logger) { - const auto runtime_transformers = std::vector>{}; - // TODO enable transformers - //const auto runtime_transformers = optimizer_utils::GenerateOrtFormatRuntimeTransformers(); - for (const auto& runtime_transformer : runtime_transformers) { - bool modified = false; - ORT_RETURN_IF_ERROR(runtime_transformer->Apply(graph, modified, logger)); +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) +Status ReplaySavedRuntimeOptimizations( + onnxruntime::Graph& graph, const logging::Logger& logger, const SessionOptions& session_options) { + bool modified = false; + + for (int level = static_cast(TransformerLevel::Level2); + level <= static_cast(session_options.graph_optimization_level); + ++level) { + // don't need to specify optimizers to disable, optimizers will process whatever runtime optimizations there are + const auto transformers = optimizer_utils::GenerateTransformersForRuntimeOptimizations( + static_cast(level), session_options, SatRuntimeOptimizationLoadContext{}); + for (const auto& transformer : transformers) { + ORT_RETURN_IF_ERROR(transformer->Apply(graph, modified, logger)); + } } return Status::OK(); } -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) #endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Status AssignNodesToEpsFromHashesImpl(Graph& graph, const fbs::SessionState& fbs_session_state, @@ -1180,18 +1182,33 @@ Status AssignNodesToEpsFromHashesImpl(Graph& graph, const fbs::SessionState& fbs } } - for (FbsSessionStateViewer::Index i = 0, end = fbs_session_state_viewer.GetNumNodeKernelInfos(); i < end; ++i) { - const auto node_kernel_info = fbs_session_state_viewer.GetNodeKernelInfo(i); - Node* node = graph.GetNode(node_kernel_info.node_index); - if (!node || !node->GetExecutionProviderType().empty()) continue; + const auto set_node_ep = [&](NodeIndex node_idx, HashValue kernel_def_hash) -> Status { + Node* node = graph.GetNode(node_idx); + if (!node || !node->GetExecutionProviderType().empty()) { + return Status::OK(); + } const KernelCreateInfo* kci = nullptr; - ORT_RETURN_IF_NOT(kernel_registry_manager.SearchKernelRegistriesByHash(node_kernel_info.kernel_def_hash, &kci), - "Failed to find kernel def hash (", node_kernel_info.kernel_def_hash, ") in kernel registries for ", + ORT_RETURN_IF_NOT(kernel_registry_manager.SearchKernelRegistriesByHash(kernel_def_hash, &kci), + "Failed to find kernel def hash (", kernel_def_hash, ") in kernel registries for ", node->OpType(), "(", node->SinceVersion(), ") node with name '", node->Name(), "'."); node->SetExecutionProviderType(kci->kernel_def->Provider()); + + return Status::OK(); + }; + + for (FbsSessionStateViewer::Index i = 0, end = fbs_session_state_viewer.GetNumNodeKernelInfos(); i < end; ++i) { + const auto node_kernel_info = fbs_session_state_viewer.GetNodeKernelInfo(i); + ORT_RETURN_IF_ERROR(set_node_ep(node_kernel_info.node_index, node_kernel_info.kernel_def_hash)); } +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + for (const auto& [node_index, kernel_def_hash] : + graph.RuntimeOptimizationReplayCtx().produced_node_index_to_kernel_def_hash) { + ORT_RETURN_IF_ERROR(set_node_ep(node_index, kernel_def_hash)); + } +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + return Status::OK(); } @@ -1376,13 +1393,13 @@ common::Status InferenceSession::Initialize() { *session_state_)); } -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) - ORT_RETURN_IF_ERROR_SESSIONID_(TransformGraphForOrtFormatModel(graph, *session_logger_)); -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + ORT_RETURN_IF_ERROR_SESSIONID_(ReplaySavedRuntimeOptimizations(graph, *session_logger_, session_options_)); +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) #endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) - ORT_RETURN_IF_ERROR(AssignNodesToEpsFromHashes(graph, *serialized_session_state, - kernel_registry_manager_, *session_logger_)); + ORT_RETURN_IF_ERROR(AssignNodesToEpsFromHashes(graph, *serialized_session_state, kernel_registry_manager_, + *session_logger_)); } ORT_RETURN_IF_ERROR_SESSIONID_( @@ -2250,14 +2267,14 @@ common::Status InferenceSession::AddPredefinedTransformers(GraphTransformerManag TransformerLevel level = static_cast(i); if (graph_optimization_level >= level) { // Generate and register transformers for level - std::vector> transformers_to_register = [&]() { - if (level != TransformerLevel::Level1 && saving_runtime_optimizations) { - RuntimeOptimizationSaveContext save_context{kernel_registry_manager_}; - return optimizer_utils::GenerateTransformersForRuntimeOptimizations(level, save_context, - optimizers_to_disable_); - } else { + auto transformers_to_register = [&]() { + if (!saving_runtime_optimizations || level == TransformerLevel::Level1) { return optimizer_utils::GenerateTransformers(level, session_options_, cpu_ep, optimizers_to_disable_); + } else { + SatRuntimeOptimizationSaveContext save_context{kernel_registry_manager_}; + return optimizer_utils::GenerateTransformersForRuntimeOptimizations(level, session_options_, save_context, + optimizers_to_disable_); } }(); diff --git a/onnxruntime/test/framework/test_utils.cc b/onnxruntime/test/framework/test_utils.cc index 44c4003aa0..2289589619 100644 --- a/onnxruntime/test/framework/test_utils.cc +++ b/onnxruntime/test/framework/test_utils.cc @@ -32,7 +32,7 @@ IExecutionProvider* TestCoreMLExecutionProvider(uint32_t coreml_flags) { } #endif -static void CountOpsInGraphImpl(const Graph& graph, bool recurse_into_subgraphs, std::map& ops) { +static void CountOpsInGraphImpl(const Graph& graph, bool recurse_into_subgraphs, OpCountMap& ops) { for (auto& node : graph.Nodes()) { std::string key = node.Domain() + (node.Domain().empty() ? "" : ".") + node.OpType(); @@ -48,8 +48,8 @@ static void CountOpsInGraphImpl(const Graph& graph, bool recurse_into_subgraphs, // Returns a map with the number of occurrences of each operator in the graph. // Helper function to check that the graph transformations have been successfully applied. -std::map CountOpsInGraph(const Graph& graph, bool recurse_into_subgraphs) { - std::map ops; +OpCountMap CountOpsInGraph(const Graph& graph, bool recurse_into_subgraphs) { + OpCountMap ops; CountOpsInGraphImpl(graph, recurse_into_subgraphs, ops); return ops; diff --git a/onnxruntime/test/framework/test_utils.h b/onnxruntime/test/framework/test_utils.h index 70254aa7bd..12ae831b3b 100644 --- a/onnxruntime/test/framework/test_utils.h +++ b/onnxruntime/test/framework/test_utils.h @@ -87,9 +87,11 @@ void AllocateMLValue(AllocatorPtr alloc, const std::vector& dims, OrtVa Tensor::InitOrtValue(element_type, shape, std::move(alloc), *p_mlvalue); } +using OpCountMap = std::map; + // Returns a map with the number of occurrences of each operator in the graph. // Helper function to check that the graph transformations have been successfully applied. -std::map CountOpsInGraph(const Graph& graph, bool recurse_into_subgraphs = true); +OpCountMap CountOpsInGraph(const Graph& graph, bool recurse_into_subgraphs = true); #if !defined(DISABLE_SPARSE_TENSORS) void SparseIndicesChecker(const ONNX_NAMESPACE::TensorProto& indices_proto, gsl::span expected_indicies); diff --git a/onnxruntime/test/optimizer/qdq_transformer_test.cc b/onnxruntime/test/optimizer/qdq_transformer_test.cc index d517c58a32..2a81087ef8 100644 --- a/onnxruntime/test/optimizer/qdq_transformer_test.cc +++ b/onnxruntime/test/optimizer/qdq_transformer_test.cc @@ -1774,7 +1774,7 @@ TEST(QDQTransformerTests, QDQPropagation_DQ_Q) { #endif // DISABLE_CONTRIB_OPS TEST(QDQTransformerTests, QDQ_Selector_Test) { - const ORTCHAR_T* model_file_name = ORT_TSTR("testdata/qdq_conv_model_basic.onnx"); + const ORTCHAR_T* model_file_name = ORT_TSTR("testdata/transform/qdq_conv.onnx"); SessionOptions so; // We want to keep the graph un-optimized to prevent QDQ transformer to kick in diff --git a/onnxruntime/test/optimizer/graph_runtime_optimization_test.cc b/onnxruntime/test/optimizer/runtime_optimization/graph_runtime_optimization_test.cc similarity index 56% rename from onnxruntime/test/optimizer/graph_runtime_optimization_test.cc rename to onnxruntime/test/optimizer/runtime_optimization/graph_runtime_optimization_test.cc index 8a82cbd6eb..2a2bfd55e5 100644 --- a/onnxruntime/test/optimizer/graph_runtime_optimization_test.cc +++ b/onnxruntime/test/optimizer/runtime_optimization/graph_runtime_optimization_test.cc @@ -1,33 +1,40 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#if defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) - #include #include "gtest/gtest.h" -#include "core/flatbuffers/ort_format_version.h" -#include "core/flatbuffers/schema/ort.fbs.h" -#include "core/framework/kernel_registry.h" -#include "core/framework/kernel_registry_manager.h" -#include "core/graph/graph_utils.h" -#include "core/graph/model.h" -#include "core/optimizer/selectors_actions/selector_action_transformer.h" +#include "core/session/onnxruntime_session_options_config_keys.h" #include "test/framework/test_utils.h" #include "test/util/include/asserts.h" +#include "test/util/include/inference_session_wrapper.h" #include "test/util/include/test/test_environment.h" +#if !defined(ORT_MINIMAL_BUILD) +#include "core/flatbuffers/ort_format_version.h" +#include "core/flatbuffers/schema/ort.fbs.h" +#include "core/framework/kernel_registry_manager.h" +#include "core/framework/kernel_registry.h" +#include "core/graph/graph_utils.h" +#include "core/graph/model.h" +#include "core/optimizer/graph_transformer_mgr.h" +#include "core/optimizer/selectors_actions/selector_action_transformer.h" +#endif // !defined(ORT_MINIMAL_BUILD) + namespace onnxruntime::test { +#if !defined(ORT_MINIMAL_BUILD) + +namespace { namespace sat { class TestTransformer : public SelectorActionTransformer { public: static constexpr const char* kTransformerName = "test_transformer"; static constexpr const char* kSelectorActionId = "remove_identity"; - TestTransformer(std::optional save_context) - : SelectorActionTransformer{kTransformerName, GetSelectorsAndActions(), std::move(save_context)} { + TestTransformer(const SatApplyContextVariant& apply_context) + : SelectorActionTransformer{kTransformerName, CreateSelectorActionRegistry(), apply_context} { } private: @@ -69,8 +76,8 @@ class TestTransformer : public SelectorActionTransformer { }; } - static SelectorsAndActions GetSelectorsAndActions() { - SelectorsAndActions result{}; + static SelectorActionRegistry CreateSelectorActionRegistry() { + SelectorActionRegistry result{}; auto selector = std::make_unique(); auto action = std::make_unique(kOnnxDomain, "Add", GetBinaryMoves()); result.RegisterSelectorAndAction(kSelectorActionId, {{"Add", {}}}, std::move(selector), std::move(action)); @@ -79,13 +86,14 @@ class TestTransformer : public SelectorActionTransformer { }; } // namespace sat -static std::unique_ptr CreateKernelRegistryManager() { +std::unique_ptr CreateKernelRegistryManager() { auto krm = std::make_unique(); krm->RegisterKernelRegistry(TestCPUExecutionProvider()->GetKernelRegistry()); return krm; } +} // namespace -TEST(GraphRuntimeOptimizationTest, TestTransformerSavesRuntimeOptimization) { +TEST(GraphRuntimeOptimizationTest, SaveRuntimeOptimizationToOrtFormat) { const auto logger = DefaultLoggingManager().CreateLogger("graph_runtime_optimization_test"); const auto model_path = ORT_TSTR("testdata/transform/runtime_optimization/add_with_surrounding_identities.onnx"); @@ -93,7 +101,7 @@ TEST(GraphRuntimeOptimizationTest, TestTransformerSavesRuntimeOptimization) { ASSERT_STATUS_OK(Model::Load(model_path, model, nullptr, *logger)); Graph& graph = model->MainGraph(); - const auto original_ops = CountOpsInGraph(graph); + const auto loaded_ops = CountOpsInGraph(graph); for (auto& node : graph.Nodes()) { node.SetExecutionProviderType(kCpuExecutionProvider); @@ -102,16 +110,17 @@ TEST(GraphRuntimeOptimizationTest, TestTransformerSavesRuntimeOptimization) { // run SAT to save runtime optimization { auto kernel_registry_manager = CreateKernelRegistryManager(); - auto save_context = RuntimeOptimizationSaveContext{std::cref(*kernel_registry_manager)}; - sat::TestTransformer test_transformer(std::move(save_context)); - bool modified = false; - ASSERT_STATUS_OK(test_transformer.Apply(graph, modified, *logger)); + auto save_context = SatRuntimeOptimizationSaveContext{std::cref(*kernel_registry_manager)}; + auto test_transformer = std::make_unique(save_context); + auto transformer_manager = GraphTransformerManager{/* steps */ 5}; + ASSERT_STATUS_OK(transformer_manager.Register(std::move(test_transformer), TransformerLevel::Level1)); + ASSERT_STATUS_OK(transformer_manager.ApplyTransformers(graph, TransformerLevel::Level1, *logger)); } // check that graph nodes are not updated { - const auto ops = CountOpsInGraph(graph); - EXPECT_EQ(ops, original_ops); + const auto initialized_ops = CountOpsInGraph(graph); + EXPECT_EQ(initialized_ops, loaded_ops); } flatbuffers::FlatBufferBuilder builder; @@ -163,6 +172,82 @@ TEST(GraphRuntimeOptimizationTest, TestTransformerSavesRuntimeOptimization) { } } -} // namespace onnxruntime::test +#endif // !defined(ORT_MINIMAL_BUILD) -#endif // defined(ORT_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION) +namespace { +using GraphOpCountsCheckerFn = std::function; + +void LoadAndInitializeSession(const SessionOptions& so, const PathString& input_model_path, + const GraphOpCountsCheckerFn& graph_op_count_checker_fn) { + InferenceSessionWrapper session{so, GetEnvironment()}; + + ASSERT_STATUS_OK(session.Load(input_model_path)); + + const auto loaded_ops = CountOpsInGraph(session.GetGraph()); + + ASSERT_STATUS_OK(session.Initialize()); + + const auto initialized_ops = CountOpsInGraph(session.GetGraph()); + + graph_op_count_checker_fn(loaded_ops, initialized_ops); +} + +void SaveAndLoadRuntimeOptimizationsForQdqConvsModel(bool do_save) { + constexpr auto model_path = ORT_TSTR("testdata/transform/runtime_optimization/qdq_convs.onnx"); + + // the .ort and .generated.ort files should be the same + // the .ort file is checked in and the .generated.ort file is generated by the test + const auto saved_runtime_optimizations_model_path = + do_save + ? ORT_TSTR("testdata/transform/runtime_optimization/qdq_convs.runtime_optimizations.generated.ort") + : ORT_TSTR("testdata/transform/runtime_optimization/qdq_convs.runtime_optimizations.ort"); + + // save runtime optimizations + if (do_save) { + SessionOptions so{}; + ASSERT_STATUS_OK(so.config_options.AddConfigEntry(kOrtSessionOptionsConfigSaveModelFormat, "ORT")); + ASSERT_STATUS_OK(so.config_options.AddConfigEntry(kOrtSessionOptionsConfigSaveRuntimeOptimizations, "1")); + so.graph_optimization_level = TransformerLevel::Level2; + so.optimized_model_filepath = saved_runtime_optimizations_model_path; + + ASSERT_NO_FATAL_FAILURE(LoadAndInitializeSession( + so, model_path, + [](const OpCountMap& loaded_ops, const OpCountMap& initialized_ops) { + EXPECT_EQ(initialized_ops, loaded_ops); + })); + } + + // load and replay runtime optimizations + { + SessionOptions so{}; + ASSERT_STATUS_OK(so.config_options.AddConfigEntry(kOrtSessionOptionsConfigLoadModelFormat, "ORT")); + so.graph_optimization_level = TransformerLevel::Level2; + + ASSERT_NO_FATAL_FAILURE(LoadAndInitializeSession( + so, saved_runtime_optimizations_model_path, + [](const OpCountMap& loaded_ops, const OpCountMap& initialized_ops) { + constexpr int n = 3; // expected number of QDQ Convs to fuse + + EXPECT_EQ(loaded_ops, + (OpCountMap{{{"DequantizeLinear", n * 3}, + {"QuantizeLinear", n}, + {"Conv", n}}})); + + EXPECT_EQ(initialized_ops, + (OpCountMap{{{"QLinearConv", n}}})); + })); + } +} +} // namespace + +#if !defined(ORT_MINIMAL_BUILD) +TEST(GraphRuntimeOptimizationTest, SaveAndLoadRuntimeOptimizationWithSession) { + SaveAndLoadRuntimeOptimizationsForQdqConvsModel(/* do_save */ true); +} +#endif // !defined(ORT_MINIMAL_BUILD) + +TEST(GraphRuntimeOptimizationTest, LoadRuntimeOptimizationWithSession) { + SaveAndLoadRuntimeOptimizationsForQdqConvsModel(/* do_save */ false); +} + +} // namespace onnxruntime::test diff --git a/onnxruntime/test/testdata/qdq_conv_model_basic.onnx b/onnxruntime/test/testdata/qdq_conv_model_basic.onnx deleted file mode 100644 index 4825eb28f51abf96e2cb9a2e323ca493ccac81ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 575 zcmZ{hJx{|h5QgJ?Q0sswSQQdsBBMuG5ED2VDN@8x+QmwP1(vF$v?9VlQcZ+q99Qpbyie* zs~&ZsvNb#bnf}l4^RoDqUrN8d8&c07;7!04I@=5(F{_(vc4CkVywjxC@dj`Ya7Z3{ zk3%Px9UE?0SNQ4BZJfxB(LxNrrJ=;ydXZU3+i;mie%dJ$8>dMs8=Rb!uWBhpw$V91 zqa+}aYgxNkw0+8i9Zc7(otVBMd4SJ;Bcsev1~{BLy##yMKDI+3sc|uCH9`3 a!tRCBCjzBEZ;XS*TH}lEGFS z@sWNlGh3KXJvLTnE0_YE{72)9+`g+1ZJwTM=H5;Vc>TH6Act@YYjjxEN2ScoPrA1L$RgrqL#*_yKA>@r(S8PPZ-D zZl^#RpxuFocjuvlvw!*56(eC!WgzzNo@TERop=w?$6UV6<76S1^mHKuPsGXFav`tB zGU#dNefK(gU(S+6{2PtpB$|DQsjw&8XztTI`I6sJ{QQzLD=Q3nBHCd*`>cag(g9M` zu7W?N?^JP(YX*EHv@MBB6k!m&j{1iAa*?(q=(W{l(BB)0(S|4W(a&ZQ~x>Mi8yweo-3M;l|Nea+RDnXxr}w?M}pH>Wy&_e?X1kf NwK4}+<*?~?{sFa&1YZCE literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/transform/runtime_optimization/qdq_convs.runtime_optimizations.ort b/onnxruntime/test/testdata/transform/runtime_optimization/qdq_convs.runtime_optimizations.ort new file mode 100644 index 0000000000000000000000000000000000000000..2fc70dedb3c529ebff9afbc1badabeedee6e313a GIT binary patch literal 10536 zcmb`Ne`uB08OPtWS(>%ZWiHDy=d#pgE`OA8%_KMxacwGLxKwRsT@g)|+;}gGH(9*e zAd-b4PKF!ewi1en6e*#I6W0aVN-3ojDI(I95{i>h#7PmCwOy8VE_a{reV^y%_08+l zc1Ir1bDs13KF>Mt`<|QHAPAn=)bV{f+Jiw=upp=m%E1D#AeaGeHiG}9P|&y>P+P+I zAic()2PRkD-2aF6nYG?u+_CoOKmO~HU!UD|@`2o2zuk5EJAeA~>R*1C^?C0oxizI1oKfAG8A`D}l#W3Vf?tG9n}XL^w7pzgy$VT!=&!J~Rl zQAb_FbRkD#=he|0|zWfa^V$pf@T1 zZ@|}v-bd!?tuErfT1;37?^}u?HV1Q!Sf>VbH=yeh> zMZgWf0)lTv*5$7tdkq6`BYzRuav+6#2lAcB=aC;n{%vF{fokL%k$?W9LP7PUJSk^t z%B$+k+q3X&VIYu9C(r}jL}&^-k{AETH>n}|PCz=O@5a9h1>tI#Ez(5q8p`exO%1n- z{Ni&s`;Cyk0Odnpr;fiQ&af$u{k!u6yYt&OZf_2P-hUJdvhTGh9rDSW^h?GYsVX+{ zDQ-3SHjJKw^a90s82AlP4O1I=l?};`HUz;Tdd*8tdrmQB{yA5tsxwj_v_H}D2@k}q<$e2x01_og)~`v0SB*RJiY z#kGBuoGRx@acKS2THuj?0lQ-$np7f^urKWn(^I1*4 zjicuvy`T}$xuA375=>PnkPX#fXMOUyah$!Ry(W8iIyctvZ1j5dyxh&Xafk)1`=sR!h9HK3EZ zx)`M*E-#+b@p$fLo$D>0n>+x|^Rlo(iL*BE93ie>kYmM}6qnl{h9_y?RU`NaAbG_# zTE|+__W+WWzd3T^dKli*IkKO`Xl*X){2-QVdZ=4dSg~`2XoBGBn}vebJt-c|tF^O_kFb3>H!D)Kw(fOj6 z?vr$)Nv;*po~z=Y@>>ZgTZB;@OHR1z`gZRr>xjYqf~`~ss+~K%t4wkb$cEk#CrI21 zdd2@3?gx{w6@>o!OX3K6;Tyy@^@h+L-JHx-y#IMsb{J!Pb zDZb+<_C`Q)Wq>>i4gu1mxM#jHKkkK*=LRgLb-bInm!MQ@uz(_(1kcNeHPuh-d?NA( zi}j_*wI`Bdc6q)6BN2z+jq#Wjqo4s80JO(PfKfoMR1)tA`Y}K`P|a(nhTq5X@Yd&y zW>q7KU2vy$Pf?(Xf9sctpB&@?*?4Tj4;~*%ckkAx?S{erJ=vb{yH*xk(?7Y*DG|QE zmENVu*2C~O@Sc)UJpn6GaELSW8bvh%yh@POzyNlufD>%?DO#KIs9$_M%b+93A6_|Ngy)>e;Ak`Sq;F;h$|0E{}#RvDX-gZgg9tf2e|Soo>k!L z1zUjCKs})GW}DkU&#+86Q_C4W6Qdt6`iRkGL+zN+M`LuYb+Oj$kZorCj``dMzQ}OU zvPy9G`G)E9@vM!HPlbNEUF3@Ad(lSZ8)OxHq_tRYdm=XaA~rUG-!3mXo6FG4H=Uho z2aG-vqaQQ+sL|cOaigD((Y41)^+ZzMkNCUHa9GNgfO`(^1HYZWbv9Q^FF9Yw7Ne(P z^me1S8QuNuHF{@^9$!aZ1A=3J4|A+_d>4M@n^txa+8Xn4v&rasW)XV*K<` zdXv!`jqd*GUQ+yPWAt0r5r6j*m-29hbA23M&&f$}e-0fnT}l3)vbiyO`Q_`Vdr9%X z8lzt}`h?Nl-)W;y#psK<_mWTR@o%&FDm&}J-M?mV*-G-S-R9cpCFlP28oe_{A2#}s z(cM4YGfMyA82yjt-%C6brzV?!}^d!HakLPp1dDhwRVh^4o!LH_J{PywWW@Pn%89vJK##;}&rF z?RM7L_}ZQA?8eYa**Rc#l&9AscFux(JjY^oPT6>jUgkaTr95#~UXJ*`*l_VyfxBMa zjYa*hU{2#P?x~`B!ISfZoptakPxAj~5j#WRo~Lc5*YlLKvF?WvEBU{OL1Zn$9AV={ zvvHL9tH}78Ujla-O?7j`{1)#)@KXGy$H&7quIJ7~yivWpwgyjjclD*WFAvU`Zsp-dME8}5 z?l(P}R z!vm(*^YW~XS913v-e_JDYlUaaJNV>w78x$tN^sY!-(VD%k7sSHd&jt)x%{VsX6B{4 zg9n=Kw}jKmdcZw~?}1BqQvQ2wu9IGJ{+t~)`cRDitkDk}-Qz!H^syNIE%Q(B0SgV6 zopNyZ?|qX^@=w3Ph#t^O&g-Mj=(RC=i_ud?cmLXr-WH=v-&54_UhbfjJJscRJGJbnxOmQ0zONlZf9|;FZ6v zz@WteT9yI#b5-|@^21}<3n6I+a2k!oDGT9{mayFNtmz>wx z0i%z^=*Ns6U#D@SpEiE?JFK(j;63y61V-u%m%VDc^OA2Ln~o$ubvGt@6}{x#&nBZc z#^~#ezSijO&o;(fQ*irJ&2ItW@9xs)^WaJK#@hkEEpSie_2%(FE}KB7*V`**SNi1d z1sk8E7q8nXy&q6x;hmH;hkqv`>=1>r&g?NPTMh2(xfEQwlk&92=2p^6&g*Tn(Kp2C zIiqKc?*1KM9OkL!wt14@3(2ATt$U{o;CE~fSv-0U(aLn!=zr_r`Qf^wv_EA}H@^CN z8RaLmUzKQo?pe@W{5yk-6ht4808_fd|Jr+eRQxUuJ zc_r}4>t2uZx!+#3|Mia6gg2I)imZO9^SuqHto!I5BBfs@69)*hX&Gv*`4WJ zzN_z6ewPXFts*i^9E|BzzPqwb{khyw)4*VQPd5EbQ+}{3o6F{QNYB|Azv6fPDBmP} zsv9-=tGglR+lhbr+qCe+o;yRtr=NmvjVsrkd8QkF{T`$f-hT6>SCfo4/onnxruntime/test/testdata/, so the tests for those models are skipped. # 5. Build baseline minimal ORT for Android arm64-v8a including no kernels and disable exceptions. # This step is to report the baseline binary size for Android. -# 6. Build full (6a) and extended minimal (6b) ORT with runtime optimizations enabled. +# 6. Build extended minimal ORT with runtime optimization replay enabled. # 7. Build with all optional features disabled and no kernels. # 7a: regular build with python enabled checks that the exclusions don't break code paths in a full build. -# 7b: minimal build with exceptions and python disabled checks that the exclusions don't break code paths in a +# 7b: minimal build with exceptions and python disabled checks that the exclusions don't break code paths in a # minimal build. +# 7c: extended minimal build with exceptions and python disabled checks that the exclusions don't break code paths +# in an extended minimal build. jobs: - job: Linux_CPU_Minimal_Build_E2E @@ -196,7 +198,7 @@ jobs: workingDirectory: '$(Build.BinariesDirectory)' - task: CmdLine@2 - displayName: 6a. Build full onnxruntime with runtime optimizations enabled + displayName: 6. Build extended minimal onnxruntime with runtime optimization replay enabled inputs: script: | docker run --rm \ @@ -207,37 +209,17 @@ jobs: -e BUILD_BUILDNUMBER \ onnxruntimecpubuild \ /opt/python/cp37-cp37m/bin/python3 /onnxruntime_src/tools/ci_build/build.py \ - --build_dir /build/6a --cmake_generator Ninja \ - --config Debug \ - --skip_submodule_sync \ - --build_shared_lib \ - --parallel \ - --cmake_extra_defines onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION=ON - workingDirectory: $(Build.SourcesDirectory) - - - task: CmdLine@2 - displayName: 6b. Build extended minimal onnxruntime with runtime optimizations enabled - inputs: - script: | - docker run --rm \ - --volume $(Build.SourcesDirectory):/onnxruntime_src \ - --volume $(Build.BinariesDirectory):/build \ - -e ALLOW_RELEASED_ONNX_OPSET_ONLY=1 \ - -e NIGHTLY_BUILD \ - -e BUILD_BUILDNUMBER \ - onnxruntimecpubuild \ - /opt/python/cp37-cp37m/bin/python3 /onnxruntime_src/tools/ci_build/build.py \ - --build_dir /build/6b --cmake_generator Ninja \ + --build_dir /build/6 --cmake_generator Ninja \ --config Debug \ --skip_submodule_sync \ --build_shared_lib \ --parallel \ --minimal_build extended \ - --cmake_extra_defines onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION=ON + --cmake_extra_defines onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD=ON workingDirectory: $(Build.SourcesDirectory) - task: CmdLine@2 - displayName: 7a. Regular build with python and all optional features disabled. + displayName: 7a. Regular build with python and all optional features disabled. inputs: script: | docker run --rm \ @@ -261,12 +243,11 @@ jobs: --include_ops_by_config /home/onnxruntimedev/.test_data/include_no_operators.config \ --cmake_extra_defines onnxruntime_DISABLE_SPARSE_TENSORS=ON \ onnxruntime_DISABLE_OPTIONAL_TYPE=ON \ - onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION=OFF \ - onnxruntime_BUILD_UNIT_TESTS=OFF + onnxruntime_BUILD_UNIT_TESTS=OFF workingDirectory: $(Build.SourcesDirectory) - task: CmdLine@2 - displayName: 7b. Minimal build with all optional features disabled. + displayName: 7b. Minimal build with all optional features disabled. inputs: script: | docker run --rm \ @@ -292,8 +273,38 @@ jobs: --include_ops_by_config /home/onnxruntimedev/.test_data/include_no_operators.config \ --cmake_extra_defines onnxruntime_DISABLE_SPARSE_TENSORS=ON \ onnxruntime_DISABLE_OPTIONAL_TYPE=ON \ - onnxruntime_ENABLE_ORT_FORMAT_RUNTIME_GRAPH_OPTIMIZATION=OFF \ - onnxruntime_BUILD_UNIT_TESTS=OFF + onnxruntime_BUILD_UNIT_TESTS=OFF + workingDirectory: $(Build.SourcesDirectory) + + - task: CmdLine@2 + displayName: 7c. Extended minimal build with all optional features disabled. + inputs: + script: | + docker run --rm \ + --volume $(Build.SourcesDirectory):/onnxruntime_src \ + --volume $(Build.BinariesDirectory):/build \ + --volume $(test_data_directory):/home/onnxruntimedev/.test_data \ + -e ALLOW_RELEASED_ONNX_OPSET_ONLY=1 \ + -e NIGHTLY_BUILD \ + -e BUILD_BUILDNUMBER \ + onnxruntimecpubuild \ + /opt/python/cp37-cp37m/bin/python3 /onnxruntime_src/tools/ci_build/build.py \ + --build_dir /build/7c \ + --cmake_generator Ninja \ + --config MinSizeRel \ + --skip_submodule_sync \ + --build_shared_lib \ + --parallel \ + --minimal_build extended\ + --disable_exceptions \ + --disable_ml_ops \ + --skip_tests \ + --enable_reduced_operator_type_support \ + --include_ops_by_config /home/onnxruntimedev/.test_data/include_no_operators.config \ + --cmake_extra_defines onnxruntime_DISABLE_SPARSE_TENSORS=ON \ + onnxruntime_DISABLE_OPTIONAL_TYPE=ON \ + onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD=OFF \ + onnxruntime_BUILD_UNIT_TESTS=OFF workingDirectory: $(Build.SourcesDirectory) - task: PublishTestResults@2 From 2078210a1cc2f9defc01452300ac582b0053f8cd Mon Sep 17 00:00:00 2001 From: yz Date: Mon, 3 Jan 2022 18:51:07 -0800 Subject: [PATCH 085/113] Improve logging for symbolic shape inference --- .../python/tools/symbolic_shape_infer.py | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/onnxruntime/python/tools/symbolic_shape_infer.py b/onnxruntime/python/tools/symbolic_shape_infer.py index ad878b4ed8..8fd6af49eb 100755 --- a/onnxruntime/python/tools/symbolic_shape_infer.py +++ b/onnxruntime/python/tools/symbolic_shape_infer.py @@ -3,6 +3,7 @@ # -*- coding: UTF-8 -*- import argparse +import logging import numpy as np import onnx from onnx import helper, numpy_helper, shape_inference @@ -11,6 +12,8 @@ import sympy from packaging import version assert version.parse(onnx.__version__) >= version.parse("1.8.0") +logger = logging.getLogger(__name__) + def get_attribute(node, attr_name, default_value=None): found = [attr for attr in node.attribute if attr.name == attr_name] @@ -237,7 +240,7 @@ class SymbolicShapeInference: # when nothing to map to, use the shorter one if map_to is None: if self.verbose_ > 0: - print('Potential unsafe merge between symbolic expressions: ({})'.format(','.join(symbols))) + logger.warning('Potential unsafe merge between symbolic expressions: ({})'.format(','.join(symbols))) symbols_list = list(symbols) lens = [len(s) for s in symbols_list] map_to = symbols_list[lens.index(min(lens))] @@ -286,13 +289,13 @@ class SymbolicShapeInference: if sum(is_int) == 1: int_dim = is_int.index(1) if self.verbose_ > 0: - print('dim {} has been merged with value {}'.format( + logger.debug('dim {} has been merged with value {}'.format( unique_dims[:int_dim] + unique_dims[int_dim + 1:], unique_dims[int_dim])) self._check_merged_dims(unique_dims, allow_broadcast=False) return unique_dims[int_dim] else: if self.verbose_ > 0: - print('dim {} has been mergd with dim {}'.format(unique_dims[1:], unique_dims[0])) + logger.debug('dim {} has been mergd with dim {}'.format(unique_dims[1:], unique_dims[0])) return dims[0] else: return None @@ -327,7 +330,7 @@ class SymbolicShapeInference: if self.auto_merge_: self._add_suggested_merge([dim1, dim2], apply=True) else: - print('unsupported broadcast between ' + str(dim1) + ' ' + str(dim2)) + logger.warning('unsupported broadcast between ' + str(dim1) + ' ' + str(dim2)) new_shape = [new_dim] + new_shape return new_shape @@ -426,7 +429,7 @@ class SymbolicShapeInference: def _onnx_infer_subgraph(self, node, subgraph, use_node_input=True, inc_subgraph_id=True): if self.verbose_ > 2: - print('Inferencing subgraph of node {} with output({}...): {}'.format(node.name, node.output[0], + logger.debug('Inferencing subgraph of node {} with output({}...): {}'.format(node.name, node.output[0], node.op_type)) # node inputs are not passed directly to the subgraph # it's up to the node dispatcher to prepare subgraph input @@ -997,7 +1000,7 @@ class SymbolicShapeInference: if need_second_infer: if self.verbose_ > 2: - print("Rerun Loop: {}({}...), because of sequence in loop carried variables".format( + logger.debug("Rerun Loop: {}({}...), because of sequence in loop carried variables".format( node.name, node.output[0])) self._onnx_infer_subgraph(node, subgraph, inc_subgraph_id=False) @@ -1447,7 +1450,7 @@ class SymbolicShapeInference: return index return bound + index except TypeError: - print("Cannot determine if {} < 0".format(index)) + logger.warning("Cannot determine if {} < 0".format(index)) return index if get_opset(self.out_mp_) <= 9: @@ -1502,7 +1505,7 @@ class SymbolicShapeInference: if not less_equal(e, new_sympy_shape[i]): e = new_sympy_shape[i] except Exception: - print('Unable to determine if {} <= {}, treat as equal'.format(e, new_sympy_shape[i])) + logger.warning('Unable to determine if {} <= {}, treat as equal'.format(e, new_sympy_shape[i])) e = new_sympy_shape[i] s = handle_negative_index(s, new_sympy_shape[i]) @@ -1582,8 +1585,8 @@ class SymbolicShapeInference: if self.verbose_ > 0: symbolic_dimensions = [s for s in input_shape if type(s) != int] if len(symbolic_dimensions) > 0: - print(f"Symbolic dimensions in input shape of op: '{node.op_type}' node: '{node.name}'. " + - f"Assuming the following dimensions are never equal to 1: {symbolic_dimensions}") + logger.debug(f"Symbolic dimensions in input shape of op: '{node.op_type}' node: '{node.name}'. " + + f"Assuming the following dimensions are never equal to 1: {symbolic_dimensions}") else: axes = [handle_negative_axis(a, len(input_shape)) for a in axes] output_shape = [] @@ -1593,8 +1596,8 @@ class SymbolicShapeInference: else: assert input_shape[i] == 1 or type(input_shape[i]) != int if self.verbose_ > 0 and type(input_shape[i]) != int: - print(f"Symbolic dimensions in input shape of op: '{node.op_type}' node: '{node.name}'. " + - f"Assuming the dimension '{input_shape[i]}' at index {i} of the input to be equal to 1.") + logger.debug(f"Symbolic dimensions in input shape of op: '{node.op_type}' node: '{node.name}'. " + + f"Assuming the dimension '{input_shape[i]}' at index {i} of the input to be equal to 1.") vi = self.known_vi_[node.output[0]] vi.CopyFrom( @@ -1904,9 +1907,9 @@ class SymbolicShapeInference: break if self.verbose_ > 2: - print(node.op_type + ': ' + node.name) + logger.debug(node.op_type + ': ' + node.name) for i, name in enumerate(node.input): - print(' Input {}: {} {}'.format(i, name, 'initializer' if name in self.initializers_ else '')) + logger.debug(' Input {}: {} {}'.format(i, name, 'initializer' if name in self.initializers_ else '')) # onnx automatically merge dims with value, i.e. Mul(['aaa', 'bbb'], [1000, 1]) -> [1000, 'bbb'] # symbolic shape inference needs to apply merge of 'aaa' -> 1000 in this case @@ -1932,23 +1935,23 @@ class SymbolicShapeInference: if out_type_kind == 'sequence_type': seq_cls_type = out_type.sequence_type.elem_type.WhichOneof('value') if 'tensor_type' == seq_cls_type: - print(' {}: sequence of {} {}'.format( + logger.debug(' {}: sequence of {} {}'.format( node.output[i_o], str(get_shape_from_value_info(vi)), onnx.TensorProto.DataType.Name( vi.type.sequence_type.elem_type.tensor_type.elem_type))) else: - print(' {}: sequence of {}'.format(node.output[i_o], seq_cls_type)) + logger.debug(' {}: sequence of {}'.format(node.output[i_o], seq_cls_type)) else: - print(' {}: {}'.format(node.output[i_o], out_type_kind)) + logger.debug(' {}: {}'.format(node.output[i_o], out_type_kind)) continue out_shape = get_shape_from_value_info(vi) out_type_undefined = out_type.tensor_type.elem_type == onnx.TensorProto.UNDEFINED if self.verbose_ > 2: - print(' {}: {} {}'.format(node.output[i_o], str(out_shape), + logger.debug(' {}: {} {}'.format(node.output[i_o], str(out_shape), onnx.TensorProto.DataType.Name(vi.type.tensor_type.elem_type))) if node.output[i_o] in self.sympy_data_: - print(' Sympy Data: ' + str(self.sympy_data_[node.output[i_o]])) + logger.debug(' Sympy Data: ' + str(self.sympy_data_[node.output[i_o]])) if (out_shape is not None and None in out_shape) or out_type_undefined: if self.auto_merge_: @@ -2013,25 +2016,25 @@ class SymbolicShapeInference: if self.verbose_ > 0: if is_unknown_op: - print("Possible unknown op: {} node: {}, guessing {} shape".format( - node.op_type, node.name, vi.name)) + logger.debug("Possible unknown op: {} node: {}, guessing {} shape".format( + node.op_type, node.name, vi.name)) if self.verbose_ > 2: - print(' {}: {} {}'.format(node.output[i_o], str(new_shape), - vi.type.tensor_type.elem_type)) + logger.debug(' {}: {} {}'.format(node.output[i_o], str(new_shape), + vi.type.tensor_type.elem_type)) self.run_ = True continue # continue the inference after guess, no need to stop as no merge is needed if self.verbose_ > 0 or not self.auto_merge_ or out_type_undefined: - print('Stopping at incomplete shape inference at ' + node.op_type + ': ' + node.name) - print('node inputs:') + logger.debug('Stopping at incomplete shape inference at ' + node.op_type + ': ' + node.name) + logger.debug('node inputs:') for i in node.input: - print(self.known_vi_[i]) - print('node outputs:') + logger.debug(self.known_vi_[i]) + logger.debug('node outputs:') for o in node.output: - print(self.known_vi_[o]) + logger.debug(self.known_vi_[o]) if self.auto_merge_ and not out_type_undefined: - print('Merging: ' + str(self.suggested_merge_)) + logger.debug('Merging: ' + str(self.suggested_merge_)) return False self.run_ = False @@ -2046,7 +2049,7 @@ class SymbolicShapeInference: def infer_shapes(in_mp, int_max=2**31 - 1, auto_merge=False, guess_output_rank=False, verbose=0): onnx_opset = get_opset(in_mp) if (not onnx_opset) or onnx_opset < 7: - print('Only support models of onnx opset 7 and above.') + logger.warning('Only support models of onnx opset 7 and above.') return None symbolic_shape_inference = SymbolicShapeInference(int_max, auto_merge, guess_output_rank, verbose) all_shapes_inferred = False @@ -2084,12 +2087,12 @@ def parse_arguments(): if __name__ == '__main__': args = parse_arguments() - print('input model: ' + args.input) + logger.info('input model: ' + args.input) if args.output: - print('output model ' + args.output) - print('Doing symbolic shape inference...') + logger.info('output model ' + args.output) + logger.info('Doing symbolic shape inference...') out_mp = SymbolicShapeInference.infer_shapes(onnx.load(args.input), args.int_max, args.auto_merge, args.guess_output_rank, args.verbose) if args.output and out_mp: onnx.save(out_mp, args.output) - print('Done!') + logger.info('Done!') From 2803a9465db8a2f0d4e8fb4c783b8b687faf610f Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Wed, 5 Jan 2022 09:22:15 -0800 Subject: [PATCH 086/113] Add example of registering custom cuda op as shared lib (#10025) --- cmake/onnxruntime_unittests.cmake | 14 +++++++++++--- .../InferenceTest.netcore.cs | 6 ++++++ .../test/java/ai/onnxruntime/InferenceTest.java | 3 +++ onnxruntime/test/shared_lib/test_inference.cc | 5 +++++ .../custom_op_library/custom_op_library.cc | 15 +++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 11c94655e3..aa94e05a26 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -1165,7 +1165,13 @@ if (NOT onnxruntime_ENABLE_TRAINING_TORCH_INTEROP) endif() endif() -onnxruntime_add_shared_library_module(custom_op_library ${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.cc) +if (onnxruntime_USE_CUDA) + onnxruntime_add_shared_library_module(custom_op_library ${ONNXRUNTIME_SHARED_LIB_TEST_SRC_DIR}/cuda_ops.cu + ${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.cc) + target_include_directories(custom_op_library PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) +else() + onnxruntime_add_shared_library_module(custom_op_library ${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.cc) +endif() target_include_directories(custom_op_library PRIVATE ${REPO_ROOT}/include) if(UNIX) if (APPLE) @@ -1175,8 +1181,10 @@ if(UNIX) endif() else() set(ONNXRUNTIME_CUSTOM_OP_LIB_LINK_FLAG "-DEF:${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.def") - target_compile_options(custom_op_library PRIVATE "$<$:-Xcompiler /wd26409>" - "$<$>:/wd26409>") + if (NOT onnxruntime_USE_CUDA) + target_compile_options(custom_op_library PRIVATE "$<$:-Xcompiler /wd26409>" + "$<$>:/wd26409>") + endif() endif() set_property(TARGET custom_op_library APPEND_STRING PROPERTY LINK_FLAGS ${ONNXRUNTIME_CUSTOM_OP_LIB_LINK_FLAG}) diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs index e60627158c..6e3c9c5f89 100644 --- a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs +++ b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs @@ -565,6 +565,12 @@ namespace Microsoft.ML.OnnxRuntime.Tests string libFullPath = Path.Combine(Directory.GetCurrentDirectory(), libName); Assert.True(File.Exists(libFullPath), $"Expected lib {libFullPath} does not exist."); + var ortEnvInstance = OrtEnv.Instance(); + string[] providers = ortEnvInstance.GetAvailableProviders(); + if (Array.Exists(providers, provider => provider == "CUDAExecutionProvider")) { + option.AppendExecutionProvider_CUDA(0); + } + IntPtr libraryHandle = IntPtr.Zero; try { diff --git a/java/src/test/java/ai/onnxruntime/InferenceTest.java b/java/src/test/java/ai/onnxruntime/InferenceTest.java index 0290258aeb..2fdc0b506d 100644 --- a/java/src/test/java/ai/onnxruntime/InferenceTest.java +++ b/java/src/test/java/ai/onnxruntime/InferenceTest.java @@ -1129,6 +1129,9 @@ public class InferenceTest { try (OrtEnvironment env = OrtEnvironment.getEnvironment("testLoadCustomLibrary"); SessionOptions options = new SessionOptions()) { options.registerCustomOpLibrary(customLibraryName); + if (OnnxRuntime.extractCUDA()) { + options.addCUDA(); + } try (OrtSession session = env.createSession(customOpLibraryTestModel, options)) { Map container = new HashMap<>(); diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 70878c53d3..00a42f1af1 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -778,8 +778,13 @@ lib_name = "./libcustom_op_library.so"; #endif void* library_handle = nullptr; +#ifdef USE_CUDA + TestInference(*ort_env, CUSTOM_OP_LIBRARY_TEST_MODEL_URI, inputs, "output", expected_dims_y, + expected_values_y, 1, nullptr, lib_name.c_str(), &library_handle); +#else TestInference(*ort_env, CUSTOM_OP_LIBRARY_TEST_MODEL_URI, inputs, "output", expected_dims_y, expected_values_y, 0, nullptr, lib_name.c_str(), &library_handle); +#endif #ifdef _WIN32 bool success = ::FreeLibrary(reinterpret_cast(library_handle)); diff --git a/onnxruntime/test/testdata/custom_op_library/custom_op_library.cc b/onnxruntime/test/testdata/custom_op_library/custom_op_library.cc index 9bb26b2690..2165596178 100644 --- a/onnxruntime/test/testdata/custom_op_library/custom_op_library.cc +++ b/onnxruntime/test/testdata/custom_op_library/custom_op_library.cc @@ -8,6 +8,12 @@ #include #include +#ifdef USE_CUDA +#include +template +void cuda_add(int64_t, T3*, const T1*, const T2*, cudaStream_t compute_stream); +#endif + static const char* c_OpDomain = "test.customop"; struct OrtCustomOpDomainDeleter { @@ -63,9 +69,14 @@ struct KernelOne { ort_.ReleaseTensorTypeAndShapeInfo(output_info); // Do computation +#ifdef USE_CUDA + cudaStream_t stream = reinterpret_cast(ort_.KernelContext_GetGPUComputeStream(context)); + cuda_add(size, out, X, Y, stream); +#else for (int64_t i = 0; i < size; i++) { out[i] = X[i] + Y[i]; } +#endif } private: @@ -112,6 +123,10 @@ struct CustomOpOne : Ort::CustomOpBase { const char* GetName() const { return "CustomOpOne"; }; +#ifdef USE_CUDA + const char* GetExecutionProviderType() const { return "CUDAExecutionProvider"; }; +#endif + size_t GetInputTypeCount() const { return 2; }; ONNXTensorElementDataType GetInputType(size_t /*index*/) const { return ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT; }; From 34c025109c45f6dba9b642f5153686ade7d17b9a Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Wed, 5 Jan 2022 09:22:38 -0800 Subject: [PATCH 087/113] Exclude graph_runtime_optimization_test.cc from reduced ops build. (#10191) --- cmake/onnxruntime_unittests.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index aa94e05a26..9ae293a3cf 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -233,7 +233,8 @@ else() # minimal and/or reduced ops build endif() endif() -if(NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) +if((NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_REPLAY_IN_MINIMAL_BUILD) + AND NOT onnxruntime_REDUCED_OPS_BUILD) list(APPEND onnxruntime_test_optimizer_src "${TEST_SRC_DIR}/optimizer/runtime_optimization/graph_runtime_optimization_test.cc") endif() From 7b5464ed7bdd4eda5ea33977c008538b08da9025 Mon Sep 17 00:00:00 2001 From: ashari4 <70242157+ashari4@users.noreply.github.com> Date: Wed, 5 Jan 2022 09:33:28 -0800 Subject: [PATCH 088/113] aten add_ op supports bf16 (#10084) * hand implemented add_ --- .../orttraining/eager/opgen/opgen/atenops.py | 50 ++++++------ orttraining/orttraining/eager/ort_aten.cpp | 77 ++++++++++++++++++- orttraining/orttraining/eager/ort_aten.h | 5 ++ orttraining/orttraining/eager/ort_ops.cpp | 5 +- orttraining/orttraining/eager/test/ort_ops.py | 1 + 5 files changed, 112 insertions(+), 26 deletions(-) diff --git a/orttraining/orttraining/eager/opgen/opgen/atenops.py b/orttraining/orttraining/eager/opgen/opgen/atenops.py index f8cda84df4..d3fd008ef6 100644 --- a/orttraining/orttraining/eager/opgen/opgen/atenops.py +++ b/orttraining/orttraining/eager/opgen/opgen/atenops.py @@ -25,8 +25,32 @@ class GeluGrad(ONNXOp): super().__init__('GeluGrad', 1, [{'at::kHalf', 'at::kFloat', 'at::kBFloat16'}, {'at::kHalf', 'at::kFloat', 'at::kBFloat16'}], dY, X) self.domain = kMSDomain -ops = { - # Hand-Implemented Ops +ops = {} + +for binary_op, onnx_op in { + 'add': Add('self', Mul('alpha', 'other')), + 'sub': Sub('self', Mul('alpha', 'other')), + 'mul': Mul('self', 'other'), + 'div': Div('self', 'other')}.items(): + for dtype in ['Tensor', 'Scalar']: + for variant in ['', '_']: + name = f'aten::{binary_op}{variant}.{dtype}' + if name not in ops: + ops[f'aten::{binary_op}{variant}.{dtype}'] = deepcopy(onnx_op) + +for unary_op in [ + 'abs','acos','acosh', 'asinh', 'atanh', 'asin', 'atan', 'ceil', 'cos', + 'cosh', 'erf', 'exp', 'floor', 'isnan', 'log', 'reciprocal', 'neg', 'round', + 'relu', 'selu', 'sigmoid', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'nonzero', + 'sign', 'hardsigmoid', 'isinf', 'det']: + aten_name = f'aten::{unary_op}' + onnx_op = onnx_ops[unary_op]('self') + ops[aten_name] = onnx_op + # produce the in-place variant as well for ops that support it + if unary_op not in ['isnan', 'nonzero', 'min', 'max', 'isinf', 'det']: + ops[f'{aten_name}_'] = onnx_op + +hand_implemented = { 'aten::empty.memory_format': SignatureOnly(), 'aten::empty_strided': SignatureOnly(), 'aten::zero_': SignatureOnly(), @@ -35,6 +59,7 @@ ops = { 'aten::view': SignatureOnly(), 'aten::_copy_from_and_resize' : SignatureOnly(), 'aten::addmm': Gemm('mat1', 'mat2', 'self', alpha='alpha', beta='beta'), + 'aten::add_.Tensor': SignatureOnly(), 'aten::t': Transpose('self'), 'aten::mm': MatMul('self', 'mat2'), 'aten::zeros_like': ConstantOfShape(Shape('self')), #the default constant is 0, so don't need to speicify attribute @@ -65,23 +90,4 @@ ops = { 'aten::gt.Scalar_out' : MakeTorchFallback(), } -for binary_op, onnx_op in { - 'add': Add('self', Mul('alpha', 'other')), - 'sub': Sub('self', Mul('alpha', 'other')), - 'mul': Mul('self', 'other'), - 'div': Div('self', 'other')}.items(): - for dtype in ['Tensor', 'Scalar']: - for variant in ['', '_']: - ops[f'aten::{binary_op}{variant}.{dtype}'] = deepcopy(onnx_op) - -for unary_op in [ - 'abs','acos','acosh', 'asinh', 'atanh', 'asin', 'atan', 'ceil', 'cos', - 'cosh', 'erf', 'exp', 'floor', 'isnan', 'log', 'reciprocal', 'neg', 'round', - 'relu', 'selu', 'sigmoid', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'nonzero', - 'sign', 'hardsigmoid', 'isinf', 'det']: - aten_name = f'aten::{unary_op}' - onnx_op = onnx_ops[unary_op]('self') - ops[aten_name] = onnx_op - # produce the in-place variant as well for ops that support it - if unary_op not in ['isnan', 'nonzero', 'min', 'max', 'isinf', 'det']: - ops[f'{aten_name}_'] = onnx_op +ops = {**ops, **hand_implemented} diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index d62e783805..d11db28333 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -80,16 +80,38 @@ onnxruntime::MLDataType ort_scalar_type_from_aten( OrtValue create_ort_value( onnxruntime::ORTInvoker& invoker, const at::Scalar& scalar) { - // TODO: support more types + return create_ort_value(invoker, scalar, at::kFloat); +} + +OrtValue create_ort_value( + onnxruntime::ORTInvoker& invoker, + const at::Scalar& scalar, + at::ScalarType type) { float val = scalar.toFloat(); OrtValue ort_val; CreateMLValue( invoker.GetCurrentExecutionProvider().GetAllocator(0, OrtMemTypeDefault), - ort_scalar_type_from_aten(at::kFloat), + ort_scalar_type_from_aten(type), {}, &ort_val); auto* ort_tensor = ort_val.GetMutable(); - CopyVectorToTensor(invoker, &val, 1, *ort_tensor); + switch (type) { + case at::ScalarType::Float: + CopyVectorToTensor(invoker, &val, 1, *ort_tensor); + break; + case at::ScalarType::BFloat16: { + at::BFloat16 valBFloat16 = scalar.toBFloat16(); + Ort::BFloat16_t *valOrtBFloat16 = reinterpret_cast(&valBFloat16); + CopyVectorToTensor(invoker, valOrtBFloat16, 1, *ort_tensor); + break; + } + default: + // TODO: support more types + // For most at::ScalarType, it should be safe to just call value.to<> + // on it, but for now we want to explicitly know when we've encountered + // a new scalar type while bringing up ORT eager mode. + ORT_THROW("Unsupported: at::ScalarType::", scalar.type()); + } return ort_val; } @@ -387,6 +409,55 @@ at::Tensor& zero_(at::Tensor& self){ return self; } +// TODO: enhance opgen.py to support inplace binary operations. +// aten::add_.Tensor(Tensor(a!) self, Tensor other, *, Scalar alpha=1) -> Tensor(a!) +at::Tensor& add__Tensor( + at::Tensor& self, + const at::Tensor& other, + const at::Scalar& alpha) { + ORT_LOG_FN(self, other, alpha); + + if ( + !IsSupportedType(alpha, {at::kDouble,at::kLong,at::kHalf,at::kShort,at::kInt,at::kByte,at::kFloat,at::kBFloat16}) || + !IsSupportedType(other, {at::kDouble,at::kLong,at::kHalf,at::kShort,at::kInt,at::kByte,at::kFloat,at::kBFloat16}) || + !IsSupportedType(self, {at::kDouble,at::kLong,at::kHalf,at::kShort,at::kInt,at::kByte,at::kFloat,at::kBFloat16})) { + return at::native::call_fallback_fn< + &at::native::cpu_fallback, + ATEN_OP(add__Tensor)>::call(self, other, alpha); + } + auto& invoker = GetORTInvoker(self.device()); + + auto ort_input_alpha = create_ort_value(invoker, alpha, other.scalar_type()); + auto ort_input_other = create_ort_value(invoker, other); + + std::vector ort_outputs_0_Mul(1); + + auto status = invoker.Invoke("Mul", { + std::move(ort_input_alpha), + std::move(ort_input_other), + }, ort_outputs_0_Mul, nullptr); + + if (!status.IsOK()) + throw std::runtime_error( + "ORT return failure status:" + status.ErrorMessage()); + + auto ort_input_self = create_ort_value(invoker, self); + + std::vector ort_outputs_1_Add(1); + ort_outputs_1_Add[0] = ort_input_self; + + status = invoker.Invoke("Add", { + std::move(ort_input_self), + std::move(ort_outputs_0_Mul[0]), + }, ort_outputs_1_Add, nullptr); + + if (!status.IsOK()) + throw std::runtime_error( + "ORT return failure status:" + status.ErrorMessage()); + + return self; +} + } // namespace aten //#pragma endregion diff --git a/orttraining/orttraining/eager/ort_aten.h b/orttraining/orttraining/eager/ort_aten.h index fc560914e2..58bdf626d3 100644 --- a/orttraining/orttraining/eager/ort_aten.h +++ b/orttraining/orttraining/eager/ort_aten.h @@ -28,6 +28,11 @@ OrtValue create_ort_value( onnxruntime::ORTInvoker& invoker, const at::Scalar& scalar); +OrtValue create_ort_value( + onnxruntime::ORTInvoker& invoker, + const at::Scalar& scalar, + at::ScalarType type); + OrtValue create_ort_value( onnxruntime::ORTInvoker& invoker, const at::Tensor& tensor); diff --git a/orttraining/orttraining/eager/ort_ops.cpp b/orttraining/orttraining/eager/ort_ops.cpp index 9b5f2e8f50..473b92c315 100644 --- a/orttraining/orttraining/eager/ort_ops.cpp +++ b/orttraining/orttraining/eager/ort_ops.cpp @@ -30,8 +30,11 @@ void createInplaceOutputValue(OrtValue& input, V shape, OrtValue* p_mlv element_type, new_shape, p_mlvalue); } +template +using Vector = std::vector>; + template <> -void createInplaceOutputValue(OrtValue& input, std::vector shape, OrtValue* p_mlvalue){ +void createInplaceOutputValue(OrtValue& input, Vector shape, OrtValue* p_mlvalue){ auto* input_ort_tensor = input.GetMutable(); auto element_type = onnxruntime::DataTypeImpl::GetType(); CreateMLValue(input_ort_tensor->MutableDataRaw(), diff --git a/orttraining/orttraining/eager/test/ort_ops.py b/orttraining/orttraining/eager/test/ort_ops.py index f8f27e163a..84be88d73a 100644 --- a/orttraining/orttraining/eager/test/ort_ops.py +++ b/orttraining/orttraining/eager/test/ort_ops.py @@ -34,6 +34,7 @@ class OrtOpTests(unittest.TestCase): torch.mul(cpu_ones, cpu_ones), torch.mul(ort_ones, ort_ones).cpu()) + # TODO: Add BFloat16 test coverage def test_add_(self): device = self.get_device() cpu_ones = torch.Tensor([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) From 4ab891999a04e2aeee2377fb7fae69f2d6f6749f Mon Sep 17 00:00:00 2001 From: ashari4 <70242157+ashari4@users.noreply.github.com> Date: Thu, 6 Jan 2022 09:28:22 -0800 Subject: [PATCH 089/113] fix hardcoded type (#10205) --- orttraining/orttraining/eager/ort_aten.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orttraining/orttraining/eager/ort_aten.h b/orttraining/orttraining/eager/ort_aten.h index 58bdf626d3..bb235aa2ac 100644 --- a/orttraining/orttraining/eager/ort_aten.h +++ b/orttraining/orttraining/eager/ort_aten.h @@ -51,7 +51,7 @@ OrtValue create_ort_value( {1,}, &ort_val); auto* ort_tensor = ort_val.GetMutable(); - CopyVectorToTensor(invoker, &val, 1, *ort_tensor); + CopyVectorToTensor(invoker, &val, 1, *ort_tensor); return ort_val; } From 08f512b25e1624be166d6dd0284e2e737b8c994a Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Thu, 6 Jan 2022 09:46:34 -0800 Subject: [PATCH 090/113] Fix a Win GPU reduced ops pipeline (#10202) --- onnxruntime/test/shared_lib/test_inference.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 00a42f1af1..4d033432d8 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -744,6 +744,9 @@ TEST(CApiTest, RegisterCustomOpForCPUAndCUDA) { //It has memory leak. The OrtCustomOpDomain created in custom_op_library.cc:RegisterCustomOps function was not freed #if defined(__ANDROID__) TEST(CApiTest, DISABLED_test_custom_op_library) { +//To accomodate a reduced op build pipeline +#elif defined(REDUCED_OPS_BUILD) && defined(USE_CUDA) +TEST(CApiTest, DISABLED_test_custom_op_library) { #else TEST(CApiTest, test_custom_op_library) { #endif From 0552a47ec2791a5f32fd768c6dad0cccb044117b Mon Sep 17 00:00:00 2001 From: Hariharan Seshadri Date: Thu, 6 Jan 2022 11:03:14 -0800 Subject: [PATCH 091/113] Enable CUDA provider option configuration for C# (#10188) --- .../NativeMethods.shared.cs | 81 ++++++++++ .../ProviderOptions.shared.cs | 98 ++++++++++++ .../SessionOptions.shared.cs | 38 ++++- .../InferenceTest.netcore.cs | 62 ++++++++ .../onnxruntime/core/common/string_helper.h | 2 +- .../providers/cuda/cuda_provider_options.h | 28 ++++ .../tensorrt}/tensorrt_provider_options.h | 4 +- .../core/session/onnxruntime_c_api.h | 80 +++++++++- .../cuda/cuda_execution_provider_info.cc | 14 ++ .../cuda/cuda_execution_provider_info.h | 1 + .../providers/cuda/cuda_provider_factory.cc | 26 ++- onnxruntime/core/session/onnxruntime_c_api.cc | 15 +- onnxruntime/core/session/ort_apis.h | 9 ++ .../core/session/provider_bridge_ort.cc | 149 +++++++++++++++++- onnxruntime/core/session/provider_stubs.cc | 36 +++++ onnxruntime/test/shared_lib/test_inference.cc | 46 +++++- onnxruntime/test/shared_lib/utils.cc | 8 + .../test/util/include/default_providers.h | 1 + 18 files changed, 683 insertions(+), 15 deletions(-) create mode 100644 include/onnxruntime/core/providers/cuda/cuda_provider_options.h rename include/onnxruntime/core/{platform => providers/tensorrt}/tensorrt_provider_options.h (94%) diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs index ba774b44e9..5b3c05e9c9 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs +++ b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs @@ -235,6 +235,11 @@ namespace Microsoft.ML.OnnxRuntime public IntPtr SetGlobalCustomJoinThreadFn; public IntPtr SynchronizeBoundInputs; public IntPtr SynchronizeBoundOutputs; + public IntPtr SessionOptionsAppendExecutionProvider_CUDA_V2; + public IntPtr CreateCUDAProviderOptions; + public IntPtr UpdateCUDAProviderOptions; + public IntPtr GetCUDAProviderOptionsAsString; + public IntPtr ReleaseCUDAProviderOptions; } internal static class NativeMethods @@ -397,6 +402,15 @@ namespace Microsoft.ML.OnnxRuntime OrtUpdateTensorRTProviderOptions = (DOrtUpdateTensorRTProviderOptions)Marshal.GetDelegateForFunctionPointer(api_.UpdateTensorRTProviderOptions, typeof(DOrtUpdateTensorRTProviderOptions)); OrtGetTensorRTProviderOptionsAsString = (DOrtGetTensorRTProviderOptionsAsString)Marshal.GetDelegateForFunctionPointer(api_.GetTensorRTProviderOptionsAsString, typeof(DOrtGetTensorRTProviderOptionsAsString)); OrtReleaseTensorRTProviderOptions = (DOrtReleaseTensorRTProviderOptions)Marshal.GetDelegateForFunctionPointer(api_.ReleaseTensorRTProviderOptions, typeof(DOrtReleaseTensorRTProviderOptions)); + + SessionOptionsAppendExecutionProvider_CUDA = (DSessionOptionsAppendExecutionProvider_CUDA)Marshal.GetDelegateForFunctionPointer( + api_.SessionOptionsAppendExecutionProvider_CUDA, typeof(DSessionOptionsAppendExecutionProvider_CUDA)); + SessionOptionsAppendExecutionProvider_CUDA_V2 = (DSessionOptionsAppendExecutionProvider_CUDA_V2)Marshal.GetDelegateForFunctionPointer( + api_.SessionOptionsAppendExecutionProvider_CUDA_V2, typeof(DSessionOptionsAppendExecutionProvider_CUDA_V2)); + OrtCreateCUDAProviderOptions = (DOrtCreateCUDAProviderOptions)Marshal.GetDelegateForFunctionPointer(api_.CreateCUDAProviderOptions, typeof(DOrtCreateCUDAProviderOptions)); + OrtUpdateCUDAProviderOptions = (DOrtUpdateCUDAProviderOptions)Marshal.GetDelegateForFunctionPointer(api_.UpdateCUDAProviderOptions, typeof(DOrtUpdateCUDAProviderOptions)); + OrtGetCUDAProviderOptionsAsString = (DOrtGetCUDAProviderOptionsAsString)Marshal.GetDelegateForFunctionPointer(api_.GetCUDAProviderOptionsAsString, typeof(DOrtGetCUDAProviderOptionsAsString)); + OrtReleaseCUDAProviderOptions = (DOrtReleaseCUDAProviderOptions)Marshal.GetDelegateForFunctionPointer(api_.ReleaseCUDAProviderOptions, typeof(DOrtReleaseCUDAProviderOptions)); } [DllImport(NativeLib.DllName, CharSet = CharSet.Ansi)] @@ -469,6 +483,49 @@ namespace Microsoft.ML.OnnxRuntime public delegate void DOrtReleaseTensorRTProviderOptions(IntPtr /*(OrtTensorRTProviderOptions*)*/ trtProviderOptionsInstance); public static DOrtReleaseTensorRTProviderOptions OrtReleaseTensorRTProviderOptions; + /// + /// Creates native OrtCUDAProviderOptions instance + /// + /// (output) native instance of OrtCUDAProviderOptions + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate IntPtr /* OrtStatus* */DOrtCreateCUDAProviderOptions( + out IntPtr /*(OrtCUDAProviderOptions**)*/ cudaProviderOptionsInstance); + public static DOrtCreateCUDAProviderOptions OrtCreateCUDAProviderOptions; + + /// + /// Updates native OrtCUDAProviderOptions instance using given key/value pairs + /// + /// native instance of OrtCUDAProviderOptions + /// configuration keys of OrtCUDAProviderOptions + /// configuration values of OrtCUDAProviderOptions + /// number of configuration keys + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate IntPtr /* OrtStatus* */DOrtUpdateCUDAProviderOptions( + IntPtr /*(OrtCUDAProviderOptions*)*/ cudaProviderOptionsInstance, + IntPtr[] /*(const char* const *)*/ providerOptionsKeys, + IntPtr[] /*(const char* const *)*/ providerOptionsValues, + UIntPtr /*(size_t)*/ numKeys); + public static DOrtUpdateCUDAProviderOptions OrtUpdateCUDAProviderOptions; + + /// + /// Get native OrtCUDAProviderOptionsV2 in serialized string + /// + /// instance of OrtAllocator + /// is a UTF-8 null terminated string allocated using 'allocator' + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate IntPtr /* OrtStatus* */DOrtGetCUDAProviderOptionsAsString( + IntPtr /*(OrtCUDAProviderOptionsV2**)*/ cudaProviderOptionsInstance, + IntPtr /*(OrtAllocator*)*/ allocator, + out IntPtr /*(char**)*/ptr); + public static DOrtGetCUDAProviderOptionsAsString OrtGetCUDAProviderOptionsAsString; + + /// + /// Releases native OrtCUDAProviderOptions instance + /// + /// native instance of OrtCUDAProviderOptions to be released + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate void DOrtReleaseCUDAProviderOptions(IntPtr /*(OrtCUDAProviderOptions*)*/ cudaProviderOptionsInstance); + public static DOrtReleaseCUDAProviderOptions OrtReleaseCUDAProviderOptions; #endregion #region Status API @@ -820,6 +877,30 @@ namespace Microsoft.ML.OnnxRuntime public static DSessionOptionsAppendExecutionProvider_TensorRT_V2 SessionOptionsAppendExecutionProvider_TensorRT_V2; + /// + /// Append a CUDA EP instance (configured based on given provider options) to the native OrtSessionOptions instance + /// + /// Native OrtSessionOptions instance + /// Native OrtCUDAProviderOptions instance + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate IntPtr /*(OrtStatus*)*/DSessionOptionsAppendExecutionProvider_CUDA( + IntPtr /*(OrtSessionOptions*)*/ options, + IntPtr /*(const OrtCUDAProviderOptions*)*/ cudaProviderOptions); + + public static DSessionOptionsAppendExecutionProvider_CUDA SessionOptionsAppendExecutionProvider_CUDA; + + /// + /// Append a CUDA EP instance (configured based on given provider options) to the native OrtSessionOptions instance + /// + /// Native OrtSessionOptions instance + /// Native OrtCUDAProviderOptionsV2 instance + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate IntPtr /*(OrtStatus*)*/DSessionOptionsAppendExecutionProvider_CUDA_V2( + IntPtr /*(OrtSessionOptions*)*/ options, + IntPtr /*(const OrtCUDAProviderOptionsV2*)*/ cudaProviderOptions); + + public static DSessionOptionsAppendExecutionProvider_CUDA_V2 SessionOptionsAppendExecutionProvider_CUDA_V2; + /// /// Free Dimension override (by denotation) /// diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/ProviderOptions.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/ProviderOptions.shared.cs index c9e3071e84..5e6f1b8ec3 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/ProviderOptions.shared.cs +++ b/csharp/src/Microsoft.ML.OnnxRuntime/ProviderOptions.shared.cs @@ -120,6 +120,104 @@ namespace Microsoft.ML.OnnxRuntime #endregion } + + /// + /// Holds the options for configuring a CUDA Execution Provider instance + /// + public class OrtCUDAProviderOptions : SafeHandle + { + internal IntPtr Handle + { + get + { + return handle; + } + } + + + #region Constructor + + /// + /// Constructs an empty OrtCUDAroviderOptions instance + /// + public OrtCUDAProviderOptions() : base(IntPtr.Zero, true) + { + NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateCUDAProviderOptions(out handle)); + } + + #endregion + + #region Public Methods + + /// + /// Get CUDA EP provider options + /// + /// return C# UTF-16 encoded string + public string GetOptions() + { + var allocator = OrtAllocator.DefaultInstance; + + // Process provider options string + IntPtr providerOptions = IntPtr.Zero; + NativeApiStatus.VerifySuccess(NativeMethods.OrtGetCUDAProviderOptionsAsString(handle, allocator.Pointer, out providerOptions)); + using (var ortAllocation = new OrtMemoryAllocation(allocator, providerOptions, 0)) + { + return NativeOnnxValueHelper.StringFromNativeUtf8(providerOptions); + } + } + + /// + /// Updates the configuration knobs of OrtCUDAProviderOptions that will eventually be used to configure a CUDA EP + /// Please refer to the following on different key/value pairs to configure a CUDA EP and their meaning: + /// https://www.onnxruntime.ai/docs/reference/execution-providers/CUDA-ExecutionProvider.html + /// + /// key/value pairs used to configure a CUDA Execution Provider + public void UpdateOptions(Dictionary providerOptions) + { + + using (var cleanupList = new DisposableList()) + { + var keysArray = NativeOnnxValueHelper.ConvertNamesToUtf8(providerOptions.Keys.ToArray(), n => n, cleanupList); + var valuesArray = NativeOnnxValueHelper.ConvertNamesToUtf8(providerOptions.Values.ToArray(), n => n, cleanupList); + + NativeApiStatus.VerifySuccess(NativeMethods.OrtUpdateCUDAProviderOptions(handle, keysArray, valuesArray, (UIntPtr)providerOptions.Count)); + } + } + + #endregion + + #region Public Properties + + /// + /// Overrides SafeHandle.IsInvalid + /// + /// returns true if handle is equal to Zero + public override bool IsInvalid { get { return handle == IntPtr.Zero; } } + + #endregion + + #region Private Methods + + + #endregion + + #region SafeHandle + /// + /// Overrides SafeHandle.ReleaseHandle() to properly dispose of + /// the native instance of OrtCUDAProviderOptions + /// + /// always returns true + protected override bool ReleaseHandle() + { + NativeMethods.OrtReleaseCUDAProviderOptions(handle); + handle = IntPtr.Zero; + return true; + } + + #endregion + } + + /// /// This helper class contains methods to handle values of provider options /// diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs index ef7140a3ec..34db0bd12f 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs +++ b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs @@ -66,6 +66,28 @@ namespace Microsoft.ML.OnnxRuntime return options; } + /// + /// A helper method to construct a SessionOptions object for CUDA execution provider. + /// Use only if CUDA is installed and you have the onnxruntime package specific to this Execution Provider. + /// + /// CUDA EP provider options + /// A SessionsOptions() object configured for execution on provider options + public static SessionOptions MakeSessionOptionWithCudaProvider(OrtCUDAProviderOptions cudaProviderOptions) + { + CheckCudaExecutionProviderDLLs(); + SessionOptions options = new SessionOptions(); + try + { + options.AppendExecutionProvider_CUDA(cudaProviderOptions); + return options; + } + catch (Exception) + { + options.Dispose(); + throw; + } + } + /// /// A helper method to construct a SessionOptions object for TensorRT execution. /// Use only if CUDA/TensorRT are installed and you have the onnxruntime package specific to this Execution Provider. @@ -191,6 +213,20 @@ namespace Microsoft.ML.OnnxRuntime #endif } + /// + /// Append a CUDA EP instance (based on specified configuration) to the SessionOptions instance. + /// Use only if you have the onnxruntime package specific to this Execution Provider. + /// + /// CUDA EP provider options + public void AppendExecutionProvider_CUDA(OrtCUDAProviderOptions cudaProviderOptions) + { +#if __MOBILE__ + throw new NotSupportedException("The CUDA Execution Provider is not supported in this build"); +#else + NativeApiStatus.VerifySuccess(NativeMethods.SessionOptionsAppendExecutionProvider_CUDA_V2(handle, cudaProviderOptions.Handle)); +#endif + } + /// /// Use only if you have the onnxruntime package specific to this Execution Provider. /// @@ -245,7 +281,7 @@ namespace Microsoft.ML.OnnxRuntime #if __MOBILE__ throw new NotSupportedException("The TensorRT Execution Provider is not supported in this build"); #else - NativeApiStatus.VerifySuccess(NativeMethods.SessionOptionsAppendExecutionProvider_TensorRT(handle, trtProviderOptions.Handle)); + NativeApiStatus.VerifySuccess(NativeMethods.SessionOptionsAppendExecutionProvider_TensorRT_V2(handle, trtProviderOptions.Handle)); #endif } diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs index 6e3c9c5f89..139d588f27 100644 --- a/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs +++ b/csharp/test/Microsoft.ML.OnnxRuntime.Tests.NetCoreApp/InferenceTest.netcore.cs @@ -46,6 +46,68 @@ namespace Microsoft.ML.OnnxRuntime.Tests } } +#if USE_CUDA + + [Fact(DisplayName = "TestCUDAProviderOptions")] + private void TestCUDAProviderOptions() + { + string modelPath = Path.Combine(Directory.GetCurrentDirectory(), "squeezenet.onnx"); + + using (var cleanUp = new DisposableListTest()) + { + var cudaProviderOptions = new OrtCUDAProviderOptions(); + cleanUp.Add(cudaProviderOptions); + + var providerOptionsDict = new Dictionary(); + providerOptionsDict["device_id"] = "0"; + providerOptionsDict["gpu_mem_limit"] = "20971520"; + providerOptionsDict["arena_extend_strategy"] = "kSameAsRequested"; + providerOptionsDict["cudnn_conv_algo_search"] = "DEFAULT"; + providerOptionsDict["do_copy_in_default_stream"] = "1"; + providerOptionsDict["cudnn_conv_use_max_workspace"] = "1"; + cudaProviderOptions.UpdateOptions(providerOptionsDict); + + var resultProviderOptionsDict = new Dictionary(); + ProviderOptionsValueHelper.StringToDict(cudaProviderOptions.GetOptions(), resultProviderOptionsDict); + + // test provider options configuration + string value; + value = resultProviderOptionsDict["device_id"]; + Assert.Equal("0", value); + value = resultProviderOptionsDict["gpu_mem_limit"]; + Assert.Equal("20971520", value); + value = resultProviderOptionsDict["arena_extend_strategy"]; + Assert.Equal("kSameAsRequested", value); + value = resultProviderOptionsDict["cudnn_conv_algo_search"]; + Assert.Equal("DEFAULT", value); + value = resultProviderOptionsDict["do_copy_in_default_stream"]; + Assert.Equal("1", value); + value = resultProviderOptionsDict["cudnn_conv_use_max_workspace"]; + Assert.Equal("1", value); + + // test correctness of provider options + SessionOptions options = SessionOptions.MakeSessionOptionWithCudaProvider(cudaProviderOptions); + cleanUp.Add(options); + + var session = new InferenceSession(modelPath, options); + cleanUp.Add(session); + + var inputMeta = session.InputMetadata; + var container = new List(); + float[] inputData = TestDataLoader.LoadTensorFromFile(@"bench.in"); // this is the data for only one input tensor for this model + foreach (var name in inputMeta.Keys) + { + Assert.Equal(typeof(float), inputMeta[name].ElementType); + Assert.True(inputMeta[name].IsTensor); + var tensor = new DenseTensor(inputData, inputMeta[name].Dimensions); + container.Add(NamedOnnxValue.CreateFromTensor(name, tensor)); + } + + session.Run(container); + } + } +#endif + #if USE_TENSORRT [Fact(DisplayName = "CanRunInferenceOnAModelWithTensorRT")] private void CanRunInferenceOnAModelWithTensorRT() diff --git a/include/onnxruntime/core/common/string_helper.h b/include/onnxruntime/core/common/string_helper.h index 09f153ff1e..ea6ff75f64 100644 --- a/include/onnxruntime/core/common/string_helper.h +++ b/include/onnxruntime/core/common/string_helper.h @@ -6,7 +6,7 @@ #include "core/session/onnxruntime_c_api.h" namespace onnxruntime { -#ifdef USE_TENSORRT +#if defined(USE_TENSORRT) || defined(USE_CUDA) static char* StrDup(const std::string& str, _Inout_ OrtAllocator* allocator) { char* output_string = reinterpret_cast(allocator->Alloc(allocator, str.size() + 1)); memcpy(output_string, str.c_str(), str.size()); diff --git a/include/onnxruntime/core/providers/cuda/cuda_provider_options.h b/include/onnxruntime/core/providers/cuda/cuda_provider_options.h new file mode 100644 index 0000000000..4c931e2ec4 --- /dev/null +++ b/include/onnxruntime/core/providers/cuda/cuda_provider_options.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "onnxruntime_c_api.h" +#include "core/framework/arena_extend_strategy.h" + +/// +/// Options for the CUDA provider that are passed to SessionOptionsAppendExecutionProvider_CUDA_V2. +/// Please note that this struct is *similar* to OrtCUDAProviderOptions but only to be used internally. +/// Going forward, new cuda provider options are to be supported via this struct and usage of the publicly defined +/// OrtCUDAProviderOptions will be deprecated over time. +/// User can only get the instance of OrtCUDAProviderOptionsV2 via CreateCUDAProviderOptions. +/// +struct OrtCUDAProviderOptionsV2 { + int device_id; // cuda device id. + int has_user_compute_stream; // indicator of user specified CUDA compute stream. + void* user_compute_stream; // user specified CUDA compute stream. + int do_copy_in_default_stream; // flag specifying if the default stream is to be used for copying. + OrtCudnnConvAlgoSearch cudnn_conv_algo_search; // cudnn algo search enum. + size_t gpu_mem_limit; // BFC Arena memory limit for CUDA. + // (will be overridden by contents of `default_memory_arena_cfg` is it exists) + onnxruntime::ArenaExtendStrategy arena_extend_strategy; // BFC Arena extension strategy. + // (will be overridden by contents of `default_memory_arena_cfg` is it exists) + OrtArenaCfg* default_memory_arena_cfg; // BFC Arena config flags. + int cudnn_conv_use_max_workspace; // flag specifying if maximum workspace can be used in cudnn conv algo search. +}; diff --git a/include/onnxruntime/core/platform/tensorrt_provider_options.h b/include/onnxruntime/core/providers/tensorrt/tensorrt_provider_options.h similarity index 94% rename from include/onnxruntime/core/platform/tensorrt_provider_options.h rename to include/onnxruntime/core/providers/tensorrt/tensorrt_provider_options.h index 9f5f0ba546..43b0b938f1 100644 --- a/include/onnxruntime/core/platform/tensorrt_provider_options.h +++ b/include/onnxruntime/core/providers/tensorrt/tensorrt_provider_options.h @@ -5,8 +5,8 @@ /// /// Options for the TensorRT provider that are passed to SessionOptionsAppendExecutionProvider_TensorRT_V2. -/// Please note that this sturct is identical to OrtTensorRTProviderOptions but only to be used internally. -// User can only get the instance of OrtTensorRTProviderOptionsV2 via CreateTensorRTProviderOptions. +/// Please note that this struct is identical to OrtTensorRTProviderOptions but only to be used internally. +/// User can only get the instance of OrtTensorRTProviderOptionsV2 via CreateTensorRTProviderOptions. /// struct OrtTensorRTProviderOptionsV2 { int device_id; // cuda device id. diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 8c32416061..92f27b685a 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -30,7 +30,7 @@ * * This value is used by some API functions to behave as this version of the header expects. */ -#define ORT_API_VERSION 10 +#define ORT_API_VERSION 11 #ifdef __cplusplus extern "C" { @@ -256,6 +256,7 @@ ORT_RUNTIME_CLASS(ThreadingOptions); ORT_RUNTIME_CLASS(ArenaCfg); ORT_RUNTIME_CLASS(PrepackedWeightsContainer); ORT_RUNTIME_CLASS(TensorRTProviderOptionsV2); +ORT_RUNTIME_CLASS(CUDAProviderOptionsV2); #ifdef _WIN32 typedef _Return_type_success_(return == 0) OrtStatus* OrtStatusPtr; @@ -536,7 +537,7 @@ ORT_EXPORT const OrtApiBase* ORT_API_CALL OrtGetApiBase(void) NO_EXCEPTION; */ typedef void (*OrtThreadWorkerFn)(void* ort_worker_fn_param); -typedef const struct OrtCustomHandleType{ char __place_holder; }* OrtCustomThreadHandle; +typedef const struct OrtCustomHandleType { char __place_holder; } * OrtCustomThreadHandle; /** \brief Ort custom thread creation function * @@ -3185,6 +3186,81 @@ struct OrtApi { * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(SynchronizeBoundOutputs, _Inout_ OrtIoBinding* binding_ptr); + + /// \name OrtSessionOptions + /// @{ + + /** \brief Append CUDA execution provider to the session options + * + * If CUDA is not available (due to a non CUDA enabled build), this function will return failure. + * + * This is slightly different from OrtApi::SessionOptionsAppendExecutionProvider_CUDA, it takes an + * ::OrtCUDAProviderOptions which is publicly defined. This takes an opaque ::OrtCUDAProviderOptionsV2 + * which must be created with OrtApi::CreateCUDAProviderOptions. + * + * For OrtApi::SessionOptionsAppendExecutionProvider_CUDA, the user needs to instantiate ::OrtCUDAProviderOptions + * as well as allocate/release buffers for some members of ::OrtCUDAProviderOptions. + * Here, OrtApi::CreateCUDAProviderOptions and Ortapi::ReleaseCUDAProviderOptions will do the memory management for you. + * + * \param[in] options + * \param[in] cuda_options + * + * \snippet{doc} snippets.dox OrtStatus Return Value + */ + ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_CUDA_V2, + _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptionsV2* cuda_options); + + /// @} + /// \name OrtCUDAProviderOptionsV2 + /// @{ + + /** \brief Create an OrtCUDAProviderOptionsV2 + * + * \param[out] out Newly created ::OrtCUDAProviderOptionsV2. Must be released with OrtApi::ReleaseCudaProviderOptions + * + * \snippet{doc} snippets.dox OrtStatus Return Value + */ + ORT_API2_STATUS(CreateCUDAProviderOptions, _Outptr_ OrtCUDAProviderOptionsV2** out); + + /** \brief Set options in a CUDA Execution Provider. + * + * Please refer to https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html#configuration-options + * to know the available keys and values. Key should be in null terminated string format of the member of ::OrtCUDAProviderOptionsV2 + * and value should be its related range. + * + * For example, key="device_id" and value="0" + * + * \param[in] cuda_options + * \param[in] provider_options_keys Array of UTF-8 null-terminated string for provider options keys + * \param[in] provider_options_values Array of UTF-8 null-terminated string for provider options values + * \param[in] num_keys Number of elements in the `provider_option_keys` and `provider_options_values` arrays + * + * \snippet{doc} snippets.dox OrtStatus Return Value + */ + ORT_API2_STATUS(UpdateCUDAProviderOptions, _Inout_ OrtCUDAProviderOptionsV2* cuda_options, + _In_reads_(num_keys) const char* const* provider_options_keys, + _In_reads_(num_keys) const char* const* provider_options_values, + _In_ size_t num_keys); + + /** + * Get serialized CUDA provider options string. + * + * For example, "device_id=0;arena_extend_strategy=0;......" + * + * \param cuda_options - OrtCUDAProviderOptionsV2 instance + * \param allocator - a ptr to an instance of OrtAllocator obtained with CreateAllocator() or GetAllocatorWithDefaultOptions() + * the specified allocator will be used to allocate continuous buffers for output strings and lengths. + * \param ptr - is a UTF-8 null terminated string allocated using 'allocator'. The caller is responsible for using the same allocator to free it. + */ + ORT_API2_STATUS(GetCUDAProviderOptionsAsString, _In_ const OrtCUDAProviderOptionsV2* cuda_options, _Inout_ OrtAllocator* allocator, _Outptr_ char** ptr); + + /** \brief Release an ::OrtCUDAProviderOptionsV2 + * + * \note This is an exception in the naming convention of other Release* functions, as the name of the method does not have the V2 suffix, but the type does + */ + void(ORT_API_CALL* ReleaseCUDAProviderOptions)(_Frees_ptr_opt_ OrtCUDAProviderOptionsV2* input); + + /// @} }; /* diff --git a/onnxruntime/core/providers/cuda/cuda_execution_provider_info.cc b/onnxruntime/core/providers/cuda/cuda_execution_provider_info.cc index 2214f0840f..5a043b86a1 100644 --- a/onnxruntime/core/providers/cuda/cuda_execution_provider_info.cc +++ b/onnxruntime/core/providers/cuda/cuda_execution_provider_info.cc @@ -3,6 +3,7 @@ #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_execution_provider_info.h" +#include "core/providers/cuda/cuda_provider_options.h" #include "core/common/make_string.h" #include "core/common/parse_string.h" @@ -116,4 +117,17 @@ ProviderOptions CUDAExecutionProviderInfo::ToProviderOptions(const CUDAExecution return options; } +ProviderOptions CUDAExecutionProviderInfo::ToProviderOptions(const OrtCUDAProviderOptionsV2& info) { + const ProviderOptions options{ + {cuda::provider_option_names::kDeviceId, MakeStringWithClassicLocale(info.device_id)}, + {cuda::provider_option_names::kMemLimit, MakeStringWithClassicLocale(info.gpu_mem_limit)}, + {cuda::provider_option_names::kArenaExtendStrategy, EnumToName(*arena_extend_strategy_mapping, info.arena_extend_strategy)}, + {cuda::provider_option_names::kCudnnConvAlgoSearch, EnumToName(*ort_cudnn_conv_algo_search_mapping, info.cudnn_conv_algo_search)}, + {cuda::provider_option_names::kDoCopyInDefaultStream, MakeStringWithClassicLocale(info.do_copy_in_default_stream)}, + {cuda::provider_option_names::kCudnnConvUseMaxWorkspace, MakeStringWithClassicLocale(info.cudnn_conv_use_max_workspace)}, + }; + + return options; +} + } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cuda/cuda_execution_provider_info.h b/onnxruntime/core/providers/cuda/cuda_execution_provider_info.h index 5240f818a3..7bd0a416d6 100644 --- a/onnxruntime/core/providers/cuda/cuda_execution_provider_info.h +++ b/onnxruntime/core/providers/cuda/cuda_execution_provider_info.h @@ -54,5 +54,6 @@ struct CUDAExecutionProviderInfo { static CUDAExecutionProviderInfo FromProviderOptions(const ProviderOptions& options); static ProviderOptions ToProviderOptions(const CUDAExecutionProviderInfo& info); + static ProviderOptions ToProviderOptions(const OrtCUDAProviderOptionsV2& info); }; } // namespace onnxruntime diff --git a/onnxruntime/core/providers/cuda/cuda_provider_factory.cc b/onnxruntime/core/providers/cuda/cuda_provider_factory.cc index 45e10fa14c..95eda3d4f4 100644 --- a/onnxruntime/core/providers/cuda/cuda_provider_factory.cc +++ b/onnxruntime/core/providers/cuda/cuda_provider_factory.cc @@ -4,6 +4,7 @@ #include "core/providers/shared_library/provider_api.h" #include "core/providers/cuda/cuda_provider_factory_creator.h" #include "core/providers/cuda/cuda_provider_factory.h" +#include "core/providers/cuda/cuda_provider_options.h" #include @@ -186,21 +187,42 @@ struct CUDA_Provider : Provider { void* GetInfo() override { return &g_info; } std::shared_ptr CreateExecutionProviderFactory(const void* void_params) override { - auto params = reinterpret_cast(void_params); + auto params = reinterpret_cast(void_params); CUDAExecutionProviderInfo info{}; info.device_id = gsl::narrow(params->device_id); info.gpu_mem_limit = params->gpu_mem_limit; - info.arena_extend_strategy = static_cast(params->arena_extend_strategy); + info.arena_extend_strategy = params->arena_extend_strategy; info.cudnn_conv_algo_search = params->cudnn_conv_algo_search; info.do_copy_in_default_stream = params->do_copy_in_default_stream != 0; info.has_user_compute_stream = params->has_user_compute_stream != 0; info.user_compute_stream = params->user_compute_stream; info.default_memory_arena_cfg = params->default_memory_arena_cfg; + info.cudnn_conv_use_max_workspace = params->cudnn_conv_use_max_workspace != 0; return std::make_shared(info); } + void UpdateProviderOptions(void* provider_options, const ProviderOptions& options) override { + auto internal_options = onnxruntime::CUDAExecutionProviderInfo::FromProviderOptions(options); + auto& cuda_options = *reinterpret_cast(provider_options); + + cuda_options.device_id = internal_options.device_id; + cuda_options.cudnn_conv_algo_search = internal_options.cudnn_conv_algo_search; + cuda_options.gpu_mem_limit = internal_options.gpu_mem_limit; + cuda_options.arena_extend_strategy = internal_options.arena_extend_strategy; + cuda_options.do_copy_in_default_stream = internal_options.do_copy_in_default_stream; + cuda_options.has_user_compute_stream = internal_options.has_user_compute_stream; + cuda_options.user_compute_stream = internal_options.user_compute_stream; + cuda_options.default_memory_arena_cfg = internal_options.default_memory_arena_cfg; + cuda_options.cudnn_conv_use_max_workspace = internal_options.cudnn_conv_use_max_workspace; + } + + ProviderOptions GetProviderOptions(const void* provider_options) override { + auto& options = *reinterpret_cast(provider_options); + return onnxruntime::CUDAExecutionProviderInfo::ToProviderOptions(options); + } + void Shutdown() override { Shutdown_DeleteRegistry(); } diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index 086c7236f3..b954b78870 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -2271,7 +2271,7 @@ Second example, if we wanted to add and remove some members, we'd do this: In GetApi we now make it return ort_api_3 for version 3. */ -static constexpr OrtApi ort_api_1_to_10 = { +static constexpr OrtApi ort_api_1_to_11 = { // NOTE: The ordering of these fields MUST not change after that version has shipped since existing binaries depend on this ordering. // Shipped as version 1 - DO NOT MODIFY (see above text for more information) @@ -2511,10 +2511,15 @@ static constexpr OrtApi ort_api_1_to_10 = { &OrtApis::SetGlobalCustomThreadCreationOptions, &OrtApis::SetGlobalCustomJoinThreadFn, &OrtApis::SynchronizeBoundInputs, - &OrtApis::SynchronizeBoundOutputs + &OrtApis::SynchronizeBoundOutputs, // End of Version 10 - DO NOT MODIFY ABOVE (see above text for more information) // Version 11 - In development, feel free to add/remove/rearrange here + &OrtApis::SessionOptionsAppendExecutionProvider_CUDA_V2, + &OrtApis::CreateCUDAProviderOptions, + &OrtApis::UpdateCUDAProviderOptions, + &OrtApis::GetCUDAProviderOptionsAsString, + &OrtApis::ReleaseCUDAProviderOptions, }; // Asserts to do a some checks to ensure older Versions of the OrtApi never change (will detect an addition or deletion but not if they cancel out each other) @@ -2527,17 +2532,19 @@ static_assert(offsetof(OrtApi, SetGlobalSpinControl) / sizeof(void*) == 149, "Si static_assert(offsetof(OrtApi, ReleaseArenaCfg) / sizeof(void*) == 157, "Size of version 6 API cannot change"); static_assert(offsetof(OrtApi, GetCurrentGpuDeviceId) / sizeof(void*) == 161, "Size of version 7 API cannot change"); static_assert(offsetof(OrtApi, CreateSessionFromArrayWithPrepackedWeightsContainer) / sizeof(void*) == 169, "Size of version 8 API cannot change"); +static_assert(offsetof(OrtApi, GetSparseTensorIndices) / sizeof(void*) == 191, "Size of version 9 API cannot change"); +static_assert(offsetof(OrtApi, SynchronizeBoundOutputs) / sizeof(void*) == 203, "Size of version 10 API cannot change"); // So that nobody forgets to finish an API version, this check will serve as a reminder: static_assert(std::string_view(ORT_VERSION) == "1.11.0", "ORT_Version change detected, please follow below steps to ensure OrtApi is updated properly"); // 1. Update the hardcoded version string in above static_assert to silence it -// 2. If there were any APIs added to ort_api_1_to_10 above: +// 2. If there were any APIs added to ort_api_1_to_11 above: // a. Add the 'End of version #' markers (pattern above should be obvious) // b. Add a static_assert in the directly above list of version sizes to ensure nobody adds any more functions to the just shipped API version ORT_API(const OrtApi*, OrtApis::GetApi, uint32_t version) { if (version >= 1 && version <= ORT_API_VERSION) - return &ort_api_1_to_10; + return &ort_api_1_to_11; fprintf(stderr, "The given version [%u] is not supported, only version 1 to %u is supported in this build.\n", version, ORT_API_VERSION); diff --git a/onnxruntime/core/session/ort_apis.h b/onnxruntime/core/session/ort_apis.h index 2345e00ed3..46aa26030f 100644 --- a/onnxruntime/core/session/ort_apis.h +++ b/onnxruntime/core/session/ort_apis.h @@ -327,4 +327,13 @@ ORT_API_STATUS_IMPL(SetGlobalCustomThreadCreationOptions, _Inout_ OrtThreadingOp ORT_API_STATUS_IMPL(SetGlobalCustomJoinThreadFn, _Inout_ OrtThreadingOptions* tp_options, _In_ OrtCustomJoinThreadFn ort_custom_join_thread_fn); ORT_API_STATUS_IMPL(SynchronizeBoundInputs, _Inout_ OrtIoBinding* binding_ptr); ORT_API_STATUS_IMPL(SynchronizeBoundOutputs, _Inout_ OrtIoBinding* binding_ptr); +ORT_API_STATUS_IMPL(SessionOptionsAppendExecutionProvider_CUDA_V2, + _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptionsV2* cuda_options); +ORT_API_STATUS_IMPL(CreateCUDAProviderOptions, _Outptr_ OrtCUDAProviderOptionsV2** out); +ORT_API_STATUS_IMPL(UpdateCUDAProviderOptions, _Inout_ OrtCUDAProviderOptionsV2* cuda_options, + _In_reads_(num_keys) const char* const* provider_options_keys, + _In_reads_(num_keys) const char* const* provider_options_values, + size_t num_keys); +ORT_API_STATUS_IMPL(GetCUDAProviderOptionsAsString, _In_ const OrtCUDAProviderOptionsV2* cuda_options, _Inout_ OrtAllocator* allocator, _Outptr_ char** ptr); +ORT_API(void, ReleaseCUDAProviderOptions, _Frees_ptr_opt_ OrtCUDAProviderOptionsV2*); } // namespace OrtApis diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index bec88849df..98d057d57e 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -65,9 +65,10 @@ using IndexedSubGraph_MetaDef = IndexedSubGraph::MetaDef; #include "core/providers/cuda/cuda_provider_factory.h" #include "core/providers/rocm/rocm_provider_factory.h" #include "core/providers/dnnl/dnnl_provider_factory.h" -#include "core/providers/tensorrt/tensorrt_provider_factory.h" #include "core/providers/openvino/openvino_provider_factory.h" -#include "core/platform/tensorrt_provider_options.h" +#include "core/providers/tensorrt/tensorrt_provider_factory.h" +#include "core/providers/tensorrt/tensorrt_provider_options.h" +#include "core/providers/cuda/cuda_provider_options.h" // The filename extension for a shared library is different per platform #ifdef _WIN32 @@ -1076,7 +1077,33 @@ std::unique_ptr CreateROCMPinnedAllocator(int16_t device_id, const c return nullptr; } +// Adapter to convert the legacy OrtCUDAProviderOptions to the latest OrtCUDAProviderOptionsV2 +OrtCUDAProviderOptionsV2 OrtCUDAProviderOptionsToOrtCUDAProviderOptionsV2(const OrtCUDAProviderOptions* legacy_cuda_options) { + OrtCUDAProviderOptionsV2 cuda_options_converted; + + cuda_options_converted.device_id = legacy_cuda_options->device_id; + cuda_options_converted.cudnn_conv_algo_search = legacy_cuda_options->cudnn_conv_algo_search; + cuda_options_converted.gpu_mem_limit = legacy_cuda_options->gpu_mem_limit; + cuda_options_converted.arena_extend_strategy = static_cast(legacy_cuda_options->arena_extend_strategy); + cuda_options_converted.do_copy_in_default_stream = legacy_cuda_options->do_copy_in_default_stream; + cuda_options_converted.has_user_compute_stream = legacy_cuda_options->has_user_compute_stream; + cuda_options_converted.user_compute_stream = legacy_cuda_options->user_compute_stream; + cuda_options_converted.default_memory_arena_cfg = legacy_cuda_options->default_memory_arena_cfg; + // Use default value as this field is not available in OrtCUDAProviderOptions + cuda_options_converted.cudnn_conv_use_max_workspace = 0; + + return cuda_options_converted; +} + std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptions* provider_options) { + OrtCUDAProviderOptionsV2 cuda_options_converted = onnxruntime::OrtCUDAProviderOptionsToOrtCUDAProviderOptionsV2(provider_options); + if (auto* provider = s_library_cuda.Get()) + return provider->CreateExecutionProviderFactory(&cuda_options_converted); + + return nullptr; +} + +std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptionsV2* provider_options) { if (auto* provider = s_library_cuda.Get()) return provider->CreateExecutionProviderFactory(provider_options); @@ -1215,6 +1242,20 @@ ProviderOptions GetProviderInfo_Tensorrt(const OrtTensorRTProviderOptions* provi return {}; } +void UpdateProviderInfo_Cuda(OrtCUDAProviderOptionsV2* provider_options, const ProviderOptions& options) { + if (auto provider = s_library_cuda.Get()) { + provider->UpdateProviderOptions(reinterpret_cast(provider_options), options); + } +} + +ProviderOptions GetProviderInfo_Cuda(const OrtCUDAProviderOptionsV2* provider_options) { + if (auto provider = s_library_cuda.Get()) { + return provider->GetProviderOptions(reinterpret_cast(provider_options)); + } + + return {}; +} + } // namespace onnxruntime ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Dnnl, _In_ OrtSessionOptions* options, int use_arena) { @@ -1448,3 +1489,107 @@ ORT_API(void, OrtApis::ReleaseTensorRTProviderOptions, _Frees_ptr_opt_ OrtTensor ORT_UNUSED_PARAMETER(ptr); #endif } + +ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_CUDA_V2, _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptionsV2* cuda_options) { + API_IMPL_BEGIN + auto factory = onnxruntime::CreateExecutionProviderFactory_Cuda(cuda_options); + if (!factory) { + return OrtApis::CreateStatus(ORT_FAIL, "OrtSessionOptionsAppendExecutionProvider_Cuda: Failed to load shared library"); + } + + options->provider_factories.push_back(factory); + return nullptr; + API_IMPL_END +} + +ORT_API_STATUS_IMPL(OrtApis::CreateCUDAProviderOptions, _Outptr_ OrtCUDAProviderOptionsV2** out) { + API_IMPL_BEGIN +#ifdef USE_CUDA + *out = new OrtCUDAProviderOptionsV2(); + (*out)->device_id = 0; + (*out)->cudnn_conv_algo_search = OrtCudnnConvAlgoSearch::OrtCudnnConvAlgoSearchExhaustive; + (*out)->gpu_mem_limit = std::numeric_limits::max(); + (*out)->arena_extend_strategy = static_cast(0); + (*out)->do_copy_in_default_stream = 1; + (*out)->has_user_compute_stream = 0; + (*out)->user_compute_stream = nullptr; + (*out)->default_memory_arena_cfg = nullptr; + (*out)->cudnn_conv_use_max_workspace = 0; + return nullptr; +#else + ORT_UNUSED_PARAMETER(out); + return CreateStatus(ORT_FAIL, "CUDA execution provider is not enabled in this build."); +#endif + API_IMPL_END +} + +ORT_API_STATUS_IMPL(OrtApis::UpdateCUDAProviderOptions, + _Inout_ OrtCUDAProviderOptionsV2* cuda_options, + _In_reads_(num_keys) const char* const* provider_options_keys, + _In_reads_(num_keys) const char* const* provider_options_values, + size_t num_keys) { + API_IMPL_BEGIN +#ifdef USE_CUDA + onnxruntime::ProviderOptions provider_options_map; + for (size_t i = 0; i != num_keys; ++i) { + if (provider_options_keys[i] == nullptr || provider_options_keys[i][0] == '\0' || + provider_options_values[i] == nullptr || provider_options_values[i][0] == '\0') { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "key/value cannot be empty"); + } + + provider_options_map[provider_options_keys[i]] = provider_options_values[i]; + } + + onnxruntime::UpdateProviderInfo_Cuda(cuda_options, + reinterpret_cast(provider_options_map)); + return nullptr; +#else + ORT_UNUSED_PARAMETER(cuda_options); + ORT_UNUSED_PARAMETER(provider_options_keys); + ORT_UNUSED_PARAMETER(provider_options_values); + ORT_UNUSED_PARAMETER(num_keys); + return CreateStatus(ORT_FAIL, "CUDA execution provider is not enabled in this build."); +#endif + API_IMPL_END +} + +ORT_API_STATUS_IMPL(OrtApis::GetCUDAProviderOptionsAsString, _In_ const OrtCUDAProviderOptionsV2* cuda_options, _Inout_ OrtAllocator* allocator, + _Outptr_ char** ptr) { + API_IMPL_BEGIN +#ifdef USE_CUDA + onnxruntime::ProviderOptions options = onnxruntime::GetProviderInfo_Cuda(cuda_options); + onnxruntime::ProviderOptions::iterator it = options.begin(); + std::string options_str = ""; + + while (it != options.end()) { + if (options_str == "") { + options_str += it->first; + options_str += "="; + options_str += it->second; + } else { + options_str += ";"; + options_str += it->first; + options_str += "="; + options_str += it->second; + } + it++; + } + + *ptr = onnxruntime::StrDup(options_str, allocator); + return nullptr; +#else + ORT_UNUSED_PARAMETER(cuda_options); + ORT_UNUSED_PARAMETER(allocator); + ORT_UNUSED_PARAMETER(ptr); + return CreateStatus(ORT_FAIL, "CUDA execution provider is not enabled in this build."); +#endif + API_IMPL_END +} + +ORT_API(void, OrtApis::ReleaseCUDAProviderOptions, _Frees_ptr_opt_ OrtCUDAProviderOptionsV2* ptr) { +#ifdef USE_CUDA + delete ptr; +#else + ORT_UNUSED_PARAMETER(ptr); +#endif +} diff --git a/onnxruntime/core/session/provider_stubs.cc b/onnxruntime/core/session/provider_stubs.cc index 2b3369daa8..1db6c5917a 100644 --- a/onnxruntime/core/session/provider_stubs.cc +++ b/onnxruntime/core/session/provider_stubs.cc @@ -97,6 +97,42 @@ ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_CUDA, return CreateNotEnabledStatus("CUDA"); } +ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_CUDA_V2, + _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptionsV2* cuda_options) { + ORT_UNUSED_PARAMETER(options); + ORT_UNUSED_PARAMETER(cuda_options); + return CreateNotEnabledStatus("CUDA"); +} + +ORT_API_STATUS_IMPL(OrtApis::CreateCUDAProviderOptions, _Outptr_ OrtCUDAProviderOptionsV2** out) { + ORT_UNUSED_PARAMETER(out); + return CreateNotEnabledStatus("CUDA"); +} + +ORT_API_STATUS_IMPL(OrtApis::UpdateCUDAProviderOptions, + _Inout_ OrtCUDAProviderOptionsV2* cuda_options, + _In_reads_(num_keys) const char* const* provider_options_keys, + _In_reads_(num_keys) const char* const* provider_options_values, + size_t num_keys) { + ORT_UNUSED_PARAMETER(cuda_options); + ORT_UNUSED_PARAMETER(provider_options_keys); + ORT_UNUSED_PARAMETER(provider_options_values); + ORT_UNUSED_PARAMETER(num_keys); + return CreateNotEnabledStatus("CUDA"); +} + +ORT_API_STATUS_IMPL(OrtApis::GetCUDAProviderOptionsAsString, _In_ const OrtCUDAProviderOptionsV2* cuda_options, _Inout_ OrtAllocator* allocator, + _Outptr_ char** ptr) { + ORT_UNUSED_PARAMETER(cuda_options); + ORT_UNUSED_PARAMETER(allocator); + ORT_UNUSED_PARAMETER(ptr); + return CreateStatus(ORT_FAIL, "CUDA execution provider is not enabled in this build."); +} + +ORT_API(void, OrtApis::ReleaseCUDAProviderOptions, _Frees_ptr_opt_ OrtCUDAProviderOptionsV2* ptr) { + ORT_UNUSED_PARAMETER(ptr); +} + ORT_API_STATUS_IMPL(OrtApis::GetCurrentGpuDeviceId, _In_ int* device_id) { ORT_UNUSED_PARAMETER(device_id); return CreateNotEnabledStatus("CUDA"); diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc index 4d033432d8..11a8333386 100644 --- a/onnxruntime/test/shared_lib/test_inference.cc +++ b/onnxruntime/test/shared_lib/test_inference.cc @@ -1852,6 +1852,51 @@ TEST(CApiTest, TestConfigureTensorRTProviderOptions) { } #endif +#ifdef USE_CUDA + +// This test uses CreateCUDAProviderOptions/UpdateCUDAProviderOptions APIs to configure and create a CUDA Execution Provider instance +TEST(CApiTest, TestConfigureCUDAProviderOptions) { + const auto& api = Ort::GetApi(); + + OrtCUDAProviderOptionsV2* cuda_options = nullptr; + ASSERT_TRUE(api.CreateCUDAProviderOptions(&cuda_options) == nullptr); + std::unique_ptr rel_cuda_options(cuda_options, api.ReleaseCUDAProviderOptions); + + std::vector keys{ + "device_id", "gpu_mem_limit", "arena_extend_strategy", + "cudnn_conv_algo_search", "do_copy_in_default_stream", "cudnn_conv_use_max_workspace"}; + + std::vector values{ + "0", "1024", "kSameAsRequested", + "DEFAULT", "1", "1"}; + + ASSERT_TRUE(api.UpdateCUDAProviderOptions(rel_cuda_options.get(), keys.data(), values.data(), 6) == nullptr); + + OrtAllocator* allocator; + ASSERT_TRUE(api.GetAllocatorWithDefaultOptions(&allocator) == nullptr); + + char* cuda_options_str = nullptr; + ASSERT_TRUE(api.GetCUDAProviderOptionsAsString(rel_cuda_options.get(), allocator, &cuda_options_str) == nullptr); + std::string s(cuda_options_str, strnlen(cuda_options_str, 2048)); + ASSERT_TRUE(s.find("device_id=0") != std::string::npos); + ASSERT_TRUE(s.find("gpu_mem_limit=1024") != std::string::npos); + ASSERT_TRUE(s.find("arena_extend_strategy=kSameAsRequested") != std::string::npos); + ASSERT_TRUE(s.find("cudnn_conv_algo_search=DEFAULT") != std::string::npos); + ASSERT_TRUE(s.find("do_copy_in_default_stream=1") != std::string::npos); + ASSERT_TRUE(s.find("cudnn_conv_use_max_workspace=1") != std::string::npos); + + ASSERT_TRUE(api.AllocatorFree(allocator, (void*)cuda_options_str) == nullptr); + + Ort::SessionOptions session_options; + ASSERT_TRUE(api.SessionOptionsAppendExecutionProvider_CUDA_V2(static_cast(session_options), rel_cuda_options.get()) == nullptr); + + // if session creation passes, model loads fine + std::basic_string model_uri = MODEL_URI; + Ort::Session session(*ort_env, model_uri.c_str(), session_options); +} + +#endif + namespace TestPerSessionCustomThreadHooks { std::vector threads; @@ -1933,4 +1978,3 @@ TEST(CApiTest, crop_and_resize) { #endif } // namespace TestPerSessionCustomThreadHooks - diff --git a/onnxruntime/test/shared_lib/utils.cc b/onnxruntime/test/shared_lib/utils.cc index fd2ad701bc..4df1f42a10 100644 --- a/onnxruntime/test/shared_lib/utils.cc +++ b/onnxruntime/test/shared_lib/utils.cc @@ -2,11 +2,19 @@ // Licensed under the MIT License. #include "utils.h" +#include OrtCUDAProviderOptions CreateDefaultOrtCudaProviderOptionsWithCustomStream(void* cuda_compute_stream) { OrtCUDAProviderOptions cuda_options; + + cuda_options.device_id = 0; + cuda_options.cudnn_conv_algo_search = OrtCudnnConvAlgoSearch::OrtCudnnConvAlgoSearchExhaustive; + cuda_options.gpu_mem_limit = std::numeric_limits::max(); + cuda_options.arena_extend_strategy = 0; cuda_options.do_copy_in_default_stream = true; cuda_options.has_user_compute_stream = cuda_compute_stream != nullptr ? 1 : 0; cuda_options.user_compute_stream = cuda_compute_stream; + cuda_options.default_memory_arena_cfg = nullptr; + return cuda_options; } diff --git a/onnxruntime/test/util/include/default_providers.h b/onnxruntime/test/util/include/default_providers.h index 6df390125a..078e135628 100644 --- a/onnxruntime/test/util/include/default_providers.h +++ b/onnxruntime/test/util/include/default_providers.h @@ -11,6 +11,7 @@ std::shared_ptr CreateExecutionProviderFactory_ACL(in std::shared_ptr CreateExecutionProviderFactory_ArmNN(int use_arena); std::shared_ptr CreateExecutionProviderFactory_CoreML(uint32_t); std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptions* provider_options); +std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptionsV2* provider_options); std::shared_ptr CreateExecutionProviderFactory_Dnnl(int use_arena); std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id); std::shared_ptr CreateExecutionProviderFactory_Nnapi( From cab4579b834c8fa53d23b961355209daecb14ad7 Mon Sep 17 00:00:00 2001 From: Chris Hua Date: Thu, 6 Jan 2022 13:52:20 -0800 Subject: [PATCH 092/113] remove six references (#9941) Python 2 compatibility is no longer necessary and helps unblock upgrades to mypy and others. --- onnxruntime/python/tools/quantization/calibrate.py | 2 +- onnxruntime/test/python/quantization/op_test_utils.py | 5 ++--- onnxruntime/test/testdata/sparse_initializer_as_output.py | 7 +++---- onnxruntime/test/testdata/sparse_to_dense_matmul.py | 7 +++---- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/onnxruntime/python/tools/quantization/calibrate.py b/onnxruntime/python/tools/quantization/calibrate.py index e82eb46d8f..40b852c6de 100644 --- a/onnxruntime/python/tools/quantization/calibrate.py +++ b/onnxruntime/python/tools/quantization/calibrate.py @@ -45,7 +45,7 @@ class CalibraterBase: :param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors. :param augmented_model_path: save augmented model to this path. ''' - if isinstance(model, string_types): + if isinstance(model, str): self.model = onnx.load(model) elif isinstance(model, ModelProto): self.model = model diff --git a/onnxruntime/test/python/quantization/op_test_utils.py b/onnxruntime/test/python/quantization/op_test_utils.py index a3f0192289..1764f675bb 100644 --- a/onnxruntime/test/python/quantization/op_test_utils.py +++ b/onnxruntime/test/python/quantization/op_test_utils.py @@ -1,7 +1,6 @@ import onnx import numpy as np -from six import string_types import onnxruntime from pathlib import Path from onnxruntime.quantization import CalibrationDataReader @@ -35,7 +34,7 @@ def InputFeedsNegOneZeroOne(n, name2shape): return dr def check_op_type_order(testcase, model_to_check, ops): - if isinstance(model_to_check, string_types): + if isinstance(model_to_check, str): model = onnx.load(model_to_check) elif isinstance(model_to_check, onnx.ModelProto): model = model_to_check @@ -79,7 +78,7 @@ def check_op_nodes(testcase, model_path, node_checker): testcase.assertTrue(node_checker(node)) def check_qtype_by_node_type(testcase, model_to_check, check_list): - if isinstance(model_to_check, string_types): + if isinstance(model_to_check, str): model = onnx.load(model_to_check) elif isinstance(model_to_check, onnx.ModelProto): model = model_to_check diff --git a/onnxruntime/test/testdata/sparse_initializer_as_output.py b/onnxruntime/test/testdata/sparse_initializer_as_output.py index 0e1d9d7f13..8b6c964b44 100644 --- a/onnxruntime/test/testdata/sparse_initializer_as_output.py +++ b/onnxruntime/test/testdata/sparse_initializer_as_output.py @@ -9,7 +9,6 @@ from onnx import AttributeProto, SparseTensorProto, TensorProto, GraphProto, Val import traceback from typing import Text, Sequence, Any, Optional, Dict, Union, TypeVar, Callable, Tuple, List, cast -from six import text_type, integer_types, binary_type def parse_arguments(): @@ -59,14 +58,14 @@ def make_sparse_tensor_value_info( dim = sparse_tensor_shape_proto.dim.add() if d is None: pass - elif isinstance(d, integer_types): + elif isinstance(d, int): dim.dim_value = d - elif isinstance(d, text_type): + elif isinstance(d, str): dim.dim_param = d else: raise ValueError( 'Invalid item in shape: {}. ' - 'Needs to of integer_types or text_type.'.format(d)) + 'Needs to be one of `int` or `str`.'.format(d)) if shape_denotation: dim.denotation = shape_denotation[i] diff --git a/onnxruntime/test/testdata/sparse_to_dense_matmul.py b/onnxruntime/test/testdata/sparse_to_dense_matmul.py index 1083f234f8..68c24651dd 100644 --- a/onnxruntime/test/testdata/sparse_to_dense_matmul.py +++ b/onnxruntime/test/testdata/sparse_to_dense_matmul.py @@ -9,7 +9,6 @@ from onnx import AttributeProto, SparseTensorProto, TensorProto, GraphProto, Val import traceback from typing import Text, Sequence, Any, Optional, Dict, Union, TypeVar, Callable, Tuple, List, cast -from six import text_type, integer_types, binary_type def parse_arguments(): parser = argparse.ArgumentParser() @@ -55,14 +54,14 @@ def make_sparse_tensor_value_info( dim = sparse_tensor_shape_proto.dim.add() if d is None: pass - elif isinstance(d, integer_types): + elif isinstance(d, int): dim.dim_value = d - elif isinstance(d, text_type): + elif isinstance(d, str): dim.dim_param = d else: raise ValueError( 'Invalid item in shape: {}. ' - 'Needs to of integer_types or text_type.'.format(d)) + 'Needs to be one of `int` or `text`.'.format(d)) if shape_denotation: dim.denotation = shape_denotation[i] From 4ac327774334312a856716f8126fcc3fa5f0a521 Mon Sep 17 00:00:00 2001 From: Abhishek Jindal Date: Thu, 6 Jan 2022 14:56:35 -0800 Subject: [PATCH 093/113] adding definition of concat operator for mapping it to onnx (#10062) * adding definition of concat operator for mapping it to onnx * adding the opgen generator file to include tensorlist type for eager mode --- .../orttraining/eager/opgen/opgen/atenops.py | 1 + .../eager/opgen/opgen/generator.py | 21 ++++++++++++++----- orttraining/orttraining/eager/ort_aten.cpp | 14 +++++++++++++ orttraining/orttraining/eager/ort_aten.h | 6 ++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/orttraining/orttraining/eager/opgen/opgen/atenops.py b/orttraining/orttraining/eager/opgen/opgen/atenops.py index d3fd008ef6..e64f4a7d87 100644 --- a/orttraining/orttraining/eager/opgen/opgen/atenops.py +++ b/orttraining/orttraining/eager/opgen/opgen/atenops.py @@ -77,6 +77,7 @@ hand_implemented = { 'aten::max' : ReduceMax('self', keepdims=1), 'aten::min' : ReduceMin('self', keepdims=1), 'aten::slice.Tensor' : Slice('self', 'start', 'end', 'dim', 'step'), + 'aten::_cat': Concat('tensors', 'dim'), 'aten::ne.Scalar':MakeTorchFallback(), 'aten::ne.Scalar_out': MakeTorchFallback(), diff --git a/orttraining/orttraining/eager/opgen/opgen/generator.py b/orttraining/orttraining/eager/opgen/opgen/generator.py index 3a8268eb12..d58eb5d813 100644 --- a/orttraining/orttraining/eager/opgen/opgen/generator.py +++ b/orttraining/orttraining/eager/opgen/opgen/generator.py @@ -254,6 +254,16 @@ class ORTGen: onnx_op.eval(ctx) ctx.prepare_outputs() + # Fetch the ORT invoker from an at::Tensor.device() + # FIXME: find the first at::Tensor param anywhere in the signature + # instead of simply the first parameter? + first_param = cpp_func.parameters[0].member + # Check if the first parameter is tensorlist and if yes it's size should be > 0 + if first_param.parameter_type.desugar().identifier_tokens[0].value == 'TensorList': + writer.write('assert(') + writer.write(first_param.identifier.value) + writer.writeline('.size()>0);') + # generate the type check need_type_check = False if not self._custom_ops: @@ -281,10 +291,6 @@ class ORTGen: writer.pop_indent() writer.writeline('}') - # Fetch the ORT invoker from an at::Tensor.device() - # FIXME: find the first at::Tensor param anywhere in the signature - # instead of simply the first parameter? - first_param = cpp_func.parameters[0].member if not isinstance( first_param.parameter_type.desugar(), ast.ConcreteType) or 'Tensor' not in first_param.parameter_type.desugar().identifier_tokens[0].value: @@ -294,6 +300,8 @@ class ORTGen: writer.write('auto& invoker = GetORTInvoker(') writer.write(first_param.identifier.value) + if first_param.parameter_type.desugar().identifier_tokens[0].value == 'TensorList': + writer.write('[0]') writer.writeline('.device());') writer.writeline() @@ -402,7 +410,10 @@ class ORTGen: writer.writeline(f'{first_param.identifier.value}.options());') else: writer.writeline(f'std::move({return_outputs}[0]),') - writer.writeline(f'{first_param.identifier.value}.options());') + writer.write(first_param.identifier.value) + if first_param.parameter_type.desugar().identifier_tokens[0].value == 'TensorList': + writer.write('[0]') + writer.writeline('.options());') writer.pop_indent() return diff --git a/orttraining/orttraining/eager/ort_aten.cpp b/orttraining/orttraining/eager/ort_aten.cpp index d11db28333..4bbfc2c2db 100644 --- a/orttraining/orttraining/eager/ort_aten.cpp +++ b/orttraining/orttraining/eager/ort_aten.cpp @@ -139,6 +139,16 @@ OrtValue create_ort_value(const at::Tensor& tensor){ return create_ort_value(invoker, tensor); } +std::vector create_ort_value( + onnxruntime::ORTInvoker& invoker, + at::TensorList values) { + auto output = std::vector{}; + for (auto element: values){ + output.push_back(create_ort_value(element)); + } + return output; +} + onnx::AttributeProto create_ort_attribute( const char* name, at::Scalar value) { @@ -204,6 +214,10 @@ bool IsSupportedType(c10::optional val, const std::vector& valid_types){ + return IsSupportedType(tensors[0], valid_types); +} + //#pragma endregion //#pragma region Hand-Implemented ATen Ops diff --git a/orttraining/orttraining/eager/ort_aten.h b/orttraining/orttraining/eager/ort_aten.h index bb235aa2ac..1f3190cabe 100644 --- a/orttraining/orttraining/eager/ort_aten.h +++ b/orttraining/orttraining/eager/ort_aten.h @@ -37,6 +37,10 @@ OrtValue create_ort_value( onnxruntime::ORTInvoker& invoker, const at::Tensor& tensor); +std::vector create_ort_value( + onnxruntime::ORTInvoker& invoker, + at::TensorList tensors); + OrtValue create_ort_value(const at::Tensor& tensor); // Create 1-dimensional ORT tensor from a given value @@ -112,5 +116,7 @@ bool IsSupportedType(int64_t val, const std::vector& valid_types bool IsSupportedType(c10::optional val, const std::vector& valid_types); +bool IsSupportedType(at::TensorList tensors, const std::vector& valid_types); + } // namespace eager } // namespace torch_ort \ No newline at end of file From e7efcc93fe310dbc63f4d90ec33dbc9d9ec6303a Mon Sep 17 00:00:00 2001 From: Jeff Daily Date: Thu, 6 Jan 2022 17:21:02 -0800 Subject: [PATCH 094/113] [ROCm] update hipify-perl location (#10102) * [ROCm] update hipify-perl location Depending on the ROCm version installed, hipify-perl might not always live in the hard-coded path of /opt/rocm/bin. Use python 3.3's shutil.which to locate the script. * provide alternative locations for hipify-perl if not in PATH * implement hipify-perl search as a function This avoids running the logic during module import since all builds import the amd_hipify module. * fix flake8 errors --- tools/ci_build/amd_hipify.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/ci_build/amd_hipify.py b/tools/ci_build/amd_hipify.py index c1a227dc92..4f7be01519 100644 --- a/tools/ci_build/amd_hipify.py +++ b/tools/ci_build/amd_hipify.py @@ -2,7 +2,9 @@ # Licensed under the MIT License. import concurrent.futures +import functools import os +import shutil import subprocess from logger import get_logger @@ -173,7 +175,25 @@ training_ops_excluded_files = [ 'cuda_training_kernels.h', ] -HIPIFY_PERL = '/opt/rocm/bin/hipify-perl' + +@functools.lru_cache(maxsize=1) +def get_hipify_path(): + # prefer the hipify-perl in PATH + HIPIFY_PERL = shutil.which('hipify-perl') + # if not found, attempt hard-coded location 1 + if HIPIFY_PERL is None: + print('hipify-perl not found, trying default location 1') + hipify_path = '/opt/rocm/hip/bin/hipify-perl' + HIPIFY_PERL = hipify_path if os.access(hipify_path, os.X_OK) else None + # if not found, attempt hard-coded location 2 + if HIPIFY_PERL is None: + print('hipify-perl not found, trying default location 2') + hipify_path = '/opt/rocm/bin/hipify-perl' + HIPIFY_PERL = hipify_path if os.access(hipify_path, os.X_OK) else None + # fail + if HIPIFY_PERL is None: + raise RuntimeError('Could not locate hipify-perl script') + return HIPIFY_PERL def hipify(src_file_path, dst_file_path): @@ -182,7 +202,7 @@ def hipify(src_file_path, dst_file_path): if not os.path.exists(dir_name): os.makedirs(dir_name, exist_ok=True) # Run hipify-perl first, capture output - s = subprocess.run([HIPIFY_PERL, src_file_path], stdout=subprocess.PIPE, universal_newlines=True).stdout + s = subprocess.run([get_hipify_path(), src_file_path], stdout=subprocess.PIPE, universal_newlines=True).stdout # Additional exact-match replacements. # Order matters for all of the following replacements, reglardless of appearing in logical sections. @@ -323,6 +343,8 @@ def list_files(prefix, path): def amd_hipify(config_build_dir): + # determine hipify script path now to avoid doing so concurrently in the thread pool + print('Using %s' % get_hipify_path()) with concurrent.futures.ThreadPoolExecutor() as executor: cuda_path = os.path.join(contrib_ops_path, 'cuda') rocm_path = os.path.join(config_build_dir, 'amdgpu', contrib_ops_path, 'rocm') From 2bbf1ac1e07586808ceae6e895678950acb05733 Mon Sep 17 00:00:00 2001 From: Zhang Lei Date: Fri, 7 Jan 2022 09:17:23 -0800 Subject: [PATCH 095/113] Using better words. (#10210) --- onnxruntime/python/tools/quantization/operators/direct_q8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/python/tools/quantization/operators/direct_q8.py b/onnxruntime/python/tools/quantization/operators/direct_q8.py index 9ec70436c7..cabe709b20 100644 --- a/onnxruntime/python/tools/quantization/operators/direct_q8.py +++ b/onnxruntime/python/tools/quantization/operators/direct_q8.py @@ -29,7 +29,7 @@ class Direct8BitOp(QuantOperatorBase): self.quantizer.new_nodes += [node] else: - # Force quantize those ops if possible, use black list on node if this is not you want + # Force quantize those ops if possible, use exclude node list if this is not you want if (not self.quantizer.is_valid_quantize_weight(node.input[0])): super().quantize() return From bacae967a21898141ac06d02cd9c9e6c30fbd139 Mon Sep 17 00:00:00 2001 From: vade Date: Fri, 7 Jan 2022 13:00:44 -0800 Subject: [PATCH 096/113] Update Cuda to 11.4.2, update architectures, support Ubuntu 20.04 (#10169) --- dockerfiles/Dockerfile.cuda | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dockerfiles/Dockerfile.cuda b/dockerfiles/Dockerfile.cuda index bc1347330b..5ec7ba2b95 100644 --- a/dockerfiles/Dockerfile.cuda +++ b/dockerfiles/Dockerfile.cuda @@ -5,16 +5,18 @@ # Dockerfile to run ONNXRuntime with CUDA, CUDNN integration # nVidia cuda 11.4 Base Image -FROM nvcr.io/nvidia/cuda:11.4.1-cudnn8-devel-ubuntu18.04 +FROM nvcr.io/nvidia/cuda:11.4.2-cudnn8-devel-ubuntu20.04 +ENV DEBIAN_FRONTEND=noninteractive MAINTAINER Changming Sun "chasun@microsoft.com" ADD . /code ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH} RUN apt-get update && apt-get install -y --no-install-recommends python3-dev ca-certificates g++ python3-numpy gcc make git python3-setuptools python3-wheel python3-pip aria2 && aria2c -q -d /tmp -o cmake-3.21.0-linux-x86_64.tar.gz https://github.com/Kitware/CMake/releases/download/v3.21.0/cmake-3.21.0-linux-x86_64.tar.gz && tar -zxf /tmp/cmake-3.21.0-linux-x86_64.tar.gz --strip=1 -C /usr -RUN cd /code && /bin/bash ./build.sh --skip_submodule_sync --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu/ --use_cuda --config Release --build_wheel --update --build --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) 'CMAKE_CUDA_ARCHITECTURES=37;50;52;60;70' +RUN cd /code && /bin/bash ./build.sh --skip_submodule_sync --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu/ --use_cuda --config Release --build_wheel --update --build --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) 'CMAKE_CUDA_ARCHITECTURES=52;60;61;70;75;86' -FROM nvcr.io/nvidia/cuda:11.4.1-cudnn8-runtime-ubuntu18.04 +FROM nvcr.io/nvidia/cuda:11.4.2-cudnn8-runtime-ubuntu20.04 +ENV DEBIAN_FRONTEND=noninteractive COPY --from=0 /code/build/Linux/Release/dist /root COPY --from=0 /code/dockerfiles/LICENSE-IMAGE.txt /code/LICENSE-IMAGE.txt ENV DEBIAN_FRONTEND=noninteractive From 5ebb857501eb2b3145a42185f02bde7903862749 Mon Sep 17 00:00:00 2001 From: Ye Wang <52801275+wangyems@users.noreply.github.com> Date: Fri, 7 Jan 2022 16:14:15 -0800 Subject: [PATCH 097/113] Update onnxruntime_unittests.cmake (#10215) --- cmake/onnxruntime_unittests.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 9ae293a3cf..cd8e65ec61 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -1170,6 +1170,9 @@ if (onnxruntime_USE_CUDA) onnxruntime_add_shared_library_module(custom_op_library ${ONNXRUNTIME_SHARED_LIB_TEST_SRC_DIR}/cuda_ops.cu ${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.cc) target_include_directories(custom_op_library PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + if (HAS_QSPECTRE) + target_compile_options(custom_op_library PRIVATE "$<$:SHELL:-Xcompiler /Qspectre>") + endif() else() onnxruntime_add_shared_library_module(custom_op_library ${TEST_SRC_DIR}/testdata/custom_op_library/custom_op_library.cc) endif() From d52d3c00520a10075e3bc75fe90db5b4c83ee557 Mon Sep 17 00:00:00 2001 From: "Nat Kershaw (MSFT)" Date: Fri, 7 Jan 2022 16:16:47 -0800 Subject: [PATCH 098/113] Update C/C++ API docs automation to create a PR (instead of push to publish branch) (#10093) --- .github/workflows/publish-c-apidocs.yml | 29 ++++++++++++++----- docs/c_cxx/README.md | 16 ++++------ .../core/session/onnxruntime_c_api.h | 4 +-- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish-c-apidocs.yml b/.github/workflows/publish-c-apidocs.yml index db2f88dbc3..12e3e9760a 100644 --- a/.github/workflows/publish-c-apidocs.yml +++ b/.github/workflows/publish-c-apidocs.yml @@ -1,10 +1,10 @@ -name: Publish C/C++ API Docs +name: Update C/C++ API Docs on: workflow_dispatch jobs: publish: - name: Publish C/C++ API docs + name: Generate C/C++ API docs runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -15,16 +15,29 @@ jobs: sudo apt-get install libclang-cpp9 wget https://www.doxygen.nl/files/doxygen-1.9.2.linux.bin.tar.gz tar xvzf doxygen-1.9.2.linux.bin.tar.gz + - name: Set commit ID + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: Run doxygen run: | mkdir -p build/doxygen cd docs/c_cxx ../../doxygen-1.9.2/bin/doxygen - - name: Publish - uses: JamesIves/github-pages-deploy-action@releases/v3 + - uses: actions/checkout@v2 with: - BRANCH: gh-pages - FOLDER: build/doxygen/html - TARGET_FOLDER: docs/api/c - CLEAN_EXCLUDE: '["_config.yml"]' + ref: gh-pages + clean: false + - name: Move API docs into target area + run: | + rm -rf docs/api/c + mv build/doxygen/html docs/api/c + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + branch: gh-pages-pr + base: gh-pages + title: '[Automated]: Update C/C++ API docs' + commit-message: 'Update C/C++ API docs to commit ${{ steps.vars.outputs.sha_short }}' + add-paths: docs/api/c + \ No newline at end of file diff --git a/docs/c_cxx/README.md b/docs/c_cxx/README.md index 24b11e4f72..960c5f3e47 100644 --- a/docs/c_cxx/README.md +++ b/docs/c_cxx/README.md @@ -1,13 +1,7 @@ -How to build the Doxygen HTML pages on Windows: +# ONNX Runtime C/C++ docs source files -* Install Doxygen (https://www.doxygen.nl/download.html) -* Running from the command line: - * cd to (Repository Root)\docs\c_cxx - * Run "\Program Files\doxygen\bin\doxygen.exe" Doxyfile -* Using the Doxygen GUI app: - * Launch Doxygen GUI (Doxywizard) - * File->Open (Repository Root)\docs\c_cxx\Doxyfile - * Switch to Run tab, click 'Run doxygen' -* Generated docs are written to (Repository Root)\build\doxygen\html +This directory contains doxygen configuration to generate the C/C++ API docs for ONNX Runtime. -The generated documentation is online in the gh-pages branch of the project: https://github.com/microsoft/onnxruntime/tree/gh-pages/docs/api/c +The actual generation is performed by a GitHub actions workflow: [publish-c-apidocs.yml](../../.github/workflows/publish-c-apidocs.yml). + +The workflow is currently manually triggered, and generates a PR to the gh-pages branch, for publication on https://onnxruntime.ai. \ No newline at end of file diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 92f27b685a..31b0442775 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -7,11 +7,11 @@ * *

C

* -* ::OrtApi - Click here to jump to the structure with all C API functions. +* ::OrtApi - Click here to go to the structure with all C API functions. * *

C++

* -* ::Ort - Click here to jump to the namespace holding all of the C++ wrapper classes +* ::Ort - Click here to go to the namespace holding all of the C++ wrapper classes * * It is a set of header only wrapper classes around the C API. The goal is to turn the C style return value error codes into C++ exceptions, and to * automate memory management through standard C++ RAII principles. From 6e88c11cae30c259ae4a7531d5943662c6fa2e32 Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Mon, 10 Jan 2022 10:57:50 +1000 Subject: [PATCH 099/113] Refactor QDQ node group selection infrastructure (#10195) * Separate out the QDQ node group selection from the SAT specific NodeSelector to make re-use in NNAPI etc. cleaner. * Make MatMulIntegerToFloat matching optional. Add move ctor to BaseSelector. Required now that it has a unique_ptr member. * Avoid Guardian warning by using rvalue unique_ptr created with make_unique --- .../qdq_selector_action_transformer.cc | 2 +- .../selectors_actions/qdq_selectors.cc | 63 +++++----- .../selectors_actions/qdq_selectors.h | 116 ++++++++++++++---- .../test/optimizer/qdq_transformer_test.cc | 2 +- 4 files changed, 123 insertions(+), 60 deletions(-) diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc index f3eb9ce39d..e39a11a1e8 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc @@ -31,7 +31,7 @@ void DropQDQNodesRules(SelectorActionRegistry& qdq_selector_action_registry) { std::unique_ptr action = std::make_unique(std::move(moves)); #if !defined(ORT_MINIMAL_BUILD) - std::unique_ptr selector = std::make_unique(); + std::unique_ptr selector = std::make_unique(); qdq_selector_action_registry.RegisterSelectorAndAction(action_name, {{"Gather", {}}, {"Reshape", {}}, diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc index 6acb4478bb..582d215cfc 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc @@ -37,10 +37,10 @@ static std::vector FindQDQNodes(const GraphViewer& graph_viewer, co return nodes; } -bool BaseSelector::CheckQDQNodes(const GraphViewer& graph_viewer, const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes, - int num_dq_inputs) const { +bool NodeGroupSelector::CheckQDQNodes(const GraphViewer& graph_viewer, const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes, + int num_dq_inputs) const { if (num_dq_inputs == -1) { num_dq_inputs = NumActualValues(node, true); } @@ -54,7 +54,7 @@ bool BaseSelector::CheckQDQNodes(const GraphViewer& graph_viewer, const Node& no !graph_viewer.NodeProducesGraphOutput(node); } -std::optional BaseSelector::GetQDQSelection(const GraphViewer& graph_viewer, const Node& node) const { +std::optional NodeGroupSelector::GetQDQSelection(const GraphViewer& graph_viewer, const Node& node) const { std::vector dq_nodes = FindQDQNodes(graph_viewer, node, true); std::vector q_nodes = FindQDQNodes(graph_viewer, node, false); if (!Check(graph_viewer, node, dq_nodes, q_nodes)) { @@ -72,7 +72,7 @@ std::optional BaseSelector::GetQDQSelection(const GraphViewer& graph_ } std::optional BaseSelector::Select(const GraphViewer& graph_viewer, const Node& node) const { - const auto qdq_group = GetQDQSelection(graph_viewer, node); + const auto qdq_group = node_group_selector_->GetQDQSelection(graph_viewer, node); if (!qdq_group.has_value()) { return std::nullopt; } @@ -86,10 +86,10 @@ std::optional BaseSelector::Select(const GraphViewer& gr return builder.Build(); } -bool DropDQDNodesSelector::Check(const GraphViewer& graph_viewer, - const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool DropQDQNodeGroupSelector::Check(const GraphViewer& graph_viewer, + const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (!CheckQDQNodes(graph_viewer, node, dq_nodes, q_nodes, 1)) { return false; } @@ -104,9 +104,9 @@ bool DropDQDNodesSelector::Check(const GraphViewer& graph_viewer, return IsQDQPairSupported(q_node, dq_node, get_const_initializer, graph_viewer.ModelPath()); } -bool UnarySelector::Check(const GraphViewer& graph_viewer, const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool UnaryNodeGroupSelector::Check(const GraphViewer& graph_viewer, const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (!CheckQDQNodes(graph_viewer, node, dq_nodes, q_nodes, 1)) { return false; } @@ -117,10 +117,10 @@ bool UnarySelector::Check(const GraphViewer& graph_viewer, const Node& node, return dt_input == dt_output; } -bool BinarySelector::Check(const GraphViewer& graph_viewer, - const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool BinaryNodeGroupSelector::Check(const GraphViewer& graph_viewer, + const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (!CheckQDQNodes(graph_viewer, node, dq_nodes, q_nodes)) { return false; } @@ -132,10 +132,10 @@ bool BinarySelector::Check(const GraphViewer& graph_viewer, dt_input_1 == dt_output; } -bool VariadicSelector::Check(const GraphViewer& graph_viewer, - const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool VariadicNodeGroupSelector::Check(const GraphViewer& graph_viewer, + const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (!CheckQDQNodes(graph_viewer, node, dq_nodes, q_nodes)) { return false; } @@ -156,10 +156,10 @@ void VariadicSelector::UpdateBuilder(NodesToOptimizeIndicesBuilder& builder) con builder.num_input_defs = 1; // set to 1 as the first input is variadic } -bool ConvSelector::Check(const GraphViewer& graph_viewer, - const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool ConvNodeGroupSelector::Check(const GraphViewer& graph_viewer, + const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (!CheckQDQNodes(graph_viewer, node, dq_nodes, q_nodes)) { return false; } @@ -190,10 +190,10 @@ void ConvSelector::UpdateBuilder(NodesToOptimizeIndicesBuilder& builder) const { builder.input_nodes.resize(3, NodesToOptimizeIndices::kEmptyNodeIndex); } -bool MatMulSelector::Check(const GraphViewer& graph_viewer, - const Node& node, - const std::vector& dq_nodes, - const std::vector& q_nodes) const { +bool MatMulNodeGroupSelector::Check(const GraphViewer& graph_viewer, + const Node& node, + const std::vector& dq_nodes, + const std::vector& q_nodes) const { if (dq_nodes.size() != 2) { return false; } @@ -218,9 +218,10 @@ bool MatMulSelector::Check(const GraphViewer& graph_viewer, int32_t dt_output = q_nodes[0]->OutputDefs()[0]->TypeAsProto()->tensor_type().elem_type(); return dt_input == dt_output; + } else { + // can be converted to MatMulIntegerToFloat if EP supports that. + return matmulintegertofloat_allowed_; } - - return true; } } // namespace QDQ diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h index ecd2ea602b..75ec972c9a 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h @@ -20,19 +20,15 @@ struct NodeGroup { NodeIndex target_node; }; -// Base QDQ checker. Finds and provides the DQ and Q nodes to the operator specific checkers, as the QDQ optimizations -// always involve those nodes. -class BaseSelector : public NodeSelector { +class NodeGroupSelector { public: - std::optional Select(const GraphViewer& graph_viewer, const Node& node) const override; - // This is a QDQ Selectors only function, will return QDQ::NodeGroup instead of NodesToOptimizeIndices // Can be used in QDQ handling in EPs such as NNAPI std::optional GetQDQSelection(const GraphViewer& graph_viewer, const Node& node) const; - protected: - BaseSelector() = default; + virtual ~NodeGroupSelector() = default; + protected: // base check that we have the expected number of QDQ inputs/outputs, and `node` isn't producing a graph output. // num_dq_inputs defaults to the number of inputs `node` has if not explicitly specified bool CheckQDQNodes(const GraphViewer& graph_viewer, const Node& node, @@ -45,42 +41,37 @@ class BaseSelector : public NodeSelector { bool virtual Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const = 0; - - // override if you need to adjust the values in NodesToOptimize. - // e.g. add entries for missing optional DQ inputs or set num_inputs to handle variadic inputs - // Called post-Check, if Check returned `true` - virtual void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const {} }; +/* + * NodeGroup selectors. These are general purpose and used in both the QDQ SelectorActionTransformer setup that the + * CPU EP has, and directly in compiling EPs such as NNAPI and CoreML. + */ + // Single DQ -> node that does not change data -> Q. // Zero point and scale are constant scalars and must match -class DropDQDNodesSelector : public BaseSelector { - private: +class DropQDQNodeGroupSelector : public NodeGroupSelector { bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; }; // single input. default is to only support uint8. -class UnarySelector : public BaseSelector { +class UnaryNodeGroupSelector : public NodeGroupSelector { bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; - }; // 2 DQ nodes providing input -> node -> Q -class BinarySelector : public BaseSelector { +class BinaryNodeGroupSelector : public NodeGroupSelector { bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; }; // Variadic DQ nodes -> node -> Q -class VariadicSelector : public BaseSelector { - public: - void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const override; - +class VariadicNodeGroupSelector : public NodeGroupSelector { private: bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, @@ -88,11 +79,10 @@ class VariadicSelector : public BaseSelector { }; // DQ nodes for X, W and optionally B -> node -> Q -class ConvSelector : public BaseSelector { +class ConvNodeGroupSelector : public NodeGroupSelector { public: - ConvSelector(bool int8_allowed = false) : int8_allowed_(int8_allowed) {} - - void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const override; + // default to 'true' + ConvNodeGroupSelector(bool int8_allowed = true) : int8_allowed_(int8_allowed) {} private: bool Check(const GraphViewer& graph_viewer, const Node& node, @@ -103,16 +93,88 @@ class ConvSelector : public BaseSelector { }; // 2 DQ nodes for input -> node -> optional Q if QLinearMatMul, MatMulIntegerToFloat if not -class MatMulSelector : public BaseSelector { +// The lack of a trailing Q isn't really a QDQ node group, so we default support for that to off. +class MatMulNodeGroupSelector : public NodeGroupSelector { public: - MatMulSelector(bool int8_allowed = false) : int8_allowed_(int8_allowed) {} + MatMulNodeGroupSelector(bool int8_allowed = true, + bool matmulintegertofloat_allowed = false) + : int8_allowed_(int8_allowed), + matmulintegertofloat_allowed_(matmulintegertofloat_allowed) { + } private: bool Check(const GraphViewer& graph_viewer, const Node& node, const std::vector& dq_nodes, const std::vector& q_nodes) const override; bool int8_allowed_; + bool matmulintegertofloat_allowed_; }; + +/* + * NodeSelector instances for use in the QDQ::SelectorActionTransformer. + */ +// Base QDQ checker. Finds and provides the DQ and Q nodes to the operator specific checkers, as the QDQ optimizations +// always involve those nodes. +class BaseSelector : public NodeSelector { + public: + std::optional Select(const GraphViewer& graph_viewer, const Node& node) const override; + + // We std::move SelectorActionRegistry into the SelectorActionTransformer so this class needs to have a move ctor + BaseSelector(BaseSelector&& rhs) noexcept + : node_group_selector_{std::move(rhs.node_group_selector_)} { + } + + protected: + BaseSelector(std::unique_ptr node_group_selector) + : node_group_selector_{std::move(node_group_selector)} {} + + // override if you need to adjust the values in NodesToOptimize. + // e.g. add entries for missing optional DQ inputs or set num_inputs to handle variadic inputs + // Called post-Check, if Check returned `true` + virtual void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const {} + + private: + std::unique_ptr node_group_selector_; +}; + +class DropQDQNodesSelector : public BaseSelector { + public: + DropQDQNodesSelector() : BaseSelector(std::make_unique()) {} +}; + +class UnarySelector : public BaseSelector { + public: + UnarySelector() : BaseSelector(std::make_unique()) {} +}; + +class BinarySelector : public BaseSelector { + public: + BinarySelector() : BaseSelector(std::make_unique()) {} +}; + +// Variadic DQ nodes -> node -> Q +class VariadicSelector : public BaseSelector { + public: + VariadicSelector() : BaseSelector(std::make_unique()) {} + + void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const override; +}; + +// DQ nodes for X, W and optionally B -> node -> Q +class ConvSelector : public BaseSelector { + public: + ConvSelector(bool int8_allowed = false) : BaseSelector(std::make_unique(int8_allowed)) {} + + void UpdateBuilder(NodesToOptimizeIndicesBuilder&) const override; +}; + +// 2 DQ nodes for input -> node -> optional Q if QLinearMatMul, MatMulIntegerToFloat if not +class MatMulSelector : public BaseSelector { + public: + MatMulSelector(bool int8_allowed) + : BaseSelector(std::make_unique(int8_allowed, /*matmulintegertofloat_allowed*/ true)) {} +}; + } // namespace QDQ } // namespace onnxruntime diff --git a/onnxruntime/test/optimizer/qdq_transformer_test.cc b/onnxruntime/test/optimizer/qdq_transformer_test.cc index 2a81087ef8..4470eb4293 100644 --- a/onnxruntime/test/optimizer/qdq_transformer_test.cc +++ b/onnxruntime/test/optimizer/qdq_transformer_test.cc @@ -1789,7 +1789,7 @@ TEST(QDQTransformerTests, QDQ_Selector_Test) { ASSERT_TRUE(nullptr != conv_node); ASSERT_EQ("Conv", conv_node->OpType()); - onnxruntime::QDQ::ConvSelector conv_selector; + onnxruntime::QDQ::ConvNodeGroupSelector conv_selector; // Create a GraphViewer covers the whole graph const GraphViewer whole_graph_viewer(graph); From 7d93498e0ec4b1b2a6f55161539513318a908e04 Mon Sep 17 00:00:00 2001 From: PeixuanZuo <94887879+PeixuanZuo@users.noreply.github.com> Date: Mon, 10 Jan 2022 11:33:46 +0800 Subject: [PATCH 100/113] [FIX] register softmaxgrad_13/logsoftmaxgrad_13 for rocm (#10177) * [FIX] register softmaxgrad_13/logsoftmaxgrad_13 for rocm * [FIX] update softmaxgrad_13/logsoftmaxgrad_13 implementation for rocm --- .../test/training_ops/cuda/softmax_test.cc | 91 +++++++++++++++ .../training_ops/rocm/math/softmax_grad.cc | 105 +++++++++++++++--- .../rocm/rocm_training_kernels.cc | 12 ++ 3 files changed, 194 insertions(+), 14 deletions(-) diff --git a/orttraining/orttraining/test/training_ops/cuda/softmax_test.cc b/orttraining/orttraining/test/training_ops/cuda/softmax_test.cc index 517c3f0446..93d1a4be75 100644 --- a/orttraining/orttraining/test/training_ops/cuda/softmax_test.cc +++ b/orttraining/orttraining/test/training_ops/cuda/softmax_test.cc @@ -179,5 +179,96 @@ TEST(CudaKernelTest, LogSoftmaxGrad_LargeTensor_AllAxis) { TestSoftmaxGrad(dY_dims, Y_dims, dX_dims, 1, true); } +static void TestSoftmaxGrad_13(const std::vector& dY_dims, + const std::vector& Y_dims, + const std::vector& dX_dims, + int axis = 1, + bool is_log_softmax = false, + double per_sample_tolerance = 1e-4, + double relative_per_sample_tolerance = 1e-4) { + + const char* op = is_log_softmax? "LogSoftmaxGrad_13" : "SoftmaxGrad_13"; + CompareOpTester test(op, 1, kMSDomain); + test.AddAttribute("axis", axis); + + // create rand inputs + RandomValueGenerator random{}; + std::vector dY_data = random.Uniform(dY_dims, 0.0f, 1.0f); + // Add 1e-2 for numerical stability to prevent zero probability. + std::vector Y_data = random.Uniform(Y_dims, 0.02f, 1.02f); + + test.AddInput("dY", dY_dims, dY_data); + test.AddInput("Y", Y_dims, Y_data); + + std::vector dX_data = FillZeros(dX_dims); + test.AddOutput("dX", dX_dims, dX_data); + + test.CompareWithCPU(kGpuExecutionProvider, per_sample_tolerance, relative_per_sample_tolerance); +} + +// small tensor to check dispatch_softmax_backward +TEST(CudaKernelTest, SoftmaxGrad_13_SmallTensor_LastAxis) { + std::vector dY_dims{4, 2, 128}; + std::vector Y_dims{4, 2, 128}; + std::vector dX_dims{4, 2, 128}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 2); +} + +TEST(CudaKernelTest, SoftmaxGrad_13_SmallTensor_AllAxis) { + std::vector dY_dims{4, 2, 128}; + std::vector Y_dims{4, 2, 128}; + std::vector dX_dims{4, 2, 128}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 0); + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 1); +} + +// large tensor to check cuda DNN softmax backward +TEST(CudaKernelTest, SoftmaxGrad_13_LargeTensor_LastAxis) { + std::vector dY_dims{8, 16, 2048}; + std::vector Y_dims{8, 16, 2048}; + std::vector dX_dims{8, 16, 2048}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 2); +} + +// large tensor to check cuda DNN softmax backward +TEST(CudaKernelTest, SoftmaxGrad_13_LargeTensor_AllAxis) { + std::vector dY_dims{8, 16, 512}; + std::vector Y_dims{8, 16, 512}; + std::vector dX_dims{8, 16, 512}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 0); + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 1); +} + +TEST(CudaKernelTest, LogSoftmaxGrad_13_SmallTensor_LastAxis) { + std::vector dY_dims{4, 2, 128}; + std::vector Y_dims{4, 2, 128}; + std::vector dX_dims{4, 2, 128}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 2, true); +} + +TEST(CudaKernelTest, LogSoftmaxGrad_13_SmallTensor_AllAxis) { + std::vector dY_dims{4, 2, 128}; + std::vector Y_dims{4, 2, 128}; + std::vector dX_dims{4, 2, 128}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 0, true); + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 1, true); +} + +TEST(CudaKernelTest, LogSoftmaxGrad_13_LargeTensor_LastAxis) { + std::vector dY_dims{8, 16, 2048}; + std::vector Y_dims{8, 16, 2048}; + std::vector dX_dims{8, 16, 2048}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 2, true); +} + +TEST(CudaKernelTest, LogSoftmaxGrad_13_LargeTensor_AllAxis) { + std::vector dY_dims{8, 16, 512}; + std::vector Y_dims{8, 16, 512}; + std::vector dX_dims{8, 16, 512}; + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 0, true); + TestSoftmaxGrad_13(dY_dims, Y_dims, dX_dims, 1, true); +} + + } // namespace test } // namespace onnxruntime diff --git a/orttraining/orttraining/training_ops/rocm/math/softmax_grad.cc b/orttraining/orttraining/training_ops/rocm/math/softmax_grad.cc index 052dc86670..c4a52cf9a8 100644 --- a/orttraining/orttraining/training_ops/rocm/math/softmax_grad.cc +++ b/orttraining/orttraining/training_ops/rocm/math/softmax_grad.cc @@ -7,6 +7,7 @@ #include "core/providers/rocm/miopen_common.h" #include "core/providers/rocm/math/softmax.h" #include "core/providers/rocm/shared_inc/accumulation_type.h" +#include "core/providers/rocm/tensor/transpose.h" namespace onnxruntime { namespace rocm { @@ -61,13 +62,21 @@ Status SoftMaxGradComputeHelper( return Status::OK(); } -#define REGISTER_GRADIENT_KERNEL_TYPED(T) \ - ONNX_OPERATOR_TYPED_KERNEL_EX( \ - SoftmaxGrad, \ - kMSDomain, \ - 1, \ - T, \ - kRocmExecutionProvider, \ +#define REGISTER_GRADIENT_KERNEL_TYPED(T) \ + ONNX_OPERATOR_TYPED_KERNEL_EX( \ + SoftmaxGrad, \ + kMSDomain, \ + 1, \ + T, \ + kRocmExecutionProvider, \ + (*KernelDefBuilder::Create()).TypeConstraint("T", DataTypeImpl::GetTensorType()), \ + SoftmaxGrad); \ + ONNX_OPERATOR_TYPED_KERNEL_EX( \ + SoftmaxGrad_13, \ + kMSDomain, \ + 1, \ + T, \ + kRocmExecutionProvider, \ (*KernelDefBuilder::Create()).TypeConstraint("T", DataTypeImpl::GetTensorType()), \ SoftmaxGrad); \ ONNX_OPERATOR_TYPED_KERNEL_EX( \ @@ -77,6 +86,14 @@ Status SoftMaxGradComputeHelper( T, \ kRocmExecutionProvider, \ (*KernelDefBuilder::Create()).TypeConstraint("T", DataTypeImpl::GetTensorType()), \ + SoftmaxGrad); \ + ONNX_OPERATOR_TYPED_KERNEL_EX( \ + LogSoftmaxGrad_13, \ + kMSDomain, \ + 1, \ + T, \ + kRocmExecutionProvider, \ + (*KernelDefBuilder::Create()).TypeConstraint("T", DataTypeImpl::GetTensorType()), \ SoftmaxGrad); template @@ -85,16 +102,76 @@ Status SoftmaxGrad::ComputeInternal(OpKernelContext* ctx) const { const TensorShape& input_shape{dY->Shape()}; const Tensor* Y = ctx->Input(1); Tensor* dX = ctx->Output(0, input_shape); + + size_t rank = input_shape.NumDimensions(); + const size_t axis = static_cast(HandleNegativeAxis(axis_, rank)); + bool is_transpose_required = opset_ >= 13 && axis != (rank - 1); - const T* dY_data = dY->template Data(); - const T* Y_data = Y->template Data(); - T* dX_data = dX->template MutableData(); + std::unique_ptr transposed_dY; + std::unique_ptr transposed_Y; + std::vector transposed_input_dims; + std::unique_ptr intermediate_output; // output that the softmax implementation will write into while using transposed input + std::vector permutation(rank); - if (log_softmax_) { - return SoftMaxGradComputeHelper(Stream(), dY_data, input_shape, Y_data, dX_data, MiopenHandle(), axis_); - } else { - return SoftMaxGradComputeHelper(Stream(), dY_data, input_shape, Y_data, dX_data, MiopenHandle(), axis_); + if (is_transpose_required) { + AllocatorPtr alloc; + auto status = ctx->GetTempSpaceAllocator(&alloc); + if (!status.IsOK()) + return status; + + std::iota(std::begin(permutation), std::end(permutation), 0); + + // swap the innermost dim with the dim corresponding to axis + permutation[axis] = rank - 1; + permutation[rank - 1] = axis; + + transposed_input_dims.reserve(rank); + for (auto e : permutation) { + transposed_input_dims.push_back(input_shape[e]); + } + + // Allocate a temporary tensor to hold transposed input + auto temp_input0 = Tensor::Create(Y->DataType(), TensorShape(transposed_input_dims), alloc); + + // Perform the transpose + ORT_RETURN_IF_ERROR(Transpose::DoTranspose(prop_, + Stream(), + RocblasHandle(), + permutation, *Y, *temp_input0)); + transposed_Y = std::move(temp_input0); + auto temp_input1 = Tensor::Create(Y->DataType(), TensorShape(transposed_input_dims), alloc); + ORT_RETURN_IF_ERROR(Transpose::DoTranspose(prop_, + Stream(), + RocblasHandle(), + permutation, *dY, *temp_input1)); + transposed_dY = std::move(temp_input1); + + // Allocate memory for the intermediate output + intermediate_output = Tensor::Create(dX->DataType(), TensorShape(transposed_input_dims), alloc); } + const T* dY_data = is_transpose_required ? transposed_dY->template Data() : dY->template Data(); + const T* Y_data = is_transpose_required ? transposed_Y->template Data() : Y->template Data(); + T* dX_data = is_transpose_required ? intermediate_output->template MutableData() : dX->template MutableData(); + const TensorShape* compute_input_shape = is_transpose_required ? &transposed_Y->Shape() : &input_shape; + Status status; + if (log_softmax_) { + status = SoftMaxGradComputeHelper(Stream(), dY_data, *compute_input_shape, Y_data, dX_data, MiopenHandle(), is_transpose_required ? static_cast(rank) - 1 : axis); + } else { + status = SoftMaxGradComputeHelper(Stream(), dY_data, *compute_input_shape, Y_data, dX_data, MiopenHandle(), is_transpose_required ? static_cast(rank) - 1 : axis); + } + + if (!status.IsOK()) { + return status; + } + + if (is_transpose_required) { + // Perform the transpose to get the axes back to the original ordering + ORT_RETURN_IF_ERROR(Transpose::DoTranspose(prop_, + Stream(), + RocblasHandle(), + permutation, *intermediate_output, *dX)); + } + return Status::OK(); } #define SPECIALIZED_GRADIENT(T) \ diff --git a/orttraining/orttraining/training_ops/rocm/rocm_training_kernels.cc b/orttraining/orttraining/training_ops/rocm/rocm_training_kernels.cc index 322a35c566..b594c78196 100644 --- a/orttraining/orttraining/training_ops/rocm/rocm_training_kernels.cc +++ b/orttraining/orttraining/training_ops/rocm/rocm_training_kernels.cc @@ -69,6 +69,12 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1 class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, float, LogSoftmaxGrad); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, double, LogSoftmaxGrad); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, MLFloat16, LogSoftmaxGrad); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, float, SoftmaxGrad_13); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, double, SoftmaxGrad_13); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, MLFloat16, SoftmaxGrad_13); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, float, LogSoftmaxGrad_13); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, double, LogSoftmaxGrad_13); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, MLFloat16, LogSoftmaxGrad_13); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, float_float_float, BatchNormalizationGrad); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, double_double_double, BatchNormalizationGrad); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kRocmExecutionProvider, kMSDomain, 1, MLFloat16_MLFloat16_MLFloat16, BatchNormalizationGrad); @@ -247,6 +253,12 @@ Status RegisterRocmTrainingKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, // BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, + // BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + // BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, From 1f5b0735085799ee8c93c65d4f9cc2b5cbc30cc8 Mon Sep 17 00:00:00 2001 From: Dwayne Robinson Date: Mon, 10 Jan 2022 02:06:31 -0800 Subject: [PATCH 101/113] Minor DirectML EP provider factory comments (#9965) --- .../core/providers/dml/dml_provider_factory.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/onnxruntime/core/providers/dml/dml_provider_factory.h b/include/onnxruntime/core/providers/dml/dml_provider_factory.h index 308b7faa5f..72816be80e 100644 --- a/include/onnxruntime/core/providers/dml/dml_provider_factory.h +++ b/include/onnxruntime/core/providers/dml/dml_provider_factory.h @@ -25,18 +25,22 @@ extern "C" { #endif /** + * [[deprecated]] + * This export is deprecated. + * The OrtSessionOptionsAppendExecutionProvider_DML export on the OrtDmlApi should be used instead. + * * Creates a DirectML Execution Provider which executes on the hardware adapter with the given device_id, also known as * the adapter index. The device ID corresponds to the enumeration order of hardware adapters as given by * IDXGIFactory::EnumAdapters. A device_id of 0 always corresponds to the default adapter, which is typically the * primary display GPU installed on the system. A negative device_id is invalid. - * - * [[deprecated]] - * This export should be deprecated. - * The OrtSessionOptionsAppendExecutionProvider_DML export on the OrtDmlApi should be used instead. */ ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_DML, _In_ OrtSessionOptions* options, int device_id); /** + * [[deprecated]] + * This export is deprecated. + * The OrtSessionOptionsAppendExecutionProvider_DML1 export on the OrtDmlApi should be used instead. + * * Creates a DirectML Execution Provider using the given DirectML device, and which executes work on the supplied D3D12 * command queue. The DirectML device and D3D12 command queue must have the same parent ID3D12Device, or an error will * be returned. The D3D12 command queue must be of type DIRECT or COMPUTE (see D3D12_COMMAND_LIST_TYPE). If this @@ -44,10 +48,6 @@ ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_DML, _In_ OrtSessionOpti * objects. * See also: DMLCreateDevice * See also: ID3D12Device::CreateCommandQueue - * - * [[deprecated]] - * This export should be deprecated. - * The OrtSessionOptionsAppendExecutionProvider_DML1 export on the OrtDmlApi should be used instead. */ ORT_API_STATUS(OrtSessionOptionsAppendExecutionProviderEx_DML, _In_ OrtSessionOptions* options, _In_ IDMLDevice* dml_device, _In_ ID3D12CommandQueue* cmd_queue); @@ -79,21 +79,21 @@ struct OrtDmlApi { /** * CreateGPUAllocationFromD3DResource - * This api is used to create a DML EP input based on a user specified d3d12 resource. + * This API creates a DML EP resource based on a user-specified D3D12 resource. */ ORT_API2_STATUS(CreateGPUAllocationFromD3DResource, _In_ ID3D12Resource* d3d_resource, _Out_ void** dml_resource); /** * FreeGPUAllocation - * This api is used free the DML EP input created by CreateGPUAllocationFromD3DResource. + * This API frees the DML EP resource created by CreateGPUAllocationFromD3DResource. */ ORT_API2_STATUS(FreeGPUAllocation, _In_ void* dml_resource); /** * GetD3D12ResourceFromAllocation - * This api is used to get the D3D12 resource when a OrtValue has been allocated by the DML EP and accessed via GetMutableTensorData. + * This API gets the D3D12 resource when an OrtValue has been allocated by the DML EP. */ - ORT_API2_STATUS(GetD3D12ResourceFromAllocation, _In_ OrtAllocator* provider, _In_ void* dml_allocation, _Out_ ID3D12Resource** d3d_resource); + ORT_API2_STATUS(GetD3D12ResourceFromAllocation, _In_ OrtAllocator* provider, _In_ void* dml_resource, _Out_ ID3D12Resource** d3d_resource); }; #ifdef __cplusplus From 0f5e82c294fe719b1309399d7c5709c8351fb74d Mon Sep 17 00:00:00 2001 From: Dwayne Robinson Date: Mon, 10 Jan 2022 02:07:22 -0800 Subject: [PATCH 102/113] DirectML EP remove stale code for int64 via int32 double strides (#9959) --- .../inc/IWinmlExecutionProvider.h | 18 -- .../src/AbiCustomRegistry.cpp | 14 +- .../src/AbiCustomRegistry.h | 4 - .../src/GraphPartitioner.cpp | 139 +---------- .../src/Operators/DmlOperator.cpp | 28 --- .../src/Operators/DmlOperator.h | 5 - .../src/Operators/DmlOperatorGather.cpp | 6 - .../src/Operators/DmlOperatorMaxUnpool.cpp | 1 - .../src/Operators/DmlOperatorOneHot.cpp | 2 - .../src/Operators/DmlOperatorPooling.cpp | 3 +- .../src/Operators/DmlOperatorReduce.cpp | 24 -- .../Operators/DmlOperatorReverseSequence.cpp | 3 +- .../src/Operators/DmlOperatorRoiAlign.cpp | 3 +- .../src/Operators/DmlOperatorScatter.cpp | 5 +- .../src/Operators/DmlOperatorTopk.cpp | 3 +- .../src/Operators/OperatorRegistration.cpp | 220 +++++++++--------- .../DmlExecutionProvider/src/TensorDesc.cpp | 7 - .../dml/DmlExecutionProvider/src/TensorDesc.h | 1 - .../MLOperatorAuthorPrivate.h | 4 - winml/adapter/abi_custom_registry_impl.cpp | 8 - winml/adapter/abi_custom_registry_impl.h | 4 - 21 files changed, 111 insertions(+), 391 deletions(-) diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/inc/IWinmlExecutionProvider.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/inc/IWinmlExecutionProvider.h index d5c651a0c4..781930a186 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/inc/IWinmlExecutionProvider.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/inc/IWinmlExecutionProvider.h @@ -108,24 +108,6 @@ namespace Windows::AI::MachineLearning::Adapter std::vector requiredConstantCpuInputs; std::optional graphNodeFactoryRegistration; KernelSupportQuery supportQuery; - - // Many ONNX operators use 64-bit tensors, but most DML operators only support - // 32-bit indices. This flag indicates to the graph whether it's okay to compute - // the result using 32-bit tensors (ignoring the upper bits) via doubled strides. - bool supportedWith64BitTensorsVia32BitStrides = false; - - // When true, the input to the current operator may come from any execution - // provider. Otherwise it must have come from another DML node to assume it's safe - // to use 64-bit to 32-bit striding. - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp = false; - - // Operator supports true 64-bit tensors directly, no strides needed. - // So fallback to strided 32-bit only occurs when the device lacks 64-bit support. - bool prefer64BitTensorsDirectly = false; - - // The operator supports emulation for uint64/int64 even if the hardware doesn't - // support native uint64/int64 data types. - bool support64BitTensorsViaEmulation = false; }; using InternalRegistrationInfoMap = std::unordered_map>; diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp index 04d1e6859f..33df3d6df4 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.cpp @@ -342,10 +342,6 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel( bool canAliasFirstInput, bool supportsGraph, const uint32_t* requiredInputCountForGraph, - bool supportedWith64BitTensorsVia32BitStrides, - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp, - bool prefer64BitTensorsDirectly, - bool support64BitTensorsViaEmulation, _In_reads_(constantCpuInputCount) const uint32_t* requiredConstantCpuInputs, uint32_t constantCpuInputCount) const noexcept { @@ -471,10 +467,6 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel( { auto regInfo = std::make_shared(); regInfo->requiredConstantCpuInputs = constantCpuInputCapture; - regInfo->supportedWith64BitTensorsVia32BitStrides = supportedWith64BitTensorsVia32BitStrides; - regInfo->supportedWith64BitTensorsVia32BitStridesFromAnyEp = supportedWith64BitTensorsVia32BitStridesFromAnyEp; - regInfo->prefer64BitTensorsDirectly = prefer64BitTensorsDirectly; - regInfo->support64BitTensorsViaEmulation = support64BitTensorsViaEmulation; // Only internal operators support usage in DML graphs if (supportsGraph) @@ -546,11 +538,7 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel( if (canAliasFirstInput || supportsGraph || requiredInputCountForGraph || - requiredConstantCpuInputs || - supportedWith64BitTensorsVia32BitStrides || - supportedWith64BitTensorsVia32BitStridesFromAnyEp || - prefer64BitTensorsDirectly || - support64BitTensorsViaEmulation) + requiredConstantCpuInputs) { ORT_THROW_HR(E_INVALIDARG); } diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.h index 2482d3af8b..d6b1448b55 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/AbiCustomRegistry.h @@ -41,10 +41,6 @@ class AbiCustomRegistry : public WRL::BaseExists()) - { - const onnx::TypeProto* typeProto = arg->TypeAsProto(); - if (typeProto->value_case() == onnx::TypeProto::kTensorType) - { - const onnx::TypeProto_Tensor tensorType = typeProto->tensor_type(); - if (tensorType.has_elem_type()) - { - // TODO: Remove this by handling zeroing on the output of fused graph nodes and handling of non-float - // types in DML's identity operator, which is used for strided copies. - - MLOperatorTensorDataType mlDataType = ToMLTensorDataType(static_cast(tensorType.elem_type())); - - // Do not include operators in the graph if tensor types are unsupported, - // except cases that are always supported via emulation. - if ((mlDataType == MLOperatorTensorDataType::UInt64 || - mlDataType == MLOperatorTensorDataType::Int64) && - !supports64BitTensorsViaEmulation) - { - constexpr uint32_t deviceDataTypeMask64bit = (1 << DML_TENSOR_DATA_TYPE_UINT64) | (1 << DML_TENSOR_DATA_TYPE_INT64); - if ((supportedDeviceDataTypeMask & deviceDataTypeMask64bit) != deviceDataTypeMask64bit) - { - return false; - } - } - - } - } - } - - return true; - } - - bool NodeTensorTypesSupportedInGraph(const onnxruntime::Node& node, const InternalRegistrationInfo& registration, uint32_t supportedDeviceDataTypeMask) - { - for (size_t i = 0; i < node.InputDefs().size(); ++i) - { - bool isConstantCpuInput = std::find(registration.requiredConstantCpuInputs.begin(), registration.requiredConstantCpuInputs.end(), i) != - registration.requiredConstantCpuInputs.end(); - - if (!isConstantCpuInput && - !NodeArgSupportedInGraph( - node.InputDefs()[i], - registration.support64BitTensorsViaEmulation, - supportedDeviceDataTypeMask - )) - { - return false; - } - } - - for (auto arg : node.OutputDefs()) - { - if (!NodeArgSupportedInGraph( - arg, - registration.support64BitTensorsViaEmulation, - supportedDeviceDataTypeMask - )) - { - return false; - } - } - - return true; - } - bool TryGetTensorDataType( const onnxruntime::NodeArg& nodeArg, _Out_ MLOperatorTensorDataType* onnxElementType @@ -242,26 +170,10 @@ namespace Dml { ORT_THROW_HR_IF(E_INVALIDARG, allow64BitInputThroughStrides && !nodeNameToPartitionMap); - bool prefer64BitTensorsDirectly = false; - bool support64BitTensorsViaEmulation = false; - bool supportedWith64BitTensorsVia32BitStrides = false; - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp = false; std::vector constantCpuInputs; if (regInfo != nullptr) { - // Read the operator flags for handling 64-bit tensors and whether it's allowed to fall back - // to 32-bit tensors via strides. If the caller passes allow64BitInputThroughStrides = false - // in this particular call, then the operator-specific flags do not matter as the caller has - // disabled 64-bit support. - prefer64BitTensorsDirectly = regInfo->prefer64BitTensorsDirectly; - support64BitTensorsViaEmulation = regInfo->support64BitTensorsViaEmulation; - if (allow64BitInputThroughStrides) - { - supportedWith64BitTensorsVia32BitStridesFromAnyEp = regInfo->supportedWith64BitTensorsVia32BitStridesFromAnyEp; - supportedWith64BitTensorsVia32BitStrides = regInfo->supportedWith64BitTensorsVia32BitStrides | supportedWith64BitTensorsVia32BitStridesFromAnyEp; - } - // Collect the list of CPU-bound input tensors, needed when checking 64-bit fallback // or for other data types like int-8 which may be supported for CPU inputs but not // GPU inputs. @@ -317,55 +229,7 @@ namespace Dml return; } - // If this operator implements 64-bit support in terms of strided 32-bit tensors, - // then the data type needs to be remapped, regardless of whether input or output. - // - // Some operators can fairly safely implement 64-bit tensors in terms of - // strided 32-bit tensors regardless of input tensor's execution provider - // because the indices measure along a single axis and should fall within - // the range of an int32/uint32. - // - // Currently all DML kernels outputting int64 and uint64 are expected to - // not *introduce* values out of range, which allows the temporary trick - // using strides to emulate 64 bit tensors to work. If the source is a CPU - // operator, graph input or initializer, it's not safe to assume the input - // can be represented with 32 bits. - // bool isDataTypeSupported = (1 << dmlElementType) & supportedDeviceDataTypeMask; - bool is64BitIntType = (dmlElementType == DML_TENSOR_DATA_TYPE_UINT64 || dmlElementType == DML_TENSOR_DATA_TYPE_INT64); - if (is64BitIntType) - { - if (support64BitTensorsViaEmulation) - { - // Consider it supported regardless of hardware support. - isDataTypeSupported = true; - } - else if (prefer64BitTensorsDirectly && isDataTypeSupported) - { - // Operator supports native int64/uint64 tensors. - } - else if (supportedWith64BitTensorsVia32BitStrides || supportedWith64BitTensorsVia32BitStridesFromAnyEp) - { - dmlElementType = Remap64bitDmlDataTypeTo32bit(dmlElementType); - isDataTypeSupported = (1 << dmlElementType) & supportedDeviceDataTypeMask; - - if (isInput && !supportedWith64BitTensorsVia32BitStridesFromAnyEp) - { - // Look up the input partition. If it's a graph input or initializer it will be missing - // from the partition map. - const std::string& argName = nodeArg.Name(); - - // If input tensor's data comes from the output of a different execution provider, - // consider it unsafe to apply fallback to. - auto partitionIter = nodeNameToPartitionMap->find(argName); - if (partitionIter == nodeNameToPartitionMap->end() || !partitionIter->second->IsDmlPartition()) - { - nodeContainsSupportedDataTypes = false; - return; - } - } - } - } // Reject node if the data type is unsupported by the device. if (!isDataTypeSupported) @@ -465,8 +329,7 @@ namespace Dml { auto internalRegInfo = regInfoIter->second; - if (internalRegInfo && internalRegInfo->graphNodeFactoryRegistration && - NodeTensorTypesSupportedInGraph(node, *internalRegInfo, supportedDeviceDataTypeMask)) + if (internalRegInfo && internalRegInfo->graphNodeFactoryRegistration) { bool requiredCpuInputsConstant = true; for (uint32_t inputIndex : internalRegInfo->requiredConstantCpuInputs) diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.cpp index f0e2b2893b..2b44b68650 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.cpp @@ -389,34 +389,6 @@ namespace Dml )); } - void DmlOperator::Remap64bitDmlDataTypesTo32bit() - { - for (auto& tensor : m_inputTensorDescs) - { - tensor.Remap64bitDmlDataTypeTo32bit(); - } - - for (auto& tensor : m_outputTensorDescs) - { - tensor.Remap64bitDmlDataTypeTo32bit(); - } - } - - void DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded() - { - // Conditionally remap 64-bit data types to strided 32-bit if DML does not - // support 64-bit data types directly on the device. - - uint32_t deviceTypeMask = Dml::GetSupportedDeviceDataTypeMask(m_dmlDevice.Get()); - uint32_t deviceTypeMask64bit = (1 << DML_TENSOR_DATA_TYPE_INT64) | (1 << DML_TENSOR_DATA_TYPE_UINT64); - - // If the device doesn't support 64-bit tensors, fall back to 32-bit with strides. - if (!(deviceTypeMask & deviceTypeMask64bit)) - { - Remap64bitDmlDataTypesTo32bit(); - } - } - TensorDesc DmlOperator::CreateTensorDescFromInput( const MLOperatorKernelCreationContext& kernelInfo, uint32_t index, diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.h index fcd892807d..55720048a9 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperator.h @@ -85,11 +85,6 @@ namespace Dml void ExecuteZeroInt64Tensor(IDMLCompiledOperator* compiledOperator, IMLOperatorTensor* tensor); - // Remap 64-bit data types to 32-bit via doubled strides. - // These should be called before GetDmlInputDescs or GetDmlOutputDescs. - void Remap64bitDmlDataTypesTo32bit(); - void Remap64bitDmlDataTypesTo32bitIfNeeded(); - TensorDesc CreateTensorDescFromInput( const MLOperatorKernelCreationContext& kernelInfo, uint32_t index, diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorGather.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorGather.cpp index 6dfdf0cec6..4c1845a0ad 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorGather.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorGather.cpp @@ -24,8 +24,6 @@ public: size_t dimensionCountMax = std::max({dataDimensions.size(), indicesDimensions.size(), outputDimensions.size()}); DmlOperator::Initialize(kernelCreationContext, gsl::narrow_cast(dimensionCountMax)); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); assert(inputDescs.size() == 2); @@ -62,8 +60,6 @@ public: size_t dimensionCountMax = std::max({dataDimensions.size(), indicesDimensions.size(), outputDimensions.size()}); DmlOperator::Initialize(kernelCreationContext, gsl::narrow_cast(dimensionCountMax)); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); assert(inputDescs.size() == 2); @@ -101,8 +97,6 @@ public: size_t dimensionCountMax = std::max({dataDimensions.size(), indicesDimensions.size(), outputDimensions.size()}); DmlOperator::Initialize(kernelCreationContext, gsl::narrow_cast(dimensionCountMax)); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); assert(inputDescs.size() == 2); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorMaxUnpool.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorMaxUnpool.cpp index e58bb0a674..a47c85211b 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorMaxUnpool.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorMaxUnpool.cpp @@ -22,7 +22,6 @@ public: std::vector> inputIndices = { 0, 1 }; // The 3rd tensor ('output_shape') is not bound, just 'X' and 'I' indices. std::vector> outputIndices = { 0 }; DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices); - DmlOperator::Remap64bitDmlDataTypesTo32bit(); m_inputTensorDescs[1].ForceUnsignedDataType(); // MaxUnpool accepts uint32_t. std::vector inputDescs = GetDmlInputDescs(); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorOneHot.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorOneHot.cpp index f1ba681d99..ca5b91b1f7 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorOneHot.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorOneHot.cpp @@ -53,8 +53,6 @@ public: 0 ); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - // Adjust the axis so it's in DML's terms rather than the original ONNX indexing. uint32_t dmlAxis = GetDmlAdjustedAxis( m_absoluteAxis, diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorPooling.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorPooling.cpp index 7985c94fe8..18fd53199c 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorPooling.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorPooling.cpp @@ -111,8 +111,7 @@ public: if (hasOutputIndices) { - DmlOperator::Remap64bitDmlDataTypesTo32bit(); - m_outputTensorDescs[1].ForceUnsignedDataType(); // MaxPool accepts uint32_t. + m_outputTensorDescs[1].ForceUnsignedDataType(); // MaxPool accepts uint32_t/uint64_t. desc.OutputIndicesTensor = &outputDescs[1]; } diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReduce.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReduce.cpp index d44180c141..2e02df98b1 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReduce.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReduce.cpp @@ -67,14 +67,6 @@ public: argmaxDesc.Axes = dmlAxes.data(); argmaxDesc.AxisCount = gsl::narrow_cast(dmlAxes.size()); - // If the 64-bit tensors were remapped to 32-bit, then we need to clear the upper 32-bits - // of each element. If the device directly supports 64-bit elements, then no need. - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - if (m_outputTensorDescs[0].WasRemapped64bitTo32bit()) - { - m_zeroOperator = InitializeZeroInt64Tensor(m_outputTensorDescs[0].GetBufferSizeInBytes()); - } - DML_OPERATOR_DESC opDesc = { DML_OPERATOR_ARGMAX, &argmaxDesc }; SetDmlOperatorDesc(opDesc, kernelInfo); } @@ -87,14 +79,6 @@ public: argminDesc.Axes = dmlAxes.data(); argminDesc.AxisCount = gsl::narrow_cast(dmlAxes.size()); - // If the 64-bit tensors were remapped to 32-bit, then we need to clear the upper 32-bits - // of each element. If the device directly supports 64-bit elements, then no need. - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); - if (m_outputTensorDescs[0].WasRemapped64bitTo32bit()) - { - m_zeroOperator = InitializeZeroInt64Tensor(m_outputTensorDescs[0].GetBufferSizeInBytes()); - } - DML_OPERATOR_DESC opDesc = { DML_OPERATOR_ARGMIN, &argminDesc }; SetDmlOperatorDesc(opDesc, kernelInfo); } @@ -117,20 +101,12 @@ public: std::vector inputTensors = GetInputTensorsForExecute(kernelContext); std::vector outputTensors = GetOutputTensorsForExecute(kernelContext); - if (m_zeroOperator) - { - ExecuteZeroInt64Tensor(m_zeroOperator.Get(), outputTensors[0]); - } - ORT_THROW_IF_FAILED(m_executionProvider->ExecuteOperator( m_compiledOperator.Get(), m_persistentResourceBinding ? &*m_persistentResourceBinding : nullptr, gsl::make_span(inputTensors), gsl::make_span(outputTensors))); } - -private: - ComPtr m_zeroOperator; }; // A specific type of operation for registration. diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReverseSequence.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReverseSequence.cpp index 8e2af57299..2065c99911 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReverseSequence.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorReverseSequence.cpp @@ -47,8 +47,7 @@ public: 0 ); - DmlOperator::Remap64bitDmlDataTypesTo32bit(); - m_inputTensorDescs[1].ForceUnsignedDataType(); // DML operator accepts uint32_t. + m_inputTensorDescs[1].ForceUnsignedDataType(); // DML operator accepts uint32_t/uint64_t for sequence_lengths. std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorRoiAlign.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorRoiAlign.cpp index 533c894119..c3a25ca8d4 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorRoiAlign.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorRoiAlign.cpp @@ -19,8 +19,7 @@ public: ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1, "RoiAlign expects 1 output tensor."); DmlOperator::Initialize(kernelCreationContext); - DmlOperator::Remap64bitDmlDataTypesTo32bit(); - m_inputTensorDescs[2].ForceUnsignedDataType(); + m_inputTensorDescs[2].ForceUnsignedDataType(); // DML operator accepts uint32_t/uint64_t for batch_indices tensor. std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorScatter.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorScatter.cpp index a58098a81e..68b567e086 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorScatter.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorScatter.cpp @@ -24,13 +24,12 @@ public: ML_CHECK_VALID_ARGUMENT(indicesDimensions == updatesDimensions); ML_CHECK_VALID_ARGUMENT(dataDimensions.size() == indicesDimensions.size()); - // When the indices tensor is empty, Scatter is basically Identity. But since DML doesn't support empty or null + // When the indices tensor is empty, Scatter is basically Identity. But since DML doesn't yet support empty // tensors, we have to special-case it outside of DML. if (OperatorHelper::ContainsEmptyDimensions(indicesDimensions)) { std::vector> kernelInputIndices(1, 0); DmlOperator::Initialize(kernelCreationContext, kernelInputIndices); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); @@ -49,7 +48,6 @@ public: else { DmlOperator::Initialize(kernelCreationContext); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); @@ -91,7 +89,6 @@ public: size_t dimensionCountMax = std::max({dataDimensions.size(), updatesDimensions.size(), indicesDimensions.size(), outputDimensions.size()}); DmlOperator::Initialize(kernelCreationContext, gsl::narrow_cast(dimensionCountMax)); - DmlOperator::Remap64bitDmlDataTypesTo32bitIfNeeded(); std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorTopk.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorTopk.cpp index 7277e44c95..12637c3d3e 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorTopk.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorTopk.cpp @@ -22,8 +22,7 @@ public: std::vector> inputIndices = { 0 }; // Use only the first tensor. The second tensor is CPU-based. std::vector> outputIndices = { 0, 1 }; DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices); - DmlOperator::Remap64bitDmlDataTypesTo32bit(); - m_outputTensorDescs[1].ForceUnsignedDataType(); + m_outputTensorDescs[1].ForceUnsignedDataType(); // DML operator accepts uint32_t/uint64 for indices tensor. std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp index ff33a8d55a..4c2937ee49 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp @@ -55,10 +55,6 @@ enum class DmlGraphSupport : uint32_t { Supported = 0, NotSupported = 1, - SupportedWith64BitTensorsVia32BitStrides = 2, // Supports them via 32-bit tensors and doubled strides. - SupportedWith64BitTensorsVia32BitStridesFromAnyEp = 4, // Supports input from any execution provider (otherwise only inputs from other DML nodes) - Prefer64BitTensorsDirectly = 8, // Natively supports 64-bit tensors. So avoid strided 32-bit unless the device lacks support. - Support64BitTensorsViaEmulation = 16,// supports int/uint64 tensors via emulation of 32-bit types. }; DEFINE_ENUM_FLAG_OPERATORS(DmlGraphSupport); @@ -375,18 +371,18 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 10, AveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 11, AveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, GlobalAveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO( 7, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported|DmlGraphSupport::SupportedWith64BitTensorsVia32BitStrides)}, - {REG_INFO( 8, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, - {REG_INFO( 10, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, - {REG_INFO( 11, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, - {REG_INFO( 12, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, + {REG_INFO( 7, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, + {REG_INFO( 8, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, + {REG_INFO( 10, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, + {REG_INFO( 11, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, + {REG_INFO( 12, MaxPool, typeNameListMaxPool, supportedTypeListMaxPool, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryMaxPool)}, {REG_INFO( 7, GlobalMaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, LpPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 11, LpPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, GlobalLpPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, MaxRoiPool, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO_VER( 10, RoiAlign, typeNameListTwo, supportedTypeListRoiAlign, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO_VER( 10, RoiAlign, typeNameListTwo, supportedTypeListRoiAlign, DmlGraphSupport::Supported)}, {REG_INFO( 7, InstanceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 9, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, // v9 just removes 'spatial' attribute. @@ -402,60 +398,60 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO_MS( 1, ConvTransposeWithDynamicPads, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))}, // Data Reorganization Layers - {REG_INFO( 7, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, // Adds negative axis. - {REG_INFO( 7, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, // Adds negative axis. - {REG_INFO( 13, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, // Adds negative axis. - {REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, // Adds negative axes. - {REG_INFO_VER( 11, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, - {REG_INFO_VER( 13, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, - {REG_INFO_VER( 7, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 11, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1, 2) /*pads, value*/)}, // https://microsoft.visualstudio.com/OS/_workitems/edit/26007728 - {REG_INFO_VER( 13, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1, 2) /*pads, value*/)}, // https://microsoft.visualstudio.com/OS/_workitems/edit/26007728 - {REG_INFO( 7, SpaceToDepth, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, SpaceToDepth, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Tile, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 13, Tile, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 8, Expand, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 13, Expand, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 9, ConstantOfShape, typeNameListConstantOfShape, supportedTypeListConstantOfShape, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(0))}, - {REG_INFO( 7, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, GatherElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, GatherElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 12, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 9, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 11, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 13, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 7, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 11, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis. + {REG_INFO( 7, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 11, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis. + {REG_INFO( 13, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis. + {REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, // Adds negative axes. + {REG_INFO_VER( 11, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, + {REG_INFO_VER( 13, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, + {REG_INFO_VER( 7, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 11, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2) /*pads, value*/)}, // https://microsoft.visualstudio.com/OS/_workitems/edit/26007728 + {REG_INFO_VER( 13, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2) /*pads, value*/)}, // https://microsoft.visualstudio.com/OS/_workitems/edit/26007728 + {REG_INFO( 7, SpaceToDepth, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 13, SpaceToDepth, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 7, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 11, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 13, DepthToSpace, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Tile, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 13, Tile, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 8, Expand, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 13, Expand, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 9, ConstantOfShape, typeNameListConstantOfShape, supportedTypeListConstantOfShape, DmlGraphSupport::Supported, requiredConstantCpuInputs(0))}, + {REG_INFO( 7, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 11, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 11, GatherElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 13, GatherElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 11, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)}, + {REG_INFO( 12, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)}, + {REG_INFO( 13, GatherND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 9, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 11, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 13, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 11, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)}, + {REG_INFO( 11, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)}, {REG_INFO( 9, EyeLike, typeNameListEyeLike, supportedTypeListScalars8to32, DmlGraphSupport::Supported)}, // Data reorganization that merely changes the dimensions while keeping the data identical. - {REG_INFO_ID( 7, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 13, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 7, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 9, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 11, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 13, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 7, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 11, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 7, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 11, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_ID( 7, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO_ID( 13, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, + {REG_INFO_ID( 7, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 13, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 7, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 9, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 11, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 13, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 7, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 11, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 7, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 11, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, + {REG_INFO_ID( 7, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO_ID( 13, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, // Elementwise {REG_INFO( 7, Sqrt, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, @@ -477,14 +473,14 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 13, Floor, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO_VER( 7, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO_VER( 11, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))}, - {REG_INFO_VER( 12, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1,2))}, - {REG_INFO_VER( 13, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1,2))}, - {REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO_VER( 12, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))}, + {REG_INFO_VER( 13, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))}, + {REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)}, {REG_INFO( 7, Div, typeNameListDefault, supportedTypeListFloat16to32Ints32, DmlGraphSupport::Supported)}, {REG_INFO( 13, Div, typeNameListDefault, supportedTypeListFloat16to32Ints32, DmlGraphSupport::Supported)}, {REG_INFO( 7, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, @@ -495,12 +491,12 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 13, Mean, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, {REG_INFO( 7, Max, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, {REG_INFO( 8, Max, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, - {REG_INFO( 12, Max, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), 2)}, - {REG_INFO( 13, Max, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), 2)}, + {REG_INFO( 12, Max, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, + {REG_INFO( 13, Max, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, {REG_INFO( 7, Min, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, {REG_INFO( 8, Min, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, - {REG_INFO( 12, Min, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), 2)}, - {REG_INFO( 13, Min, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(), 2)}, + {REG_INFO( 12, Min, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, + {REG_INFO( 13, Min, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)}, {REG_INFO( 7, Cos, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, Sin, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, Tan, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, @@ -550,37 +546,37 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 13, ReduceL2, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 11, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO( 12, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 12, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)}, {REG_INFO( 7, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 11, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO( 12, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 12, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 12, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 12, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)}, + {REG_INFO( 7, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 11, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 12, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ArgMax, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 7, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 11, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 12, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, + {REG_INFO( 13, ArgMin, typeNameListDefault, supportedTypeListArgMinMax, DmlGraphSupport::Supported)}, {REG_INFO( 7, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 9, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 11, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 13, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 7, Neg, typeNameListDefault, supportedTypeListSigned, DmlGraphSupport::Supported)}, {REG_INFO( 13, Neg, typeNameListDefault, supportedTypeListSigned, DmlGraphSupport::Supported)}, - {REG_INFO( 7, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 9, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 9, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 12, GreaterOrEqual, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 12, LessOrEqual, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 7, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 11, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 7, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported)}, + {REG_INFO( 9, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Greater, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported)}, + {REG_INFO( 9, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Less, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 12, GreaterOrEqual, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 12, LessOrEqual, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 7, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison7, DmlGraphSupport::Supported)}, + {REG_INFO( 11, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Equal, typeNameListLogicalComparison, supportedTypeListLogicalComparison9, DmlGraphSupport::Supported)}, {REG_INFO( 7, Not, typeNameListDefault, supportedTypeListBool, DmlGraphSupport::Supported)}, {REG_INFO( 7, And, typeNameListDefault, supportedTypeListBool, DmlGraphSupport::Supported)}, {REG_INFO( 7, Or, typeNameListDefault, supportedTypeListBool, DmlGraphSupport::Supported)}, @@ -629,16 +625,16 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 7, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 9, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO( 13, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO( 7, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 9, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO( 13, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 7, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)}, + {REG_INFO( 9, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)}, + {REG_INFO( 13, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)}, {REG_INFO( 7, MemcpyFromHost, typeNameListDefault, supportedTypeListAll)}, {REG_INFO( 7, MemcpyToHost, typeNameListDefault, supportedTypeListAll)}, - {REG_INFO_VER( 7, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, - {REG_INFO_VER( 10, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO_VER( 11, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 9, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, - {REG_INFO( 11, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(1))}, + {REG_INFO_VER( 7, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported)}, + {REG_INFO_VER( 10, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO_VER( 11, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 9, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, + {REG_INFO( 11, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, // Fused operators {REG_INFO_MSDML(1, FusedConv, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, @@ -654,14 +650,14 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO( 10, IsInf, typeNameListTwo, supportedTypeListIsInf, DmlGraphSupport::Supported)}, {REG_INFO( 10, Mod, typeNameListDefault, supportedTypeListNumericDefault, DmlGraphSupport::Supported)}, {REG_INFO( 13, Mod, typeNameListDefault, supportedTypeListNumericDefault, DmlGraphSupport::Supported)}, - {REG_INFO( 11, BitShift, typeNameListDefault, supportedTypeListUInt8to64, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 11, BitShift, typeNameListDefault, supportedTypeListUInt8to64, DmlGraphSupport::Supported)}, {REG_INFO( 11, Round, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, - {REG_INFO( 10, ReverseSequence, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly)}, + {REG_INFO( 10, ReverseSequence, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, {REG_INFO( 11, CumSum, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, {REG_INFO( 11, Range, typeNameListDefault, supportedTypeListRange, DmlGraphSupport::Supported, requiredConstantCpuInputs(0,1,2))}, - {REG_INFO( 9, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(2))}, - {REG_INFO( 11, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported|DmlGraphSupport::Prefer64BitTensorsDirectly, requiredConstantCpuInputs(2))}, // 11 is identical to 9. + {REG_INFO( 9, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))}, + {REG_INFO( 11, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))}, // 11 is identical to 9. {REG_INFO_MS( 1, QLinearAdd, typeNameListDefault, supportedTypeListInteger8, DmlGraphSupport::Supported)}, {REG_INFO( 10, QLinearConv, typeNameListFour, supportedTypeListQLinearConv, DmlGraphSupport::Supported)}, @@ -696,10 +692,6 @@ void RegisterDmlOperators(IMLOperatorRegistry* registry) // The graph must be configured with operators from only the legacy DML API, or only the new DML API bool kernelSupportsGraph = !bool(information.dmlGraphSupport & DmlGraphSupport::NotSupported); - bool prefer64BitTensorsDirectly = bool(information.dmlGraphSupport & DmlGraphSupport::Prefer64BitTensorsDirectly); - bool support64BitTensorsViaEmulation = bool(information.dmlGraphSupport & DmlGraphSupport::Support64BitTensorsViaEmulation); - bool supportedWith64BitTensorsVia32BitStrides = bool(information.dmlGraphSupport & DmlGraphSupport::SupportedWith64BitTensorsVia32BitStrides); - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp = bool(information.dmlGraphSupport & DmlGraphSupport::SupportedWith64BitTensorsVia32BitStridesFromAnyEp); desc.options = information.shapeInferenceFunction ? MLOperatorKernelOptions::None : MLOperatorKernelOptions::AllowDynamicInputShapes; @@ -780,10 +772,6 @@ void RegisterDmlOperators(IMLOperatorRegistry* registry) information.canAliasFirstInput, // alias kernelSupportsGraph, // supportsGraph information.requiredInputCountForDmlGraphSupport ? &(*information.requiredInputCountForDmlGraphSupport) : nullptr, - supportedWith64BitTensorsVia32BitStrides, - supportedWith64BitTensorsVia32BitStridesFromAnyEp, - prefer64BitTensorsDirectly, - support64BitTensorsViaEmulation, information.requiredConstantCpuInputs.first.data(), static_cast(information.requiredConstantCpuInputs.second) )); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.cpp index 401b425f8f..b8382d59b2 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.cpp @@ -257,13 +257,6 @@ void TensorDesc::Remap64bitDmlDataTypeTo32bit() ) + endPaddingInBytes; } -bool TensorDesc::WasRemapped64bitTo32bit() const -{ - bool was64BitIntType = (m_mlOperatorTensorDataType == MLOperatorTensorDataType::UInt64 || m_mlOperatorTensorDataType == MLOperatorTensorDataType::Int64); - bool is32BitIntType = (m_bufferTensorDesc.DataType == DML_TENSOR_DATA_TYPE_UINT32 || m_bufferTensorDesc.DataType == DML_TENSOR_DATA_TYPE_INT32); - return was64BitIntType && is32BitIntType; -} - gsl::span TensorDesc::GetStrides() const { if (m_bufferTensorDesc.Strides == nullptr) diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.h index 055f2ad5fd..b48725eb11 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/TensorDesc.h @@ -38,7 +38,6 @@ namespace Dml inline MLOperatorTensorDataType GetMlOperatorDataType() const { return m_mlOperatorTensorDataType; } void ForceUnsignedDataType(); void Remap64bitDmlDataTypeTo32bit(); - bool WasRemapped64bitTo32bit() const; inline bool IsValid() const { return m_tensorType != DML_TENSOR_TYPE_INVALID; } inline uint32_t GetDimensionCount() const { return m_bufferTensorDesc.DimensionCount; } diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/MLOperatorAuthorPrivate.h b/onnxruntime/core/providers/dml/OperatorAuthorHelper/MLOperatorAuthorPrivate.h index dd6032f81e..96ee182145 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/MLOperatorAuthorPrivate.h +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/MLOperatorAuthorPrivate.h @@ -111,10 +111,6 @@ IMLOperatorRegistryPrivate : public IUnknown bool canAliasFirstInput, bool supportsGraph, const uint32_t* requiredInputCountForGraph = nullptr, - bool supportedWith64BitTensorsVia32BitStrides = false, - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp = false, - bool prefer64BitTensorsDirectly = false, - bool support64BitTensorsViaEmulation = false, _In_reads_(constantCpuInputCount) const uint32_t* constantCpuInputs = nullptr, uint32_t constantCpuInputCount = 0 ) const noexcept PURE; diff --git a/winml/adapter/abi_custom_registry_impl.cpp b/winml/adapter/abi_custom_registry_impl.cpp index d87d50a9ee..9fcc2485ef 100644 --- a/winml/adapter/abi_custom_registry_impl.cpp +++ b/winml/adapter/abi_custom_registry_impl.cpp @@ -55,10 +55,6 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistryImpl::RegisterOperatorKernel( bool canAliasFirstInput, bool supportsGraph, const uint32_t* requiredInputCountForGraph, - bool supportedWith64BitTensorsVia32BitStrides, - bool supportedWith64BitTensorsVia32BitStridesFromAnyEp, - bool prefer64BitTensorsDirectly, - bool support64BitTensorsViaEmulation, _In_reads_(constantCpuInputCount) const uint32_t* requiredConstantCpuInputs, uint32_t constantCpuInputCount) const noexcept try { #ifdef LAYERING_DONE @@ -81,10 +77,6 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistryImpl::RegisterOperatorKernel( canAliasFirstInput, supportsGraph, requiredInputCountForGraph, - supportedWith64BitTensorsVia32BitStrides, - supportedWith64BitTensorsVia32BitStridesFromAnyEp, - prefer64BitTensorsDirectly, - support64BitTensorsViaEmulation, requiredConstantCpuInputs, constantCpuInputCount); } diff --git a/winml/adapter/abi_custom_registry_impl.h b/winml/adapter/abi_custom_registry_impl.h index f24ddd4b02..67d6b9127e 100644 --- a/winml/adapter/abi_custom_registry_impl.h +++ b/winml/adapter/abi_custom_registry_impl.h @@ -28,10 +28,6 @@ class AbiCustomRegistryImpl : public AbiCustomRegistry { bool can_alias_first_input, bool supports_graph, const uint32_t* required_input_count_for_graph = nullptr, - bool supports_64bit_directly = false, - bool allows_64bit_via_strides = false, - bool allows_64bit_via_strides_from_any_ep = false, - bool supports_64bit_tensors_via_emulation = false, _In_reads_(constant_cpu_input_count) const uint32_t* required_constant_cpu_inputs = nullptr, uint32_t constant_cpu_input_count = 0) const noexcept override; From edd1a2cf61dd0c08bfc7a03e72a42e3e06d22014 Mon Sep 17 00:00:00 2001 From: Edward Chen <18449977+edgchen1@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:42:46 -0800 Subject: [PATCH 103/113] Add more Java test logging. (#10221) --- java/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/build.gradle b/java/build.gradle index 1872d1d784..fa76ae927f 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -175,6 +175,8 @@ test { testLogging { events "passed", "skipped", "failed" showStandardStreams = true + showStackTraces = true + exceptionFormat = "full" } } From 5cd57bb726a2c3751cc4e8f93e2c5e8b29223cd8 Mon Sep 17 00:00:00 2001 From: Jingqiao Fu Date: Mon, 10 Jan 2022 10:51:48 -0800 Subject: [PATCH 104/113] add load from buffer (#10162) * Add LoadFromBuffer API --- winml/api/Windows.AI.MachineLearning.idl | 28 +++++++++++-- winml/lib/Api/LearningModel.cpp | 53 ++++++++++++++++++++++++ winml/lib/Api/LearningModel.h | 22 ++++++++++ winml/test/api/LearningModelAPITest.cpp | 15 +++++++ winml/test/api/LearningModelAPITest.h | 2 + 5 files changed, 116 insertions(+), 4 deletions(-) diff --git a/winml/api/Windows.AI.MachineLearning.idl b/winml/api/Windows.AI.MachineLearning.idl index 2b55fa8c7a..2ca2145aac 100644 --- a/winml/api/Windows.AI.MachineLearning.idl +++ b/winml/api/Windows.AI.MachineLearning.idl @@ -33,7 +33,7 @@ import "windows.storage.idl"; namespace ROOT_NS.AI.MachineLearning { - [contractversion(5)] + [contractversion(6)] apicontract MachineLearningContract{}; //! Forward declarations @@ -104,22 +104,42 @@ namespace ROOT_NS.AI.MachineLearning //! Loads an ONNX model from a stream asynchronously. [remote_async] static Windows.Foundation.IAsyncOperation LoadFromStreamAsync(Windows.Storage.Streams.IRandomAccessStreamReference modelStream); + //! Loads an ONNX model from a buffer asynchronously. + [contract(MachineLearningContract, 6)] + { + [remote_async] + static Windows.Foundation.IAsyncOperation LoadFromBufferAsync(Windows.Storage.Streams.IBuffer modelBuffer); + } //! Loads an ONNX model from a file on disk. static LearningModel LoadFromFilePath(String filePath); //! Loads an ONNX model from a stream. static LearningModel LoadFromStream(Windows.Storage.Streams.IRandomAccessStreamReference modelStream); - + //! Loads an ONNX model from a buffer. + [contract(MachineLearningContract, 6)] + { + static LearningModel LoadFromBuffer(Windows.Storage.Streams.IBuffer modelBuffer); + } //! Loads an ONNX model from a StorageFile asynchronously. [remote_async] [method_name("LoadFromStorageFileWithOperatorProviderAsync")] static Windows.Foundation.IAsyncOperation LoadFromStorageFileAsync(Windows.Storage.IStorageFile modelFile, ILearningModelOperatorProvider operatorProvider); //! Loads an ONNX model from a stream asynchronously. [remote_async] [method_name("LoadFromStreamWithOperatorProviderAsync")] static Windows.Foundation.IAsyncOperation LoadFromStreamAsync(Windows.Storage.Streams.IRandomAccessStreamReference modelStream, ILearningModelOperatorProvider operatorProvider); - //! Loads an ONNX model from a file on disk. + //! Loads an ONNX model from a buffer asynchronously. + [contract(MachineLearningContract, 6)] + { + [remote_async] + [method_name("LoadFromBufferWithOperatorProviderAsync")] static Windows.Foundation.IAsyncOperation LoadFromBufferAsync(Windows.Storage.Streams.IBuffer modelBuffer, ILearningModelOperatorProvider operatorProvider); + } + //! Loads an ONNX model from a file on disk. [method_name("LoadFromFilePathWithOperatorProvider")] static LearningModel LoadFromFilePath(String filePath, ILearningModelOperatorProvider operatorProvider); //! Loads an ONNX model from a stream. [method_name("LoadFromStreamWithOperatorProvider")] static LearningModel LoadFromStream(Windows.Storage.Streams.IRandomAccessStreamReference modelStream, ILearningModelOperatorProvider operatorProvider); - + //! Loads an ONNX model from a buffer. + [contract(MachineLearningContract, 6)] + { + [method_name("LoadFromBufferWithOperatorProvider")] static LearningModel LoadFromBuffer(Windows.Storage.Streams.IBuffer modelBuffer, ILearningModelOperatorProvider operatorProvider); + } //! The name of the model author. String Author{ get; }; //! The name of the model. diff --git a/winml/lib/Api/LearningModel.cpp b/winml/lib/Api/LearningModel.cpp index b0b988adf8..787c2afd62 100644 --- a/winml/lib/Api/LearningModel.cpp +++ b/winml/lib/Api/LearningModel.cpp @@ -165,6 +165,30 @@ LearningModel::LearningModel( } WINML_CATCH_ALL +static HRESULT CreateModelFromBuffer( + _winml::IEngineFactory* engine_factory, + const wss::IBuffer buffer, + _winml::IModel** model) { + + size_t len = buffer.Length(); + if (FAILED(engine_factory->CreateModel((void*)buffer.data(), len, model))) { + WINML_THROW_HR(E_INVALIDARG); + } + + return S_OK; +} + +LearningModel::LearningModel( + const wss::IBuffer buffer, + const winml::ILearningModelOperatorProvider operator_provider) try : operator_provider_(operator_provider) { + _winmlt::TelemetryEvent loadModel_event(_winmlt::EventCategory::kModelLoad); + + WINML_THROW_IF_FAILED(CreateOnnxruntimeEngineFactory(engine_factory_.put())); + WINML_THROW_IF_FAILED(CreateModelFromBuffer(engine_factory_.get(), buffer, model_.put())); + WINML_THROW_IF_FAILED(model_->GetModelInfo(model_info_.put())); +} +WINML_CATCH_ALL + hstring LearningModel::Author() try { const char* out; @@ -293,6 +317,20 @@ LearningModel::LoadFromStreamAsync( return make(model_stream, provider); } +wf::IAsyncOperation +LearningModel::LoadFromBufferAsync( + wss::IBuffer const model_buffer) { + return LoadFromBufferAsync(model_buffer, nullptr); +} + +wf::IAsyncOperation +LearningModel::LoadFromBufferAsync( + wss::IBuffer const model_buffer, + winml::ILearningModelOperatorProvider const provider) { + co_await resume_background(); + return make(model_buffer, provider); +} + winml::LearningModel LearningModel::LoadFromFilePath( hstring const& path) try { @@ -323,6 +361,21 @@ LearningModel::LoadFromStream( } WINML_CATCH_ALL +winml::LearningModel +LearningModel::LoadFromBuffer( + wss::IBuffer const model_buffer) try { + return LoadFromBuffer(model_buffer, nullptr); +} +WINML_CATCH_ALL + +winml::LearningModel +LearningModel::LoadFromBuffer( + wss::IBuffer const model_buffer, + winml::ILearningModelOperatorProvider const provider) try { + return make(model_buffer, provider); +} +WINML_CATCH_ALL + _winml::IModel* LearningModel::DetachModel() { com_ptr<_winml::IModel> detached_model; diff --git a/winml/lib/Api/LearningModel.h b/winml/lib/Api/LearningModel.h index 5510521e84..0a7975a144 100644 --- a/winml/lib/Api/LearningModel.h +++ b/winml/lib/Api/LearningModel.h @@ -24,6 +24,10 @@ struct LearningModel : LearningModelT { LearningModel( const wss::IRandomAccessStreamReference stream, const winml::ILearningModelOperatorProvider operator_provider); + + LearningModel( + const wss::IBuffer stream, + const winml::ILearningModelOperatorProvider operator_provider); LearningModel( _winml::IEngineFactory* engine_factory, @@ -77,6 +81,15 @@ struct LearningModel : LearningModelT { wss::IRandomAccessStreamReference const stream, winml::ILearningModelOperatorProvider const operator_provider); + static wf::IAsyncOperation + LoadFromBufferAsync( + wss::IBuffer const buffer); + + static wf::IAsyncOperation + LoadFromBufferAsync( + wss::IBuffer const buffer, + winml::ILearningModelOperatorProvider const operator_provider); + static winml::LearningModel LoadFromFilePath( hstring const& path); @@ -89,11 +102,20 @@ struct LearningModel : LearningModelT { static winml::LearningModel LoadFromStream( wss::IRandomAccessStreamReference const stream); + + static winml::LearningModel + LoadFromBuffer( + wss::IBuffer const buffer); static winml::LearningModel LoadFromStream( wss::IRandomAccessStreamReference const stream, winml::ILearningModelOperatorProvider const operator_provider); + + static winml::LearningModel + LoadFromBuffer( + wss::IBuffer const buffer, + winml::ILearningModelOperatorProvider const operator_provider); public: /* Non-ABI methods */ diff --git a/winml/test/api/LearningModelAPITest.cpp b/winml/test/api/LearningModelAPITest.cpp index 447b98137b..1354baec83 100644 --- a/winml/test/api/LearningModelAPITest.cpp +++ b/winml/test/api/LearningModelAPITest.cpp @@ -90,6 +90,20 @@ static void CreateModelFromIStream() { WINML_EXPECT_EQUAL(L"onnx-caffe2", author); } +static void CreateModelFromIBuffer() { + std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx"; + auto storageFile = ws::StorageFile::GetFileFromPathAsync(path).get(); + IBuffer buffer = FileIO::ReadBufferAsync(storageFile).get(); + + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromBufferAsync(buffer).get()); + WINML_EXPECT_TRUE(learningModel != nullptr); + + // check the author so we know the model was populated correctly. + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); +} + static void ModelGetAuthor() { LearningModel learningModel = nullptr; WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); @@ -323,6 +337,7 @@ const LearningModelApiTestsApi& getapi() { CreateModelFromIStorage, CreateModelFromIStorageOutsideCwd, CreateModelFromIStream, + CreateModelFromIBuffer, ModelGetAuthor, ModelGetName, ModelGetDomain, diff --git a/winml/test/api/LearningModelAPITest.h b/winml/test/api/LearningModelAPITest.h index c87bdd6144..df23461908 100644 --- a/winml/test/api/LearningModelAPITest.h +++ b/winml/test/api/LearningModelAPITest.h @@ -11,6 +11,7 @@ struct LearningModelApiTestsApi VoidTest CreateModelFromIStorage; VoidTest CreateModelFromIStorageOutsideCwd; VoidTest CreateModelFromIStream; + VoidTest CreateModelFromIBuffer; VoidTest ModelGetAuthor; VoidTest ModelGetName; VoidTest ModelGetDomain; @@ -36,6 +37,7 @@ WINML_TEST(LearningModelAPITests, CreateModelFileNotFound) WINML_TEST(LearningModelAPITests, CreateModelFromIStorage) WINML_TEST(LearningModelAPITests, CreateModelFromIStorageOutsideCwd) WINML_TEST(LearningModelAPITests, CreateModelFromIStream) +WINML_TEST(LearningModelAPITests, CreateModelFromIBuffer) WINML_TEST(LearningModelAPITests, ModelGetAuthor) WINML_TEST(LearningModelAPITests, ModelGetName) WINML_TEST(LearningModelAPITests, ModelGetDomain) From 32ee379f50721f86d7ad4fdc93d30e277a6d02b5 Mon Sep 17 00:00:00 2001 From: Jeff Bloomfield <38966965+jeffbloo@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:01:08 -0800 Subject: [PATCH 105/113] GraphPartitioner.cpp: fixed Merge function to handle duplicated partitions. (#9929) Co-authored-by: Achira --- .../providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp index 594f821aaf..0862b07d6b 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/GraphPartitioner.cpp @@ -105,7 +105,7 @@ namespace Dml for (GraphPartition* partitionToMerge : partitionsToMerge) { - if (partitionToMerge == this) + if (partitionToMerge->GetRootMergedPartition() == this) { continue; } From be9cc40aa51679daed51c88f9ce8ceecd5e6a800 Mon Sep 17 00:00:00 2001 From: Chi Lo <54722500+chilo-ms@users.noreply.github.com> Date: Mon, 10 Jan 2022 13:00:58 -0800 Subject: [PATCH 106/113] Make some parameters configurable for calibration (#10204) --- .../python/tools/quantization/calibrate.py | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/onnxruntime/python/tools/quantization/calibrate.py b/onnxruntime/python/tools/quantization/calibrate.py index 40b852c6de..c902d956ac 100644 --- a/onnxruntime/python/tools/quantization/calibrate.py +++ b/onnxruntime/python/tools/quantization/calibrate.py @@ -275,8 +275,9 @@ class HistogramCalibrater(CalibraterBase): op_types_to_calibrate=[], augmented_model_path='augmented_model.onnx', method='percentile', - num_quantized_bins=128, - percentile=99.99): + num_bins=128, + num_quantized_bins=2048, + percentile=99.999): ''' :param model: ONNX model to calibrate. It can be a ModelProto or a model path :param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors. @@ -292,6 +293,7 @@ class HistogramCalibrater(CalibraterBase): self.model_original_outputs = set(output.name for output in self.model.graph.output) self.collector = None self.method = method + self.num_bins = num_bins self.num_quantized_bins = num_quantized_bins self.percentile = percentile @@ -347,6 +349,7 @@ class HistogramCalibrater(CalibraterBase): if not self.collector: self.collector = HistogramCollector(method=self.method, + num_bins=self.num_bins, num_quantized_bins=self.num_quantized_bins, percentile=self.percentile) self.collector.collect(clean_merged_dict) @@ -369,16 +372,18 @@ class EntropyCalibrater(HistogramCalibrater): op_types_to_calibrate=[], augmented_model_path='augmented_model.onnx', method='entropy', + num_bins=128, num_quantized_bins=128): ''' :param model: ONNX model to calibrate. It can be a ModelProto or a model path :param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors. :param augmented_model_path: save augmented model to this path. :param method: A string. One of ['entropy', 'percentile']. + :param num_bins: number of bins to create a new histogram for collecting tensor values. :param num_quantized_bins: number of quantized bins. Default 128. ''' super(EntropyCalibrater, self).__init__(model, op_types_to_calibrate, augmented_model_path, - method=method, num_quantized_bins=num_quantized_bins) + method=method, num_bins=num_bins, num_quantized_bins=num_quantized_bins) class PercentileCalibrater(HistogramCalibrater): def __init__(self, @@ -386,7 +391,7 @@ class PercentileCalibrater(HistogramCalibrater): op_types_to_calibrate=[], augmented_model_path='augmented_model.onnx', method='percentile', - num_quantized_bins=2048, + num_bins=2048, percentile=99.999): ''' :param model: ONNX model to calibrate. It can be a ModelProto or a model path @@ -397,7 +402,7 @@ class PercentileCalibrater(HistogramCalibrater): :param percentile: A float number between [0, 100]. Default 99.99. ''' super(PercentileCalibrater, self).__init__(model, op_types_to_calibrate, augmented_model_path, - method=method, num_quantized_bins=num_quantized_bins, + method=method, num_bins=num_bins, percentile=percentile) class CalibrationDataCollector(metaclass=abc.ABCMeta): @@ -429,9 +434,10 @@ class HistogramCollector(CalibrationDataCollector): ref: https://docs.nvidia.com/deeplearning/tensorrt/pytorch-quantization-toolkit/docs/_modules/ pytorch_quantization/calib/histogram.html """ - def __init__(self, method, num_quantized_bins, percentile): + def __init__(self, method, num_bins, num_quantized_bins, percentile): self.histogram_dict = {} self.method = method + self.num_bins = num_bins self.num_quantized_bins= num_quantized_bins self.percentile = percentile @@ -439,7 +445,9 @@ class HistogramCollector(CalibrationDataCollector): return self.histogram_dict def collect(self, name_to_arr): - # TODO: Currently we have different collect() for percentile and percentile method respectively. + print("Collecting tensor data and making histogram ...") + + # TODO: Currently we have different collect() for entropy and percentile method respectively. # Need unified collect in the future. if self.method == 'entropy': return self.collect_for_entropy(name_to_arr) @@ -455,8 +463,8 @@ class HistogramCollector(CalibrationDataCollector): data_arr = np.absolute(data_arr) # only consider absolute value if tensor not in self.histogram_dict: - # first time it uses num_quantized_bins to compute histogram. - hist, hist_edges = np.histogram(data_arr, bins=self.num_quantized_bins) + # first time it uses num_bins to compute histogram. + hist, hist_edges = np.histogram(data_arr, bins=self.num_bins) self.histogram_dict[tensor] = (hist, hist_edges) else: old_histogram = self.histogram_dict[tensor] @@ -491,7 +499,7 @@ class HistogramCollector(CalibrationDataCollector): old_histogram = self.histogram_dict[tensor] self.histogram_dict[tensor] = self.merge_histogram(old_histogram, data_arr, min_value, max_value, threshold) else: - hist, hist_edges = np.histogram(data_arr, self.num_quantized_bins, range=(-threshold, threshold)) + hist, hist_edges = np.histogram(data_arr, self.num_bins, range=(-threshold, threshold)) self.histogram_dict[tensor] = (hist, hist_edges, min_value, max_value, threshold) def merge_histogram(self, old_histogram, data_arr, new_min, new_max, new_threshold): @@ -518,6 +526,7 @@ class HistogramCollector(CalibrationDataCollector): def compute_collection_result(self): if not self.histogram_dict or len(self.histogram_dict) == 0: raise ValueError("Histogram has not been collected. Please run collect() first.") + print("Finding optimal threshold for each tensor using {} algorithm ...".format(self.method)) if self.method == 'entropy': return self.compute_entropy() @@ -535,6 +544,10 @@ class HistogramCollector(CalibrationDataCollector): thresholds_dict = {} # per tensor thresholds + print("Number of tensors : {}".format(len(histogram_dict))) + print("Number of histogram bins : {}".format(self.num_bins)) + print("Percentile : {}".format(percentile)) + for tensor, histogram in histogram_dict.items(): hist = histogram[0] hist_edges = histogram[1] @@ -551,6 +564,10 @@ class HistogramCollector(CalibrationDataCollector): thresholds_dict = {} # per tensor thresholds + print("Number of tensors : {}".format(len(histogram_dict))) + print("Number of histogram bins : {} (The number may increase depends on the data it collects)".format(self.num_bins)) + print("Number of quantized bins : {}".format(self.num_quantized_bins)) + for tensor, histogram in histogram_dict.items(): optimal_threshold = self.get_entropy_threshold(histogram, num_quantized_bins) thresholds_dict[tensor] = optimal_threshold @@ -631,12 +648,19 @@ class HistogramCollector(CalibrationDataCollector): def create_calibrator(model, op_types_to_calibrate=[], augmented_model_path='augmented_model.onnx', - calibrate_method=CalibrationMethod.MinMax): + calibrate_method=CalibrationMethod.MinMax, + extra_options={}): if calibrate_method == CalibrationMethod.MinMax: return MinMaxCalibrater(model, op_types_to_calibrate, augmented_model_path) elif calibrate_method == CalibrationMethod.Entropy: - return EntropyCalibrater(model, op_types_to_calibrate, augmented_model_path) + # default settings for entropy algorithm + num_bins = 128 if 'num_bins' not in extra_options else extra_options['num_bins'] + num_quantized_bins = 128 if 'num_quantized_bins' not in extra_options else extra_options['num_quantized_bins'] + return EntropyCalibrater(model, op_types_to_calibrate, augmented_model_path, num_bins=num_bins, num_quantized_bins=num_quantized_bins) elif calibrate_method == CalibrationMethod.Percentile: - return PercentileCalibrater(model, op_types_to_calibrate, augmented_model_path) + # default settings for percentile algorithm + num_bins = 2048 if 'num_bins' not in extra_options else extra_options['num_bins'] + percentile = 99.999 if 'percentile' not in extra_options else extra_options['percentile'] + return PercentileCalibrater(model, op_types_to_calibrate, augmented_model_path, num_bins=num_bins, percentile=percentile) raise ValueError('Unsupported calibration method {}'.format(calibrate_method)) From ce103ace934bd397ec4e58e066fd625147b64c85 Mon Sep 17 00:00:00 2001 From: Shucai Xiao Date: Mon, 10 Jan 2022 17:18:43 -0600 Subject: [PATCH 107/113] Amdmigraphx fix build error (#9272) * fix build error * rename a missing api for the MIGraphX EP --- cmake/onnxruntime.cmake | 1 - cmake/onnxruntime_providers.cmake | 43 +- cmake/onnxruntime_python.cmake | 11 +- cmake/onnxruntime_unittests.cmake | 6 +- dockerfiles/Dockerfile.migraphx | 8 +- dockerfiles/Dockerfile.rocm | 2 +- dockerfiles/README.md | 2 +- .../migraphx/migraphx_provider_factory.h | 15 - .../core/session/onnxruntime_c_api.h | 35 + .../core/session/onnxruntime_cxx_api.h | 1 + .../core/session/onnxruntime_cxx_inline.h | 5 + ...ai_onnxruntime_OrtSession_SessionOptions.c | 1 - .../providers/migraphx/exported_symbols.lst | 1 + .../providers/migraphx/gpu_data_transfer.cc | 25 +- .../providers/migraphx/gpu_data_transfer.h | 3 +- .../core/providers/migraphx/hip_allocator.cc | 48 +- .../core/providers/migraphx/hip_allocator.h | 27 + .../core/providers/migraphx/hip_fence.cc | 25 +- .../core/providers/migraphx/hip_fence.h | 4 +- .../core/providers/migraphx/migraphx_call.cc | 66 ++ .../core/providers/migraphx/migraphx_call.h | 21 + .../migraphx/migraphx_execution_provider.cc | 862 ++++++++++-------- .../migraphx/migraphx_execution_provider.h | 17 +- .../migraphx_execution_provider_info.cc | 64 ++ .../migraphx_execution_provider_info.h | 24 + .../migraphx/migraphx_provider_factory.cc | 105 ++- .../migraphx/migraphx_provider_factory.h | 20 + .../core/providers/migraphx/symbols.def | 2 + .../providers/migraphx/version_script.lds | 9 + .../providers/shared_library/provider_api.h | 7 +- .../provider_bridge_provider.cc | 14 + .../shared_library/provider_interfaces.h | 6 + onnxruntime/core/session/onnxruntime_c_api.cc | 2 + onnxruntime/core/session/ort_apis.h | 5 +- .../core/session/provider_bridge_ort.cc | 69 ++ onnxruntime/core/session/provider_stubs.cc | 7 + .../python/onnxruntime_pybind_schema.cc | 8 +- .../python/onnxruntime_pybind_state_common.h | 1 + .../test/python/onnx_backend_test_series.py | 11 +- onnxruntime/test/util/default_providers.cc | 16 +- .../test/util/include/default_providers.h | 3 +- tools/ci_build/gen_def.py | 2 +- 42 files changed, 1143 insertions(+), 461 deletions(-) delete mode 100644 include/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h create mode 100644 onnxruntime/core/providers/migraphx/exported_symbols.lst create mode 100644 onnxruntime/core/providers/migraphx/migraphx_call.cc create mode 100644 onnxruntime/core/providers/migraphx/migraphx_call.h create mode 100644 onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.cc create mode 100644 onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.h create mode 100644 onnxruntime/core/providers/migraphx/migraphx_provider_factory.h create mode 100644 onnxruntime/core/providers/migraphx/symbols.def create mode 100644 onnxruntime/core/providers/migraphx/version_script.lds diff --git a/cmake/onnxruntime.cmake b/cmake/onnxruntime.cmake index 3ed69a8ad7..5f23122164 100644 --- a/cmake/onnxruntime.cmake +++ b/cmake/onnxruntime.cmake @@ -164,7 +164,6 @@ set(onnxruntime_INTERNAL_LIBRARIES ${PROVIDERS_ARMNN} ${PROVIDERS_COREML} ${PROVIDERS_DML} - ${PROVIDERS_MIGRAPHX} ${PROVIDERS_NNAPI} ${PROVIDERS_NUPHAR} ${PROVIDERS_STVM} diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index 8fba42e3e8..462791f2b9 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -1022,6 +1022,23 @@ if (onnxruntime_USE_DML) endif() if (onnxruntime_USE_MIGRAPHX) + add_definitions(-DUSE_MIGRAPHX=1) + set(BUILD_LIBRARY_ONLY 1) + add_definitions("-DONNX_ML=1") + add_definitions("-DONNX_NAMESPACE=onnx") + include_directories(${PROJECT_SOURCE_DIR}/external/protobuf ${PROJECT_SOURCE_DIR}/external/eigen) + set(MIGRAPHX_ROOT ${onnxruntime_MIGRAPHX_HOME}) + include_directories(${ONNXRUNTIME_ROOT}/../cmake/external/onnx) + set(OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + if ( CMAKE_COMPILER_IS_GNUCC ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers") + endif() + set(CXX_VERSION_DEFINED TRUE) + set(CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS}) + if ( CMAKE_COMPILER_IS_GNUCC ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter") + endif() + # Add search paths for default rocm installation list(APPEND CMAKE_PREFIX_PATH /opt/rocm/hcc /opt/rocm/hip /opt/rocm) @@ -1033,18 +1050,28 @@ if (onnxruntime_USE_MIGRAPHX) file(GLOB_RECURSE onnxruntime_providers_migraphx_cc_srcs CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/migraphx/*.h" "${ONNXRUNTIME_ROOT}/core/providers/migraphx/*.cc" + "${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.h" + "${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.cc" ) - source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_migraphx_cc_srcs}) - onnxruntime_add_static_library(onnxruntime_providers_migraphx ${onnxruntime_providers_migraphx_cc_srcs}) - target_link_libraries(onnxruntime_providers_migraphx PRIVATE ${migraphx_libs}) - set_target_properties(onnxruntime_providers_migraphx PROPERTIES FOLDER "ONNXRuntime") - target_compile_options(onnxruntime_providers_migraphx PRIVATE -Wno-error=sign-compare) - target_include_directories(onnxruntime_providers_migraphx PRIVATE ${ONNXRUNTIME_ROOT}) - onnxruntime_add_include_to_target(onnxruntime_providers_migraphx onnxruntime_common onnxruntime_framework onnx flatbuffers) - add_dependencies(onnxruntime_providers_migraphx ${onnxruntime_EXTERNAL_DEPENDENCIES}) + onnxruntime_add_shared_library_module(onnxruntime_providers_migraphx ${onnxruntime_providers_migraphx_cc_srcs}) + onnxruntime_add_include_to_target(onnxruntime_providers_migraphx onnxruntime_common onnx flatbuffers) + add_dependencies(onnxruntime_providers_migraphx onnxruntime_providers_shared ${onnxruntime_EXTERNAL_DEPENDENCIES}) + target_link_libraries(onnxruntime_providers_migraphx PRIVATE ${migraphx_libs} ${ONNXRUNTIME_PROVIDERS_SHARED} onnx flatbuffers) + target_include_directories(onnxruntime_providers_migraphx PRIVATE ${ONNXRUNTIME_ROOT} ${CMAKE_CURRENT_BINARY_DIR}) install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/providers/migraphx DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/core/providers) set_target_properties(onnxruntime_providers_migraphx PROPERTIES LINKER_LANGUAGE CXX) + set_target_properties(onnxruntime_providers_migraphx PROPERTIES FOLDER "ONNXRuntime") + target_compile_definitions(onnxruntime_providers_migraphx PRIVATE ONNXIFI_BUILD_LIBRARY=1) + target_compile_options(onnxruntime_providers_migraphx PRIVATE -Wno-error=sign-compare) + set_property(TARGET onnxruntime_providers_migraphx APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-deprecated-declarations") + set_property(TARGET onnxruntime_providers_migraphx APPEND_STRING PROPERTY LINK_FLAGS "-Xlinker --version-script=${ONNXRUNTIME_ROOT}/core/providers/migraphx/version_script.lds -Xlinker --gc-sections") + target_link_libraries(onnxruntime_providers_migraphx PRIVATE nsync_cpp stdc++fs) + + install(TARGETS onnxruntime_providers_migraphx + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if (onnxruntime_USE_ACL) diff --git a/cmake/onnxruntime_python.cmake b/cmake/onnxruntime_python.cmake index c47f2b94ee..4a1a6a360b 100644 --- a/cmake/onnxruntime_python.cmake +++ b/cmake/onnxruntime_python.cmake @@ -136,7 +136,6 @@ endif() target_link_libraries(onnxruntime_pybind11_state PRIVATE onnxruntime_session ${onnxruntime_libs} - ${PROVIDERS_MIGRAPHX} ${PROVIDERS_NUPHAR} ${PROVIDERS_STVM} ${PROVIDERS_VITISAI} @@ -603,6 +602,16 @@ if (onnxruntime_USE_TENSORRT) ) endif() +if (onnxruntime_USE_MIGRAPHX) + add_custom_command( + TARGET onnxruntime_pybind11_state POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + $ + $/onnxruntime/capi/ + ) +endif() + if (onnxruntime_USE_OPENVINO) add_custom_command( TARGET onnxruntime_pybind11_state POST_BUILD diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index cd8e65ec61..341d0a7ad6 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -440,7 +440,8 @@ if(onnxruntime_USE_DML) endif() if(onnxruntime_USE_MIGRAPHX) - list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_migraphx) + list(APPEND onnxruntime_test_framework_libs onnxruntime_providers_migraphx) + list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_migraphx onnxruntime_providers_shared) endif() if(onnxruntime_USE_ROCM) @@ -483,8 +484,7 @@ set(ONNXRUNTIME_TEST_LIBS onnxruntime_session ${ONNXRUNTIME_INTEROP_TEST_LIBS} ${onnxruntime_libs} - # CUDA, ROCM, TENSORRT, DNNL, and OpenVINO are dynamically loaded at runtime - ${PROVIDERS_MIGRAPHX} + # CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime ${PROVIDERS_NUPHAR} ${PROVIDERS_NNAPI} ${PROVIDERS_RKNPU} diff --git a/dockerfiles/Dockerfile.migraphx b/dockerfiles/Dockerfile.migraphx index 259d13521b..7106735a47 100644 --- a/dockerfiles/Dockerfile.migraphx +++ b/dockerfiles/Dockerfile.migraphx @@ -20,12 +20,12 @@ ENV LANG C.UTF-8 # Install rocm RUN apt-get update && apt-get install -y gnupg2 --no-install-recommends curl && \ - curl -sL http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | apt-key add - && \ - sh -c 'echo deb [arch=amd64] http://repo.radeon.com/rocm/apt/4.2/ xenial main > /etc/apt/sources.list.d/rocm.list' + curl -sL http://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - && \ + sh -c 'echo deb [arch=amd64] http://repo.radeon.com/rocm/apt/4.5/ ubuntu main > /etc/apt/sources.list.d/rocm.list' RUN apt-get update &&\ apt-get install -y sudo git bash build-essential rocm-dev libpython3.6-dev python3-pip miopen-hip \ - rocblas half aria2 + rocblas half aria2 libnuma-dev RUN aria2c -q -d /tmp -o cmake-3.21.0-linux-x86_64.tar.gz \ https://github.com/Kitware/CMake/releases/download/v3.21.0/cmake-3.21.0-linux-x86_64.tar.gz &&\ @@ -39,7 +39,7 @@ ENV PATH /opt/miniconda/bin:/code/cmake-3.21.0-linux-x86_64/bin:${PATH} # Install MIGraphX from source RUN mkdir -p /migraphx RUN cd /migraphx && git clone --depth=1 --branch migraphx_for_ort https://github.com/ROCmSoftwarePlatform/AMDMIGraphX src -RUN cd /migraphx && rbuild package --cxx /opt/rocm-4.2.0/llvm/bin/clang++ -d /migraphx/deps -B /migraphx/build -S /migraphx/src/ -DPYTHON_EXECUTABLE=/usr/bin/python3 +RUN cd /migraphx && rbuild package --cxx /opt/rocm-4.5.0/llvm/bin/clang++ -d /migraphx/deps -B /migraphx/build -S /migraphx/src/ -DPYTHON_EXECUTABLE=/usr/bin/python3 RUN dpkg -i /migraphx/build/*.deb RUN rm -rf /migraphx diff --git a/dockerfiles/Dockerfile.rocm b/dockerfiles/Dockerfile.rocm index a48e94a431..f323f50945 100644 --- a/dockerfiles/Dockerfile.rocm +++ b/dockerfiles/Dockerfile.rocm @@ -19,7 +19,7 @@ ENV LANG C.UTF-8 # Install rocm RUN apt-get update && apt-get install -y gnupg2 --no-install-recommends curl && \ - curl -sL http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | apt-key add - && \ + curl -sL http://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - && \ sh -c 'echo deb [arch=amd64] http://repo.radeon.com/rocm/apt/4.0/ xenial main > /etc/apt/sources.list.d/rocm.list' RUN apt-get update &&\ diff --git a/dockerfiles/README.md b/dockerfiles/README.md index fe16cfbdba..611721caf1 100644 --- a/dockerfiles/README.md +++ b/dockerfiles/README.md @@ -295,7 +295,7 @@ git submodule update --init ``` ## MIGraphX -**Ubuntu 16.04, rocm3.3, AMDMIGraphX v0.7** +**Ubuntu 18.04, rocm4.5, AMDMIGraphX v1.2** 1. Build the docker image from the Dockerfile in this repository. ``` diff --git a/include/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h b/include/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h deleted file mode 100644 index 8f8219fde0..0000000000 --- a/include/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019 AMD AMDMIGraphX - -#include "onnxruntime_c_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id); - -#ifdef __cplusplus -} -#endif - - diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 31b0442775..0ad3aec377 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -484,6 +484,16 @@ typedef struct OrtTensorRTProviderOptions { int trt_force_sequential_engine_build; // force building TensorRT engine sequentially. Default 0 = false, nonzero = true } OrtTensorRTProviderOptions; +/** \brief MIGraphX Provider Options +* +* \see OrtApi::SessionOptionsAppendExecutionProvider_MIGraphX +*/ +typedef struct OrtMIGraphXProviderOptions { + int device_id; // hip device id. + int migraphx_fp16_enable; // enable MIGraphX FP16 precision. Default 0 = false, nonzero = true + int migraphx_int8_enable; // enable MIGraphX INT8 precision. Default 0 = false, nonzero = true +} OrtMIGraphXProviderOptions; + /** \brief OpenVINO Provider Options * * \see OrtApi::SessionOptionsAppendExecutionProvider_OpenVINO @@ -3049,6 +3059,9 @@ struct OrtApi { * \snippet{doc} snippets.dox OrtStatus Return Value */ ORT_API2_STATUS(GetSparseTensorIndices, _In_ const OrtValue* ort_value, enum OrtSparseIndicesFormat indices_format, _Out_ size_t* num_indices, _Outptr_ const void** indices); + /// @} + /// \name OrtSessionOptions + /// @{ /** * \brief Sets out to 1 iff an optional type OrtValue has an element, 0 otherwise (OrtValue is None) @@ -3260,6 +3273,17 @@ struct OrtApi { */ void(ORT_API_CALL* ReleaseCUDAProviderOptions)(_Frees_ptr_opt_ OrtCUDAProviderOptionsV2* input); + /** \brief Append MIGraphX provider to session options + * + * If MIGraphX is not available (due to a non MIGraphX enabled build, or if MIGraphX is not installed on the system), this function will return failure. + * + * \param[in] options + * \param[in] migraphx_options + * + * \snippet{doc} snippets.dox OrtStatus Return Value + */ + ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_MIGraphX, + _In_ OrtSessionOptions* options, _In_ const OrtMIGraphXProviderOptions* migraphx_options); /// @} }; @@ -3321,6 +3345,17 @@ struct OrtCustomOp { */ ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_CUDA, _In_ OrtSessionOptions* options, int device_id); +/* + * This is the old way to add the MIGraphX provider to the session, please use + * SessionOptionsAppendExecutionProvider_MIGraphX above to access the latest functionality + * This function always exists, but will only succeed if Onnxruntime was built with + * HIP support and the MIGraphX provider shared library exists + * + * \param device_id HIP device id, starts from zero. +*/ +ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id); + + #ifdef __cplusplus } #endif diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_api.h b/include/onnxruntime/core/session/onnxruntime_cxx_api.h index 1358d13072..12370aafa8 100644 --- a/include/onnxruntime/core/session/onnxruntime_cxx_api.h +++ b/include/onnxruntime/core/session/onnxruntime_cxx_api.h @@ -351,6 +351,7 @@ struct SessionOptions : Base { SessionOptions& AppendExecutionProvider_ROCM(const OrtROCMProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_ROCM SessionOptions& AppendExecutionProvider_OpenVINO(const OrtOpenVINOProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_OpenVINO SessionOptions& AppendExecutionProvider_TensorRT(const OrtTensorRTProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_TensorRT + SessionOptions& AppendExecutionProvider_MIGraphX(const OrtMIGraphXProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_MIGraphX SessionOptions& SetCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn); ///< Wraps OrtApi::SessionOptionsSetCustomCreateThreadFn SessionOptions& SetCustomThreadCreationOptions(void* ort_custom_thread_creation_options); ///< Wraps OrtApi::SessionOptionsSetCustomThreadCreationOptions diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_inline.h b/include/onnxruntime/core/session/onnxruntime_cxx_inline.h index 1f31dffca8..d281bb5542 100644 --- a/include/onnxruntime/core/session/onnxruntime_cxx_inline.h +++ b/include/onnxruntime/core/session/onnxruntime_cxx_inline.h @@ -518,6 +518,11 @@ inline SessionOptions& SessionOptions::AppendExecutionProvider_TensorRT(const Or return *this; } +inline SessionOptions& SessionOptions::AppendExecutionProvider_MIGraphX(const OrtMIGraphXProviderOptions& provider_options) { + ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_MIGraphX(p_, &provider_options)); + return *this; +} + inline SessionOptions& SessionOptions::SetCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn) { ThrowOnError(GetApi().SessionOptionsSetCustomCreateThreadFn(p_, ort_custom_create_thread_fn)); return *this; diff --git a/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c b/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c index 5a1b8d004f..c91463722d 100644 --- a/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c +++ b/java/src/main/native/ai_onnxruntime_OrtSession_SessionOptions.c @@ -21,7 +21,6 @@ #include "onnxruntime/core/providers/stvm/stvm_provider_factory.h" #include "onnxruntime/core/providers/openvino/openvino_provider_factory.h" #include "onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.h" -#include "onnxruntime/core/providers/migraphx/migraphx_provider_factory.h" #include "onnxruntime/core/providers/acl/acl_provider_factory.h" #include "onnxruntime/core/providers/armnn/armnn_provider_factory.h" #include "onnxruntime/core/providers/coreml/coreml_provider_factory.h" diff --git a/onnxruntime/core/providers/migraphx/exported_symbols.lst b/onnxruntime/core/providers/migraphx/exported_symbols.lst new file mode 100644 index 0000000000..f4c4141259 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/exported_symbols.lst @@ -0,0 +1 @@ +_GetProvider diff --git a/onnxruntime/core/providers/migraphx/gpu_data_transfer.cc b/onnxruntime/core/providers/migraphx/gpu_data_transfer.cc index 2d443d43b7..f047565be7 100644 --- a/onnxruntime/core/providers/migraphx/gpu_data_transfer.cc +++ b/onnxruntime/core/providers/migraphx/gpu_data_transfer.cc @@ -1,20 +1,21 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "migraphx_inc.h" +#include "core/providers/shared_library/provider_api.h" #include "gpu_data_transfer.h" +#include "migraphx_call.h" namespace onnxruntime { -GPUDataTransfer::GPUDataTransfer() { +GPUDataTransfer::GPUDataTransfer(hipStream_t stream) { // create streams, default is nullptr - streams_[kHipStreamDefault] = nullptr; - hipStreamCreateWithFlags(&streams_[kHipStreamCopyIn], hipStreamNonBlocking); - hipStreamCreateWithFlags(&streams_[kHipStreamCopyOut], hipStreamNonBlocking); + streams_[kHipStreamDefault] = stream; + HIP_CALL_THROW(hipStreamCreateWithFlags(&streams_[kHipStreamCopyIn], hipStreamNonBlocking)); + HIP_CALL_THROW(hipStreamCreateWithFlags(&streams_[kHipStreamCopyOut], hipStreamNonBlocking)); } GPUDataTransfer::~GPUDataTransfer() { - hipStreamDestroy(streams_[kHipStreamCopyIn]); - hipStreamDestroy(streams_[kHipStreamCopyOut]); + HIP_CALL_THROW(hipStreamDestroy(streams_[kHipStreamCopyIn])); + HIP_CALL_THROW(hipStreamDestroy(streams_[kHipStreamCopyOut])); } bool GPUDataTransfer::CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const { @@ -33,21 +34,21 @@ common::Status GPUDataTransfer::CopyTensor(const Tensor& src, Tensor& dst, int e if (dst_device.Type() == OrtDevice::GPU) { if (src_device.Type() == OrtDevice::CPU && src_device.MemType() == OrtDevice::MemType::HIP_PINNED) { // copy from pinned memory to GPU, this is non-blocking - hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyHostToDevice, streams_[exec_queue_id]); + HIP_CALL_THROW(hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyHostToDevice, streams_[exec_queue_id])); } else if (src_device.Type() == OrtDevice::GPU) { // copying between GPU, this is non-blocking - hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyDeviceToDevice, streams_[kHipStreamDefault]); + HIP_CALL_THROW(hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyDeviceToDevice, streams_[kHipStreamDefault])); } else { // copy from other CPU memory to GPU, this is blocking - hipMemcpy(dst_data, src_data, bytes, hipMemcpyHostToDevice); + HIP_CALL_THROW(hipMemcpy(dst_data, src_data, bytes, hipMemcpyHostToDevice)); } } else if (src_device.Type() == OrtDevice::GPU) { if (dst_device.Type() == OrtDevice::CPU && dst_device.MemType() == OrtDevice::MemType::HIP_PINNED) { // copying from GPU to pinned memory, this is non-blocking - hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyDeviceToHost, streams_[exec_queue_id]); + HIP_CALL_THROW(hipMemcpyAsync(dst_data, src_data, bytes, hipMemcpyDeviceToHost, streams_[exec_queue_id])); } else { // copying from GPU to CPU memory, this is blocking - hipMemcpy(dst_data, src_data, bytes, hipMemcpyDeviceToHost); + HIP_CALL_THROW(hipMemcpy(dst_data, src_data, bytes, hipMemcpyDeviceToHost)); } } else { // copying between cpu memory diff --git a/onnxruntime/core/providers/migraphx/gpu_data_transfer.h b/onnxruntime/core/providers/migraphx/gpu_data_transfer.h index 9b966236cd..db84a9ee10 100644 --- a/onnxruntime/core/providers/migraphx/gpu_data_transfer.h +++ b/onnxruntime/core/providers/migraphx/gpu_data_transfer.h @@ -17,7 +17,7 @@ enum HIPStreamType : int { class GPUDataTransfer : public IDataTransfer { public: - GPUDataTransfer(); + GPUDataTransfer(hipStream_t stream); ~GPUDataTransfer(); bool CanCopy(const OrtDevice& src_device, const OrtDevice& dst_device) const override; @@ -30,6 +30,7 @@ class GPUDataTransfer : public IDataTransfer { } private: + bool do_copy_in_default_stream_; hipStream_t streams_[kTotalHipStreams]; }; diff --git a/onnxruntime/core/providers/migraphx/hip_allocator.cc b/onnxruntime/core/providers/migraphx/hip_allocator.cc index d645c74e5b..f4b813e6cd 100644 --- a/onnxruntime/core/providers/migraphx/hip_allocator.cc +++ b/onnxruntime/core/providers/migraphx/hip_allocator.cc @@ -1,10 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "migraphx_inc.h" +#include "core/providers/shared_library/provider_api.h" +#include "migraphx_call.h" #include "hip_allocator.h" +#include "core/common/status.h" +#include "core/framework/float16.h" +#include "core/common/status.h" #include "core/framework/allocatormgr.h" -#include "core/framework/session_state.h" #include "hip_fence.h" #include "gpu_data_transfer.h" @@ -13,7 +16,7 @@ namespace onnxruntime { static const GPUDataTransfer* GetGPUDataTransfer(const SessionState* session_state) { OrtDevice gpu_device(OrtDevice::GPU, OrtDevice::MemType::DEFAULT, 0); OrtDevice cpu_device; - return dynamic_cast(session_state->GetDataTransferMgr().GetDataTransfer(gpu_device, cpu_device)); + return static_cast(session_state->GetDataTransferMgr().GetDataTransfer(gpu_device, cpu_device)); } void HIPAllocator::CheckDevice() const { @@ -32,14 +35,45 @@ void* HIPAllocator::Alloc(size_t size) { CheckDevice(); void* p = nullptr; if (size > 0) { - hipMalloc((void**)&p, size); + HIP_CALL_THROW(hipMalloc((void**)&p, size)); } return p; } void HIPAllocator::Free(void* p) { CheckDevice(); - hipFree(p); // do not throw error since it's OK for hipFree to fail during shutdown + (void)hipFree(p); // do not throw error since it's OK for hipFree to fail during shutdown +} + +void* HIPExternalAllocator::Alloc(size_t size) { + void* p = nullptr; + if (size > 0) { + p = alloc_(size); + + // review(codemzs): ORT_ENFORCE does not seem appropiate. + ORT_ENFORCE(p != nullptr); + } + + return p; +} + +void HIPExternalAllocator::Free(void* p) { + free_(p); + std::lock_guard lock(lock_); + auto it = reserved_.find(p); + if (it != reserved_.end()) { + reserved_.erase(it); + if (empty_cache_) empty_cache_(); + } +} + +void* HIPExternalAllocator::Reserve(size_t size) { + void* p = Alloc(size); + if (!p) return nullptr; + std::lock_guard lock(lock_); + ORT_ENFORCE(reserved_.find(p) == reserved_.end()); + reserved_.insert(p); + return p; } FencePtr HIPAllocator::CreateFence(const SessionState* session_state) { @@ -49,13 +83,13 @@ FencePtr HIPAllocator::CreateFence(const SessionState* session_state) { void* HIPPinnedAllocator::Alloc(size_t size) { void* p = nullptr; if (size > 0) { - hipHostMalloc((void**)&p, size); + HIP_CALL_THROW(hipHostMalloc((void**)&p, size)); } return p; } void HIPPinnedAllocator::Free(void* p) { - hipHostFree(p); + HIP_CALL_THROW(hipHostFree(p)); } FencePtr HIPPinnedAllocator::CreateFence(const SessionState* session_state) { diff --git a/onnxruntime/core/providers/migraphx/hip_allocator.h b/onnxruntime/core/providers/migraphx/hip_allocator.h index 27a3fa8294..896ca59f14 100644 --- a/onnxruntime/core/providers/migraphx/hip_allocator.h +++ b/onnxruntime/core/providers/migraphx/hip_allocator.h @@ -3,7 +3,9 @@ #pragma once +#include #include "core/framework/allocator.h" +#include "core/platform/ort_mutex.h" namespace onnxruntime { @@ -23,6 +25,31 @@ class HIPAllocator : public IAllocator { void CheckDevice() const; }; +class HIPExternalAllocator : public HIPAllocator { + typedef void* (*ExternalAlloc)(size_t size); + typedef void (*ExternalFree)(void* p); + typedef void (*ExternalEmptyCache)(); + + public: + HIPExternalAllocator(OrtDevice::DeviceId device_id, const char* name, void* alloc, void* free, void* empty_cache) + : HIPAllocator(device_id, name) { + alloc_ = reinterpret_cast(alloc); + free_ = reinterpret_cast(free); + empty_cache_ = reinterpret_cast(empty_cache); + } + + void* Alloc(size_t size) override; + void Free(void* p) override; + void* Reserve(size_t size) override; + + private: + mutable OrtMutex lock_; + ExternalAlloc alloc_; + ExternalFree free_; + ExternalEmptyCache empty_cache_; + std::unordered_set reserved_; +}; + //TODO: add a default constructor class HIPPinnedAllocator : public IAllocator { public: diff --git a/onnxruntime/core/providers/migraphx/hip_fence.cc b/onnxruntime/core/providers/migraphx/hip_fence.cc index 44313c756a..2f9800dc63 100644 --- a/onnxruntime/core/providers/migraphx/hip_fence.cc +++ b/onnxruntime/core/providers/migraphx/hip_fence.cc @@ -1,27 +1,30 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "migraphx_inc.h" -#include "hip_fence.h" +#include "core/providers/shared_library/provider_api.h" +#include "core/common/status.h" +#include "core/framework/float16.h" +#include "migraphx_call.h" #include "gpu_data_transfer.h" +#include "hip_fence.h" namespace onnxruntime { HIPFence::HIPFence(const GPUDataTransfer* data_transfer) : data_transfer_(data_transfer) { - hipEventCreate(&read_event_); - hipEventCreate(&write_event_); + HIP_CALL_THROW(hipEventCreate(&read_event_)); + HIP_CALL_THROW(hipEventCreate(&write_event_)); } HIPFence::~HIPFence() { - hipEventDestroy(read_event_); - hipEventDestroy(write_event_); + HIP_CALL_THROW(hipEventDestroy(read_event_)); + HIP_CALL_THROW(hipEventDestroy(write_event_)); } void HIPFence::BeforeUsingAsInput(onnxruntime::ProviderType provider_type, int async_queue_id) { (void)provider_type; (void)async_queue_id; // sync on CPU for all other providers, this is blocking - hipEventSynchronize(write_event_); + HIP_CALL_THROW(hipEventSynchronize(write_event_)); } void HIPFence::BeforeUsingAsOutput(onnxruntime::ProviderType provider_type, int queue_id) { @@ -29,8 +32,8 @@ void HIPFence::BeforeUsingAsOutput(onnxruntime::ProviderType provider_type, int (void)queue_id; // sync on CPU for all other providers, this is blocking - hipEventSynchronize(read_event_); - hipEventSynchronize(write_event_); + HIP_CALL_THROW(hipEventSynchronize(read_event_)); + HIP_CALL_THROW(hipEventSynchronize(write_event_)); } bool HIPFence::CanRelease() { @@ -41,13 +44,13 @@ bool HIPFence::CanRelease() { void HIPFence::AfterUsedAsInput(int queue_id) { // update read fence hipStream_t stream = data_transfer_->GetStream(queue_id); - hipEventRecord(read_event_, stream); + HIP_CALL_THROW(hipEventRecord(read_event_, stream)); } void HIPFence::AfterUsedAsOutput(int queue_id) { // update write fence hipStream_t stream = data_transfer_->GetStream(queue_id); - hipEventRecord(write_event_, stream); + HIP_CALL_THROW(hipEventRecord(write_event_, stream)); } } // namespace onnxruntime diff --git a/onnxruntime/core/providers/migraphx/hip_fence.h b/onnxruntime/core/providers/migraphx/hip_fence.h index ba9803ee37..b15ad8fce5 100644 --- a/onnxruntime/core/providers/migraphx/hip_fence.h +++ b/onnxruntime/core/providers/migraphx/hip_fence.h @@ -2,8 +2,8 @@ // Licensed under the MIT License. #pragma once -#include "core/framework/tensor.h" -#include "core/graph/basic_types.h" + +#include "core/framework/fence.h" namespace onnxruntime { class GPUDataTransfer; diff --git a/onnxruntime/core/providers/migraphx/migraphx_call.cc b/onnxruntime/core/providers/migraphx/migraphx_call.cc new file mode 100644 index 0000000000..f42bb99a67 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/migraphx_call.cc @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "core/providers/shared_library/provider_api.h" +#include +#include +#include "migraphx_call.h" +#include "core/common/common.h" +#include "core/common/status.h" + +namespace onnxruntime { + +using namespace common; + +template +const char* RocmErrString(ERRTYPE x) { + ORT_NOT_IMPLEMENTED(); +} + +#define CASE_ENUM_TO_STR(x) \ + case x: \ + return #x + +template <> +const char* RocmErrString(hipError_t x) { + (void)hipDeviceSynchronize(); + return hipGetErrorString(x); +} + +template +bool RocmCall(ERRTYPE retCode, const char* exprString, const char* libName, ERRTYPE successCode, const char* msg) { + if (retCode != successCode) { + try { + char hostname[HOST_NAME_MAX]; + if (gethostname(hostname, HOST_NAME_MAX) != 0) + strcpy(hostname, "?"); + int currentHipDevice; + (void)hipGetDevice(¤tHipDevice); + (void)hipGetLastError(); // clear last HIP error + static char str[1024]; + snprintf(str, 1024, "%s failure %d: %s ; GPU=%d ; hostname=%s ; expr=%s; %s", + libName, (int)retCode, RocmErrString(retCode), currentHipDevice, + hostname, + exprString, msg); + if (THRW) { + // throw an exception with the error info + ORT_THROW(str); + } else { + LOGS_DEFAULT(ERROR) << str; + } + } catch (const std::exception& e) { // catch, log, and rethrow since HIP code sometimes hangs in destruction, so we'd never get to see the error + if (THRW) { + ORT_THROW(e.what()); + } else { + LOGS_DEFAULT(ERROR) << e.what(); + } + } + return false; + } + return true; +} + +template bool RocmCall(hipError_t retCode, const char* exprString, const char* libName, hipError_t successCode, const char* msg); +template bool RocmCall(hipError_t retCode, const char* exprString, const char* libName, hipError_t successCode, const char* msg); + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/migraphx/migraphx_call.h b/onnxruntime/core/providers/migraphx/migraphx_call.h new file mode 100644 index 0000000000..3cf90bf7a6 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/migraphx_call.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include "migraphx_inc.h" + +#pragma once + +namespace onnxruntime { + +// ----------------------------------------------------------------------- +// Error handling +// ----------------------------------------------------------------------- + +template +bool RocmCall(ERRTYPE retCode, const char* exprString, const char* libName, ERRTYPE successCode, const char* msg = ""); + +#define HIP_CALL(expr) (RocmCall((expr), #expr, "HIP", hipSuccess)) +#define HIP_CALL_THROW(expr) (RocmCall((expr), #expr, "HIP", hipSuccess)) + +} \ No newline at end of file diff --git a/onnxruntime/core/providers/migraphx/migraphx_execution_provider.cc b/onnxruntime/core/providers/migraphx/migraphx_execution_provider.cc index ed2d2811c4..3ec5a55c08 100644 --- a/onnxruntime/core/providers/migraphx/migraphx_execution_provider.cc +++ b/onnxruntime/core/providers/migraphx/migraphx_execution_provider.cc @@ -1,23 +1,19 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License -#include "core/common/common.h" -#include "core/common/logging/logging.h" -#include "core/framework/compute_capability.h" -#include "core/framework/allocatormgr.h" -#include "core/framework/kernel_registry.h" -#include "core/framework/memcpy.h" -#include "core/graph/graph_viewer.h" -#include "core/graph/model.h" -#include "core/graph/graph_utils.h" -#include "core/platform/env.h" +#include "core/providers/shared_library/provider_api.h" +#define ORT_API_MANUAL_INIT #include "core/session/onnxruntime_cxx_api.h" -#include "migraphx_inc.h" +#include "core/common/safeint.h" #include "migraphx_execution_provider.h" #include "hip_allocator.h" +#include "hip_fence.h" #include "gpu_data_transfer.h" +#include "migraphx_call.h" + #include #include +#include #if defined(_MSC_VER) #pragma warning(disable : 4244 4245) @@ -35,12 +31,27 @@ namespace onnxruntime { +class Memcpy final : public OpKernel { + public: + Memcpy(const OpKernelInfo& info) : OpKernel(info) {} + + Status Compute(OpKernelContext* ctx) const override { + const auto* X = ctx->Input(0); + Tensor* Y = ctx->Output(0, X->Shape()); + Status retval = Info().GetDataTransferManager().CopyTensor(*X, *Y, Info().GetKernelDef().ExecQueueId()); + return retval; + } +}; + +template +KernelCreateInfo BuildKernelCreateInfo(); + ONNX_OPERATOR_KERNEL_EX( MemcpyFromHost, kOnnxDomain, 1, kMIGraphXExecutionProvider, - KernelDefBuilder() + (*KernelDefBuilder::Create()) .InputMemoryType(OrtMemTypeCPUInput, 0) .ExecQueueId(kHipStreamCopyIn) .TypeConstraint("T", DataTypeImpl::AllFixedSizeTensorTypes()), @@ -51,7 +62,7 @@ ONNX_OPERATOR_KERNEL_EX( kOnnxDomain, 1, kMIGraphXExecutionProvider, - KernelDefBuilder() + (*KernelDefBuilder::Create()) .OutputMemoryType(OrtMemTypeCPUOutput, 0) .ExecQueueId(kHipStreamCopyOut) .TypeConstraint("T", DataTypeImpl::AllFixedSizeTensorTypes()), @@ -60,7 +71,7 @@ ONNX_OPERATOR_KERNEL_EX( class ONNX_OPERATOR_KERNEL_CLASS_NAME(kMIGraphXExecutionProvider, kOnnxDomain, 1, MemcpyFromHost); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kMIGraphXExecutionProvider, kOnnxDomain, 1, MemcpyToHost); -static void RegisterMIGraphXKernels(KernelRegistry& kernel_registry) { +static Status RegisterMIGraphXKernels(KernelRegistry& kernel_registry) { static const BuildKernelCreateInfoFn function_table[] = { BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -69,49 +80,35 @@ static void RegisterMIGraphXKernels(KernelRegistry& kernel_registry) { for (auto& function_table_entry : function_table) { ORT_ENFORCE(kernel_registry.Register(function_table_entry()).IsOK()); } + + return Status::OK(); } -std::shared_ptr GetMIGraphXKernelRegistry() { - std::shared_ptr kernel_registry = std::make_shared(); - RegisterMIGraphXKernels(*kernel_registry); - - return kernel_registry; +static std::shared_ptr s_kernel_registry; +void Shutdown_DeleteRegistry() { + s_kernel_registry.reset(); } std::shared_ptr MIGraphXExecutionProvider::GetKernelRegistry() const { - static std::shared_ptr kernel_registry = onnxruntime::GetMIGraphXKernelRegistry(); - return kernel_registry; + if (!s_kernel_registry) { + s_kernel_registry = KernelRegistry::Create(); + auto status = RegisterMIGraphXKernels(*s_kernel_registry); + if (!status.IsOK()) + s_kernel_registry.reset(); + ORT_THROW_IF_ERROR(status); + } + + return s_kernel_registry; } MIGraphXExecutionProvider::MIGraphXExecutionProvider(const MIGraphXExecutionProviderInfo& info) - : IExecutionProvider{onnxruntime::kMIGraphXExecutionProvider} { + : IExecutionProvider{onnxruntime::kMIGraphXExecutionProvider, true} { // Set GPU device to be used - hipSetDevice(info.device_id); - AllocatorCreationInfo default_memory_info( - [](int id) { return std::make_unique(id, MIGRAPHX); }, device_id_); - allocator_ = CreateAllocator(default_memory_info); - InsertAllocator(allocator_); - - AllocatorCreationInfo pinned_memory_info( - [](int) { return std::make_unique(0, MIGRAPHX_PINNED); }, - device_id_); - InsertAllocator(CreateAllocator(pinned_memory_info)); - - // create the target based on the device_id - hipDeviceProp_t prop; - hipGetDeviceProperties(&prop, device_id_); - std::set valid_targets = {"gpu", "cpu"}; - if (valid_targets.count(info.target_device) == 0) { - LOGS_DEFAULT(FATAL) << "Device " << info.target_device << " are not supported"; - } - + HIP_CALL_THROW(hipSetDevice(info.device_id)); t_ = migraphx::target(info.target_device.c_str()); - // Get environment variables - const Env& env_instance = Env::Default(); - // whether fp16 is enable - const std::string fp16_enable_env = env_instance.GetEnvironmentVar(migraphx_env_vars::kFP16Enable); + const std::string fp16_enable_env = onnxruntime::GetEnvironmentVar(migraphx_env_vars::kFP16Enable); if (!fp16_enable_env.empty()) { fp16_enable_ = (std::stoi(fp16_enable_env) == 0 ? false : true); } @@ -125,8 +122,53 @@ AllocatorPtr MIGraphXExecutionProvider::GetAllocator(int id, OrtMemType mem_type } } +void MIGraphXExecutionProvider::RegisterAllocator(std::shared_ptr allocator_manager) { + // Try to get a HIP allocator from allocator manager first + // Used to allocate HIP device memory + allocator_ = allocator_manager->GetAllocator(device_id_, OrtMemTypeDefault); + if (nullptr == allocator_) { + AllocatorCreationInfo default_memory_info( + [](OrtDevice::DeviceId device_id) { return CreateHIPAllocator(device_id, onnxruntime::MIGRAPHX); }, device_id_); + allocator_ = CreateAllocator(default_memory_info); + allocator_manager->InsertAllocator(allocator_); + } + TryInsertAllocator(allocator_); + + // OrtMemTypeCPUOutput -- allocated by hipMallocHost, used to copy HIP device memory to CPU + // Use pinned memory instead of pageable memory make the data transfer faster + // Used by node MemcpyToHost only + auto hip_pinned_alloc = allocator_manager->GetAllocator(DEFAULT_CPU_ALLOCATOR_DEVICE_ID, OrtMemTypeCPUOutput); + if (nullptr == hip_pinned_alloc) { + AllocatorCreationInfo pinned_allocator_info( + [](OrtDevice::DeviceId device_id) { + return CreateHIPPinnedAllocator(device_id, onnxruntime::MIGRAPHX_PINNED); + }, + DEFAULT_CPU_ALLOCATOR_DEVICE_ID); + hip_pinned_alloc = CreateAllocator(pinned_allocator_info); + allocator_manager->InsertAllocator(hip_pinned_alloc); + } + TryInsertAllocator(hip_pinned_alloc); + + auto hip_cpu_alloc = allocator_manager->GetAllocator(DEFAULT_CPU_ALLOCATOR_DEVICE_ID, OrtMemTypeCPUInput); + if (nullptr == hip_cpu_alloc) { + // This will be refactored/removed when allocator and execution provider are decoupled. + // Need to move the OrtMemoryType out of Allocator, that's one thing blocking us to share it with CPU EP + // CPUAllocator is OrtMemTypeDefault for CPU EP + AllocatorCreationInfo cpu_memory_info( + [](int device_id) { + return std::make_unique( + OrtMemoryInfo("MIP_CPU", OrtAllocatorType::OrtDeviceAllocator, OrtDevice(), device_id, + OrtMemTypeCPUInput)); + }, + DEFAULT_CPU_ALLOCATOR_DEVICE_ID); + hip_cpu_alloc = CreateAllocator(cpu_memory_info); + allocator_manager->InsertAllocator(hip_cpu_alloc); + } + TryInsertAllocator(hip_cpu_alloc); +} + std::unique_ptr MIGraphXExecutionProvider::GetDataTransfer() const { - return std::make_unique(); + return std::make_unique(static_cast(GetComputeStream())); } static bool IsTypeSupported(const NodeArg* node_arg) { @@ -203,14 +245,70 @@ static bool get_migraphx_type(ONNXTensorElementDataType type, return true; } +static bool IsGraphInput(const GraphViewer& graph, const std::string& name) +{ + const auto& graph_inputs = graph.GetInputs(); + std::vector input_names(graph_inputs.size()); + std::transform(graph_inputs.begin(), graph_inputs.end(), input_names.begin(), [](auto in) { + return in->Name(); + }); + return (std::find(input_names.begin(), input_names.end(), name) != input_names.end()); +} -static bool can_eval_shape_general(const Graph& graph, const Node* node, const logging::Logger& logger, std::vector& input_nodes) +static bool IsGraphInitializer(const GraphViewer& graph, const std::string& name, bool check_outer_scope = true) { + const ONNX_NAMESPACE::TensorProto* initializer = nullptr; + return graph.GetInitializedTensor(name, initializer); +} + +const Node* GetInputNode(const Node& node, int arg_index) { + int index = 0; + for (auto nit = node.InputNodesBegin(); nit != node.InputNodesEnd(); ++nit, ++index) + { + if (index == arg_index) + { + return &(*nit); + } + } + + return nullptr; +} + +std::vector to_vector(const ONNX_NAMESPACE::int64s& nums) +{ + std::vector result; + int num = nums.size(); + for(int i = 0; i < num; ++i) + { + result.push_back(nums[i]); + } + + return result; +} + +std::size_t node_input_num(const Node& node) +{ + std::size_t node_num = 0; + for(auto it = node.InputNodesBegin(); it != node.InputNodesEnd(); ++it) + { + node_num++; + } + + return node_num; +} + +static bool can_eval_shape_general(const GraphViewer& graph, const Node* node, const logging::Logger& logger, std::vector& input_nodes) { if (node == nullptr) { return false; } + std::vector in_nodes; + for (auto nit = node->InputNodesBegin(); nit != node->InputNodesEnd(); ++nit) + { + in_nodes.push_back(&(*nit)); + } + if (node->OpType() == "Shape") { input_nodes.push_back(node->Index()); @@ -220,26 +318,29 @@ static bool can_eval_shape_general(const Graph& graph, const Node* node, const l auto inputs = node->InputDefs(); for (std::size_t i = 0; i < inputs.size(); ++i) { - const std::string& input_name = graph_utils::GetNodeInputName(*node, i); + const std::string& input_name = inputs.at(i)->Name(); // If it is an initializer, it can be constant folded - if (graph_utils::IsInitializer(graph, input_name, true)) + if (IsGraphInitializer(graph, input_name)) { continue; } // Input for sure cannot be constant folded - if (graph_utils::IsGraphInput(graph, inputs[i])) + if (IsGraphInput(graph, input_name)) { return false; } - // get the corresponding input node - auto input_node = graph_utils::GetInputNode(*node, i); - if (input_node == nullptr) + // find the node corresponding to the name + auto nit = std::find_if(in_nodes.begin(), in_nodes.end(), [&](auto n) { + return input_name.find(n->Name()) != std::string::npos; + }); + if (nit == in_nodes.end()) { return false; } + auto input_node = (*nit); // shape node, it is OK if (input_node->OpType() == "Shape") { @@ -255,32 +356,45 @@ static bool can_eval_shape_general(const Graph& graph, const Node* node, const l } input_nodes.push_back(node->Index()); - return true; } -static bool can_eval_node_argument(const Graph& graph, const Node* node, std::vector indices, const logging::Logger& logger, std::vector& input_nodes) +static bool can_eval_node_argument(const GraphViewer& graph, const Node* node, std::vector indices, const logging::Logger& logger, std::vector& input_nodes) { input_nodes.clear(); - for (auto& arg_index : indices) + std::vector in_nodes; + for (auto nit = node->InputNodesBegin(); nit != node->InputNodesEnd(); ++nit) + { + in_nodes.push_back(&(*nit)); + } + + auto inputs = node->InputDefs(); + for (auto index : indices) { - const std::string& input_name = graph_utils::GetNodeInputName(*node, arg_index); // an initializer itself is a constant - if (graph_utils::IsInitializer(graph, input_name, true)) + auto input_name = inputs.at(index)->Name(); + if (IsGraphInitializer(graph, input_name)) { continue; } // Input cannot be constant folded - auto inputs = node->InputDefs(); - if (graph_utils::IsGraphInput(graph, inputs[arg_index])) + if (IsGraphInput(graph, input_name)) { return false; } - auto input_node = graph_utils::GetInputNode(*node, arg_index); - if (!can_eval_shape_general(graph, input_node, logger, input_nodes)) + // find the node corresponding to the name + auto nit = std::find_if(in_nodes.begin(), in_nodes.end(), [&](auto n) { + return input_name.find(n->Name()) != std::string::npos; + }); + if (nit == in_nodes.end()) + { + return false; + } + + if (!can_eval_shape_general(graph, *nit, logger, input_nodes)) { return false; } @@ -292,16 +406,15 @@ static bool can_eval_node_argument(const Graph& graph, const Node* node, std::ve static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, const Node* node, const logging::Logger& logger) { std::vector input_nodes; const auto& optype = node->OpType(); - // const auto& initializers = graph_viewer.GetAllInitializedTensors(); if (optype == "ArgMax" or optype == "ArgMin") { const auto& attributes = node->GetAttributes(); // we do not support select_last_index = 1 for now - const auto sli_attr = attributes.find("select_last_index"); - if (sli_attr != attributes.end() && sli_attr->second.i() != 0) { + auto sli_attr = attributes.find("select_last_index"); + if (sli_attr != attributes.end() && (*sli_attr).second.i() != 0) { return true; } } else if (optype == "ConstantOfShape") { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {0}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {0}, logger, input_nodes)) { return true; } @@ -326,28 +439,12 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co } } else if (optype == "Expand") { // MIGraphX only supports constant shape input values - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return true; } - } else if (optype == "Pow") { - // we do not have a implementation to support different types of - // the input data - const auto args = node->InputDefs(); - const auto& input1_type = args[0]->TypeAsProto(); - if (input1_type == nullptr) { - return true; - } - auto data_type1 = input1_type->tensor_type().elem_type(); - const auto& input2_type = args[1]->TypeAsProto(); - if (input2_type == nullptr) { - return true; - } - auto data_type2 = input2_type->tensor_type().elem_type(); - if (data_type1 != data_type2) { - return true; - } - } else if (optype == "MaxPool") { + } + else if (optype == "MaxPool") { //MaxPool "indices" output is not currently supported. if (node->OutputDefs().size() > 1) { return true; @@ -357,7 +454,7 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co const auto& attributes = node->GetAttributes(); auto dila_attr = attributes.find("dilations"); if (dila_attr != attributes.end()) { - auto dilas = dila_attr->second.ints(); + auto dilas = to_vector((*dila_attr).second.ints()); bool ret = std::all_of(dilas.begin(), dilas.end(), [](auto i) { return i == 1; }); if (ret == false) { return true; @@ -365,8 +462,8 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co } // storage order 1 (column major format) is not supported - const auto storage_order_attr = attributes.find("storage_order"); - if (storage_order_attr != attributes.end() and storage_order_attr->second.i() != 0) { + auto storage_order_attr = attributes.find("storage_order"); + if (storage_order_attr != attributes.end() and (*storage_order_attr).second.i() != 0) { return true; } @@ -396,12 +493,12 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co return true; } } else if (optype == "NonZero") { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {0}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {0}, logger, input_nodes)) { return true; } } else if (optype == "OneHot") { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return true; } @@ -409,7 +506,7 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co const auto& args = node->InputDefs(); // if pad size is not constant, migraphx cannot support if (args.size() >= 2) { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return true; } @@ -417,10 +514,10 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co const auto& attributes = node->GetAttributes(); // Pad only support constant mode - const auto mode_attr = attributes.find("mode"); + auto mode_attr = attributes.find("mode"); std::string mode = "constant"; if (mode_attr != attributes.end()) { - mode = mode_attr->second.s(); + mode = (*mode_attr).second.s(); } static const std::set allowed_modes = {"constant", "reflect"}; if (allowed_modes.count(mode) == 0) { @@ -430,7 +527,7 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co // input value only applied to constant mode if (mode == "constant") { if (args.size() == 3) { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {2}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {2}, logger, input_nodes)) { return true; } @@ -440,14 +537,45 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co auto arg_num = node->InputDefs().size(); std::vector vec(arg_num); std::iota(vec.begin(), vec.end(), 0); - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, vec, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, vec, logger, input_nodes)) { return true; } } else if (optype == "Reshape") { const auto& args = node->InputDefs(); if (args.size() == 2) { - if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) + { + return false; + } + return true; + } + } else if (optype == "Resize") { + const auto& attributes = node->GetAttributes(); + auto ct_attr = attributes.find("coordinate_transformation_mode"); + if (ct_attr != attributes.end()) { + auto ct = (*ct_attr).second.s(); + if (ct == "tf_crop_and_resize") + { + return true; + } + } + + auto mode_attr = attributes.find("mode"); + if (mode_attr != attributes.end()) { + auto mode = (*mode_attr).second.s(); + if (mode == "cubic") + { + return true; + } + } + + const auto& args = node->InputDefs(); + if (args.size() > 1) + { + std::vector indices(args.size() - 1); + std::iota(indices.begin(), indices.end(), 1); + if (can_eval_node_argument(graph_viewer, node, indices, logger, input_nodes)) { return false; } @@ -456,7 +584,7 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co } else if (optype == "ReduceSum") { const auto& args = node->InputDefs(); if (args.size() == 2) { - if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return false; } @@ -470,17 +598,17 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co std::vector vec(arg_num); std::iota(vec.begin(), vec.end(), 0); vec.erase(vec.begin()); - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, vec, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, vec, logger, input_nodes)) { return true; } const auto& attributes = node->GetAttributes(); if (attributes.count("starts") > 0 and attributes.count("ends") > 0) { - const auto& starts = attributes.find("starts")->second.ints(); - const auto& ends = attributes.find("ends")->second.ints(); - for (int i = 0; i < starts.size(); ++i) { - if (starts.Get(i) > ends.Get(i)) { + auto starts = to_vector((*attributes.find("starts")).second.ints()); + auto ends = to_vector((*attributes.find("ends")).second.ints()); + for (std::size_t i = 0; i < starts.size(); ++i) { + if (starts.at(i) > ends.at(i)) { return true; } } @@ -489,7 +617,7 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co // cannot process input dim of 0 size const auto arg_s = node->InputDefs()[0]->Shape(); if (arg_s != nullptr) { - auto tensor_dims = arg_s->dim(); + const auto& tensor_dims = arg_s->dim(); std::vector dims; std::transform(tensor_dims.begin(), tensor_dims.end(), @@ -508,21 +636,26 @@ static bool IsUnsupportedOpMode(const onnxruntime::GraphViewer& graph_viewer, co const auto& args = node->InputDefs(); if (args.size() == 2) { - if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return false; } return true; } } else if (optype == "Tile") { - if (!can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (!can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) + { + return true; + } + } else if (optype == "TopK") { + if (!can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return true; } } else if (optype == "Unsqueeze" or optype == "Squeeze") { const auto& args = node->InputDefs(); if (args.size() == 2) { - if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, input_nodes)) + if (can_eval_node_argument(graph_viewer, node, {1}, logger, input_nodes)) { return false; } @@ -557,7 +690,8 @@ void SubgraphPostProcessing(const onnxruntime::GraphViewer& graph_viewer, std::v const auto& args = node->InputDefs(); if (args.size() == 2) { std::vector node_inputs; - if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, node_inputs)) + // if (can_eval_node_argument(graph_viewer.GetGraph(), node, {1}, logger, node_inputs)) + if (can_eval_node_argument(graph_viewer, node, {1}, logger, node_inputs)) { return (not std::all_of(node_inputs.begin(), node_inputs.end(), [&](auto index) { return std::find(git.begin(), git.end(), index) != git.end(); @@ -598,7 +732,7 @@ void SubgraphPostProcessing(const onnxruntime::GraphViewer& graph_viewer, std::v if (std::any_of(inputs.begin(), inputs.end(), [&](auto& arg) { const auto& arg_s = arg->Shape(); if (arg_s == nullptr) return false; - auto tensor_dims = arg_s->dim(); + const auto& tensor_dims = arg_s->dim(); std::vector dims; std::transform(tensor_dims.begin(), tensor_dims.end(), @@ -671,41 +805,208 @@ static bool IsNodeSupported(const std::set& op_set, return true; } -static void AppendNodesToSubGraph(const std::vector& nodes, - const std::vector& inputs, - const std::vector& outputs, - std::vector>& result) { - static size_t op_counter = 0; +// Convert GraphViewer graph to GraphProto +void ToGraphProtoInternal(const GraphViewer& graph, ONNX_NAMESPACE::GraphProto& graph_proto) { + for (const auto* input_arg : graph.GetInputs()) { + *(graph_proto.mutable_input()->Add()) = input_arg->ToProto(); + } - auto meta_def = std::make_unique(); - meta_def->name = "MIGraphX_" + std::to_string(++op_counter); - meta_def->domain = kMIGraphXDomain; - meta_def->since_version = 1; - meta_def->status = ONNX_NAMESPACE::EXPERIMENTAL; - meta_def->inputs = inputs; - meta_def->outputs = outputs; + // Add all graph's initializers to the subgraph + const auto& init_tensors = graph.GetAllInitializedTensors(); + for (const auto& tensor : init_tensors) { + *(graph_proto.mutable_initializer()->Add()) = *(tensor.second); + } - std::unique_ptr sub_graph = std::make_unique(); - sub_graph->nodes = nodes; + for (const auto* output_arg : graph.GetOutputs()) { + *(graph_proto.mutable_output()->Add()) = output_arg->ToProto(); + } + + for (const auto* value_info : graph.GetValueInfo()) { + *(graph_proto.mutable_value_info()->Add()) = value_info->ToProto(); + } + + // Nodes must be sorted in Topological Order in the GraphProto per ONNX spec. + for (auto& node_idx : graph.GetNodesInTopologicalOrder()) { + const gsl::not_null node_proto{graph_proto.add_node()}; + const gsl::not_null p_node{graph.GetNode(node_idx)}; + p_node->ToProto(*node_proto); + } +} + +std::unique_ptr MIGraphXExecutionProvider::GetSubGraph(const std::vector& graph_nodes_index, const GraphViewer& graph) const { + std::unordered_set node_set; + node_set.reserve(graph_nodes_index.size()); + for (const auto& index : graph_nodes_index) { + node_set.insert(index); + } + + // Get parent graph output names + std::vector graph_output_names; + for (const auto* output_arg : graph.GetOutputs()) { + graph_output_names.push_back(output_arg->Name()); + } + + // Find inputs and outputs of the subgraph + std::unique_ptr sub_graph = onnxruntime::IndexedSubGraph::Create(); + std::unordered_map fused_inputs, fused_outputs, fused_outputs_to_add, graph_outputs_to_add; + std::unordered_set erased; + int input_order = 0; + int output_order = 0; + + for (const auto& index : graph_nodes_index) { + sub_graph->Nodes().push_back(index); + const auto& node = graph.GetNode(index); + for (const auto& input : node->InputDefs()) { + const auto& it = fused_outputs.find(input); + if (it != fused_outputs.end()) { + fused_outputs.erase(it); + erased.insert(input); + } else if (erased.find(input) == erased.end()) { + // Only when input is neither in output list nor erased list, add the input to input list + fused_inputs[input] = input_order++; + } + } + + for (const auto& input : node->ImplicitInputDefs()) { + const auto& it = fused_outputs.find(input); + if (it != fused_outputs.end()) { + fused_outputs.erase(it); + erased.insert(input); + } else if (erased.find(input) == erased.end()) { + // Only when input is neither in output list nor erased list, add the input to input list + fused_inputs[input] = input_order++; + } + } + + // For output searching, there are two special cases, + // One is, if node's OutputEdges are more than its outputs, meaning certain output is used more than once, + // if the output is connected to nodes that don't belong to the subgraph, the output need to be added + // to the output list + // The other one is, if subgraph's node output is parent graph's output. the node output should + // be also added to the subgraph's output list + if (node->GetOutputEdgesCount() > node->OutputDefs().size()) { + for (auto it = node->OutputEdgesBegin(), end = node->OutputEdgesEnd(); it != end; ++it) { + const auto& node_idx = it->GetNode().Index(); + const auto& output = (it->GetNode()).InputDefs()[it->GetDstArgIndex()]; + if (node_set.find(node_idx) != node_set.end()) { + const auto& iter = fused_inputs.find(output); + if (iter != fused_inputs.end()) { + fused_inputs.erase(iter); + erased.insert(output); + } else if (erased.find(output) == erased.end()) { + if (std::find(graph_output_names.begin(), graph_output_names.end(), output->Name()) != graph_output_names.end()) { + graph_outputs_to_add[output] = output_order; + } + fused_outputs[output] = output_order++; + } + } else { + fused_outputs_to_add[output] = output_order++; + } + } + } else { + for (const auto& output : node->OutputDefs()) { + const auto& it = fused_inputs.find(output); + if (it != fused_inputs.end()) { + fused_inputs.erase(it); + erased.insert(output); + } + // Only when output is neither in input list nor erased list, add the output to output list + else if (erased.find(output) == erased.end()) { + if (std::find(graph_output_names.begin(), graph_output_names.end(), output->Name()) != graph_output_names.end()) { + graph_outputs_to_add[output] = output_order; + } + fused_outputs[output] = output_order++; + } + } + } + } + + fused_outputs.insert(fused_outputs_to_add.begin(), fused_outputs_to_add.end()); + fused_outputs.insert(graph_outputs_to_add.begin(), graph_outputs_to_add.end()); + + // Sort inputs and outputs by the order they were added + std::multimap inputs, outputs; + for (auto it = fused_inputs.begin(), end = fused_inputs.end(); it != end; ++it) { + inputs.insert(std::pair(it->second, it->first)); + } + + for (auto it = fused_outputs.begin(), end = fused_outputs.end(); it != end; ++it) { + outputs.insert(std::pair(it->second, it->first)); + } + + // It is possible that an output of an node is put bebind the output of an later + // node in the graph output list. So we should sort the output name according + // to the graph output names + std::vector output_names; + std::unordered_set graph_out_names; + for (const auto& output : outputs) { + if (output.second->Exists()) { + auto name = output.second->Name(); + if (std::find(graph_output_names.begin(), graph_output_names.end(), name) == graph_output_names.end()) + { + output_names.push_back(name); + } + else + { + graph_out_names.insert(name); + } + } + } + + for (auto& name : graph_output_names) + { + if(std::find(graph_out_names.begin(), graph_out_names.end(), name) != graph_out_names.end()) + output_names.push_back(name); + } + + + + // Generate unique kernel name for MIGraphX subgraph + uint64_t model_hash = 0; + int id = GenerateMetaDefId(graph, model_hash); + std::string subgraph_id = std::to_string(model_hash) + "_" + std::to_string(id); + auto meta_def = IndexedSubGraph_MetaDef::Create(); + const std::string graph_type = graph.IsSubgraph() ? "subgraph" : "graph"; + meta_def->name() = "MGXKernel_" + graph_type + "_" + graph.Name() + "_" + subgraph_id; + + // Assign inputs and outputs to subgraph's meta_def + for (const auto& input : inputs) { + if (input.second->Exists()) { + meta_def->inputs().push_back(input.second->Name()); + } + } + + for (const auto& output : output_names) { + meta_def->outputs().push_back(output); + } + + meta_def->domain() = kMSDomain; + meta_def->since_version() = 1; sub_graph->SetMetaDef(std::move(meta_def)); - result.push_back(std::make_unique(std::move(sub_graph))); + + return sub_graph; } static std::vector GetUnsupportedNodeIndices(const GraphViewer& graph_viewer, /*out*/ std::unordered_set& mgx_required_initializers, const logging::Logger& logger) { - static std::set mgx_supported_ops = {"Abs", "Acos", "Acosh", "Add", "And", "ArgMax", "ArgMin", - "Asin", "Asinh", "Atan", "Atanh", "AveragePool", "BatchNormalization", "Cast", "Ceil", "Clip", - "Concat", "Constant", "ConstantFill", "ConstantOfShape", "Conv", "Cos", "Cosh", "DequantizeLinear", - "Div", "Dropout", "Elu", "Equal", "Erf", "Exp", "Expand", "Flatten", "Floor", "GRU", "Gather", - "GatherElements", "Gemm", "GlobalAveragePool", "GlobalMaxPool", "Greater", "Identity", "ImageScaler", - "InstanceNormalization", "LRN", "LSTM", "LeakyRelu", "Less", "LessOrEqual", "Log", "LogSoftmax", - "MatMul", "Max", "MaxPool", "Min", "Mul", "Neg", "NonZero", "OneHot", "Or", "Pad", "Pow", "PRelu", - "QuantizeLinear", "RNN", "Range", "Reciprocal", "ReduceL1", "ReduceL2", "ReduceLogSum", "ReduceLogSumExp", - "ReduceMax", "ReduceMean", "ReduceMin", "ReduceProd", "ReduceSum", "ReduceSumSquare", "Relu", "Reshape", - "Round", "Selu", "Shape", "Sigmoid", "Sign", "Sin", "Sinh", "Slice", "Softmax", "Split", "Sqrt", "Squeeze", - "Sub", "Sum", "Tan", "Tanh", "Tile", "Transpose", "Unsqueeze", "Where", "Xor"}; + static std::set mgx_supported_ops = {"Abs", "Acos", "Acosh", "Add", "And", + "ArgMax", "ArgMin", "Asin", "Asinh", "Atan", "Atanh", "AveragePool", + "BatchNormalization", "Cast", "Ceil", "Clip", "Concat", "Constant", "ConstantFill", + "ConstantOfShape", "Conv", "Cos", "Cosh", "DepthToSpace", "DequantizeLinear", "Div", + "Dropout", "Elu", "Equal", "Erf", "Exp", "Expand", "Flatten", "Floor", "GRU", "Gather", + "GatherElements", "Gemm", "GlobalAveragePool", "GlobalMaxPool", "Greater", "Identity", + "If", "ImageScaler", "InstanceNormalization", "LRN", "LSTM", "LeakyRelu", "Less", + "LessOrEqual", "Log", "LogSoftmax", "Loop", "MatMul", "Max", "MaxPool", "Min", "Mul", + "Multinomial", "Neg", "NonZero", "Not", "NonMaxSuppression", "OneHot", "Or", "Pad", "Pow", + "PRelu", "QuantizeLinear", "RNN", "RandomNormal", "RandomNormalLike", "RandomUniform", + "RandomUniformLike", "Range", "Reciprocal", "ReduceL1", "ReduceL2", "ReduceLogSum", + "ReduceLogSumExp", "ReduceMax", "ReduceMean", "ReduceMin", "ReduceProd", "ReduceSum", + "ReduceSumSquare", "Relu", "Reshape", "Resize", "Roialign", "Round", "Scatter", "Selu", + "Shape", "Sigmoid", "Sign", "Sin", "Sinh", "Slice", "Softmax", "SpaceToDepth", "Split", + "Sqrt", "Squeeze", "Sub", "Sum", "Tan", "Tanh", "Tile", "TopK", "Transpose", "Unsqueeze", + "Where", "Xor"}; std::vector unsupported_nodes_idx; for (const auto& node_idx : graph_viewer.GetNodesInTopologicalOrder()) { if (IsNodeSupported(mgx_supported_ops, graph_viewer, node_idx, logger)) { @@ -752,146 +1053,17 @@ GetPartitionedSubgraphs(const std::vector& topological_order, const s return mgx_subgraphx; } -static void GetInputsOutputsOfSubgraph(const GraphViewer& graph_viewer, - const std::vector& nodes, - const std::unordered_set& mgx_required_initializers, - std::vector& nodes_inputs, - std::vector& nodes_outputs) { - std::unordered_set input_args; - std::vector ordered_input_args; - std::unordered_set output_args; - std::unordered_set external_output_args; - - for (const auto& node_idx : nodes) { - const auto& node = graph_viewer.GetNode(node_idx); - - // Collect all inputs and outputs - node->ForEachDef( - [&input_args, &ordered_input_args, &output_args](const NodeArg& node_arg, bool is_input) { - if (is_input) { - if (!input_args.count(node_arg.Name())) { - ordered_input_args.push_back(node_arg.Name()); - } - input_args.insert(node_arg.Name()); - } else { - output_args.insert(node_arg.Name()); - } - }, - true); - - // Check if output of this node is used by nodes outside - // subgraph. If yes add this to cluster outputs - for (auto it = node->OutputNodesBegin(); it != node->OutputNodesEnd(); ++it) { - const auto& ext_node = graph_viewer.GetNode((*it).Index()); - - if (std::find(nodes.begin(), nodes.end(), ext_node->Index()) == nodes.end()) { - // Node is external to subgraph. Search through its - // inputs to find the output that is generated by subgraph. - std::set ext_node_inputs; - ext_node->ForEachDef( - [&ext_node_inputs](const onnxruntime::NodeArg& arg, bool is_input) { - if (is_input) { - ext_node_inputs.insert(arg.Name()); - } - }, - true); - - for (const auto& out_def : node->OutputDefs()) { - if (ext_node_inputs.find(out_def->Name()) != ext_node_inputs.end()) { - external_output_args.insert(out_def->Name()); - } - } - } - } - } - - //Extract initializers used by subgraph. - std::unordered_set original_graph_inputs; - for (const auto& node_arg : graph_viewer.GetInputsIncludingInitializers()) { - original_graph_inputs.insert(node_arg->Name()); - } - - const auto& initializers = graph_viewer.GetAllInitializedTensors(); - std::vector const_inputs; - for (const auto& in_arg : ordered_input_args) { - if ((initializers.count(in_arg) && !original_graph_inputs.count(in_arg)) || - mgx_required_initializers.count(in_arg)) { - const_inputs.push_back(in_arg); - } - } - - for (const auto& in_arg : ordered_input_args) { - if (!output_args.count(in_arg) && - !((initializers.count(in_arg) && !original_graph_inputs.count(in_arg)) || - mgx_required_initializers.count(in_arg))) { - nodes_inputs.push_back(in_arg); - } - } - - for (const auto& in_arg : const_inputs) { - nodes_inputs.push_back(in_arg); - } - - std::copy(external_output_args.begin(), external_output_args.end(), std::back_inserter(nodes_outputs)); - for (const auto& node_arg : graph_viewer.GetOutputs()) { - const auto& name = node_arg->Name(); - if (output_args.count(name) && !external_output_args.count(name)) { - nodes_outputs.push_back(name); - } - } -} - std::vector> MIGraphXExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_viewer, const std::vector& /*kernel_registries*/) const { std::vector> result; - if (graph_viewer.IsSubgraph()) { - return result; - } + auto model = graph_viewer.CreateModel(*GetLogger()); + auto model_proto = model->ToProto(); + ToGraphProtoInternal(graph_viewer, *model_proto->mutable_graph()); + model_proto->set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - for (const auto& tensor : graph_viewer.GetAllInitializedTensors()) { - if (tensor.second->has_data_location() && tensor.second->data_location() == ONNX_NAMESPACE::TensorProto_DataLocation_EXTERNAL) { - LOGS_DEFAULT(WARNING) << "MIGraphX: Initializers with external data lepcation are not currently supported"; - return result; - } - } - - // Construct modelproto from graph - onnxruntime::Model model(graph_viewer.Name(), true, ModelMetaData(), PathString{}, - IOnnxRuntimeOpSchemaRegistryList(), graph_viewer.DomainToVersionMap(), - std::vector(), *GetLogger()); - - std::unordered_map map_dim_param_values; - onnxruntime::Graph& graph_build = model.MainGraph(); - - for (const auto& node : graph_viewer.Nodes()) { - std::vector inputs, outputs; - for (auto input : node.InputDefs()) { - auto& n_input = graph_build.GetOrCreateNodeArg(input->Name(), input->TypeAsProto()); - inputs.push_back(&n_input); - } - for (auto output : node.OutputDefs()) { - auto& n_output = graph_build.GetOrCreateNodeArg(output->Name(), output->TypeAsProto()); - outputs.push_back(&n_output); - } - graph_build.AddNode(node.Name(), node.OpType(), node.Description(), inputs, outputs, &node.GetAttributes(), node.Domain()); - } - - //Add initializer to graph - std::size_t init_tensor_num = 0; - const auto& init_tensors = graph_viewer.GetAllInitializedTensors(); - for (const auto& tensor : init_tensors) { - init_tensor_num++; - graph_build.AddInitializedTensor(*(tensor.second)); - } - - ONNX_NAMESPACE::ModelProto model_proto = model.ToProto(); - model_proto.set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - - auto status = graph_build.Resolve(); - std::string onnx_string_buffer; - model_proto.SerializeToString(&onnx_string_buffer); + model_proto->SerializeToString(onnx_string_buffer); // This is a list of initializers that migraphx considers as constants. // Example weights, reshape shape etc. @@ -900,115 +1072,72 @@ MIGraphXExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_v //If all ops are supported, no partitioning is required. Short-circuit and avoid splitting. if (unsupported_nodes.empty()) { - std::vector inputs; - std::vector outputs; - - //Fill inputs with names - std::for_each(graph_viewer.GetInputs().begin(), graph_viewer.GetInputs().end(), - [&inputs](const NodeArg* node_arg) { inputs.push_back(node_arg->Name()); }); - - // In scenarios, when there are no inputs or all inputs being initializers, - // ConstantFolding optimization in onnxruntime pre-computes the value. - if (inputs.empty()) { + auto node_indices = graph_viewer.GetNodesInTopologicalOrder(); + auto sub_graph = GetSubGraph(node_indices, graph_viewer); + result.push_back(ComputeCapability::Create(std::move(sub_graph))); + } else { // unsupported_nodes_idx.empty() + if (unsupported_nodes.size() > 10) + { return result; } - // Initializers need to be part of meta_def->inputs - std::for_each(mgx_required_initializers.begin(), mgx_required_initializers.end(), - [&inputs](const std::string& initializer) { inputs.push_back(initializer); }); + // migraphx cannot handle Loop, If, and SoftmaxCrossEntropyLoss for now, + // so if a model contain any of these operators, fall back to CPU + std::unordered_set vec_ops = {"SoftmaxCrossEntropyLoss"}; + if (std::any_of(unsupported_nodes.begin(), unsupported_nodes.end(), [&](auto i) { + return (vec_ops.count(graph_viewer.GetNode(i)->OpType()) > 0); + })) { + return result; + } - // Fill outputs with names - std::for_each(graph_viewer.GetOutputs().begin(), graph_viewer.GetOutputs().end(), - [&outputs](const NodeArg* node_arg) { outputs.push_back(node_arg->Name()); }); - - // Create and add this graph to result. - AppendNodesToSubGraph(graph_viewer.GetNodesInTopologicalOrder(), inputs, outputs, result); - - } else { // unsupported_nodes_idx.empty() auto mgx_clusters = GetPartitionedSubgraphs(graph_viewer.GetNodesInTopologicalOrder(), unsupported_nodes); // check whether a subgrap should fallback to CPU SubgraphPostProcessing(graph_viewer, mgx_clusters, *GetLogger()); for (const auto& this_cluster : mgx_clusters) { - std::vector cluster_inputs, cluster_outputs; - GetInputsOutputsOfSubgraph(graph_viewer, this_cluster, mgx_required_initializers, cluster_inputs, cluster_outputs); - - if (!cluster_inputs.empty()) { - AppendNodesToSubGraph(this_cluster, cluster_inputs, cluster_outputs, result); - } + auto sub_graph = GetSubGraph(this_cluster, graph_viewer); + result.push_back(ComputeCapability::Create(std::move(sub_graph))); } } return result; } -static ONNX_NAMESPACE::ModelProto GetModelProtoFromFusedNode(const onnxruntime::Node* fused_node, - const logging::Logger& logger) { - const auto* node_function = fused_node->GetFunctionBody(); - - ORT_ENFORCE(node_function != nullptr, "Could not extract function body for node: ", fused_node->Name()); - - const Graph& node_subgraph = node_function->Body(); - onnxruntime::Model model{node_subgraph.Name(), true, ModelMetaData{}, PathString{}, - IOnnxRuntimeOpSchemaRegistryList{}, node_subgraph.DomainToVersionMap(), - std::vector(), logger}; - - ONNX_NAMESPACE::ModelProto model_proto = model.ToProto(); - //model_proto.set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - - *(model_proto.mutable_graph()) = node_subgraph.ToGraphProto(); - - auto opset = model_proto.add_opset_import(); - opset->set_domain(kOnnxDomain); - opset->set_version(node_subgraph.DomainToVersionMap().at(kOnnxDomain)); - - return model_proto; -} - -bool get_input_output_names(std::string& onnx_buffer, +bool get_input_output_names(const GraphViewer& graph, std::vector& input_names, std::vector& output_names) { - bool no_input_shape = false; - input_names.clear(); output_names.clear(); - onnx::ModelProto model; - if (model.ParseFromArray(onnx_buffer.data(), onnx_buffer.size())) { - if (model.has_graph()) { - // compute output names - auto& graph = model.graph(); + const auto& input_args = graph.GetInputs(); + std::transform(input_args.begin(), input_args.end(), std::back_inserter(input_names), [](auto& arg){ + return arg->Name(); + }); - // compute input names - std::unordered_set ini_names; - for (auto&& f : graph.initializer()) - ini_names.insert(f.name()); + bool no_input_shape = std::any_of(input_args.begin(), input_args.end(), [&](auto arg) { + if (arg == nullptr) + return true; - for (auto&& input : graph.input()) { - const std::string& name = input.name(); - if (ini_names.count(name) == 0) { - input_names.push_back(name); - auto dim_size = input.type().tensor_type().shape().dim_size(); - if (dim_size == 0) { - no_input_shape = true; - } - } - } + auto sptr = arg->Shape(); + if (sptr == nullptr) + return true; - auto prog_output = graph.output(); - std::vector all_output_names; - std::vector prog_output_names; - std::transform(prog_output.begin(), - prog_output.end(), - std::back_inserter(all_output_names), - [](auto& node) { return node.name(); }); - std::copy_if( - all_output_names.begin(), - all_output_names.end(), - std::back_inserter(output_names), - [&](const auto& name) { return !name.empty(); }); - } - } + auto dim_size = sptr->dim_size(); + return (dim_size == 0); + }); + + const auto& out_args = graph.GetOutputs(); + std::vector tmp_out_names; + std::transform(out_args.begin(), + out_args.end(), + std::back_inserter(tmp_out_names), + [](auto& arg) { return arg->Name(); }); + + std::copy_if( + tmp_out_names.begin(), + tmp_out_names.end(), + std::back_inserter(output_names), + [&](const auto& name) { return !name.empty(); }); return no_input_shape; } @@ -1026,13 +1155,23 @@ Status MIGraphXExecutionProvider::Compile(const std::vector& input_name_index[input_defs[i]->Name()] = i; } - // reconstruct the subgraph proto from fused nodes - onnx::ModelProto model_proto = GetModelProtoFromFusedNode(fused_node, *GetLogger()); + // Reconstruct graph proto from fused node's function body + const auto* func_body = fused_node->GetFunctionBody(); + if (!func_body) { + return common::Status(common::ONNXRUNTIME, common::INVALID_ARGUMENT, "Function body is empty"); + } + + const Graph& graph_body = func_body->Body(); + auto graph_body_viewer = graph_body.CreateGraphViewer(); + auto model = graph_body_viewer->CreateModel(*GetLogger()); + auto model_proto = model->ToProto(); + *model_proto->mutable_graph() = *graph_body.ToGraphProto(); + model_proto->set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); std::string onnx_string_buffer; - model_proto.SerializeToString(&onnx_string_buffer); + model_proto->SerializeToString(onnx_string_buffer); std::vector input_names, output_names; - no_input_shape = no_input_shape or get_input_output_names(onnx_string_buffer, input_names, output_names); + no_input_shape = no_input_shape or get_input_output_names(*graph_body_viewer, input_names, output_names); // by parsing the model_proto, create a program corresponding to // the input fused_node @@ -1163,7 +1302,6 @@ Status MIGraphXExecutionProvider::Compile(const std::vector& if (mgx_type != mgx_s.type()) { LOGS_DEFAULT(FATAL) << "MIGraphX: param type mismatch"; } - m.add(name, migraphx::argument(param_shapes[name], const_cast(ort.GetTensorData(input_tensor)))); } // It is a output argument @@ -1200,7 +1338,7 @@ Status MIGraphXExecutionProvider::Compile(const std::vector& // lock to avoid race condition std::lock_guard lock(*(mgx_state->mgx_mu_ptr)); auto prog_outputs = prog.eval(m); - hipDeviceSynchronize(); + HIP_CALL_THROW(hipDeviceSynchronize()); // In case of input parameters are reused as output parameter call hipMemcpy auto output_num = prog_outputs.size(); @@ -1214,7 +1352,7 @@ Status MIGraphXExecutionProvider::Compile(const std::vector& std::vector ort_shape{res_lens.begin(), res_lens.end()}; OrtValue* output_tensor = ort.KernelContext_GetOutput(context, i, ort_shape.data(), ort_shape.size()); void* output_data = ort.GetTensorMutableData(output_tensor); - hipMemcpy(output_data, gpu_res.data(), res_shape.bytes(), hipMemcpyDeviceToDevice); + HIP_CALL_THROW(hipMemcpy(output_data, gpu_res.data(), res_shape.bytes(), hipMemcpyDeviceToDevice)); } } } @@ -1227,4 +1365,4 @@ Status MIGraphXExecutionProvider::Compile(const std::vector& return Status::OK(); } -} // namespace onnxruntime +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/core/providers/migraphx/migraphx_execution_provider.h b/onnxruntime/core/providers/migraphx/migraphx_execution_provider.h index 36fc87d922..1bf222c193 100644 --- a/onnxruntime/core/providers/migraphx/migraphx_execution_provider.h +++ b/onnxruntime/core/providers/migraphx/migraphx_execution_provider.h @@ -3,8 +3,12 @@ #pragma once +#include "core/framework/allocatormgr.h" +#include "core/framework/arena_extend_strategy.h" #include "core/framework/execution_provider.h" #include "core/platform/ort_mutex.h" +#include "migraphx_execution_provider_info.h" + #include #include "migraphx_inc.h" @@ -14,12 +18,6 @@ namespace migraphx_env_vars { static const std::string kFP16Enable = "ORT_MIGRAPHX_FP16_ENABLE"; }; -// Information needed to construct amdmigraphx execution providers. -struct MIGraphXExecutionProviderInfo { - std::string target_device; - int device_id {0}; -}; - // Information to construct kernel function state. struct MIGraphXFuncState { AllocateFunc allocate_func = nullptr; @@ -52,11 +50,18 @@ class MIGraphXExecutionProvider : public IExecutionProvider { std::unique_ptr GetDataTransfer() const override; AllocatorPtr GetAllocator(int id, OrtMemType mem_type) const override; + void RegisterAllocator(std::shared_ptr allocator_manager) override; + + void* GetComputeStream() const override { return static_cast(stream_); } + + std::unique_ptr GetSubGraph(const std::vector& graph_nodes_index, const GraphViewer& graph) const; + private: bool fp16_enable_ = false; int device_id_; migraphx::target t_; OrtMutex mgx_mu_; + hipStream_t stream_ = nullptr; std::unordered_map map_progs_; std::unordered_map map_onnx_string_; diff --git a/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.cc b/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.cc new file mode 100644 index 0000000000..6571593499 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.cc @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "core/providers/migraphx/migraphx_execution_provider_info.h" + +#include "core/common/make_string.h" +#include "core/common/parse_string.h" +#include "core/framework/provider_options_utils.h" +#include "migraphx_inc.h" +#include "migraphx_call.h" + +namespace onnxruntime { +namespace migraphx { +namespace provider_option_names { +constexpr const char* kDeviceId = "device_id"; +constexpr const char* kFp16Enable = "trt_fp16_enable"; +constexpr const char* kInt8Enable = "trt_int8_enable"; +} // namespace provider_option_names +} // namespace migraphx + +MIGraphXExecutionProviderInfo MIGraphXExecutionProviderInfo::FromProviderOptions(const ProviderOptions& options) { + MIGraphXExecutionProviderInfo info{}; + ORT_THROW_IF_ERROR( + ProviderOptionsParser{} + .AddValueParser( + migraphx::provider_option_names::kDeviceId, + [&info](const std::string& value_str) -> Status { + ORT_RETURN_IF_ERROR(ParseStringWithClassicLocale(value_str, info.device_id)); + int num_devices{}; + ORT_RETURN_IF_NOT( + HIP_CALL(hipGetDeviceCount(&num_devices)), + "hipGetDeviceCount() failed."); + ORT_RETURN_IF_NOT( + 0 <= info.device_id && info.device_id < num_devices, + "Invalid device ID: ", info.device_id, + ", must be between 0 (inclusive) and ", num_devices, " (exclusive)."); + return Status::OK(); + }) + .AddAssignmentToReference(migraphx::provider_option_names::kFp16Enable, info.fp16_enable) + .AddAssignmentToReference(migraphx::provider_option_names::kInt8Enable, info.int8_enable) + .Parse(options)); + + return info; +} + +ProviderOptions MIGraphXExecutionProviderInfo::ToProviderOptions(const MIGraphXExecutionProviderInfo& info) { + const ProviderOptions options{ + {migraphx::provider_option_names::kDeviceId, MakeStringWithClassicLocale(info.device_id)}, + {migraphx::provider_option_names::kFp16Enable, MakeStringWithClassicLocale(info.fp16_enable)}, + {migraphx::provider_option_names::kInt8Enable, MakeStringWithClassicLocale(info.int8_enable)} + }; + return options; +} + +ProviderOptions MIGraphXExecutionProviderInfo::ToProviderOptions(const OrtMIGraphXProviderOptions& info) { + + const ProviderOptions options{ + {migraphx::provider_option_names::kDeviceId, MakeStringWithClassicLocale(info.device_id)}, + {migraphx::provider_option_names::kFp16Enable, MakeStringWithClassicLocale(info.migraphx_fp16_enable)}, + {migraphx::provider_option_names::kInt8Enable, MakeStringWithClassicLocale(info.migraphx_int8_enable)} + }; + return options; +} +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.h b/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.h new file mode 100644 index 0000000000..6fa514e20c --- /dev/null +++ b/onnxruntime/core/providers/migraphx/migraphx_execution_provider_info.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include + +#include "core/framework/ortdevice.h" +#include "core/framework/provider_options.h" +#include "core/session/onnxruntime_c_api.h" + +namespace onnxruntime { +// Information needed to construct trt execution providers. +struct MIGraphXExecutionProviderInfo { + std::string target_device; + int device_id{0}; + bool fp16_enable{false}; + bool int8_enable{false}; + + static MIGraphXExecutionProviderInfo FromProviderOptions(const ProviderOptions& options); + static ProviderOptions ToProviderOptions(const MIGraphXExecutionProviderInfo& info); + static ProviderOptions ToProviderOptions(const OrtMIGraphXProviderOptions& info); +}; +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/migraphx/migraphx_provider_factory.cc b/onnxruntime/core/providers/migraphx/migraphx_provider_factory.cc index 7b616b8fc7..b1512a6e54 100644 --- a/onnxruntime/core/providers/migraphx/migraphx_provider_factory.cc +++ b/onnxruntime/core/providers/migraphx/migraphx_provider_factory.cc @@ -1,36 +1,107 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License +#include "core/providers/shared_library/provider_api.h" #include "core/providers/migraphx/migraphx_provider_factory.h" -#include #include "migraphx_execution_provider.h" -#include "core/session/abi_session_options_impl.h" +#include "hip_allocator.h" +#include "gpu_data_transfer.h" +#include "core/framework/provider_options.h" +#include + +#include "core/session/onnxruntime_c_api.h" using namespace onnxruntime; + namespace onnxruntime { + +void Shutdown_DeleteRegistry(); + struct MIGraphXProviderFactory : IExecutionProviderFactory { - MIGraphXProviderFactory(int device_id) : device_id_(device_id) {} - ~MIGraphXProviderFactory() = default; + MIGraphXProviderFactory(const MIGraphXExecutionProviderInfo& info) : info_{info} {} + ~MIGraphXProviderFactory() override {} - std::unique_ptr CreateProvider() override { - MIGraphXExecutionProviderInfo info; - info.device_id = device_id_; - info.target_device = "gpu"; - return std::make_unique(info); - } + std::unique_ptr CreateProvider() override; -private: - int device_id_; + private: + MIGraphXExecutionProviderInfo info_; }; -std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id) { - return std::make_shared(device_id); +std::unique_ptr MIGraphXProviderFactory::CreateProvider() { + return std::make_unique(info_); } +// std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id) { +// MIGraphXExecutionProviderInfo info; +// info.device_id = device_id; +// return std::make_shared(info); +// } + +std::shared_ptr CreateExecutionProviderFactory_MIGraphX(const MIGraphXExecutionProviderInfo& info) { + return std::make_shared(info); +} + + +struct ProviderInfo_MIGRAPHX_Impl : ProviderInfo_MIGRAPHX { + std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name) override { + return std::make_unique(device_id, name); + } + + std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) override { + return std::make_unique(device_id, name); + } + + std::unique_ptr CreateGPUDataTransfer(void* stream) override { + return std::make_unique(static_cast(stream)); + } +} g_info; + +struct MIGraphX_Provider : Provider { + void* GetInfo() override { return &g_info; } + + std::shared_ptr CreateExecutionProviderFactory(int device_id) override { + MIGraphXExecutionProviderInfo info; + info.device_id = device_id; + info.target_device = "gpu"; + return std::make_shared(info); + } + + std::shared_ptr CreateExecutionProviderFactory(const void* provider_options) override { + auto& options = *reinterpret_cast(provider_options); + MIGraphXExecutionProviderInfo info; + info.device_id = options.device_id; + info.target_device = "gpu"; + info.fp16_enable = options.migraphx_fp16_enable; + info.int8_enable = options.migraphx_int8_enable; + return std::make_shared(info); + } + + void UpdateProviderOptions(void* provider_options, const ProviderOptions& options) override { + auto internal_options = onnxruntime::MIGraphXExecutionProviderInfo::FromProviderOptions(options); + auto& trt_options = *reinterpret_cast(provider_options); + trt_options.device_id = internal_options.device_id; + trt_options.migraphx_fp16_enable = internal_options.fp16_enable; + trt_options.migraphx_int8_enable = internal_options.int8_enable; + } + + ProviderOptions GetProviderOptions(const void* provider_options) override { + auto& options = *reinterpret_cast(provider_options); + return onnxruntime::MIGraphXExecutionProviderInfo::ToProviderOptions(options); + } + + void Shutdown() override { + Shutdown_DeleteRegistry(); + } + +} g_provider; + } // namespace onnxruntime -ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id) { - options->provider_factories.push_back(onnxruntime::CreateExecutionProviderFactory_MIGraphX(device_id)); - return nullptr; +extern "C" { + +ORT_API(onnxruntime::Provider*, GetProvider) { + return &onnxruntime::g_provider; +} + } diff --git a/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h b/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h new file mode 100644 index 0000000000..ac4aaedf20 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/migraphx_provider_factory.h @@ -0,0 +1,20 @@ +// Copyright 2019 AMD AMDMIGraphX + +#include "core/framework/provider_options.h" +#include "onnxruntime_c_api.h" + +namespace onnxruntime { +class IAllocator; +class IDataTransfer; +struct IExecutionProviderFactory; +struct MIGraphXExecutionProviderInfo; +enum class ArenaExtendStrategy : int32_t; +struct MIGraphXExecutionProviderExternalAllocatorInfo; + +struct ProviderInfo_MIGRAPHX { + virtual std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name) = 0; + virtual std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) = 0; + virtual std::unique_ptr CreateGPUDataTransfer(void* stream) = 0; +}; +} + diff --git a/onnxruntime/core/providers/migraphx/symbols.def b/onnxruntime/core/providers/migraphx/symbols.def new file mode 100644 index 0000000000..4ec2f7914c --- /dev/null +++ b/onnxruntime/core/providers/migraphx/symbols.def @@ -0,0 +1,2 @@ +EXPORTS + GetProvider diff --git a/onnxruntime/core/providers/migraphx/version_script.lds b/onnxruntime/core/providers/migraphx/version_script.lds new file mode 100644 index 0000000000..094abb3329 --- /dev/null +++ b/onnxruntime/core/providers/migraphx/version_script.lds @@ -0,0 +1,9 @@ +#_init and _fini should be local +VERS_1.0 { + global: + GetProvider; + + # Hide everything else. + local: + *; +}; diff --git a/onnxruntime/core/providers/shared_library/provider_api.h b/onnxruntime/core/providers/shared_library/provider_api.h index 221a1b8e22..881987b4b8 100644 --- a/onnxruntime/core/providers/shared_library/provider_api.h +++ b/onnxruntime/core/providers/shared_library/provider_api.h @@ -232,15 +232,20 @@ constexpr const char* kDnnlExecutionProvider = "DnnlExecutionProvider"; constexpr const char* kOpenVINOExecutionProvider = "OpenVINOExecutionProvider"; constexpr const char* kRocmExecutionProvider = "ROCMExecutionProvider"; constexpr const char* kTensorrtExecutionProvider = "TensorrtExecutionProvider"; +constexpr const char* kMIGraphXExecutionProvider = "MIGraphXExecutionProvider"; template using IAllocatorUniquePtr = std::unique_ptr >; inline OrtStatus* CreateStatus(OrtErrorCode code, _In_ const char* msg) noexcept { return g_host->CreateStatus(code, msg); } - + std::unique_ptr CreateCPUAllocator(const OrtMemoryInfo& memory_info); std::unique_ptr CreateCUDAAllocator(int16_t device_id, const char* name); std::unique_ptr CreateCUDAPinnedAllocator(int16_t device_id, const char* name); + +std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name); +std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name); + std::unique_ptr CreateGPUDataTransfer(void* stream); std::unordered_set GetCpuPreferredNodes(const onnxruntime::GraphViewer& graph, diff --git a/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc b/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc index d2e0be2176..a1993e80b8 100644 --- a/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc +++ b/onnxruntime/core/providers/shared_library/provider_bridge_provider.cc @@ -321,6 +321,20 @@ std::unique_ptr CreateGPUDataTransfer(void* stream) { } #endif +#ifdef USE_MIGRAPHX +std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name) { + return g_host->CreateHIPAllocator(device_id, name); +} + +std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) { + return g_host->CreateHIPPinnedAllocator(device_id, name); +} + +std::unique_ptr CreateGPUDataTransfer(void* stream) { + return g_host->CreateGPUDataTransfer(stream); +} +#endif + std::string GetEnvironmentVar(const std::string& var_name) { return g_host->GetEnvironmentVar(var_name); } diff --git a/onnxruntime/core/providers/shared_library/provider_interfaces.h b/onnxruntime/core/providers/shared_library/provider_interfaces.h index 37ce00a4e8..862b082d6d 100644 --- a/onnxruntime/core/providers/shared_library/provider_interfaces.h +++ b/onnxruntime/core/providers/shared_library/provider_interfaces.h @@ -151,6 +151,12 @@ struct ProviderHost { virtual bool CudaCall_true(int retCode, const char* exprString, const char* libName, int successCode, const char* msg) = 0; #endif +#ifdef USE_MIGRAPHX + virtual std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name) = 0; + virtual std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) = 0; + virtual std::unique_ptr CreateGPUDataTransfer(void* stream) = 0; +#endif + #ifdef USE_ROCM virtual std::unique_ptr CreateROCMAllocator(int16_t device_id, const char* name) = 0; virtual std::unique_ptr CreateROCMPinnedAllocator(int16_t device_id, const char* name) = 0; diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index b954b78870..52f9754476 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -2500,6 +2500,7 @@ static constexpr OrtApi ort_api_1_to_11 = { &OrtApis::GetSparseTensorIndices, // End of Version 9 - DO NOT MODIFY ABOVE (see above text for more information) + // Version 10 - In development, feel free to add/remove/rearrange here &OrtApis::HasValue, &OrtApis::KernelContext_GetGPUComputeStream, &OrtApis::GetTensorMemoryInfo, @@ -2520,6 +2521,7 @@ static constexpr OrtApi ort_api_1_to_11 = { &OrtApis::UpdateCUDAProviderOptions, &OrtApis::GetCUDAProviderOptionsAsString, &OrtApis::ReleaseCUDAProviderOptions, + &OrtApis::SessionOptionsAppendExecutionProvider_MIGraphX, }; // Asserts to do a some checks to ensure older Versions of the OrtApi never change (will detect an addition or deletion but not if they cancel out each other) diff --git a/onnxruntime/core/session/ort_apis.h b/onnxruntime/core/session/ort_apis.h index 46aa26030f..ad48ee80d3 100644 --- a/onnxruntime/core/session/ort_apis.h +++ b/onnxruntime/core/session/ort_apis.h @@ -151,7 +151,8 @@ ORT_API_STATUS_IMPL(GetTypeInfo, _In_ const OrtValue* value, _Outptr_result_mayb ORT_API_STATUS_IMPL(GetValueType, _In_ const OrtValue* value, _Out_ enum ONNXType* out); ORT_API_STATUS_IMPL(AddFreeDimensionOverride, _Inout_ OrtSessionOptions* options, _In_ const char* dim_denotation, _In_ int64_t dim_value); -ORT_API_STATUS_IMPL(CreateMemoryInfo, _In_ const char* name1, enum OrtAllocatorType type, int id1, enum OrtMemType mem_type1, _Outptr_ OrtMemoryInfo** out); +ORT_API_STATUS_IMPL(CreateMemoryInfo, _In_ const char* name1, enum OrtAllocatorType type, int id1, enum OrtMemType mem_type1, _Outptr_ OrtMemoryInfo** out) +ORT_ALL_ARGS_NONNULL; ORT_API_STATUS_IMPL(CreateCpuMemoryInfo, enum OrtAllocatorType type, enum OrtMemType mem_type1, _Outptr_ OrtMemoryInfo** out) ORT_ALL_ARGS_NONNULL; ORT_API_STATUS_IMPL(CompareMemoryInfo, _In_ const OrtMemoryInfo* info1, _In_ const OrtMemoryInfo* info2, _Out_ int* out) @@ -260,6 +261,8 @@ ORT_API_STATUS_IMPL(CreateArenaCfg, _In_ size_t max_mem, int arena_extend_strate ORT_API(void, ReleaseArenaCfg, _Frees_ptr_opt_ OrtArenaCfg*); ORT_API_STATUS_IMPL(SessionOptionsAppendExecutionProvider_TensorRT, _In_ OrtSessionOptions* options, _In_ const OrtTensorRTProviderOptions* tensorrt_options); +ORT_API_STATUS_IMPL(SessionOptionsAppendExecutionProvider_MIGraphX, + _In_ OrtSessionOptions* options, _In_ const OrtMIGraphXProviderOptions* migraphx_options); ORT_API_STATUS_IMPL(SetCurrentGpuDeviceId, _In_ int device_id); ORT_API_STATUS_IMPL(GetCurrentGpuDeviceId, _In_ int* device_id); ORT_API_STATUS_IMPL(KernelInfoGetAttributeArray_float, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ float* out, _Inout_ size_t* size); diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index 98d057d57e..36ebf32f04 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -65,6 +65,7 @@ using IndexedSubGraph_MetaDef = IndexedSubGraph::MetaDef; #include "core/providers/cuda/cuda_provider_factory.h" #include "core/providers/rocm/rocm_provider_factory.h" #include "core/providers/dnnl/dnnl_provider_factory.h" +#include "core/providers/migraphx/migraphx_provider_factory.h" #include "core/providers/openvino/openvino_provider_factory.h" #include "core/providers/tensorrt/tensorrt_provider_factory.h" #include "core/providers/tensorrt/tensorrt_provider_options.h" @@ -90,6 +91,8 @@ namespace onnxruntime { ProviderInfo_CUDA* TryGetProviderInfo_CUDA(); ProviderInfo_CUDA& GetProviderInfo_CUDA(); +ProviderInfo_MIGRAPHX* TryGetProviderInfo_MIGRAPHX(); +ProviderInfo_MIGRAPHX& GetProviderInfo_MIGRAPHX(); ProviderInfo_ROCM* TryGetProviderInfo_ROCM(); ProviderInfo_ROCM& GetProviderInfo_ROCM(); ProviderHostCPU& GetProviderHostCPU(); @@ -185,6 +188,12 @@ struct ProviderHostImpl : ProviderHost { bool CudaCall_true(int retCode, const char* exprString, const char* libName, int successCode, const char* msg) override { return GetProviderInfo_CUDA().CudaCall_true(retCode, exprString, libName, successCode, msg); } #endif +#ifdef USE_MIGRAPHX + std::unique_ptr CreateHIPAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_MIGRAPHX().CreateHIPAllocator(device_id, name); } + std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_MIGRAPHX().CreateHIPPinnedAllocator(device_id, name); } + std::unique_ptr CreateGPUDataTransfer(void* stream) override { return GetProviderInfo_MIGRAPHX().CreateGPUDataTransfer(stream); } +#endif + #ifdef USE_ROCM std::unique_ptr CreateROCMAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_ROCM().CreateROCMAllocator(device_id, name); } std::unique_ptr CreateROCMPinnedAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_ROCM().CreateROCMPinnedAllocator(device_id, name); } @@ -1052,6 +1061,7 @@ static ProviderLibrary s_library_rocm(LIBRARY_PREFIX "onnxruntime_providers_rocm static ProviderLibrary s_library_dnnl(LIBRARY_PREFIX "onnxruntime_providers_dnnl" LIBRARY_EXTENSION); static ProviderLibrary s_library_openvino(LIBRARY_PREFIX "onnxruntime_providers_openvino" LIBRARY_EXTENSION); static ProviderLibrary s_library_tensorrt(LIBRARY_PREFIX "onnxruntime_providers_tensorrt" LIBRARY_EXTENSION); +static ProviderLibrary s_library_migraphx(LIBRARY_PREFIX "onnxruntime_providers_migraphx" LIBRARY_EXTENSION); void UnloadSharedProviders() { s_library_dnnl.Unload(); @@ -1060,6 +1070,7 @@ void UnloadSharedProviders() { s_library_cuda.Unload(); s_library_rocm.Unload(); s_library_shared.Unload(); + s_library_migraphx.Unload(); } // Used by test code @@ -1070,6 +1081,12 @@ std::unique_ptr CreateCUDAPinnedAllocator(int16_t device_id, const c return nullptr; } +std::unique_ptr CreateHIPPinnedAllocator(int16_t device_id, const char* name) { + if (auto* info = onnxruntime::TryGetProviderInfo_MIGRAPHX()) + return info->CreateHIPPinnedAllocator(device_id, name); + + return nullptr; +} std::unique_ptr CreateROCMPinnedAllocator(int16_t device_id, const char* name) { if (auto* info = onnxruntime::TryGetProviderInfo_ROCM()) return info->CreateROCMPinnedAllocator(device_id, name); @@ -1131,6 +1148,13 @@ std::shared_ptr CreateExecutionProviderFactory_Tensor return nullptr; } +std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id) { + if (auto* provider = s_library_migraphx.Get()) + return provider->CreateExecutionProviderFactory(device_id); + + return nullptr; +} + std::shared_ptr CreateExecutionProviderFactory_Tensorrt(const OrtTensorRTProviderOptions* provider_options) { if (auto* provider = s_library_tensorrt.Get()) return provider->CreateExecutionProviderFactory(provider_options); @@ -1138,6 +1162,13 @@ std::shared_ptr CreateExecutionProviderFactory_Tensor return nullptr; } +std::shared_ptr CreateExecutionProviderFactory_MIGraphX(const OrtMIGraphXProviderOptions* provider_options) { + if (auto* provider = s_library_migraphx.Get()) + return provider->CreateExecutionProviderFactory(provider_options); + + return nullptr; +} + std::shared_ptr CreateExecutionProviderFactory_OpenVINO(const OrtOpenVINOProviderOptions* provider_options) { if (auto* provider = s_library_openvino.Get()) return provider->CreateExecutionProviderFactory(provider_options); @@ -1165,6 +1196,13 @@ ProviderInfo_CUDA& GetProviderInfo_CUDA() { ORT_THROW("CUDA Provider not available, can't get interface for it"); } +ProviderInfo_MIGRAPHX* TryGetProviderInfo_MIGRAPHX() { + if (auto* provider = s_library_migraphx.Get()) + return reinterpret_cast(provider->GetInfo()); + + return nullptr; +} + ProviderInfo_ROCM* TryGetProviderInfo_ROCM() { if (auto* provider = s_library_rocm.Get()) return reinterpret_cast(provider->GetInfo()); @@ -1172,6 +1210,13 @@ ProviderInfo_ROCM* TryGetProviderInfo_ROCM() { return nullptr; } +ProviderInfo_MIGRAPHX& GetProviderInfo_MIGRAPHX() { + if (auto* info = TryGetProviderInfo_MIGRAPHX()) + return *info; + + ORT_THROW("MIGRAPHX Provider not available, can't get interface for it"); +} + ProviderInfo_ROCM& GetProviderInfo_ROCM() { if (auto* info = TryGetProviderInfo_ROCM()) return *info; @@ -1282,6 +1327,18 @@ ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Tensorrt, _In_ OrtS API_IMPL_END } +ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id) { + API_IMPL_BEGIN + auto factory = onnxruntime::CreateExecutionProviderFactory_MIGraphX(device_id); + if (!factory) { + return OrtApis::CreateStatus(ORT_FAIL, "OrtSessionOptionsAppendExecutionProvider_MIGraphX: Failed to load shared library"); + } + + options->provider_factories.push_back(factory); + return nullptr; + API_IMPL_END +} + ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_TensorRT, _In_ OrtSessionOptions* options, _In_ const OrtTensorRTProviderOptions* tensorrt_options) { API_IMPL_BEGIN auto factory = onnxruntime::CreateExecutionProviderFactory_Tensorrt(tensorrt_options); @@ -1294,6 +1351,18 @@ ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_TensorRT, _In API_IMPL_END } +ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, _In_ const OrtMIGraphXProviderOptions* migraphx_options) { + API_IMPL_BEGIN + auto factory = onnxruntime::CreateExecutionProviderFactory_MIGraphX(migraphx_options); + if (!factory) { + return OrtApis::CreateStatus(ORT_FAIL, "SessionOptionsAppendExecutionProvider_MIGraphX: Failed to load shared library"); + } + + options->provider_factories.push_back(factory); + return nullptr; + API_IMPL_END +} + ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_OpenVINO, _In_ OrtSessionOptions* options, _In_ const OrtOpenVINOProviderOptions* provider_options) { API_IMPL_BEGIN auto factory = onnxruntime::CreateExecutionProviderFactory_OpenVINO(provider_options); diff --git a/onnxruntime/core/session/provider_stubs.cc b/onnxruntime/core/session/provider_stubs.cc index 1db6c5917a..d320ad3c0f 100644 --- a/onnxruntime/core/session/provider_stubs.cc +++ b/onnxruntime/core/session/provider_stubs.cc @@ -202,4 +202,11 @@ ORT_API(void, OrtApis::ReleaseTensorRTProviderOptions, _Frees_ptr_opt_ OrtTensor ORT_UNUSED_PARAMETER(ptr); } +ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider_MIGraphX, + _In_ OrtSessionOptions* options, _In_ const OrtMIGraphXProviderOptions* migraphx_options) { + ORT_UNUSED_PARAMETER(options); + ORT_UNUSED_PARAMETER(migraphx_options); + return CreateNotEnabledStatus("MIGraphX"); +} + #endif diff --git a/onnxruntime/python/onnxruntime_pybind_schema.cc b/onnxruntime/python/onnxruntime_pybind_schema.cc index 9caddaf6fb..b5b8ef2a29 100644 --- a/onnxruntime/python/onnxruntime_pybind_schema.cc +++ b/onnxruntime/python/onnxruntime_pybind_schema.cc @@ -54,7 +54,11 @@ void addGlobalSchemaFunctions(pybind11::module& m) { }()), #endif #ifdef USE_MIGRAPHX - onnxruntime::CreateExecutionProviderFactory_MIGraphX(0), + onnxruntime::CreateExecutionProviderFactory_MIGraphX( + [&]() { + MIGraphXExecutionProviderInfo info{}; + return info; + }()), #endif #ifdef USE_VITISAI onnxruntime::CreateExecutionProviderFactory_VITISAI("DPUCADX8G", 0, "", ""), @@ -209,4 +213,4 @@ void addOpSchemaSubmodule(py::module& m) { .value("EXPERIMENTAL", ONNX_NAMESPACE::OpSchema::SupportType::EXPERIMENTAL); } } -} // namespace onnxruntime \ No newline at end of file +} // namespace onnxruntime diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index db4eda1259..773db017e5 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -475,6 +475,7 @@ OrtValue FromDlpack(PyObject* dlpack_tensor, const bool is_bool_tensor); std::shared_ptr CreateExecutionProviderFactory_Tensorrt(const OrtTensorRTProviderOptions* params); std::shared_ptr CreateExecutionProviderFactory_Tensorrt(int device_id); +std::shared_ptr CreateExecutionProviderFactory_MIGraphX(const OrtMIGraphXProviderOptions* params); std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id); std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptions* params); std::shared_ptr CreateExecutionProviderFactory_Dnnl(int use_arena); diff --git a/onnxruntime/test/python/onnx_backend_test_series.py b/onnxruntime/test/python/onnx_backend_test_series.py index fb6d129192..3165c6514c 100644 --- a/onnxruntime/test/python/onnx_backend_test_series.py +++ b/onnxruntime/test/python/onnx_backend_test_series.py @@ -88,9 +88,18 @@ def create_backend_test(testname=None): '^test_softmax_cross_entropy', '^test_greater_equal', '^test_if_seq_cpu', + '^test_loop11_cpu', '^test_loop13_seq_cpu', '^test_sequence_insert_at_back_cpu', - '^test_sequence_insert_at_front_cpu' + '^test_sequence_insert_at_front_cpu', + '^test_nonmaxsuppression_two_classes_cpu', + '^test_nonmaxsuppression_two_batches_cpu', + '^test_nonmaxsuppression_suppress_by_IOU_cpu', + '^test_nonmaxsuppression_suppress_by_IOU_and_scores_cpu', + '^test_nonmaxsuppression_limit_output_size_cpu', + '^test_nonmaxsuppression_identical_boxes_cpu', + '^test_nonmaxsuppression_flipped_coordinates_cpu', + '^test_nonmaxsuppression_center_point_box_format_cpu' ] # Skip these tests for a "pure" DML onnxruntime python wheel. We keep these tests enabled for instances where both DML and CUDA diff --git a/onnxruntime/test/util/default_providers.cc b/onnxruntime/test/util/default_providers.cc index 978da66a0e..209d424422 100644 --- a/onnxruntime/test/util/default_providers.cc +++ b/onnxruntime/test/util/default_providers.cc @@ -56,12 +56,26 @@ std::unique_ptr TensorrtExecutionProviderWithOptions(const O std::unique_ptr DefaultMIGraphXExecutionProvider() { #ifdef USE_MIGRAPHX - return CreateExecutionProviderFactory_MIGraphX(0)->CreateProvider(); + OrtMIGraphXProviderOptions params{ + 0, + 0, + 0}; + return CreateExecutionProviderFactory_MIGraphX(¶ms)->CreateProvider(); #else return nullptr; #endif } +std::unique_ptr MIGraphXExecutionProviderWithOptions(const OrtMIGraphXProviderOptions* params) { +#ifdef USE_MIGRAPHX + if (auto factory = CreateExecutionProviderFactory_MIGraphX(params)) + return factory->CreateProvider(); +#else + ORT_UNUSED_PARAMETER(params); +#endif + return nullptr; +} + std::unique_ptr DefaultOpenVINOExecutionProvider() { #ifdef USE_OPENVINO OrtOpenVINOProviderOptions params; diff --git a/onnxruntime/test/util/include/default_providers.h b/onnxruntime/test/util/include/default_providers.h index 078e135628..6fa50c61cd 100644 --- a/onnxruntime/test/util/include/default_providers.h +++ b/onnxruntime/test/util/include/default_providers.h @@ -13,7 +13,7 @@ std::shared_ptr CreateExecutionProviderFactory_CoreML std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptions* provider_options); std::shared_ptr CreateExecutionProviderFactory_Cuda(const OrtCUDAProviderOptionsV2* provider_options); std::shared_ptr CreateExecutionProviderFactory_Dnnl(int use_arena); -std::shared_ptr CreateExecutionProviderFactory_MIGraphX(int device_id); +std::shared_ptr CreateExecutionProviderFactory_MIGraphX(const OrtMIGraphXProviderOptions* params); std::shared_ptr CreateExecutionProviderFactory_Nnapi( uint32_t flags, const optional& partitioning_stop_ops_list); std::shared_ptr CreateExecutionProviderFactory_Nuphar(bool, const char*); @@ -39,6 +39,7 @@ std::unique_ptr DefaultNupharExecutionProvider(bool allow_un std::unique_ptr DefaultTensorrtExecutionProvider(); std::unique_ptr TensorrtExecutionProviderWithOptions(const OrtTensorRTProviderOptions* params); std::unique_ptr DefaultMIGraphXExecutionProvider(); +std::unique_ptr MIGraphXExecutionProviderWithOptions(const OrtMIGraphXProviderOptions* params); std::unique_ptr DefaultOpenVINOExecutionProvider(); std::unique_ptr DefaultNnapiExecutionProvider(); std::unique_ptr DefaultRknpuExecutionProvider(); diff --git a/tools/ci_build/gen_def.py b/tools/ci_build/gen_def.py index 7e7e6651a7..d64c5e33e3 100755 --- a/tools/ci_build/gen_def.py +++ b/tools/ci_build/gen_def.py @@ -64,7 +64,7 @@ with open(args.output_source, 'w') as file: # WinML adapter should not be exported in platforms other than Windows. # Exporting OrtGetWinMLAdapter is exported without issues using .def file when compiling for Windows # so it isn't necessary to include it in generated_source.c - if c != "winml" and c != "cuda": + if c != "winml" and c != "cuda" and c != "migraphx": file.write("#include \n" % (c, c)) file.write("void* GetFunctionEntryByName(const char* name){\n") for symbol in symbols: From cb9b0275b65b56e127cba8d98dc451ee36f3a715 Mon Sep 17 00:00:00 2001 From: Yufeng Li Date: Tue, 11 Jan 2022 14:24:57 -0800 Subject: [PATCH 108/113] Set default quantization weight type to int8 (#10209) * Set default quantization weight type to int8 --- .../cpu/quantization/qembed_layer_norm.cc | 2 +- .../python/tools/quantization/quantize.py | 12 +-- .../contrib_ops/qembed_layer_norm_op_test.cc | 73 ++++++++++--------- .../test/python/quantization/test_qdq.py | 35 ++++++--- 4 files changed, 70 insertions(+), 52 deletions(-) diff --git a/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc index 2f684362e1..f9cb974cb8 100644 --- a/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc +++ b/onnxruntime/contrib_ops/cpu/quantization/qembed_layer_norm.cc @@ -198,7 +198,7 @@ Status CheckQuantizedInputs(OpKernelContext* context, bool* is_signed_inputs) { const Tensor* gamma_zero_point_tensor = context->Input(16); const Tensor* beta_zero_point_tensor = context->Input(17); - bool word_embedding_is_signed_inputs = word_embedding_scale_tensor->IsDataType(); + bool word_embedding_is_signed_inputs = word_embedding_zero_point_tensor->IsDataType(); bool has_segment_embedding = context->Input(1) != nullptr; if (!IsScalarOr1ElementVector(word_embedding_scale_tensor)) { diff --git a/onnxruntime/python/tools/quantization/quantize.py b/onnxruntime/python/tools/quantization/quantize.py index 955a74e525..a0a0b93522 100644 --- a/onnxruntime/python/tools/quantization/quantize.py +++ b/onnxruntime/python/tools/quantization/quantize.py @@ -141,7 +141,7 @@ def quantize_static(model_input, per_channel=False, reduce_range=False, activation_type=QuantType.QUInt8, - weight_type=QuantType.QUInt8, + weight_type=QuantType.QInt8, nodes_to_quantize=[], nodes_to_exclude=[], optimize_model=True, @@ -161,8 +161,8 @@ def quantize_static(model_input, :param op_types: operators to quantize :param per_channel: quantize weights per channel :param reduce_range: quantize weights with 7-bits. It may improve the accuracy for some models running on non-VNNI machine, especially for per-channel mode - :param activation_type: quantization data type of activation - :param weight_type: quantization data type of weight + :param activation_type: quantization data type of activation. Please refer to https://onnxruntime.ai/docs/performance/quantization.html for more details on data type selection + :param weight_type: quantization data type of weight. Please refer to https://onnxruntime.ai/docs/performance/quantization.html for more details on data type selection :param nodes_to_quantize: List of nodes names to quantize. When this list is not None only the nodes in this list are quantized. @@ -256,7 +256,7 @@ def quantize_dynamic(model_input: Path, per_channel=False, reduce_range=False, activation_type=QuantType.QUInt8, - weight_type=QuantType.QUInt8, + weight_type=QuantType.QInt8, nodes_to_quantize=[], nodes_to_exclude=[], optimize_model=True, @@ -270,8 +270,8 @@ def quantize_dynamic(model_input: Path, :param per_channel: quantize weights per channel :param reduce_range: quantize weights with 7-bits. It may improve the accuracy for some models running on non-VNNI machine, especially for per-channel mode :param nbits: number of bits to represent quantized data. Currently only supporting 8-bit types - :param activation_type: quantization data type of activation - :param weight_type: quantization data type of weight + :param activation_type: quantization data type of activation. Please refer to https://onnxruntime.ai/docs/performance/quantization.html for more details on data type selection + :param weight_type: quantization data type of weight. Please refer to https://onnxruntime.ai/docs/performance/quantization.html for more details on data type selection :param nodes_to_quantize: List of nodes names to quantize. When this list is not None only the nodes in this list are quantized. diff --git a/onnxruntime/test/contrib_ops/qembed_layer_norm_op_test.cc b/onnxruntime/test/contrib_ops/qembed_layer_norm_op_test.cc index 02b7c7f5f9..5c02cfda4a 100644 --- a/onnxruntime/test/contrib_ops/qembed_layer_norm_op_test.cc +++ b/onnxruntime/test/contrib_ops/qembed_layer_norm_op_test.cc @@ -12,6 +12,7 @@ namespace test { namespace { +template static void RunTest(const embedlayernorm::OpData& data, float accuracy_threshold = 0.25f) { ASSERT_TRUE(data.word_embedding_data.size() % data.hidden_size == 0); @@ -34,30 +35,30 @@ static void RunTest(const embedlayernorm::OpData& data, std::vector output_dims = {data.batch_size, data.sequence_size, data.hidden_size}; std::vector mask_index_dims = {data.batch_size}; - quantization::Params word_embedding_params; - std::vector word_embedding_data_quant = - QuantizeLinearTestVector(data.word_embedding_data, + quantization::Params word_embedding_params; + std::vector word_embedding_data_quant = + QuantizeLinearTestVector(data.word_embedding_data, word_embedding_params); - quantization::Params position_embedding_params; - std::vector position_embedding_data_quant = - QuantizeLinearTestVector(data.position_embedding_data, + quantization::Params position_embedding_params; + std::vector position_embedding_data_quant = + QuantizeLinearTestVector(data.position_embedding_data, position_embedding_params); - quantization::Params segment_embedding_params = {}; - std::vector segment_embedding_data_quant; + quantization::Params segment_embedding_params = {}; + std::vector segment_embedding_data_quant; if (data.has_segment) { - segment_embedding_data_quant = QuantizeLinearTestVector( + segment_embedding_data_quant = QuantizeLinearTestVector( data.segment_embedding_data, segment_embedding_params); } - quantization::Params gamma_params; - std::vector gamma_data_quant = - QuantizeLinearTestVector(data.gamma_data, gamma_params); + quantization::Params gamma_params; + std::vector gamma_data_quant = + QuantizeLinearTestVector(data.gamma_data, gamma_params); - quantization::Params beta_params; - std::vector beta_data_quant = - QuantizeLinearTestVector(data.beta_data, beta_params); + quantization::Params beta_params; + std::vector beta_data_quant = + QuantizeLinearTestVector(data.beta_data, beta_params); OpTester tester("QEmbedLayerNormalization", 1, onnxruntime::kMSDomain); @@ -70,27 +71,27 @@ static void RunTest(const embedlayernorm::OpData& data, } // Quantized initializer inputs: - tester.AddInput("word_embedding_data", + tester.AddInput("word_embedding_data", word_embedding_dims, word_embedding_data_quant, /*is_initializer=*/true); - tester.AddInput("position_embedding_data", + tester.AddInput("position_embedding_data", position_embedding_dims, position_embedding_data_quant, /*is_initializer=*/true); if (data.has_segment) { - tester.AddInput("segment_embedding_data", + tester.AddInput("segment_embedding_data", segment_embedding_dims, segment_embedding_data_quant, /*is_initializer=*/true); } else { - tester.AddOptionalInputEdge(); + tester.AddOptionalInputEdge(); } - tester.AddInput("gamma", + tester.AddInput("gamma", gamma_dims, gamma_data_quant, /*is_initializer=*/true); - tester.AddInput("beta", + tester.AddInput("beta", beta_dims, beta_data_quant, /*is_initializer=*/true); @@ -128,27 +129,27 @@ static void RunTest(const embedlayernorm::OpData& data, /*is_initializer=*/true); // Quantized zero points: - tester.AddInput("word_embedding_zero_point", + tester.AddInput("word_embedding_zero_point", /*dims=*/{}, {word_embedding_params.zero_point}, /*is_initializer=*/true); - tester.AddInput("position_embedding_zero_point", + tester.AddInput("position_embedding_zero_point", /*dims=*/{}, {position_embedding_params.zero_point}, /*is_initializer=*/true); if (data.has_segment) { - tester.AddInput("segment_embedding_zero_point", + tester.AddInput("segment_embedding_zero_point", /*dims=*/{}, {segment_embedding_params.zero_point}, /*is_initializer=*/true); } else { - tester.AddOptionalInputEdge(); + tester.AddOptionalInputEdge(); } - tester.AddInput("gamma_zero_point", + tester.AddInput("gamma_zero_point", /*dims=*/{}, {gamma_params.zero_point}, /*is_initializer=*/true); - tester.AddInput("beta_zero_point", + tester.AddInput("beta_zero_point", /*dims=*/{}, {beta_params.zero_point}, /*is_initializer=*/true); @@ -170,28 +171,34 @@ static void RunTest(const embedlayernorm::OpData& data, } // namespace TEST(QEmbedLayerNormTest, EmbedLayerNormBatch1) { - RunTest(embedlayernorm::EmbedLayerNormBatch1()); + RunTest(embedlayernorm::EmbedLayerNormBatch1()); + RunTest(embedlayernorm::EmbedLayerNormBatch1()); } TEST(QEmbedLayerNormTest, EmbedLayerNormBatch1_Float16) { - RunTest(embedlayernorm::EmbedLayerNormBatch1(), /*use_float16=*/true); + RunTest(embedlayernorm::EmbedLayerNormBatch1(), /*use_float16=*/true); + RunTest(embedlayernorm::EmbedLayerNormBatch1(), /*use_float16=*/true); } TEST(QEmbedLayerNormTest, EmbedLayerNormBatch2) { - RunTest(embedlayernorm::EmbedLayerNormBatch2()); + RunTest(embedlayernorm::EmbedLayerNormBatch2()); + RunTest(embedlayernorm::EmbedLayerNormBatch2()); } TEST(QEmbedLayerNormTest, EmbedLayerNormBatch2_NoMask) { - RunTest(embedlayernorm::EmbedLayerNormBatch2(/*has_mask=*/false)); + RunTest(embedlayernorm::EmbedLayerNormBatch2(/*has_mask=*/false)); + RunTest(embedlayernorm::EmbedLayerNormBatch2(/*has_mask=*/false)); } // BatchSize > HiddenSize to reproduce mask processing bug TEST(QEmbedLayerNormTest, EmbedLayerNormLargeBatchSmallHiddenSize) { - RunTest(embedlayernorm::EmbedLayerNormLargeBatchSmallHiddenSize()); + RunTest(embedlayernorm::EmbedLayerNormLargeBatchSmallHiddenSize()); + RunTest(embedlayernorm::EmbedLayerNormLargeBatchSmallHiddenSize()); } TEST(QEmbedLayerNormTest, EmbedLayerNormBatch_Distill) { - RunTest(embedlayernorm::EmbedLayerNormBatch_Distill()); + RunTest(embedlayernorm::EmbedLayerNormBatch_Distill()); + RunTest(embedlayernorm::EmbedLayerNormBatch_Distill()); } } // namespace test diff --git a/onnxruntime/test/python/quantization/test_qdq.py b/onnxruntime/test/python/quantization/test_qdq.py index 2aca1eacdb..6946280dbe 100644 --- a/onnxruntime/test/python/quantization/test_qdq.py +++ b/onnxruntime/test/python/quantization/test_qdq.py @@ -231,7 +231,7 @@ class TestQDQFormatConv(TestQDQFormat): onnx.save(model, output_model_path) - def verify_quantize_conv(self, has_bias, per_channel): + def verify_quantize_conv(self, has_bias, per_channel, is_weight_int8 = False): np.random.seed(1) model_fp32_path = 'conv_fp32.{}.{}.onnx'.format(has_bias, per_channel) model_int8_qdq_path = 'conv_quant_qdq.{}.{}.onnx'.format(has_bias, per_channel) @@ -247,7 +247,8 @@ class TestQDQFormatConv(TestQDQFormat): data_reader, quant_format=QuantFormat.QDQ, per_channel = per_channel, - reduce_range = per_channel + reduce_range = per_channel, + weight_type = QuantType.QInt8 if is_weight_int8 else QuantType.QUInt8 ) data_reader.rewind() qdq_nodes = {'Conv': 1, 'QuantizeLinear': 2, 'DequantizeLinear': 4 if has_bias else 3} @@ -260,7 +261,8 @@ class TestQDQFormatConv(TestQDQFormat): data_reader, quant_format=QuantFormat.QOperator, per_channel = per_channel, - reduce_range = per_channel + reduce_range = per_channel, + weight_type = QuantType.QInt8 if is_weight_int8 else QuantType.QUInt8 ) data_reader.rewind() qop_nodes = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 1} @@ -268,10 +270,14 @@ class TestQDQFormatConv(TestQDQFormat): check_model_correctness(self, model_fp32_path, model_int8_qop_path, data_reader.get_next()) def test_quantize_conv_without_bias(self): - self.verify_quantize_conv(False, False) # has_bias:False, per_channel:False - self.verify_quantize_conv(False, True) # has_bias:False, per_channel:True - self.verify_quantize_conv(True, False) # has_bias:True, per_channel:False - self.verify_quantize_conv(True, True) # has_bias:True, per_channel:True + # only test cases per_channel=True and reduce_range=True to avoid saturation on avx2 and avx512 for weight type int8 + self.verify_quantize_conv(False, True, True) # has_bias:False, per_channel:True, is_weight_int8:True + self.verify_quantize_conv(True, True, True) # has_bias:True, per_channel:True, is_weight_int8:True + + self.verify_quantize_conv(False, False, False) # has_bias:False, per_channel:False, is_weight_int8:False + self.verify_quantize_conv(True, False, False) # has_bias:True, per_channel:False, is_weight_int8:False + self.verify_quantize_conv(False, True, False) # has_bias:False, per_channel:True, is_weight_int8:False + self.verify_quantize_conv(True, True, False) # has_bias:True, per_channel:True, is_weight_int8:False class TestQDQFormatConvClip(TestQDQFormat): def construct_model_conv_clip(self, output_model_path, input_shape, weight_shape, output_shape): @@ -324,7 +330,7 @@ class TestQDQFormatConvClip(TestQDQFormat): onnx.save(model, output_model_path) - def verify(self, per_channel): + def verify(self, per_channel, is_weight_int8): np.random.seed(1) model_fp32_path = 'conv_clip_fp32.{}.onnx'.format(per_channel) model_int8_qdq_path = 'conv_clip_quant_qdq.{}.onnx'.format(per_channel) @@ -339,7 +345,8 @@ class TestQDQFormatConvClip(TestQDQFormat): data_reader, quant_format=QuantFormat.QDQ, per_channel = per_channel, - reduce_range = per_channel + reduce_range = per_channel, + weight_type = QuantType.QInt8 if is_weight_int8 else QuantType.QUInt8 ) data_reader.rewind() #topo sort check @@ -352,7 +359,8 @@ class TestQDQFormatConvClip(TestQDQFormat): data_reader, quant_format=QuantFormat.QOperator, per_channel = per_channel, - reduce_range = per_channel + reduce_range = per_channel, + weight_type = QuantType.QInt8 if is_weight_int8 else QuantType.QUInt8 ) data_reader.rewind() qop_nodes = {'QLinearConv': 1, 'QuantizeLinear': 1, 'DequantizeLinear': 1} @@ -360,8 +368,11 @@ class TestQDQFormatConvClip(TestQDQFormat): check_model_correctness(self, model_fp32_path, model_int8_qop_path, data_reader.get_next()) def test_quantize_conv_without_bias(self): - self.verify(False) # per_channel:False - #self.verify(True) # per_channel:True + # only test cases per_channel=True and reduce_range=True to avoid saturation on avx2 and avx512 for weight type int8 + self.verify(True, True) # per_channel:False, is_weight_int8:True + + self.verify(False, False) # per_channel:False, is_weight_int8:False + self.verify(True, False) # per_channel:True, is_weight_int8:False if __name__ == '__main__': unittest.main() From 4048ed326c62f60ed7b1440f1e72dd2b7dd0b395 Mon Sep 17 00:00:00 2001 From: Olivia Jain Date: Tue, 11 Jan 2022 16:12:32 -0800 Subject: [PATCH 109/113] Update EP Perf Pipeline (#10149) * migrate to 1ES Hosted Pool * migrate to Kusto database * refactor and organize ep names with ORT prefix * standardize TRT benchmarking with save/load engine, input binding, and workspace * Add TRT 8.2 to ep perf pipeline * update model_list.json with full onnx zoo * add anubis credentials * add anubis credentials * clarify trt variables * get system info from docker image * remove unwanted commenting --- dockerfiles/Dockerfile.tensorrt | 20 +- .../tools/tensorrt/perf/anubis/start_job.ps1 | 18 +- .../python/tools/tensorrt/perf/benchmark.py | 301 +++++++++++------- .../tools/tensorrt/perf/benchmark_wrapper.py | 8 +- .../tools/tensorrt/perf/build/build_image.sh | 9 +- .../tools/tensorrt/perf/build/checkout_trt.sh | 9 +- .../tools/tensorrt/perf/model_list.json | 122 ++++++- .../python/tools/tensorrt/perf/perf.sh | 2 +- .../python/tools/tensorrt/perf/perf_utils.py | 35 +- .../python/tools/tensorrt/perf/post.py | 144 ++++----- .../tools/tensorrt/perf/run_perf_docker.sh | 5 +- ...linux-gpu-tensorrt-daily-perf-pipeline.yml | 176 ++++++++++ .../Dockerfile.ubuntu_cuda11_4_tensorrt8_2 | 35 ++ 13 files changed, 644 insertions(+), 240 deletions(-) create mode 100644 tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-daily-perf-pipeline.yml create mode 100644 tools/ci_build/github/linux/docker/Dockerfile.ubuntu_cuda11_4_tensorrt8_2 diff --git a/dockerfiles/Dockerfile.tensorrt b/dockerfiles/Dockerfile.tensorrt index ab915a55f3..9b4db6b5f5 100644 --- a/dockerfiles/Dockerfile.tensorrt +++ b/dockerfiles/Dockerfile.tensorrt @@ -5,8 +5,9 @@ # Dockerfile to run ONNXRuntime with TensorRT integration # nVidia TensorRT Base Image -ARG TRT_VERSION=21.07 -FROM nvcr.io/nvidia/tensorrt:${TRT_VERSION}-py3 +ARG TRT_CONTAINER_VERSION=21.12 +ARG TRT_VERSION=8.2.1.8 +FROM nvcr.io/nvidia/tensorrt:${TRT_CONTAINER_VERSION}-py3 ARG ONNXRUNTIME_REPO=https://github.com/Microsoft/onnxruntime ARG ONNXRUNTIME_BRANCH=master @@ -21,11 +22,12 @@ ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:/code/cmake-3.21.0-linux-x86_ # Prepare onnxruntime repository & build onnxruntime with TensorRT RUN git clone --single-branch --branch ${ONNXRUNTIME_BRANCH} --recursive ${ONNXRUNTIME_REPO} onnxruntime &&\ - /bin/sh onnxruntime/dockerfiles/scripts/install_common_deps.sh &&\ - cp onnxruntime/docs/Privacy.md /code/Privacy.md &&\ - cp onnxruntime/dockerfiles/LICENSE-IMAGE.txt /code/LICENSE-IMAGE.txt &&\ - cp onnxruntime/ThirdPartyNotices.txt /code/ThirdPartyNotices.txt &&\ - cd onnxruntime &&\ - /bin/sh ./build.sh --parallel --skip_submodule_sync --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu/ --use_tensorrt --tensorrt_home /workspace/tensorrt --config Release --build_wheel --update --build --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) '"CMAKE_CUDA_ARCHITECTURES='${CMAKE_CUDA_ARCHITECTURES}'"' &&\ + /bin/sh onnxruntime/dockerfiles/scripts/install_common_deps.sh + +# Checkout appropriate TRT_VERSION and build +RUN cd onnxruntime &&\ + trt_version=${TRT_VERSION%.*.*} &&\ + ./onnxruntime/python/tools/tensorrt/perf/build/checkout_trt.sh ${trt_version} &&\ + /bin/sh build.sh --parallel --build_shared_lib --skip_submodule_sync --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu/ --use_tensorrt --tensorrt_home /usr/lib/x86_64-linux-gnu/ --config Release --build_wheel --skip_tests --skip_submodule_sync --cmake_extra_defines '"CMAKE_CUDA_ARCHITECTURES='${CMAKE_CUDA_ARCHITECTURES}'"' &&\ pip install /code/onnxruntime/build/Linux/Release/dist/*.whl &&\ - cd .. + cd .. \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1 b/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1 index 934fc368f5..8940857e30 100644 --- a/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1 +++ b/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1 @@ -1,4 +1,4 @@ -param([string]$file_folder, [string]$account_key, [string]$trt_container) +param([string]$file_folder, [string]$account_key, [string]$trt_container, [string]$csc) Add-Type -AssemblyName System.Web $wheel_file = [System.IO.Path]::GetFileName((Get-ChildItem $file_folder)) @@ -6,6 +6,18 @@ $ort_trt_ep_pkg_blob_path = 'ort-trt-ep/' + $env:BUILD_BUILDNUMBER + '/' + $whee $expiredays = New-TimeSpan -Days 1 $end = (Get-Date) + $expiredays +$body = @{grant_type='client_credentials' +client_id='bcb87687-5d9d-4c21-801e-317980c8b1d5' +client_secret=$csc +scope='api://2227e307-9325-4dbe-9894-5c3b25d62a2d/.default'} +$contentType = 'application/x-www-form-urlencoded' +$res = Invoke-WebRequest -Method POST -Uri https://login.microsoftonline.com/cc38825a-ff99-423f-bdde-dd14d00e33b8/oauth2/v2.0/token -body $body -ContentType $contentType | ConvertFrom-Json + +Write-Host "Before send" +$token = $res.access_token + +$headers = @{Authorization = "Bearer $token"} + $ort_trt_ep_pkg_sas_uri = az storage blob generate-sas -c upload -n $ort_trt_ep_pkg_blob_path --account-name anubiscustomerstorage --account-key $account_key --full-uri --permissions r --expiry $end.ToString("yyyy-MM-ddTHH:mmZ") --https-only $ort_trt_ep_pkg_sas_uri = $ort_trt_ep_pkg_sas_uri.Substring(1, $ort_trt_ep_pkg_sas_uri.Length-2) @@ -22,5 +34,5 @@ $anubissvctesturl = "https://anubistest.azurewebsites.net/api/mlperf/jobs" Write-Host ($body_trt_perf_compare|ConvertTo-Json) -Invoke-RestMethod -Method 'Post' -Uri $anubissvctesturl -Body ($body_trt_perf_compare|ConvertTo-Json) -ContentType "application/json" -$body.Parameters +Invoke-RestMethod -Method 'Post' -Uri $anubissvctesturl -Body ($body_trt_perf_compare|ConvertTo-Json) -ContentType "application/json" -Headers $headers -UseBasicParsing +$body.Parameters \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/benchmark.py b/onnxruntime/python/tools/tensorrt/perf/benchmark.py index 43a971de2d..dedaa5d960 100644 --- a/onnxruntime/python/tools/tensorrt/perf/benchmark.py +++ b/onnxruntime/python/tools/tensorrt/perf/benchmark.py @@ -23,23 +23,13 @@ debug = False sys.path.append('.') logger = logging.getLogger('') -# global ep variables -cpu = "CPUExecutionProvider" -acl = "ACLExecutionProvider" -cuda = "CUDAExecutionProvider" -cuda_fp16 = "CUDAExecutionProvider_fp16" -trt = "TensorrtExecutionProvider" -trt_fp16 = "TensorrtExecutionProvider_fp16" -standalone_trt = "Standalone_TRT" -standalone_trt_fp16 = "Standalone_TRT_fp16" - ep_to_provider_list = { - cpu: [cpu], - acl: [acl], - cuda: [cuda], - cuda_fp16: [cuda], - trt: [trt, cuda], - trt_fp16: [trt, cuda] + cpu: [cpu_ep], + acl: [acl_ep], + cuda: [cuda_ep], + cuda_fp16: [cuda_ep], + trt: [trt_ep, cuda_ep], + trt_fp16: [trt_ep, cuda_ep] } # latency gain headers @@ -66,36 +56,64 @@ def is_dynamic(model): return True return False -def run_trt_standalone(trtexec, model_path, ort_inputs, all_inputs_shape, fp16): +def run_trt_standalone(trtexec, model_name, model_path, ort_inputs, all_inputs_shape, fp16, track_memory): logger.info("running standalone trt") onnx_model_path = "--onnx=" + model_path + + # load inputs input_shape = [] - - logger.info(all_inputs_shape) - + loaded_inputs = [] for i in range(len(ort_inputs)): name = ort_inputs[i].name - + loaded_input = name + ':' + str(i) + '.bin' shape = [] for j in all_inputs_shape[i]: shape.append(str(j)) shape = "x".join(shape) shape = name + ':' + shape input_shape.append(shape) - + loaded_inputs.append(loaded_input) + shapes_arg = '--optShapes=' + ','.join(input_shape) - logger.info(shapes_arg) - + inputs_arg = '--loadInputs=' + ','.join(loaded_inputs) result = {} - command = [trtexec, onnx_model_path, "--percentile=90", "--explicitBatch"] + command = [trtexec, onnx_model_path, "--duration=50", "--percentile=90", "--workspace=4096"] + #command.extend([inputs_arg]) TODO: rebind IO inputs in TRT 8.2 + # add benchmarking flags model = onnx.load(model_path) if is_dynamic(model): command.extend([shapes_arg]) if fp16: command.extend(["--fp16"]) - out = get_output(command) + # save engine + engine_name = model_name + ".engine" + save_command = command + ["--saveEngine=" + engine_name] + logger.info(save_command) + out = get_output(save_command) + + # load engine and inference + load_command = command + ["--loadEngine=" + engine_name] + logger.info(load_command) + + trtexec = True + mem_usage = None + p = None + success = False + if track_memory: + p = start_memory_tracking() + try: + out = get_output(load_command) + success = True + mem_usage = end_memory_tracking(p, trtexec, success) + except Exception as e: + end_memory_tracking(p, trtexec, success) + raise(e) + else: + out = get_output(load_command) + + # parse trtexec output tmp = out.split("\n") target_list = [] for t in tmp: @@ -112,6 +130,9 @@ def run_trt_standalone(trtexec, model_path, ort_inputs, all_inputs_shape, fp16): percentile_match = re.search('percentile\(90%\) = (.*?) ms', target) if percentile_match: result["latency_90_percentile"] = percentile_match.group(1) # extract number + if mem_usage: + result["memory"] = mem_usage + logger.info(result) return result @@ -131,7 +152,6 @@ def get_latency_result(runtimes, batch_size): } return result - def get_ort_session_inputs_and_outputs(name, session, ort_input): sess_inputs = {} @@ -162,18 +182,17 @@ def get_ort_session_inputs_and_outputs(name, session, ort_input): sess_inputs[session.get_inputs()[0].name] = ort_input[0] sess_outputs = ['Identity:0'] - elif 'shufflenet-v2' in name.lower() or 'shufflenet_v2' in name.lower(): - sess_inputs[session.get_inputs()[0].name] = ort_input - else: sess_inputs = {} + sess_outputs = [] for i in range(len(session.get_inputs())): sess_inputs[session.get_inputs()[i].name] = ort_input[i] - + for i in range(len(session.get_outputs())): + sess_outputs.append(session.get_outputs()[i].name) return (sess_inputs, sess_outputs) def track_ep_memory(ep): - return trt in ep or cuda in ep or standalone_trt in ep + return cpu != ep def get_trtexec_pid(df, python_pid): for pid in df['pid'].tolist(): @@ -185,7 +204,6 @@ def get_max_memory(trtexec): pid = df['pid'].iloc[0] if trtexec: pid = get_trtexec_pid(df, pid) - mem_series = df.loc[df['pid'] == pid, ' used_gpu_memory [MiB]'] max_mem = max(mem_series.str.replace(' MiB','').astype(int)) return max_mem @@ -207,38 +225,66 @@ def end_memory_tracking(p, trtexec, success): os.remove(MEMORY_FILE) return mem_usage -def inference_ort(args, name, session, ep, ort_inputs, result_template, repeat_times, batch_size): +def inference_ort_with_ep(ep, session, repeat_times, sess_outputs, sess_inputs, io_binding): + if cpu in ep: + runtime = timeit.repeat(lambda: session.run(sess_outputs, sess_inputs), number=1, repeat=repeat_times) + else: # other eps utilize python binding + runtime = timeit.repeat(lambda: session.run_with_iobinding(io_binding), number=1, repeat=repeat_times) + success = True + return runtime, success + +def inference_ort(args, name, session, ep, ort_inputs, result_template, repeat_times, batch_size, track_memory): runtimes = [] if args.input_data == "random": repeat_times = 1 # warn-up run is included in ort_inputs else: repeat_times += 1 # add warn-up run + mem_usages = [] + p = None mem_usage = None + trtexec = False + success = False + + # get and load inputs and outputs for ort_input in ort_inputs: + io_binding = session.io_binding() sess_inputs, sess_outputs = get_ort_session_inputs_and_outputs(name, session, ort_input) if debug: logger.info("ORT session inputs:") logger.info(sess_inputs) logger.info("ORT session outputs:") logger.info(sess_outputs) - + for name, inp in sess_inputs.items(): + io_binding.bind_cpu_input(name, inp) + for out in sess_outputs: + io_binding.bind_output(out) + try: - runtime = timeit.repeat(lambda: session.run(sess_outputs, sess_inputs), number=1, repeat=repeat_times) + if track_memory: + p = start_memory_tracking() + runtime, success = inference_ort_with_ep(ep, session, repeat_times, sess_outputs, sess_inputs, io_binding) + mem_usage = end_memory_tracking(p, trtexec, success) + mem_usages.append(mem_usage) + else: + runtime, success = inference_ort_with_ep(ep, session, repeat_times, sess_outputs, sess_inputs, io_binding) runtimes += runtime[1:] # remove warmup except Exception as e: logger.error(e) - return None - - logger.info(runtimes) + if track_memory: + end_memory_tracking(p, trtexec, success) + raise(e) + if len(mem_usages) > 0: + mem_usage = max(mem_usages) + result = {} result.update(result_template) - result.update({"io_binding": False}) + result.update({"io_binding": True}) latency_result = get_latency_result(runtimes, batch_size) result.update(latency_result) - return result + return result, mem_usage def inference_ort_and_get_prediction(name, session, ort_inputs): @@ -287,7 +333,7 @@ def get_acl_version(): # inputs: [[test_data_0_input_0.pb, test_data_0_input_1.pb ...], [test_data_1_input_0.pb, test_data_1_input_1.pb ...] ...] # outputs: [[test_data_0_output_0.pb, test_data_0_output_1.pb ...], [test_data_1_output_0.pb, test_data_1_output_1.pb ...] ...] ####################################################################################################################################### -def load_onnx_model_zoo_test_data(path, all_inputs_shape, data_type="fp32"): +def load_onnx_model_zoo_test_data(path, all_inputs_shape, fp16): logger.info("Parsing test data in {} ...".format(path)) output = get_output(["find", path, "-name", "test_data*", "-type", "d"]) test_data_set_dir = split_and_sort_output(output) @@ -306,19 +352,21 @@ def load_onnx_model_zoo_test_data(path, all_inputs_shape, data_type="fp32"): pwd = os.getcwd() os.chdir(test_data_dir) - # load inputs + # load inputs and create bindings output = get_output(["find", ".", "-name", "input*"]) input_data = split_and_sort_output(output) logger.info(input_data) input_data_pb = [] + i = 0 for data in input_data: tensor = onnx.TensorProto() with open(data, 'rb') as f: tensor.ParseFromString(f.read()) tensor_to_array = numpy_helper.to_array(tensor) - if data_type == "fp16" and tensor_to_array.dtype == np.dtype(np.float32): + if fp16 and tensor_to_array.dtype == np.dtype(np.float32): tensor_to_array = tensor_to_array.astype(np.float16) + tensor_to_array.tofile(str(i) + ".bin") input_data_pb.append(tensor_to_array) if not shape_flag: all_inputs_shape.append(input_data_pb[-1].shape) @@ -340,7 +388,7 @@ def load_onnx_model_zoo_test_data(path, all_inputs_shape, data_type="fp32"): tensor_to_array = numpy_helper.to_array(tensor) - if data_type == "fp16" and tensor_to_array.dtype == np.dtype(np.float32): + if fp16 and tensor_to_array.dtype == np.dtype(np.float32): tensor_to_array = tensor_to_array.astype(np.float16) output_data_pb.append(tensor_to_array) @@ -349,7 +397,6 @@ def load_onnx_model_zoo_test_data(path, all_inputs_shape, data_type="fp32"): logger.info('Loaded {} outputs successfully.'.format(len(outputs))) os.chdir(pwd) - return inputs, outputs def generate_onnx_model_random_input(test_times, ref_input): @@ -458,6 +505,19 @@ def remove_profiling_files(path): continue subprocess.Popen(["rm","-rf", f], stdout=subprocess.PIPE) +def remove_files(path): + files = [] + out = get_output(["find", path, "-name", "onnxruntime_profile*"]) + ort_profiling_files = [] + out.split("\n") + out = get_output(["find", path, "-name", "*.profile"]) + profiling_files = [] + out.split("\n") + out = get_output(["find", path, "-name", "*.engine"]) + engine_files = [] + out.split("\n") + files = files + ort_profiling_files + profiling_files + engine_files + for f in files: + if "custom_test_data" in f: + continue + get_output(["rm","-rf", f]) def update_fail_report(fail_results, model, ep, e_type, e): result = {} @@ -683,10 +743,21 @@ def get_gpu_info(): infos = re.findall('NVIDIA.*', info) return infos +def get_cudnn_version(workspace): + cudnn_path = get_output(["whereis", "cudnn_version.h"]) + cudnn_path = re.search(': (.*)', cudnn_path).group(1) + cudnn_outputs = get_output(["cat", cudnn_path]) + major = re.search('CUDNN_MAJOR (.*)', cudnn_outputs).group(1) + minor = re.search('CUDNN_MINOR (.*)', cudnn_outputs).group(1) + patch = re.search('CUDNN_PATCHLEVEL (.*)', cudnn_outputs).group(1) + cudnn_version = major + '.' + minor + '.' + patch + return cudnn_version + def get_system_info(workspace): info = {} info["cuda"] = get_cuda_version() info["trt"] = get_trt_version(workspace) + info["cudnn"] = get_cudnn_version(workspace) info["linux_distro"] = get_linux_distro() info["cpu_info"] = get_cpu_info() info["gpu_info"] = get_gpu_info() @@ -825,13 +896,7 @@ def convert_model_from_float_to_float16(model_path): def get_test_data(fp16, test_data_dir, all_inputs_shape): inputs = [] ref_outputs = [] - - # read input/output of test data - if fp16: - inputs, ref_outputs = load_onnx_model_zoo_test_data(test_data_dir, all_inputs_shape, "fp16") - else: - inputs, ref_outputs = load_onnx_model_zoo_test_data(test_data_dir, all_inputs_shape) - + inputs, ref_outputs = load_onnx_model_zoo_test_data(test_data_dir, all_inputs_shape, fp16) return inputs, ref_outputs def run_symbolic_shape_inference(model_path, new_model_path): @@ -843,20 +908,23 @@ def run_symbolic_shape_inference(model_path, new_model_path): return True, None except Exception as e: logger.error(e) - return False, e + return False, "Symbolic shape inference error" def create_session(model_path, providers, session_options): logger.info(model_path) + try: session = onnxruntime.InferenceSession(model_path, providers=providers, sess_options=session_options) return session + except Exception as e: + # shape inference required on model if "shape inference" in str(e): logger.info("Using model from symbolic_shape_infer.py") new_model_path = model_path[:].replace(".onnx", "_new_by_trt_perf.onnx") if not os.path.exists(new_model_path): status = run_symbolic_shape_inference(model_path, new_model_path) - if not status[0]: + if not status[0]: # symbolic shape inference error e = status[1] raise Exception(e) session = onnxruntime.InferenceSession(new_model_path, providers=providers, sess_options=session_options) @@ -916,7 +984,7 @@ def run_onnxruntime(args, models): if skip_ep(name, ep, model_to_fail_ep): continue - if standalone_trt not in ep: + if not is_standalone(ep): ep_ = ep_to_provider_list[ep][0] if (ep_ not in onnxruntime.get_available_providers()): logger.error("No {} support".format(ep_)) @@ -926,11 +994,11 @@ def run_onnxruntime(args, models): test_data_dir = model_info["test_data_path"] fp16 = False - os.environ["ORT_TENSORRT_FP16_ENABLE"] = "1" if "fp16" in ep else "0" + os.environ["ORT_TENSORRT_FP16_ENABLE"] = "1" if "Fp16" in ep else "0" logger.info("[Initialize] model = {}, ep = {} ...".format(name, ep)) # use float16.py for cuda fp16 only - if "cuda_fp16" in ep: + if cuda_fp16 == ep: # handle model if "model_path_fp16" in model_info: @@ -950,8 +1018,11 @@ def run_onnxruntime(args, models): test_data_dir = model_info["test_data_path_fp16"] fp16 = False + if standalone_trt_fp16 == ep: + fp16 = True + + print(fp16) inputs, ref_outputs = get_test_data(fp16, test_data_dir, all_inputs_shape) - # generate random input data if args.input_data == "random": inputs = generate_onnx_model_random_input(args.test_times+1, inputs[0]) @@ -963,7 +1034,7 @@ def run_onnxruntime(args, models): logger.info("\n----------------------------- benchmark -------------------------------------") # resolve providers to create session - if standalone_trt in ep: + if is_standalone(ep): providers = ep_to_provider_list[trt] else: providers = ep_to_provider_list[ep] @@ -982,23 +1053,17 @@ def run_onnxruntime(args, models): continue # memory tracking variables - p = None # keep track of process to kill upon error + p = None mem_usage = None - + result = None + # get standalone TensorRT perf - if standalone_trt in ep and args.trtexec: + if is_standalone(ep) and args.trtexec: trtexec = True try: - if args.track_memory: - p = start_memory_tracking() - result = run_trt_standalone(args.trtexec, model_path, sess.get_inputs(), all_inputs_shape, fp16) - mem_usage = end_memory_tracking(p, trtexec, True) - else: - result = run_trt_standalone(args.trtexec, model_path, sess.get_inputs(), all_inputs_shape, fp16) + result = run_trt_standalone(args.trtexec, name, model_path, sess.get_inputs(), all_inputs_shape, fp16, args.track_memory) except Exception as e: logger.error(e) - if args.track_memory: - end_memory_tracking(p, trtexec, False) update_fail_model_map(model_to_fail_ep, name, ep, 'runtime error', e) continue @@ -1021,32 +1086,39 @@ def run_onnxruntime(args, models): "version": onnxruntime.__version__, "device": ep, "fp16": fp16, - "io_binding": False, + "io_binding": True, "model_name": name, "inputs": len(sess.get_inputs()), "batch_size": batch_size, "sequence_length": 1, "datetime": str(datetime.now()),} - - if args.track_memory and track_ep_memory(ep): - trtexec = False - p = start_memory_tracking() - result = inference_ort(args, name, sess, ep, inputs, result_template, args.test_times, batch_size) - success = True if result else False - mem_usage = end_memory_tracking(p, trtexec, success) - else: - result = inference_ort(args, name, sess, ep, inputs, result_template, args.test_times, batch_size) + + # run cpu fewer times + repeat_times = 100 if ep == cpu else args.test_times + track_memory = False if ep == cpu else args.track_memory + + # inference with ort + try: + result, mem_usage = inference_ort(args, name, sess, ep, inputs, result_template, repeat_times, batch_size, track_memory) + except Exception as e: + logger.error(e) + update_fail_model_map(model_to_fail_ep, name, ep, 'runtime error', e) + continue + if result: latency_result[ep] = {} latency_result[ep]["average_latency_ms"] = result["average_latency_ms"] latency_result[ep]["latency_90_percentile"] = result["latency_90_percentile"] + if "memory" in result: + mem_usage = result["memory"] if mem_usage: latency_result[ep]["memory"] = mem_usage - if not args.trtexec: # skip standalone success_results.append(result) model_to_latency[name] = copy.deepcopy(latency_result) + remove_files(model_info["working_directory"]) + logger.info("---------------------------- benchmark [end] ----------------------------------\n") @@ -1137,13 +1209,13 @@ def calculate_gain(value, ep1, ep2): def add_improvement_information(model_to_latency): for key, value in model_to_latency.items(): - if trt in value and cuda in value: + if "ORT-TRT" in value and "ORT-CUDA" in value: gain = calculate_gain(value, trt, cuda) value[trt_cuda_gain] = "{:.2f} %".format(gain) if trt_fp16 in value and cuda_fp16 in value: gain = calculate_gain(value, trt_fp16, cuda_fp16) value[trt_cuda_fp16_gain] = "{:.2f} %".format(gain) - if trt in value and standalone_trt in value: + if "ORT-TRT" in value and is_standalone(value): gain = calculate_gain(value, trt, standalone_trt) value[trt_native_gain] = "{:.2f} %".format(gain) if trt_fp16 in value and standalone_trt_fp16 in value: @@ -1226,15 +1298,7 @@ def output_status(results, csv_filename): need_write_header = False with open(csv_filename, mode="a", newline='') as csv_file: - column_names = ["Model", - cpu, - cuda + " fp32", - trt + " fp32", - standalone_trt + " fp32", - cuda + " fp16", - trt + " fp16", - standalone_trt + " fp16" - ] + column_names = table_headers csv_writer = csv.writer(csv_file) @@ -1279,37 +1343,32 @@ def output_status(results, csv_filename): standalone_fp16_status] csv_writer.writerow(row) + +def output_specs(info, csv_filename): + cpu_version = info['cpu_info'][2] + gpu_version = info['gpu_info'][0] + tensorrt_version = info['trt'] + ' , *All ORT-TRT and TRT are run in Mixed Precision mode (Fp16 and Fp32).' + cuda_version = info['cuda'] + cudnn_version = info['cudnn'] + + table = pd.DataFrame({'.': [1, 2, 3, 4, 5], + 'Spec': ['CPU', 'GPU', 'TensorRT', 'CUDA', 'CuDNN'], + 'Version': [cpu_version, gpu_version, tensorrt_version, cuda_version, cudnn_version]}) + table.to_csv(csv_filename, index=False) + def output_latency(results, csv_filename): need_write_header = True if os.path.exists(csv_filename): need_write_header = False with open(csv_filename, mode="a", newline='') as csv_file: - column_names = ["Model", - "CPU fp32 \nmean (ms)", - "CPU fp32 \n 90th percentile (ms)", - "CUDA fp32 \nmean (ms)", - "CUDA fp32 \n90th percentile (ms)", - "CUDA EP fp32 \npeak memory usage (MiB)", - "TRT EP fp32 \nmean (ms)", - "TRT EP fp32 \n90th percentile (ms)", - "TRT EP fp32 \npeak memory usage (MiB)", - "Standalone TRT fp32 \nmean (ms)", - "Standalone TRT fp32 \n90th percentile (ms)", - "Standalone TRT fp32 \npeak memory usage (MiB)", - "TRT v CUDA EP fp32 \ngain (mean) (%)", - "EP v Standalone TRT fp32 \ngain (mean) (%)", - "CUDA fp16 \nmean (ms)", - "CUDA fp16 \n90th percentile (ms)", - "CUDA EP fp16 \npeak memory usage (MiB)", - "TRT EP fp16 \nmean (ms)", - "TRT EP fp16 \n90th percentile (ms)", - "TRT EP fp16 \npeak memory usage (MiB)", - "Standalone TRT fp16 \nmean (ms)", - "Standalone TRT fp16 \n90th percentile (ms)", - "Standalone TRT fp16 \npeak memory usage (MiB)", - "TRT v CUDA EP fp16 \ngain (mean) (%)", - "EP v Standalone TRT fp16 \ngain (mean) (%)"] + column_names = [model_title] + for provider in provider_list: + column_names.append(provider + avg_ending) + column_names.append(provider + percentile_ending) + if cpu not in provider: + column_names.append(provider + memory_ending) + csv_writer = csv.writer(csv_file) if need_write_header: @@ -1408,8 +1467,6 @@ def output_latency(results, csv_filename): standalone_trt_average, standalone_trt_90_percentile, standalone_trt_memory, - value[trt_cuda_gain] if trt_cuda_gain in value else " ", - value[trt_native_gain] if trt_native_gain in value else " ", cuda_fp16_average, cuda_fp16_90_percentile, cuda_fp16_memory, @@ -1419,9 +1476,7 @@ def output_latency(results, csv_filename): standalone_trt_fp16_average, standalone_trt_fp16_90_percentile, standalone_trt_fp16_memory, - value[trt_cuda_fp16_gain] if trt_cuda_fp16_gain in value else " ", - value[trt_native_fp16_gain] if trt_native_fp16_gain in value else " " - ] + ] csv_writer.writerow(row) logger.info(f"CUDA/TRT latency comparison are saved to csv file: {csv_filename}") diff --git a/onnxruntime/python/tools/tensorrt/perf/benchmark_wrapper.py b/onnxruntime/python/tools/tensorrt/perf/benchmark_wrapper.py index 81a8551fd5..d2542c645c 100644 --- a/onnxruntime/python/tools/tensorrt/perf/benchmark_wrapper.py +++ b/onnxruntime/python/tools/tensorrt/perf/benchmark_wrapper.py @@ -7,6 +7,7 @@ import copy import json import re import pprint +from perf_utils import * from benchmark import * def write_model_info_to_file(model, path): @@ -51,6 +52,7 @@ def main(): benchmark_success_csv = 'success.csv' benchmark_latency_csv = 'latency.csv' benchmark_status_csv = 'status.csv' + specs_csv = 'specs.csv' for model, model_info in models.items(): logger.info("\n" + "="*40 + "="*len(model)) @@ -72,7 +74,7 @@ def main(): "--ep", ep, "--write_test_result", "false"] - if "Standalone" in ep: + if ep == standalone_trt or ep == standalone_trt_fp16: if args.running_mode == "validate": continue else: @@ -158,7 +160,7 @@ def main(): pretty_print(pp, model_to_latency) output_latency(model_to_latency, os.path.join(path, benchmark_latency_csv)) - logger.info("\nSaved model status results to {}".format(benchmark_latency_csv)) + logger.info("\nSaved model latency results to {}".format(benchmark_latency_csv)) logger.info("\n===========================================") logger.info("=========== System information ===========") @@ -166,6 +168,8 @@ def main(): info = get_system_info(args.workspace) pretty_print(pp, info) logger.info("\n") + output_specs(info, os.path.join(path, specs_csv)) + logger.info("\nSaved hardware specs to {}".format(specs_csv)) if __name__ == "__main__": main() diff --git a/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh b/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh index e994ef3916..88a0119e07 100755 --- a/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh +++ b/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh @@ -1,18 +1,19 @@ #!/bin/bash -while getopts o:p:b:i:t:c: parameter +while getopts o:p:b:i:t:v:c: parameter do case "${parameter}" in o) TRT_DOCKERFILE_PATH=${OPTARG};; p) PERF_DOCKERFILE_PATH=${OPTARG};; b) ORT_BRANCH=${OPTARG};; i) IMAGE_NAME=${OPTARG};; -t) TRT_VERSION=${OPTARG};; +t) TRT=${OPTARG};; +v) TRT_VERSION=${OPTARG};; c) CMAKE_CUDA_ARCHITECTURES=${OPTARG};; esac done IMAGE=onnxruntime -docker build --no-cache -t $IMAGE --build-arg CMAKE_CUDA_ARCHITECTURES=$CMAKE_CUDA_ARCHITECTURES --build-arg TRT_VERSION=$TRT_VERSION --build-arg ONNXRUNTIME_BRANCH=$ORT_BRANCH -f $TRT_DOCKERFILE_PATH . -docker build --no-cache --build-arg IMAGE=$IMAGE --build-arg CMAKE_CUDA_ARCHITECTURES=$CMAKE_CUDA_ARCHITECTURES --build-arg ONNXRUNTIME_BRANCH=$ORT_BRANCH --build-arg TRT_VERSION=$TRT_VERSION -t $IMAGE_NAME -f $PERF_DOCKERFILE_PATH . +docker build --no-cache -t $IMAGE --build-arg CMAKE_CUDA_ARCHITECTURES=$CMAKE_CUDA_ARCHITECTURES --build-arg TRT=$TRT --build-arg TRT_VERSION=$TRT_VERSION --build-arg ONNXRUNTIME_BRANCH=$ORT_BRANCH -f $TRT_DOCKERFILE_PATH . +docker build --no-cache --build-arg IMAGE=$IMAGE --build-arg CMAKE_CUDA_ARCHITECTURES=$CMAKE_CUDA_ARCHITECTURES --build-arg ONNXRUNTIME_BRANCH=$ORT_BRANCH --build-arg TRT_VERSION=$TRT_VERSION -t $IMAGE_NAME -f $PERF_DOCKERFILE_PATH . \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/build/checkout_trt.sh b/onnxruntime/python/tools/tensorrt/perf/build/checkout_trt.sh index accf14f2f4..20e51fba2e 100755 --- a/onnxruntime/python/tools/tensorrt/perf/build/checkout_trt.sh +++ b/onnxruntime/python/tools/tensorrt/perf/build/checkout_trt.sh @@ -1,13 +1,18 @@ #!/bin/bash -if [ ! "$1" = "8.0" ] +echo "$1" +if [ ! "$1" = "8.2" ] then CUR_PWD=$(pwd) cd cmake/external/onnx-tensorrt/ git remote update + if [ "$1" = "8.0" ] + then + git checkout "$1"'-GA' + fi if [ "$1" = "7.2" ] then git checkout "$1"'.1' fi cd $CUR_PWD -fi +fi \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/model_list.json b/onnxruntime/python/tools/tensorrt/perf/model_list.json index b400aae4b9..9b87cee0df 100644 --- a/onnxruntime/python/tools/tensorrt/perf/model_list.json +++ b/onnxruntime/python/tools/tensorrt/perf/model_list.json @@ -11,12 +11,36 @@ "model_path": "./resnet50v1/resnet50-v1-7.onnx", "test_data_path": "./resnet50v1/" }, + { + "model_name": "resnet101-v1-7", + "working_directory": "./onnx-zoo-models/resnet101-v1-7/", + "model_path": "./resnet101v1/resnet101-v1-7.onnx", + "test_data_path": "./resnet101v1/" + }, + { + "model_name": "resnet152-v1-7", + "working_directory": "./onnx-zoo-models/resnet152-v1-7/", + "model_path": "./resnet152v1/resnet152-v1-7.onnx", + "test_data_path": "./resnet152v1/" + }, { "model_name": "resnet18-v2-7", "working_directory": "./onnx-zoo-models/resnet18-v2-7/", "model_path": "./resnet18v2/resnet18-v2-7.onnx", "test_data_path": "./resnet18v2/" }, + { + "model_name": "resnet34-v2-7", + "working_directory": "./onnx-zoo-models/resnet34-v2-7/", + "model_path": "./resnet34v2/resnet34-v2-7.onnx", + "test_data_path": "./resnet34v2/" + }, + { + "model_name": "resnet50-v2-7", + "working_directory": "./onnx-zoo-models/resnet50-v2-7/", + "model_path": "./resnet50v2/resnet50-v2-7.onnx", + "test_data_path": "./resnet50v2/" + }, { "model_name": "resnet101-v2-7", "working_directory": "./onnx-zoo-models/resnet101-v2-7/", @@ -29,6 +53,12 @@ "model_path": "./resnet152v2/resnet152-v2-7.onnx", "test_data_path": "./resnet152v2/" }, + { + "model_name": "squeezenet1.1-7", + "working_directory": "./onnx-zoo-models/squeezenet1.1-7/", + "model_path": "./squeezenet1.1/squeezenet1.1.onnx", + "test_data_path": "./squeezenet1.1/" + }, { "model_name": "vgg16-7", "working_directory": "./onnx-zoo-models/vgg16-7/", @@ -47,6 +77,36 @@ "model_path": "./bvlc_alexnet/model.onnx", "test_data_path": "./bvlc_alexnet/" }, + { + "model_name": "googlenet-9", + "working_directory": "./onnx-zoo-models/googlenet-9/", + "model_path": "./bvlc_googlenet/model.onnx", + "test_data_path": "./bvlc_googlenet/" + }, + { + "model_name": "caffenet-9", + "working_directory": "./onnx-zoo-models/caffenet-9/", + "model_path": "./bvlc_reference_caffenet/model.onnx", + "test_data_path": "./bvlc_reference_caffenet/" + }, + { + "model_name": "rcnn-ilsvrc13-9", + "working_directory": "./onnx-zoo-models/rcnn-ilsvrc13-9/", + "model_path": "./bvlc_reference_rcnn_ilsvrc13/model.onnx", + "test_data_path": "./bvlc_reference_rcnn_ilsvrc13/" + }, + { + "model_name": "densenet-9", + "working_directory": "./onnx-zoo-models/densenet-9/", + "model_path": "./densenet121/model.onnx", + "test_data_path": "./densenet121/" + }, + { + "model_name": "inception-v1-9", + "working_directory": "./onnx-zoo-models/inception-v1-9/", + "model_path": "./inception_v1/model.onnx", + "test_data_path": "./inception_v1/" + }, { "model_name": "inception-v2-9", "working_directory": "./onnx-zoo-models/inception-v2-9/", @@ -59,12 +119,24 @@ "model_path": "./shufflenet/model.onnx", "test_data_path": "./shufflenet/" }, + { + "model_name": "shufflenet-v2-10", + "working_directory": "./onnx-zoo-models/shufflenet-v2-10/", + "model_path": "./model/test_shufflenetv2/model.onnx", + "test_data_path": "./model/test_shufflenetv2/" + }, { "model_name": "mnist-8", "working_directory": "./onnx-zoo-models/mnist-8/", "model_path": "./mnist/model.onnx", "test_data_path": "./mnist/" }, + { + "model_name": "tinyyolov2-8", + "working_directory": "./onnx-zoo-models/tinyyolov2-8/", + "model_path": "./tiny_yolov2/Model.onnx", + "test_data_path": "./tiny_yolov2/" + }, { "model_name": "ssd-10", "working_directory": "./onnx-zoo-models/ssd-10/", @@ -77,18 +149,6 @@ "model_path": "./ssd_mobilenet_v1/ssd_mobilenet_v1.onnx", "test_data_path": "./ssd_mobilenet_v1/" }, - { - "model_name": "FasterRCNN-10", - "working_directory": "./onnx-zoo-models/FasterRCNN-10/", - "model_path": "./faster_rcnn_R_50_FPN_1x.onnx", - "test_data_path": "./" - }, - { - "model_name": "MaskRCNN-10", - "working_directory": "./onnx-zoo-models/MaskRCNN-10/", - "model_path": "./mask_rcnn_R_50_FPN_1x.onnx", - "test_data_path": "./" - }, { "model_name": "retinanet-9", "working_directory": "./onnx-zoo-models/retinanet-9/", @@ -119,10 +179,46 @@ "model_path": "./ResNet101_DUC_HDC/ResNet101_DUC_HDC.onnx", "test_data_path": "./ResNet101_DUC_HDC/" }, + { + "model_name": "emotion-ferplus-8", + "working_directory": "./onnx-zoo-models/emotion-ferplus-8/", + "model_path": "./emotion_ferplus/model.onnx", + "test_data_path": "./emotion_ferplus/" + }, { "model_name": "bertsquad-10", "working_directory": "./onnx-zoo-models/bertsquad-10/", "model_path": "./bertsquad-10/bertsquad10.onnx", "test_data_path": "./bertsquad-10/" + }, + { + "model_name": "gpt2-lm-head-10", + "working_directory": "./onnx-zoo-models/gpt2-lm-head-10/", + "model_path": "./GPT-2-LM-HEAD/model.onnx", + "test_data_path": "./GPT-2-LM-HEAD/" + }, + { + "model_name": "gpt2-10", + "working_directory": "./onnx-zoo-models/gpt2-10/", + "model_path": "./GPT2/model.onnx", + "test_data_path": "./GPT2/" + }, + { + "model_name": "zfnet512-9", + "working_directory": "./onnx-zoo-models/zfnet512-9/", + "model_path": "./zfnet512/model.onnx", + "test_data_path": "./zfnet512/" + }, + { + "model_name": "arcfaceresnet100-8", + "working_directory": "./onnx-zoo-models/arcfaceresnet100-8/", + "model_path": "./resnet100/resnet100.onnx", + "test_data_path": "./resnet100/" + }, + { + "model_name": "mosaic-9", + "working_directory": "./onnx-zoo-models/mosaic-9/", + "model_path": "./mosaic/mosaic.onnx", + "test_data_path": "./mosaic/" } -] +] \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/perf.sh b/onnxruntime/python/tools/tensorrt/perf/perf.sh index 9d642cae1c..a30028bfdb 100755 --- a/onnxruntime/python/tools/tensorrt/perf/perf.sh +++ b/onnxruntime/python/tools/tensorrt/perf/perf.sh @@ -55,4 +55,4 @@ setup() { setup python3 benchmark_wrapper.py -r validate -m $MODEL_PATH -o result/$OPTION -w $WORKSPACE $RUN_EPS -python3 benchmark_wrapper.py -r benchmark -t 10 -m $MODEL_PATH -o result/$OPTION -w $WORKSPACE $RUN_EPS +python3 benchmark_wrapper.py -r benchmark -t 1200 -m $MODEL_PATH -o result/$OPTION -w $WORKSPACE $RUN_EPS diff --git a/onnxruntime/python/tools/tensorrt/perf/perf_utils.py b/onnxruntime/python/tools/tensorrt/perf/perf_utils.py index dc99749d0f..08528147fe 100644 --- a/onnxruntime/python/tools/tensorrt/perf/perf_utils.py +++ b/onnxruntime/python/tools/tensorrt/perf/perf_utils.py @@ -9,6 +9,37 @@ import sys debug = False debug_verbose = False +# ORT ep names +cpu_ep = "CPUExecutionProvider" +cuda_ep = "CUDAExecutionProvider" +trt_ep = "TensorrtExecutionProvider" +acl_ep = "ACLExecutionProvider" + +# provider names +cpu = "ORT-CPUFp32" +cuda = "ORT-CUDAFp32" +cuda_fp16 = "ORT-CUDAFp16" +trt = "ORT-TRTFp32" +trt_fp16 = "ORT-TRTFp16" +standalone_trt = "TRTFp32" +standalone_trt_fp16 = "TRTFp16" +acl = "ORT-ACLFp32" + +# column names +model_title = 'Model' +group_title = 'Group' + +# endings +avg_ending = ' \nmean (ms)' +percentile_ending = ' \n90th percentile (ms)' +memory_ending = ' \npeak memory usage (MiB)' + +provider_list = [cpu, cuda, trt, standalone_trt, cuda_fp16, trt_fp16, standalone_trt_fp16] +table_headers = [model_title] + provider_list + +def is_standalone(ep): + return ep == standalone_trt or ep == standalone_trt_fp16 + def get_output(command): p = subprocess.run(command, check=True, stdout=subprocess.PIPE) output = p.stdout.decode("ascii").strip() @@ -203,7 +234,6 @@ def calculate_trt_latency_percentage(trt_op_map): return (total_trt_execution_time, total_execution_time, ratio_of_trt_execution_time) - def get_profile_metrics(path, profile_already_parsed, logger=None): logger.info("Parsing/Analyzing profiling files in {} ...".format(path)) p1 = subprocess.Popen(["find", path, "-name", "onnxruntime_profile*", "-printf", "%T+\t%p\n"], stdout=subprocess.PIPE) @@ -230,5 +260,4 @@ def get_profile_metrics(path, profile_already_parsed, logger=None): logger.info("No profile metrics got.") return None - return data[-1] - + return data[-1] \ No newline at end of file diff --git a/onnxruntime/python/tools/tensorrt/perf/post.py b/onnxruntime/python/tools/tensorrt/perf/post.py index 6433a263a6..6285a64772 100644 --- a/onnxruntime/python/tools/tensorrt/perf/post.py +++ b/onnxruntime/python/tools/tensorrt/perf/post.py @@ -1,16 +1,22 @@ import argparse -import mysql.connector import sys import os import pandas as pd -from sqlalchemy import create_engine +import time +from datetime import datetime, timedelta +from azure.kusto.data import KustoConnectionStringBuilder +from azure.kusto.data.helpers import dataframe_from_result_table +from azure.kusto.ingest import ( + IngestionProperties, + DataFormat, + ReportLevel, + QueuedIngestClient, +) +from perf_utils import * # database connection strings -sql_connector = 'mysql+mysqlconnector://' -user='ort@onnxruntimedashboard' -password=os.environ.get('DASHBOARD_MYSQL_ORT_PASSWORD') -host='onnxruntimedashboard.mysql.database.azure.com' -database='onnxruntime' +cluster_ingest = "https://ingest-onnxruntimedashboarddb.southcentralus.kusto.windows.net" +database = "ep_perf_dashboard" # table names fail = 'fail' @@ -18,7 +24,10 @@ memory = 'memory' latency = 'latency' status = 'status' latency_over_time = 'latency_over_time' - +specs = 'specs' + +time_string_format = '%Y-%m-%d %H:%M:%S' + def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument( @@ -37,106 +46,83 @@ def parse_csv(report_file): table = pd.read_csv(report_file) return table -def get_latency_over_time(commit_hash, report_url, branch, latency_table): - if not latency_table.empty: - to_drop = ['TrtGain_CudaFp32', 'EpGain_TrtFp32', 'TrtGain_CudaFp16', 'EpGain_TrtFp16'] - over_time = latency_table.drop(to_drop, axis='columns') - over_time = over_time.melt(id_vars=['Model', 'Group'], var_name='Ep', value_name='Latency') - over_time = over_time.assign(CommitId=commit_hash) - over_time = over_time.assign(ReportUrl=report_url) - over_time = over_time.assign(Branch=branch) - over_time = over_time[['CommitId', 'Model', 'Ep', 'Latency', 'ReportUrl', 'Group', 'Branch']] - over_time.rename(columns={"Group":"ModelGroup"}, inplace=True) - over_time.fillna('', inplace=True) - return over_time - def adjust_columns(table, columns, db_columns, model_group): table = table[columns] table = table.set_axis(db_columns, axis=1) table = table.assign(Group=model_group) return table +def get_latency_over_time(commit_hash, report_url, branch, latency_table): + if not latency_table.empty: + over_time = latency_table + over_time = over_time.melt(id_vars=[model_title, group_title], var_name='Ep', value_name='Latency') + over_time = over_time.assign(CommitId=commit_hash) + over_time = over_time.assign(ReportUrl=report_url) + over_time = over_time.assign(Branch=branch) + over_time = over_time[['CommitId', model_title, 'Ep', 'Latency', 'ReportUrl', group_title, 'Branch']] + over_time.fillna('', inplace=True) + return over_time + def get_failures(fail, model_group): fail_columns = fail.keys() - fail_db_columns = ['Model', 'Ep', 'ErrorType', 'ErrorMessage'] + fail_db_columns = [model_title, 'Ep', 'ErrorType', 'ErrorMessage'] fail = adjust_columns(fail, fail_columns, fail_db_columns, model_group) return fail def get_memory(memory, model_group): - memory_columns = ['Model', \ - 'CUDA EP fp32 \npeak memory usage (MiB)', \ - 'TRT EP fp32 \npeak memory usage (MiB)', \ - 'Standalone TRT fp32 \npeak memory usage (MiB)', \ - 'CUDA EP fp16 \npeak memory usage (MiB)', \ - 'TRT EP fp16 \npeak memory usage (MiB)', \ - 'Standalone TRT fp16 \npeak memory usage (MiB)' \ - ] - memory_db_columns = ['Model', 'CudaFp32', 'TrtFp32', 'StandaloneFp32', 'CudaFp16', 'TrtFp16', 'StandaloneFp16'] + memory_columns = [model_title] + for provider in provider_list: + if cpu not in provider: + memory_columns.append(provider + memory_ending) + memory_db_columns = [model_title, cuda, trt, standalone_trt, cuda_fp16, trt_fp16, standalone_trt_fp16] memory = adjust_columns(memory, memory_columns, memory_db_columns, model_group) return memory def get_latency(latency, model_group): - latency_columns = ['Model', \ - 'CPU fp32 \nmean (ms)', \ - 'CUDA fp32 \nmean (ms)', \ - 'TRT EP fp32 \nmean (ms)', \ - 'Standalone TRT fp32 \nmean (ms)', \ - 'TRT v CUDA EP fp32 \ngain (mean) (%)', \ - 'EP v Standalone TRT fp32 \ngain (mean) (%)', - 'CUDA fp16 \nmean (ms)', \ - 'TRT EP fp16 \nmean (ms)', \ - 'Standalone TRT fp16 \nmean (ms)', \ - 'TRT v CUDA EP fp16 \ngain (mean) (%)', \ - 'EP v Standalone TRT fp16 \ngain (mean) (%)' \ - ] - latency_db_columns = ['Model', 'CpuFp32', 'CudaEpFp32', 'TrtEpFp32', 'StandaloneFp32', 'TrtGain_CudaFp32', 'EpGain_TrtFp32', \ - 'CudaEpFp16', 'TrtEpFp16', 'StandaloneFp16', 'TrtGain_CudaFp16', 'EpGain_TrtFp16'] + latency_columns = [model_title] + for provider in provider_list: + latency_columns.append(provider + avg_ending) + latency_db_columns = table_headers latency = adjust_columns(latency, latency_columns, latency_db_columns, model_group) return latency def get_status(status, model_group): status_columns = status.keys() - status_db_columns = ['Model', 'CpuFp32', 'CudaEpFp32', 'TrtEpFp32', 'StandaloneFp32', 'CudaEpFp16', 'TrtEpFp16', 'StandaloneFp16'] + status_db_columns = table_headers status = adjust_columns(status, status_columns, status_db_columns, model_group) return status -def delete_old_records(engine, table_name): +def get_specs(specs, branch, commit_id): + specs = specs.append({'.': 6, 'Spec': 'Branch', 'Version' : branch}, ignore_index=True) + specs = specs.append({'.': 7, 'Spec': 'CommitId', 'Version' : commit_id}, ignore_index=True) + return specs - # delete using cursor for large table - conn = engine.raw_connection() - cursor = conn.cursor() - delete_query = ('DELETE FROM onnxruntime.' + table_name + ' ' - 'WHERE UploadTime < DATE_SUB(Now(), INTERVAL 100 DAY);' - ) - cursor.execute(delete_query) - conn.commit() - cursor.close() - conn.close() - -def write_table(engine, table, table_name, trt_version, upload_time): - delete_old_records(engine, table_name) +def write_table(ingest_client, table, table_name, trt_version, upload_time): if table.empty: return table = table.assign(TrtVersion=trt_version) # add TrtVersion table = table.assign(UploadTime=upload_time) # add UploadTime - table.to_sql(table_name, con=engine, if_exists='append', index=False, chunksize=1) + ingestion_props = IngestionProperties( + database=database, + table=table_name, + data_format=DataFormat.CSV, + report_level=ReportLevel.FailuresAndSuccesses + ) + # append rows + ingest_client.ingest_from_dataframe(table, ingestion_properties=ingestion_props) + +def get_time(): + date_time = time.strftime(time_string_format) + return date_time -def get_time(): - import time - datetime = time.strftime('%Y-%m-%d %H:%M:%S') - return datetime - def main(): - # connect to database args = parse_arguments() - connection_string = sql_connector + \ - user + ':' + \ - password + \ - '@' + host + '/' + \ - database - engine = create_engine(connection_string) - datetime = get_time() + + # connect to database + kcsb_ingest = KustoConnectionStringBuilder.with_az_cli_authentication(cluster_ingest) + ingest_client = QueuedIngestClient(kcsb_ingest) + date_time = get_time() try: result_file = args.report_folder @@ -144,7 +130,7 @@ def main(): folders = os.listdir(result_file) os.chdir(result_file) - tables = [fail, memory, latency, status, latency_over_time] + tables = [fail, memory, latency, status, latency_over_time, specs] table_results = {} for table_name in tables: table_results[table_name] = pd.DataFrame() @@ -154,6 +140,8 @@ def main(): csv_filenames = os.listdir() for csv in csv_filenames: table = parse_csv(csv) + if specs in csv: + table_results[specs] = table_results[specs].append(get_specs(table, args.branch, args.commit_hash), ignore_index=True) if fail in csv: table_results[fail] = table_results[fail].append(get_failures(table, model_group), ignore_index=True) if latency in csv: @@ -164,9 +152,9 @@ def main(): table_results[status] = table_results[status].append(get_status(table, model_group), ignore_index=True) os.chdir(result_file) for table in tables: - print('writing ' + table + ' over time to database') + print('writing ' + table + ' to database') db_table_name = 'ep_model_' + table - write_table(engine, table_results[table], db_table_name, args.trt_version, datetime) + write_table(ingest_client, table_results[table], db_table_name, args.trt_version, date_time) except BaseException as e: print(str(e)) diff --git a/onnxruntime/python/tools/tensorrt/perf/run_perf_docker.sh b/onnxruntime/python/tools/tensorrt/perf/run_perf_docker.sh index ba39655982..bbfe0ca2aa 100755 --- a/onnxruntime/python/tools/tensorrt/perf/run_perf_docker.sh +++ b/onnxruntime/python/tools/tensorrt/perf/run_perf_docker.sh @@ -1,7 +1,7 @@ #!/bin/bash # Parse Arguments -while getopts d:o:m:p:e: parameter +while getopts d:o:m:p:e:v: parameter do case "${parameter}" in d) DOCKER_IMAGE=${OPTARG};; @@ -9,6 +9,7 @@ o) OPTION=${OPTARG};; m) MODEL_PATH=${OPTARG};; p) PERF_DIR=${OPTARG};; e) EP_LIST=${OPTARG};; +v) MODEL_VOLUME=${OPTARG};; esac done @@ -18,4 +19,4 @@ HOME_PERF_DIR='/home/hcsuser/perf/' WORKSPACE='/' MODEL_PATH=$WORKSPACE$MODEL_PATH -docker run --gpus all -v $PERF_DIR:$DOCKER_PERF_DIR -v $HOME_PERF_DIR$OPTION:$DOCKER_PERF_DIR$OPTION $DOCKER_IMAGE /bin/bash $DOCKER_PERF_DIR'perf.sh' -d $DOCKER_PERF_DIR -o $OPTION -m $MODEL_PATH -w $WORKSPACE -e "$EP_LIST" +docker run --gpus all -v $PERF_DIR:$DOCKER_PERF_DIR -v $MODEL_VOLUME/$OPTION:/perf/$OPTION $DOCKER_IMAGE /bin/bash $DOCKER_PERF_DIR'perf.sh' -d $DOCKER_PERF_DIR -o $OPTION -m $MODEL_PATH -w $WORKSPACE -e "$EP_LIST" \ No newline at end of file diff --git a/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-daily-perf-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-daily-perf-pipeline.yml new file mode 100644 index 0000000000..6b18a83e93 --- /dev/null +++ b/tools/ci_build/github/azure-pipelines/linux-gpu-tensorrt-daily-perf-pipeline.yml @@ -0,0 +1,176 @@ +parameters: + +- name: BuildORT + displayName: Build ORT + type: boolean + default: true + +- name: PostToDashboard + displayName: Post to Dashboard + type: boolean + default: true + +- name: RunNvidiaContainer + displayName: Run in Nvidia Container (or set trtContainer Variable) + type: boolean + default: true + +- name: RunDocker + displayName: Run on Docker + type: boolean + default: true + +- name: TrtVersion + displayName: TensorRT Version + type: string + default: 8.2.1.8 + values: + - 8.2.1.8 + - 8.0.1.6 + - 7.2.3.4 + +- name: ConfigureEPs + displayName: Configure EPs (set epList variable - separate by spaces) + type: boolean + default: false + +- name: PublishWheel + displayName: Publish Wheel + type: boolean + default: false + +- name: ModelGroups + type: object + default: + - "onnx-zoo-models" + - "partner-models" + +- name: MemTest + displayName: Run Memory Test + type: boolean + default: false + +jobs: +- job: 'Onnxruntime_Linux_GPU_TensorRT_Perf' + workspace: + clean: all + timeoutInMinutes: 3000 + pool: 'Onnxruntime-Linux-GPU-TensorRT-Perf' + + variables: + - name: trt_dockerfile + ${{ if eq(parameters.TrtVersion, '8.2.1.8') }}: + value: Dockerfile.ubuntu_cuda11_4_tensorrt8_2 + ${{ if eq(parameters.TrtVersion, '8.0.1.6') }}: + value: Dockerfile.ubuntu_cuda11_4_tensorrt8_0 + ${{ if eq(parameters.TrtVersion, '7.2.3.4') }}: + value: Dockerfile.ubuntu_cuda11_4_tensorrt7_2 + + - name: trtContainer + ${{ if eq(parameters.TrtVersion, '8.2.1.8') }}: + value: 21.12 + ${{ if eq(parameters.TrtVersion, '8.0.1.6') }}: + value: 21.07 + ${{ if eq(parameters.TrtVersion, '7.2.3.4') }}: + value: 20.12 + + - name: anubis_image + value: ort-master-py38 + + - name: build_args + ${{ if eq(parameters.RunNvidiaContainer, true) }}: + value: Dockerfile.tensorrt-perf -t $(trtContainer) -v ${{parameters.TrtVersion}} -o $(Build.SourcesDirectory)/dockerfiles/Dockerfile.tensorrt + ${{ if ne(parameters.RunNvidiaContainer, true) }}: + value: Dockerfile.custom-trt-perf -t ${{ parameters.TrtVersion }} -o $(Build.SourcesDirectory)/tools/ci_build/github/linux/docker/$(trt_dockerfile) + + - name: environment + ${{ if eq(parameters.RunDocker, true) }}: + value: docker.sh -d ort-$(branch) -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf -v $(modelVolume) + ${{ if ne(parameters.RunDocker, true) }}: + value: machine.sh + + - name: with_arguments + value: $(environment) -e "$(epList)" + + steps: + + - ${{ if eq(parameters.BuildORT, true) }}: + + - ${{ if eq(parameters.RunDocker, true) }}: + - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/build_image.sh -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/$(build_args) -b $(branch) -i ort-$(branch) -c 75' + displayName: 'Build latest ORT Image' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' + + - ${{ if ne(parameters.RunDocker, true) }}: + - script: 'python3 $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/ort_build_latest.py -b $(branch) -c /usr/local/cuda -o ~/repos/onnxruntime/ -t ${{ parameters.TrtVersion }}' + displayName: 'Build latest ORT' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' + + - ${{ if eq(parameters.PublishWheel, true) }}: + + - script: 'docker build --build-arg IMAGE=ort-master -t $(anubis_image) -f $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build/Dockerfile.python38 .' + displayName: 'Build Python 3.8 Images' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/build' + + - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis/copy_wheel.sh -t $(trtContainer) -i $(anubis_image)' + displayName: 'Copy Wheel from Docker' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis' + + - script: 'OUTPUT=$(ls dist) && az storage blob upload --account-name anubiscustomerstorage --account-key $(account-key) --container-name upload --file $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/dist/*.whl --name ort-trt-ep/$(Build.BuildNumber)/$OUTPUT' + displayName: 'Upload Wheel File' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' + + - task: PowerShell@2 + inputs: + filePath: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/anubis/start_job.ps1' + arguments: '-file_folder $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/dist -account_key $(account-key) -trt_container $(trtContainer) -csc $(csc)' + displayName: 'Start Anubis Job' + + - ${{ each option in parameters.ModelGroups }}: + - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/run_perf_$(with_arguments) -o ${{option}} -m $(${{option}})' + displayName: '${{option}} perf' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' + + - ${{ if eq(parameters.MemTest, true) }}: + - script: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/run_mem_test_docker.sh -d ort-$(branch) -p $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/ -w /code/ -l false' + displayName: 'Run Memory Test' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/' + + # Prepare and Publish Artifacts + + - script: 'mkdir $(Build.SourcesDirectory)/Artifact' + displayName: 'Prepare Artifacts Directory' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' + condition: always() + + - ${{ if not(eq(length(parameters.ModelGroups), 0)) }}: + - script: 'cp -r $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/result/ $(Build.SourcesDirectory)/Artifact' + displayName: 'Copy Artifacts' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' + + - ${{ if eq(parameters.MemTest, true) }}: + - script: 'cp -r $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/mem_test/build/result $(Build.SourcesDirectory)/Artifact/result_mem_test' + displayName: 'Copy Artifacts' + workingDirectory: '$(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/' + condition: always() + + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(Build.SourcesDirectory)/Artifact' + artifactName: 'result-$(Build.BuildNumber)' + + - ${{ if eq(parameters.PostToDashboard, true) }}: + + - script: 'python3 -m pip install pandas azure-kusto-data[pandas] azure-kusto-ingest[pandas] coloredlogs' + displayName: 'Install dashboard dependencies' + + - task: AzureCLI@2 + displayName: 'Azure CLI Post to Dashboard' + inputs: + azureSubscription: AIInfraBuildOnnxRuntimeOSS + scriptLocation: inlineScript + scriptType: bash + inlineScript: | + python3 $(Build.SourcesDirectory)/onnxruntime/python/tools/tensorrt/perf/post.py -r $(Build.SourcesDirectory)/Artifact/result -c $(Build.SourceVersion) -u "https://dev.azure.com/onnxruntime/onnxruntime/_build/results?buildId=$(Build.BuildId)" -t ${{ parameters.TrtVersion }} -b $(branch) + + - template: templates/clean-agent-build-directory-step.yml \ No newline at end of file diff --git a/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_cuda11_4_tensorrt8_2 b/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_cuda11_4_tensorrt8_2 new file mode 100644 index 0000000000..cb77c414be --- /dev/null +++ b/tools/ci_build/github/linux/docker/Dockerfile.ubuntu_cuda11_4_tensorrt8_2 @@ -0,0 +1,35 @@ +# -------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +# -------------------------------------------------------------- +# Dockerfile to run ONNXRuntime with TensorRT integration + +ARG OS_VERSION=20.04 +FROM nvidia/cuda:11.4.2-cudnn8-devel-ubuntu${OS_VERSION} + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update &&\ + apt-get install -y sudo git bash unattended-upgrades wget +RUN unattended-upgrade + +# Install python3 +RUN apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + python3-wheel &&\ + cd /usr/local/bin &&\ + ln -s /usr/bin/python3 python &&\ + ln -s /usr/bin/pip3 pip; + +RUN pip install --upgrade pip +RUN pip install setuptools>=41.0.0 + +# Install TensorRT +RUN v="8.2.1-1+cuda11.4" &&\ + apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub &&\ + apt-get update &&\ + sudo apt-get install -y libnvinfer8=${v} libnvonnxparsers8=${v} libnvparsers8=${v} libnvinfer-plugin8=${v} \ + libnvinfer-dev=${v} libnvonnxparsers-dev=${v} libnvparsers-dev=${v} libnvinfer-plugin-dev=${v} \ + python3-libnvinfer=${v} \ No newline at end of file From fb4dea39e2c1635325ea4eb39c586d073daa9973 Mon Sep 17 00:00:00 2001 From: Chen Fu <1316708+chenfucn@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:31:56 -0800 Subject: [PATCH 110/113] Tolerate cpuinfo init failure (#10199) Tolerate pytorch cpuinfo library init failure. --- onnxruntime/core/common/cpuid_info.cc | 30 +++++++++++++++++++++------ onnxruntime/core/common/cpuid_info.h | 3 +++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/onnxruntime/core/common/cpuid_info.cc b/onnxruntime/core/common/cpuid_info.cc index 57c5327c93..842e260c8b 100644 --- a/onnxruntime/core/common/cpuid_info.cc +++ b/onnxruntime/core/common/cpuid_info.cc @@ -18,8 +18,21 @@ #endif #endif +#if defined(CPUIDINFO_ARCH_ARM) && defined(CPUINFO_SUPPORTED) +#include +#include +// N.B. Support building with older versions of asm/hwcap.h that do not define +// this capability bit. +#ifndef HWCAP_ASIMDDP +#define HWCAP_ASIMDDP (1 << 20) +#endif + +#endif + #include #include "core/common/cpuid_info.h" +#include "core/common/logging/logging.h" +#include "core/common/logging/severity.h" #if _WIN32 #define HAS_WINDOWS_DESKTOP WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) @@ -57,10 +70,10 @@ CPUIDInfo CPUIDInfo::instance_; CPUIDInfo::CPUIDInfo() { #if (defined(CPUIDINFO_ARCH_X86) || defined(CPUIDINFO_ARCH_ARM)) && defined(CPUINFO_SUPPORTED) - if (!cpuinfo_initialize()) { - // Unfortunately we can not capture cpuinfo log!! - ORT_THROW("Failed to initialize CPU info."); - } + pytorch_cpuinfo_init_ = cpuinfo_initialize(); + if (!pytorch_cpuinfo_init_) { + LOGS_DEFAULT(WARNING) << "Failed to init pytorch cpuinfo library, may cause CPU EP performance degradation due to undetected CPU features."; + } #endif #if defined(CPUIDINFO_ARCH_X86) @@ -99,8 +112,13 @@ CPUIDInfo::CPUIDInfo() { #ifdef CPUINFO_SUPPORTED // only works on ARM linux or android, does not work on Windows - is_hybrid_ = cpuinfo_get_uarchs_count() > 1; - has_arm_neon_dot_ = cpuinfo_has_arm_neon_dot(); + if (pytorch_cpuinfo_init_) { + is_hybrid_ = cpuinfo_get_uarchs_count() > 1; + has_arm_neon_dot_ = cpuinfo_has_arm_neon_dot(); + } else { + has_arm_neon_dot_ = ((getauxval(AT_HWCAP) & HWCAP_ASIMDDP) != 0); + } + #elif defined(_WIN32) // TODO implement hardware feature detection in windows. is_hybrid_ = true; diff --git a/onnxruntime/core/common/cpuid_info.h b/onnxruntime/core/common/cpuid_info.h index 5580446f4d..754cc2e023 100644 --- a/onnxruntime/core/common/cpuid_info.h +++ b/onnxruntime/core/common/cpuid_info.h @@ -37,6 +37,9 @@ class CPUIDInfo { bool has_sse4_1_{false}; bool is_hybrid_{false}; +#if (defined(CPUIDINFO_ARCH_X86) || defined(CPUIDINFO_ARCH_ARM)) && defined(CPUINFO_SUPPORTED) + bool pytorch_cpuinfo_init_{false}; +#endif bool has_arm_neon_dot_{false}; static CPUIDInfo instance_; From 79d2a0d18572397198553e17d046568877aa502b Mon Sep 17 00:00:00 2001 From: RandySheriffH <48490400+RandySheriffH@users.noreply.github.com> Date: Tue, 11 Jan 2022 17:26:41 -0800 Subject: [PATCH 111/113] Dynamic cost model to mitigate high E2E perf variance (#9833) * commit dyamic block size * summarize granularity * add configure * add test case * call std stoi * add comments * fix typo * rename var * update comment * reset default * better comments * extend LoopCounter for dynamic blocking * fix comments and add more UT * update comments * swtich type to std::ptrdiff_t * format code with better indention * cast ptrdiff_t * fix typo --- .../onnxruntime_session_options_config_keys.h | 9 ++ onnxruntime/core/common/threadpool.cc | 76 ++++++---- onnxruntime/core/platform/env.h | 1 + onnxruntime/core/session/inference_session.cc | 5 + onnxruntime/core/util/thread_utils.cc | 1 + onnxruntime/core/util/thread_utils.h | 3 + onnxruntime/test/platform/threadpool_test.cc | 131 ++++++++++++++---- 7 files changed, 169 insertions(+), 57 deletions(-) diff --git a/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h b/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h index 853a3ad09d..916ea586b4 100644 --- a/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h +++ b/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h @@ -96,3 +96,12 @@ static const char* const kOrtSessionOptionsConfigSaveRuntimeOptimizations = "opt // If not specified, the default set of stop ops is used. To specify an empty stop ops types list and disable stop op // exclusion, set the value to "". static const char* const kOrtSessionOptionsConfigNnapiEpPartitioningStopOps = "ep.nnapi.partitioning_stop_ops"; + +// Enabling dynamic block-sizing for multithreading. +// With a positive value, thread pool will split a task of N iterations to blocks of size starting from: +// N / (num_of_threads * dynamic_block_base) +// As execution progresses, the size will decrease according to the diminishing residual of N, +// meaning the task will be distributed in smaller granularity for better parallelism. +// For some models, it helps to reduce the variance of E2E inference latency and boost performane. +// The feature will not function by default, specify any positive integer, e.g. "4", to enable it. +static const char* const kOrtSessionOptionsConfigDynamicBlockBase = "session.dynamic_block_base"; \ No newline at end of file diff --git a/onnxruntime/core/common/threadpool.cc b/onnxruntime/core/common/threadpool.cc index 8357388884..4dc42beb5c 100644 --- a/onnxruntime/core/common/threadpool.cc +++ b/onnxruntime/core/common/threadpool.cc @@ -261,13 +261,12 @@ struct alignas(CACHE_LINE_BYTES) LoopCounterShard { }; static_assert(sizeof(LoopCounterShard) == CACHE_LINE_BYTES, "Expected loop counter shards to match cache-line size"); - + class alignas(CACHE_LINE_BYTES) LoopCounter { public: LoopCounter(uint64_t num_iterations, uint64_t d_of_p, - uint64_t block_size = 1) : _block_size(block_size), - _num_shards(GetNumShards(num_iterations, + uint64_t block_size = 1) : _num_shards(GetNumShards(num_iterations, d_of_p, block_size)) { // Divide the iteration space between the shards. If the iteration @@ -308,14 +307,15 @@ class alignas(CACHE_LINE_BYTES) LoopCounter { bool ClaimIterations(unsigned my_home_shard, unsigned& my_shard, uint64_t& my_start, - uint64_t& my_end) { + uint64_t& my_end, + uint64_t block_size) { do { if (_shards[my_shard]._next < _shards[my_shard]._end) { // Appears to be work in the current shard, try to claim with atomic fetch-and-add - uint64_t temp_start = _shards[my_shard]._next.fetch_add(_block_size); + uint64_t temp_start = _shards[my_shard]._next.fetch_add(block_size); if (temp_start < _shards[my_shard]._end) { my_start = temp_start; - my_end = std::min(_shards[my_shard]._end, temp_start + _block_size); + my_end = std::min(_shards[my_shard]._end, temp_start + block_size); return true; } } @@ -357,7 +357,6 @@ class alignas(CACHE_LINE_BYTES) LoopCounter { } alignas(CACHE_LINE_BYTES) LoopCounterShard _shards[MAX_SHARDS]; - const uint64_t _block_size; const unsigned _num_shards; }; @@ -403,29 +402,50 @@ void ThreadPool::ParallelForFixedBlockSizeScheduling(const std::ptrdiff_t total, return; } - // Split the work across threads in the pool. Each work item will run a loop claiming iterations, - // hence we need at most one for each thread, even if the numberof blocks of iterations is larger. auto d_of_p = DegreeOfParallelism(this); - auto num_blocks = total / block_size; - auto num_threads_inc_main = NumThreads() + 1; - int num_work_items = static_cast(std::min(static_cast(num_threads_inc_main), num_blocks)); - assert(num_work_items > 0); + if (thread_options_.dynamic_block_base_ <= 0) { + // Split the work across threads in the pool. Each work item will run a loop claiming iterations, + // hence we need at most one for each thread, even if the number of blocks of iterations is larger. + auto num_blocks = total / block_size; + auto num_threads_inc_main = NumThreads() + 1; + int num_work_items = static_cast(std::min(static_cast(num_threads_inc_main), num_blocks)); + assert(num_work_items > 0); - LoopCounter lc(total, d_of_p, block_size); - std::function run_work = [&](unsigned idx) { - unsigned my_home_shard = lc.GetHomeShard(idx); - unsigned my_shard = my_home_shard; - uint64_t my_iter_start, my_iter_end; - while (lc.ClaimIterations(my_home_shard, my_shard, my_iter_start, my_iter_end)) { - fn(static_cast(my_iter_start), - static_cast(my_iter_end)); - } - }; - - // Run the work in the thread pool (and in the current thread). Synchronization with helping - // threads is handled within RunInParallel, hence we can deallocate lc and other state captured by - // run_work. - RunInParallel(run_work, num_work_items, block_size); + LoopCounter lc(total, d_of_p, block_size); + std::function run_work = [&](unsigned idx) { + unsigned my_home_shard = lc.GetHomeShard(idx); + unsigned my_shard = my_home_shard; + uint64_t my_iter_start, my_iter_end; + while (lc.ClaimIterations(my_home_shard, my_shard, my_iter_start, my_iter_end, block_size)) { + fn(static_cast(my_iter_start), + static_cast(my_iter_end)); + } + }; + // Run the work in the thread pool (and in the current thread). Synchronization with helping + // threads is handled within RunInParallel, hence we can deallocate lc and other state captured by + // run_work. + RunInParallel(run_work, num_work_items, block_size); + } else { + int num_of_blocks = d_of_p * thread_options_.dynamic_block_base_; + std::ptrdiff_t base_block_size = static_cast(std::max(1LL, std::llroundl(static_cast(total) / num_of_blocks))); + alignas(CACHE_LINE_BYTES) std::atomic left{total}; + LoopCounter lc(total, d_of_p, base_block_size); + std::function run_work = [&](unsigned idx) { + std::ptrdiff_t b = base_block_size; + unsigned my_home_shard = lc.GetHomeShard(idx); + unsigned my_shard = my_home_shard; + uint64_t my_iter_start, my_iter_end; + while (lc.ClaimIterations(my_home_shard, my_shard, my_iter_start, my_iter_end, b)) { + fn(static_cast(my_iter_start), + static_cast(my_iter_end)); + auto todo = left.fetch_sub(static_cast(my_iter_end - my_iter_start), std::memory_order_relaxed); + if (b > 1) { + b = static_cast(std::max(1LL, std::llroundl(static_cast(todo) / num_of_blocks))); + } + } + }; + RunInParallel(run_work, d_of_p, base_block_size); + } } void ThreadPool::SimpleParallelFor(std::ptrdiff_t total, const std::function& fn) { diff --git a/onnxruntime/core/platform/env.h b/onnxruntime/core/platform/env.h index 88ff67ace7..42a9bf7a72 100644 --- a/onnxruntime/core/platform/env.h +++ b/onnxruntime/core/platform/env.h @@ -78,6 +78,7 @@ struct ThreadOptions { OrtCustomCreateThreadFn custom_create_thread_fn = nullptr; void* custom_thread_creation_options = nullptr; OrtCustomJoinThreadFn custom_join_thread_fn = nullptr; + int dynamic_block_base_ = 0; }; /// \brief An interface used by the onnxruntime implementation to /// access operating system functionality like the filesystem etc. diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index f7b95e6d85..6ec0092f6b 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -289,11 +289,14 @@ void InferenceSession::ConstructorCommon(const SessionOptions& session_options, session_options_.execution_mode == ExecutionMode::ORT_SEQUENTIAL && to.affinity_vec_len == 0; to.allow_spinning = allow_intra_op_spinning; + to.dynamic_block_base_ = std::stoi(session_options_.config_options.GetConfigOrDefault(kOrtSessionOptionsConfigDynamicBlockBase, "0")); + LOGS(*session_logger_, INFO) << "Dynamic block base set to " << to.dynamic_block_base_; // Set custom threading functions to.custom_create_thread_fn = session_options_.custom_create_thread_fn; to.custom_thread_creation_options = session_options.custom_thread_creation_options; to.custom_join_thread_fn = session_options_.custom_join_thread_fn; + if (to.custom_create_thread_fn) { ORT_ENFORCE(to.custom_join_thread_fn, "custom join thread function not set for intra op thread pool"); } @@ -317,11 +320,13 @@ void InferenceSession::ConstructorCommon(const SessionOptions& session_options, to.name = inter_thread_pool_name_.c_str(); to.set_denormal_as_zero = set_denormal_as_zero; to.allow_spinning = allow_inter_op_spinning; + to.dynamic_block_base_ = std::stoi(session_options_.config_options.GetConfigOrDefault(kOrtSessionOptionsConfigDynamicBlockBase, "0")); // Set custom threading functions to.custom_create_thread_fn = session_options_.custom_create_thread_fn; to.custom_thread_creation_options = session_options.custom_thread_creation_options; to.custom_join_thread_fn = session_options_.custom_join_thread_fn; + if (to.custom_create_thread_fn) { ORT_ENFORCE(to.custom_join_thread_fn, "custom join thread function not set for inter op thread pool"); } diff --git a/onnxruntime/core/util/thread_utils.cc b/onnxruntime/core/util/thread_utils.cc index 312076de28..f47791baac 100644 --- a/onnxruntime/core/util/thread_utils.cc +++ b/onnxruntime/core/util/thread_utils.cc @@ -32,6 +32,7 @@ CreateThreadPoolHelper(Env* env, OrtThreadPoolParams options) { to.custom_create_thread_fn = options.custom_create_thread_fn; to.custom_thread_creation_options = options.custom_thread_creation_options; to.custom_join_thread_fn = options.custom_join_thread_fn; + to.dynamic_block_base_ = options.dynamic_block_base_; if (to.custom_create_thread_fn) { ORT_ENFORCE(to.custom_join_thread_fn, "custom join thread function not set"); } diff --git a/onnxruntime/core/util/thread_utils.h b/onnxruntime/core/util/thread_utils.h index 2780caae82..f7a668f7f5 100644 --- a/onnxruntime/core/util/thread_utils.h +++ b/onnxruntime/core/util/thread_utils.h @@ -18,6 +18,9 @@ struct OrtThreadPoolParams { bool auto_set_affinity = false; //If it is true, the thread pool will spin a while after the queue became empty. bool allow_spinning = true; + //It it is non-negative, thread pool will split a task by a decreasing block size + //of remaining_of_total_iterations / (num_of_threads * dynamic_block_base_) + int dynamic_block_base_ = 0; unsigned int stack_size = 0; //Index is thread id, value is processor ID diff --git a/onnxruntime/test/platform/threadpool_test.cc b/onnxruntime/test/platform/threadpool_test.cc index e4a06446d2..db9eb2253b 100644 --- a/onnxruntime/test/platform/threadpool_test.cc +++ b/onnxruntime/test/platform/threadpool_test.cc @@ -46,11 +46,17 @@ void ValidateTestData(TestData& test_data, int expected=1) { // test the function with a null pointer, reflecting scenarios where we // run with just the main thread. Note that the thread pool API uses // static methods and should operate across all of these cases. -void CreateThreadPoolAndTest(const std::string&, int num_threads, const std::function& test_body) { +void CreateThreadPoolAndTest(const std::string&, int num_threads, const std::function& test_body, int dynamic_block_base = 0) { if (num_threads > 0) { - auto tp = std::make_unique(&onnxruntime::Env::Default(), onnxruntime::ThreadOptions(), nullptr, - num_threads, true); - test_body(tp.get()); + if (dynamic_block_base > 0) { + onnxruntime::ThreadOptions thread_options; + thread_options.dynamic_block_base_ = dynamic_block_base; + auto tp_dynamic_block_size = std::make_unique(&onnxruntime::Env::Default(), thread_options, nullptr, num_threads, true); + test_body(tp_dynamic_block_size.get()); // test thread pool with dynamic block size + } else { + auto tp_constant_block_size = std::make_unique < ThreadPool>(&onnxruntime::Env::Default(), onnxruntime::ThreadOptions{}, nullptr, num_threads, true); + test_body(tp_constant_block_size.get()); // test thread pool with constant block size + } } else { test_body(nullptr); } @@ -74,40 +80,42 @@ void TestBatchParallelFor(const std::string& name, int num_threads, int num_task ValidateTestData(*test_data); } -void TestConcurrentParallelFor(const std::string& name, int num_threads, int num_concurrent, int num_tasks) { +void TestConcurrentParallelFor(const std::string& name, int num_threads, int num_concurrent, int num_tasks, int dynamic_block_base = 0) { // Test running multiple concurrent loops over the same thread pool. This aims to provoke a // more diverse mix of interleavings than with a single loop running at a time. for (int rep = 0; rep < 5; rep++) { - CreateThreadPoolAndTest(name, num_threads, [&](ThreadPool* tp) { - std::vector> td; - onnxruntime::Barrier b(num_concurrent - 1); + CreateThreadPoolAndTest( + name, num_threads, [&](ThreadPool* tp) { + std::vector> td; + onnxruntime::Barrier b(num_concurrent - 1); - // Each concurrent tests runs with its own set of counters - for (int c = 0; c < num_concurrent; c++) { - td.push_back(CreateTestData(num_tasks)); - } + // Each concurrent tests runs with its own set of counters + for (int c = 0; c < num_concurrent; c++) { + td.push_back(CreateTestData(num_tasks)); + } - // For a range of scenarios, run some tests via the thread pool, and one directly - for (int c = 0; c < num_concurrent - 1; c++) { - ThreadPool::Schedule(tp, [&, c]() { - ThreadPool::TrySimpleParallelFor(tp, num_tasks, [&](std::ptrdiff_t i) { + // For a range of scenarios, run some tests via the thread pool, and one directly + for (int c = 0; c < num_concurrent - 1; c++) { + ThreadPool::Schedule(tp, [&, c]() { + ThreadPool::TrySimpleParallelFor(tp, num_tasks, [&](std::ptrdiff_t i) { IncrementElement(*td[c], i); }); - b.Notify(); + b.Notify(); + }); + } + + ThreadPool::TrySimpleParallelFor(tp, num_tasks, [&](std::ptrdiff_t i) { + IncrementElement(*td[num_concurrent - 1], i); }); - } - ThreadPool::TrySimpleParallelFor(tp, num_tasks, [&](std::ptrdiff_t i) { - IncrementElement(*td[num_concurrent - 1], i); - }); - - // Validate all outputs - b.Wait(); - for (int c = 0; c < num_concurrent; c++) { - ValidateTestData(*td[c]); - } - td.clear(); - }); + // Validate all outputs + b.Wait(); + for (int c = 0; c < num_concurrent; c++) { + ValidateTestData(*td[c]); + } + td.clear(); + }, + dynamic_block_base); } } @@ -319,18 +327,82 @@ TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_0Tasks) { TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_0Tasks", 4, 4, 0); } +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_1) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_1", 4, 4, 0, 1); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_4) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_4", 4, 4, 0, 4); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_16) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_16", 4, 4, 0, 16); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_128) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_0Tasks_dynamic_block_base_128", 4, 4, 0, 128); +} + TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1Tasks) { TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1Tasks", 4, 4, 1); } +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_1) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_1", 4, 4, 1, 1); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_4) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_4", 4, 4, 1, 4); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_16) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_16", 4, 4, 1, 16); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_128) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1Tasks_dynamic_block_base_128", 4, 4, 1, 128); +} + TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_8Tasks) { TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_8Tasks", 4, 4, 8); } +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_1) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_1", 4, 4, 8, 1); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_4) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_4", 4, 4, 8, 4); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_16) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_16", 4, 4, 8, 16); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_128) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_8Tasks_dynamic_block_base_128", 4, 4, 8, 128); +} + TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1MTasks) { TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1MTasks", 4, 4, 1000000); } +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_1) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_1", 4, 4, 1000000, 1); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_4) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_4", 4, 4, 1000000, 4); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_16) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_16", 4, 4, 1000000, 16); +} + +TEST(ThreadPoolTest, TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_128) { + TestConcurrentParallelFor("TestConcurrentParallelFor_4Thread_4Conc_1MTasks_dynamic_block_base_128", 4, 4, 1000000, 128); +} + TEST(ThreadPoolTest, TestBurstScheduling_0Tasks) { TestBurstScheduling("TestBurstScheduling_0Tasks", 0); } @@ -424,6 +496,7 @@ TEST(ThreadPoolTest, TestStagedMultiLoopSections_4Thread_10Loop) { TEST(ThreadPoolTest, TestStagedMultiLoopSections_4Thread_100Loop) { TestStagedMultiLoopSections("TestStagedMultiLoopSections_4Thread_100Loop", 4, 100); } + #ifdef _WIN32 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #pragma warning(push) From a099bd454b8f4cb5098f2a45f757b1cc40e73869 Mon Sep 17 00:00:00 2001 From: Rachel Guo <35738743+YUNQIUGUO@users.noreply.github.com> Date: Tue, 11 Jan 2022 19:41:45 -0800 Subject: [PATCH 112/113] [QDQ] Add shared qdq selectors (#10178) * wip * wip * wip * wip * wip * save * minor changes * update test graph name * address pr comments * update * address pr comments * address pr comments * fix warning * minor include fix * update to nodegroupselectors * delete unnecessary includes Co-authored-by: rachguo --- cmake/onnxruntime_optimizer.cmake | 2 + .../selectors_actions/shared/utils.cc | 144 ++++++++++++++++++ .../selectors_actions/shared/utils.h | 76 +++++++++ .../test/optimizer/qdq_transformer_test.cc | 34 +++++ 4 files changed, 256 insertions(+) create mode 100644 onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc create mode 100644 onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h diff --git a/cmake/onnxruntime_optimizer.cmake b/cmake/onnxruntime_optimizer.cmake index 6350b8a0a7..8b1e84acc4 100644 --- a/cmake/onnxruntime_optimizer.cmake +++ b/cmake/onnxruntime_optimizer.cmake @@ -32,6 +32,8 @@ else() "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/*.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/*.h" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/*.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/*.h" "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/*.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/*.h" diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc new file mode 100644 index 0000000000..329ec66d94 --- /dev/null +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "utils.h" + +#include +#include +#include + +#include +#include + +#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" +#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h" + +namespace onnxruntime { +namespace QDQ { + +void Selectors::RegisterSelector(const OpVersionsAndSelector::OpVersionsMap& ops_and_versions_in, + std::unique_ptr selector_in) { + auto entry = std::make_unique( + ops_and_versions_in, + std::move(selector_in)); + + ORT_IGNORE_RETURN_VALUE(selectors_set_.insert(std::move(entry))); +} + +/* static methods to return different operator's OpVersionMap */ +static const OpVersionsAndSelector::OpVersionsMap GetMiscOpVersionsMap() { return {{"Gather", {}}, + {"Reshape", {}}, + {"Transpose", {}}, + {"MaxPool", {12}}, + {"Resize", {}}}; } + +static const OpVersionsAndSelector::OpVersionsMap GetUnaryOpVersionsMap() { return {{"AveragePool", {}}, + {"LeakyRelu", {}}}; } +static const OpVersionsAndSelector::OpVersionsMap GetBinaryOpVersionsMap() { return {{"Add", {}}, + {"Mul", {}}}; } +static const OpVersionsAndSelector::OpVersionsMap GetVariadicOpVersionsMap() { return {{"Concat", {}}}; } +static const OpVersionsAndSelector::OpVersionsMap GetConvOpVersionsMap() { return {{"Conv", {}}}; } +static const OpVersionsAndSelector::OpVersionsMap GetMatMulOpVersionsMap() { return {{"MatMul", {}}}; } + +/* Selector rules registration related */ +void RegisterMiscSelectors(Selectors& qdq_selectors) { + /* register selectors for miscellaneous ops */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetMiscOpVersionsMap(), + std::move(selector)); +} + +void RegisterUnarySelectors(Selectors& qdq_selectors) { + /* regsiter selectors for unary ops */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetUnaryOpVersionsMap(), + std::move(selector)); +} + +void RegisterBinarySelectors(Selectors& qdq_selectors) { + /* register selectors for binary ops */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetBinaryOpVersionsMap(), + std::move(selector)); +} + +void RegisterVariadicSelectors(Selectors& qdq_selectors) { + /* register selectors for variadic ops */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetVariadicOpVersionsMap(), + std::move(selector)); +} + +void RegisterConvSelector(Selectors& qdq_selectors) { + /* register selector for conv op */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetConvOpVersionsMap(), + std::move(selector)); +} + +void RegisterMatMulSelector(Selectors& qdq_selectors) { + /* register selector for matmul op */ + std::unique_ptr selector = std::make_unique(); + qdq_selectors.RegisterSelector(GetMatMulOpVersionsMap(), + std::move(selector)); +} + +void SelectorManager::CreateSelectors() { + RegisterMiscSelectors(qdq_selectors_); + RegisterUnarySelectors(qdq_selectors_); + RegisterBinarySelectors(qdq_selectors_); + RegisterVariadicSelectors(qdq_selectors_); + RegisterConvSelector(qdq_selectors_); + RegisterMatMulSelector(qdq_selectors_); +} + +void SelectorManager::InitializeSelectorsMap() { + for (const auto& entry : qdq_selectors_.SelectorsSet()) { + for (const auto& op_info : entry->op_versions_map) { + bool inserted = op_type_to_selectors_map_.insert({op_info.first, &*entry}).second; + ORT_ENFORCE(inserted, "Multiple entries for operator is not supported. OpType=", op_info.first); + } + } +} + +void SelectorManager::Initialize() { + CreateSelectors(); + InitializeSelectorsMap(); +} + +std::vector SelectorManager::GetQDQSelections(const GraphViewer& graph_viewer) const { + std::vector qdq_selections; + for (auto index : graph_viewer.GetNodesInTopologicalOrder()) { + const auto* node = graph_viewer.GetNode(index); + if (node->Domain() != kOnnxDomain) { + continue; + } + + auto op_rule = op_type_to_selectors_map_.find(node->OpType()); + if (op_rule == op_type_to_selectors_map_.cend()) { + continue; + } + + const auto& op_versions_and_selector = *op_rule->second; + + // check the supported versions if specified + const auto& versions = op_versions_and_selector.op_versions_map.find(node->OpType())->second; + if (!versions.empty()) { + if (std::find(versions.cbegin(), versions.cend(), node->SinceVersion()) == versions.cend()) { + LOGS_DEFAULT(VERBOSE) << "Op version is not supported for" << node->OpType(); + continue; + } + } + + const auto qdq_node_group_selection = op_versions_and_selector.selector->GetQDQSelection(graph_viewer, *node); + if (qdq_node_group_selection.has_value()) { + const auto& qdq_group = *qdq_node_group_selection; + qdq_selections.push_back(qdq_group); + } + } + + return qdq_selections; +} + +} // namespace QDQ +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h new file mode 100644 index 0000000000..cb44ed2fa5 --- /dev/null +++ b/onnxruntime/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include +#include "core/graph/basic_types.h" +#include "core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h" +#include "core/optimizer/selectors_actions/helpers.h" + +namespace onnxruntime { + +class GraphViewer; +class Node; + +namespace QDQ { + +// struct that provides a join between selector and op versions supported +struct OpVersionsAndSelector { + using OpVersionsMap = std::unordered_map>; + + OpVersionsAndSelector(const OpVersionsMap& ops_and_versions_in, + std::unique_ptr selector_in) + : op_versions_map{ops_and_versions_in}, + selector{std::move(selector_in)} {} + + OpVersionsMap op_versions_map; + std::unique_ptr selector; + + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(OpVersionsAndSelector); +}; + +// class that manages a set of node group selectors +class Selectors { + public: + Selectors() = default; + + // register a selector for the specified ops. + void RegisterSelector(const OpVersionsAndSelector::OpVersionsMap& ops_and_versions_in, + std::unique_ptr selector_in); + + const std::unordered_set>& SelectorsSet() const { + return selectors_set_; + } + + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(Selectors); + + private: + std::unordered_set> selectors_set_; +}; + +// class that manages qdq node group selections +class SelectorManager { + public: + SelectorManager() = default; + + void Initialize(); + + // Methods that finds and returns a vector of QDQ::NodeGroup in a given graph + // Can be used in QDQ support in different EPs + std::vector GetQDQSelections(const GraphViewer& graph_viewer) const; + + private: + Selectors qdq_selectors_; + + std::unordered_map op_type_to_selectors_map_; + + void InitializeSelectorsMap(); + + void CreateSelectors(); + + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(SelectorManager); +}; + +} // namespace QDQ +} // namespace onnxruntime \ No newline at end of file diff --git a/onnxruntime/test/optimizer/qdq_transformer_test.cc b/onnxruntime/test/optimizer/qdq_transformer_test.cc index 4470eb4293..4eea3be246 100644 --- a/onnxruntime/test/optimizer/qdq_transformer_test.cc +++ b/onnxruntime/test/optimizer/qdq_transformer_test.cc @@ -7,6 +7,7 @@ #include "core/mlas/inc/mlas.h" #include "core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h" #include "core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" +#include "core/optimizer/qdq_transformer/selectors_actions/shared/utils.h" #include "core/providers/partitioning_utils.h" #include "core/session/environment.h" #include "core/session/inference_session.h" @@ -1826,5 +1827,38 @@ TEST(QDQTransformerTests, QDQ_Selector_Test) { ASSERT_FALSE(result.has_value()); } } + +TEST(QDQTransformerTests, QDQ_Shared_GetSelectors_Test) { + const ORTCHAR_T* model_file_name = ORT_TSTR("testdata/transform/qdq_conv.onnx"); + + SessionOptions so; + so.graph_optimization_level = TransformerLevel::Default; + InferenceSessionWrapper session_object{so, GetEnvironment()}; + ASSERT_STATUS_OK(session_object.Load(model_file_name)); + ASSERT_STATUS_OK(session_object.Initialize()); + const Graph& graph = session_object.GetGraph(); + const auto* conv_node = graph.GetNode(3); + + // Make sure node 3 is the conv node + ASSERT_TRUE(nullptr != conv_node); + ASSERT_EQ("Conv", conv_node->OpType()); + + const GraphViewer graph_viewer(graph); + + // Initialize SelectorManager + QDQ::SelectorManager selector_mgr; + selector_mgr.Initialize(); + + // Check if SelectorManager get a conv qdq group selection as expected + { + const auto result = selector_mgr.GetQDQSelections(graph_viewer); + ASSERT_EQ(false, result.empty()); + const auto& qdq_group = result.at(0); + ASSERT_EQ(std::vector({0, 1, 2}), qdq_group.dq_nodes); + ASSERT_EQ(NodeIndex(3), qdq_group.target_node); + ASSERT_EQ(std::vector({4}), qdq_group.q_nodes); + } +} + } // namespace test } // namespace onnxruntime From 4af232df0ce89f0f0227ca8bd10ed8808d4398e5 Mon Sep 17 00:00:00 2001 From: CarlPoirier Date: Wed, 12 Jan 2022 02:30:40 -0500 Subject: [PATCH 113/113] Fix props file overwriting AdditionalIncludeDirectories (#10124) Co-authored-by: Carl Poirier --- .../Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml index c467dfa5c6..b0ae8603ea 100644 --- a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml +++ b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml @@ -12,13 +12,13 @@ - $(MSBuildThisFileDirectory)../../runtimes/win-x64/native/onnxruntime.lib + $(MSBuildThisFileDirectory)../../runtimes/win-x64/native/onnxruntime.lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)../../runtimes/win-x86/native/onnxruntime.lib + $(MSBuildThisFileDirectory)../../runtimes/win-x86/native/onnxruntime.lib;%(AdditionalDependencies)