diff --git a/CMakeLists.txt b/CMakeLists.txt index d11314408e..46804c8dde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,14 @@ include(${CMAKE_SOURCE_DIR}/cmake/options.cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -Werror -Wno-return-std-move -Wno-unused-private-field -Wno-unused-lambda-capture -Wno-sign-compare -Wno-overloaded-virtual -Wno-unneeded-internal-declaration -Wno-unused-variable -Wno-pessimizing-move -Wno-inconsistent-missing-override -DHALF_ENABLE_CPP11_USER_LITERALS=0 -D_FORTIFY_SOURCE=2") +else() + set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -Wl,--allow-shlib-undefined -DHALF_ENABLE_CPP11_USER_LITERALS=0 -D_FORTIFY_SOURCE=2") +endif() + set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -g2 -ggdb -fno-inline-functions -fno-omit-frame-pointer -Wl,--allow-shlib-undefined -D_LIBCPP_INLINE_VISIBILITY='' -D'_LIBCPP_EXTERN_TEMPLATE(...)=' -DHALF_ENABLE_CPP11_USER_LITERALS=0 -D_FORTIFY_SOURCE=2 -Wno-cpp") -set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -Wl,--allow-shlib-undefined -DHALF_ENABLE_CPP11_USER_LITERALS=0 -D_FORTIFY_SOURCE=2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include -std=c++17 -Werror -Wall -Wno-deprecated-declarations -fPIC") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -14,16 +20,31 @@ set(PYBIND11_CPP_STANDARD -std=c++17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPTION_CXX_FLAGS}") find_package(Threads) +find_package(Patch) +message(PATCH_EXECUTABLE = ${Patch_EXECUTABLE}) + include(${CMAKE_SOURCE_DIR}/cmake/mind_expression.cmake) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers/include/flatbuffers) include(${CMAKE_SOURCE_DIR}/cmake/dependency_utils.cmake) -find_package(Python3 COMPONENTS Interpreter Development) +find_package(Python3 3.7 COMPONENTS Interpreter Development) if(Python3_FOUND) set(PYTHON_INCLUDE_DIRS "${Python3_INCLUDE_DIRS}") set(PYTHON_LIBRARIES "${Python3_LIBRARIES}") + if (WIN32) + if (Python3_DIR) + message("Python3_DIR set already: " ${Python3_DIR}) + else() + string(LENGTH ${PYTHON_LIBRARIES} PYTHON_LIBRARIES_LEN) + string(LENGTH "libpythonxx.a" Python3_NAME_LEN) + math(EXPR Python3_DIR_LEN ${PYTHON_LIBRARIES_LEN}-${Python3_NAME_LEN}) + string(SUBSTRING ${Python3_LIBRARIES} 0 ${Python3_DIR_LEN} Python3_DIR) + message("Python3_DIR: " ${Python3_DIR}) + endif() + link_directories(${Python3_DIR}) + endif() else() find_python_package(py_inc py_lib) set(PYTHON_INCLUDE_DIRS "${py_inc}") @@ -55,3 +76,5 @@ add_subdirectory(mindspore/ccsrc) if (ENABLE_TESTCASES) add_subdirectory(tests) endif() + +include(cmake/package.cmake) \ No newline at end of file diff --git a/README.md b/README.md index be8ca5189a..e465f8e3e1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![MindSpore Logo](docs/MindSpore-logo.png "MindSpore logo") ============================================================ -- [What is MindSpore?](#what-is-MindSpore) +- [What is MindSpore?](#what-is-mindspore) - [Automatic Differentiation](#automatic-differentiation) - [Automatic Parallel](#automatic-parallel) - [Installation](#installation) @@ -53,7 +53,7 @@ The goal of MindSpore automatic parallel is to build a training method that comb Automatic Parallel -At present, MindSpore uses a fine-grained parallel strategy of splitting operators, that is, each operator in the figure is splited into a cluster to complete parallel operations. The splitting strategy during this period may be very complicated, but as a developer advocating Pythonic, you don't need to care about the underlying implementation, as long as the top-level API compute is efficient. +At present, MindSpore uses a fine-grained parallel strategy of splitting operators, that is, each operator in the figure is splitted into a cluster to complete parallel operations. The splitting strategy during this period may be very complicated, but as a developer advocating Pythonic, you don't need to care about the underlying implementation, as long as the top-level API compute is efficient. ## Installation @@ -69,10 +69,11 @@ MindSpore offers build options across multiple backends: | GPU CUDA 9.2 | Ubuntu-x86 | ✔️ | | GPU CUDA 10.1 | Ubuntu-x86 | ✔️ | | CPU | Ubuntu-x86 | ✔️ | +| | Windows-x86 | ✔️ | -For installation using pip, take `Ubuntu-x86` and `CPU` build version as an example: +For installation using `pip`, take `CPU` and `Ubuntu-x86` build version as an example: -1. Download whl from [MindSpore website](https://www.mindspore.cn/), and install the package. +1. Download whl from [MindSpore download page](https://www.mindspore.cn/versions/en), and install the package. ``` pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/cpu/ubuntu-x86/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl @@ -93,19 +94,69 @@ For installation using pip, take `Ubuntu-x86` and `CPU` build version as an exam MindSpore docker image is hosted on [Docker Hub](https://hub.docker.com/r/mindspore), currently the containerized build options are supported as follows: -| Hardware Platform | Docker Image URL | -| :---------------- | :--------------- | -| CPU | `mindspore/mindspore-cpu:0.1.0-alpha` | -| GPU CUDA 9.2 | `mindspore/mindspore-cuda9.2:0.1.0-alpha` | -| GPU CUDA 10.1 | `mindspore/mindspore-cuda10.1:0.1.0-alpha` | -| Ascend |
| +| Hardware Platform | Docker Image Repository | Tag | Description | +| :---------------- | :---------------------- | :-- | :---------- | +| CPU | `mindspore/mindspore-cpu` | `0.1.0-alpha` | Production environment with pre-installed MindSpore `0.1.0-alpha` CPU release. | +| | | `devel` | Development environment provided to build MindSpore (with `CPU` backend) from the source, refer to https://www.mindspore.cn/install/en for installation details. | +| | | `runtime` | Runtime environment provided to install MindSpore binary package with `CPU` backend. | +| GPU | `mindspore/mindspore-gpu` | `0.1.0-alpha` | Production environment with pre-installed MindSpore `0.1.0-alpha` GPU release. | +| | | `devel` | Development environment provided to build MindSpore (with `GPU CUDA10.1` backend) from the source, refer to https://www.mindspore.cn/install/en for installation details. | +| | | `runtime` | Runtime environment provided to install MindSpore binary package with `GPU` backend. | +| Ascend |
|
| Coming soon. | -Take `CPU` for example, you can directly pull the image using the below command: -``` -docker pull mindspore/mindspore-cpu:0.1.0-alpha -``` +* CPU -If anyone wants to learn more about the build process of MindSpore docker images, + For `CPU` backend, you can directly pull and run the image using the below command: + ``` + docker pull mindspore/mindspore-cpu:0.1.0-alpha + docker run -it mindspore/mindspore-cpu:0.1.0-alpha python -c 'import mindspore' + ``` + +* GPU + + For `GPU` backend, please make sure the `nvidia-container-toolkit` has been installed in advance, here are some install guidelines for `Ubuntu` users: + ``` + DISTRIBUTION=$(. /etc/os-release; echo $ID$VERSION_ID) + curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - + curl -s -L https://nvidia.github.io/nvidia-docker/$DISTRIBUTION/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list + + sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit nvidia-docker2 + sudo systemctl restart docker + ``` + + Then you can pull and run the image using the below command: + ``` + docker pull mindspore/mindspore-gpu:0.1.0-alpha + docker run -it --runtime=nvidia --privileged=true mindspore/mindspore-gpu:0.1.0-alpha /bin/bash + ``` + + To test if the docker image works, please execute the python code below and check the output: + ```python + import numpy as np + from mindspore import Tensor + from mindspore.ops import functional as F + import mindspore.context as context + + context.set_context(device_target="GPU") + x = Tensor(np.ones([1,3,3,4]).astype(np.float32)) + y = Tensor(np.ones([1,3,3,4]).astype(np.float32)) + print(F.tensor_add(x, y)) + ``` + ``` + [[[ 2. 2. 2. 2.], + [ 2. 2. 2. 2.], + [ 2. 2. 2. 2.]], + + [[ 2. 2. 2. 2.], + [ 2. 2. 2. 2.], + [ 2. 2. 2. 2.]], + + [[ 2. 2. 2. 2.], + [ 2. 2. 2. 2.], + [ 2. 2. 2. 2.]]] + ``` + +If you want to learn more about the building process of MindSpore docker images, please check out `docker` folder for the details. ## Quickstart diff --git a/build.bat b/build.bat new file mode 100644 index 0000000000..76d7f19262 --- /dev/null +++ b/build.bat @@ -0,0 +1,54 @@ +@rem Copyright 2020 Huawei Technologies Co., Ltd +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem ============================================================================ +@echo off +@title mindspore_build + +SET BASEPATH=%CD% +IF NOT EXIST %BASEPATH%/build ( + md "build" + ) + +cd %BASEPATH%/build +SET BUILD_PATH=%CD% + +IF NOT EXIST %BUILD_PATH%/mindspore ( + md "mindspore" + ) + +cd %CD%/mindspore + +cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CPU=ON -DENABLE_MINDDATA=ON -DUSE_GLOG=ON -G "CodeBlocks - MinGW Makefiles" ../.. +IF NOT %errorlevel% == 0 ( + goto run_fail + ) + +IF "%1%" == "" ( + cmake --build . --target package -- -j6 + ) ELSE ( + cmake --build . --target package -- -j%1% + ) +IF NOT %errorlevel% == 0 ( + goto run_fail + ) + +cd %BASEPATH% + +goto run_eof + +:run_fail + cd %BASEPATH% + echo "build fail." + +:run_eof diff --git a/build.sh b/build.sh index 6dc699000a..7550d76c8f 100755 --- a/build.sh +++ b/build.sh @@ -16,7 +16,6 @@ set -e BASEPATH=$(cd "$(dirname $0)"; pwd) -PROJECT_PATH="${BASEPATH}" CUDA_PATH="" CUDNN_PATH="" export BUILD_PATH="${BASEPATH}/build/" @@ -24,7 +23,7 @@ export BUILD_PATH="${BASEPATH}/build/" usage() { echo "Usage:" - echo "bash build.sh [-d] [-r] [-v] [-c on|off] [-t on|off] [-g on|off] [-h] [-s] [-b ge|cpu] [-m infer|train] \\" + echo "bash build.sh [-d] [-r] [-v] [-c on|off] [-t on|off] [-g on|off] [-h] [-b ge|cpu] [-m infer|train] \\" echo " [-a on|off] [-g on|off] [-p on|off] [-i] [-L] [-R] [-D on|off] [-j[n]] [-e gpu|d|cpu] \\" echo " [-P on|off] [-z [on|off]] [-M on|off] [-V 9.2|10.1] [-I] [-K]" echo "" @@ -36,7 +35,6 @@ usage() echo " -t Run testcases switch, default on" echo " -g Use glog to output log, default on" echo " -h Print usage" - echo " -s Install or setup" echo " -b Select other backend, available: \\" echo " ge:graph engine, cpu" echo " -m Select mode, available: infer, train, default is infer " @@ -77,7 +75,6 @@ checkopts() VERBOSE="" ENABLE_COVERAGE="off" RUN_TESTCASES="off" - EXECUTE_SETUP="off" ENABLE_BACKEND="" TRAIN_MODE="INFER" ENABLE_ASAN="off" @@ -129,9 +126,6 @@ checkopts() usage exit 0 ;; - s) - EXECUTE_SETUP="on" - ;; b) if [[ "X$OPTARG" != "Xge" && "X$OPTARG" != "Xcpu" ]]; then echo "Invalid value ${OPTARG} for option -b" @@ -139,9 +133,6 @@ checkopts() exit 1 fi ENABLE_BACKEND=$(echo "$OPTARG" | tr '[a-z]' '[A-Z]') - if [[ "X$ENABLE_BACKEND" == "XGE" ]]; then - ENABLE_GE="on" - fi if [[ "X$ENABLE_BACKEND" != "XCPU" ]]; then ENABLE_CPU="on" fi @@ -297,7 +288,7 @@ build_mindspore() if [[ "X$ENABLE_DUMPE2E" = "Xon" ]]; then CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_DUMP_E2E=ON" fi - CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_DUMP_IR=${ENABLE_DUMP_IR^^}" + CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_DUMP_IR=${ENABLE_DUMP_IR}" if [[ "X$ENABLE_MPI" = "Xon" ]]; then CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_MPI=ON" fi @@ -323,10 +314,10 @@ build_mindspore() if [[ "X$INC_BUILD" = "Xoff" ]]; then cmake ${CMAKE_ARGS} ../.. fi - make ${VERBOSE} -j$THREAD_NUM - if [[ "X$EXECUTE_SETUP" = "Xon" ]]; then - make install + if [[ -n "$VERBOSE" ]]; then + CMAKE_VERBOSE="--verbose" fi + cmake --build . --target package ${CMAKE_VERBOSE} -j$THREAD_NUM echo "success to build mindspore project!" } @@ -457,24 +448,7 @@ else build_mindspore fi -if [[ "X$INC_BUILD" = "Xoff" ]]; then - if [[ "X$ENABLE_GE" = "Xon" ]]; then - bash "${PROJECT_PATH}/package.sh" ge - elif [[ "X$ENABLE_GPU" = "Xon" ]]; then - bash "${PROJECT_PATH}/package.sh" ms gpu - elif [[ "X$ENABLE_D" = "Xon" ]]; then - bash "${PROJECT_PATH}/package.sh" ms ascend - elif [[ "X$ENABLE_CPU" = "Xon" ]]; then - bash "${PROJECT_PATH}/package.sh" ms cpu - else - bash "${PROJECT_PATH}/package.sh" debug - fi -fi - cp -rf ${BUILD_PATH}/package/mindspore/lib ${BUILD_PATH}/../mindspore cp -rf ${BUILD_PATH}/package/mindspore/*.so ${BUILD_PATH}/../mindspore -if [[ -d "${BUILD_PATH}/package/build" ]]; then - rm -rf "${BUILD_PATH}/package/build" -fi echo "---------------- mindspore: build end ----------------" diff --git a/cmake/dependency_securec.cmake b/cmake/dependency_securec.cmake index 81714c21d4..7ff5acad06 100644 --- a/cmake/dependency_securec.cmake +++ b/cmake/dependency_securec.cmake @@ -9,6 +9,9 @@ if (NOT TARGET securec) set(_ms_tmp_CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) set(CMAKE_C_FLAGS "${SECURE_CXX_FLAGS}") + if (CMAKE_SYSTEM_NAME MATCHES "Windows") + add_compile_definitions(SECUREC_ONLY_DECLARE_MEMSET) + endif() add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/securec ${CMAKE_BINARY_DIR}/securec) set(CMAKE_POSITION_INDEPENDENT_CODE ${_ms_tmp_CMAKE_POSITION_INDEPENDENT_CODE}) set(CMAKE_C_FLAGS ${_ms_tmp_CMAKE_C_FLAGS}) diff --git a/cmake/external_libs/dmlc_core.cmake b/cmake/external_libs/dmlc_core.cmake index 386a52429d..e07df83fd6 100644 --- a/cmake/external_libs/dmlc_core.cmake +++ b/cmake/external_libs/dmlc_core.cmake @@ -1,4 +1,4 @@ -mindspore_add_pkg(dmlc_core +mindspore_add_pkg(dmlc-core VER 0.3 HEAD_ONLY ./ URL https://github.com/dmlc/dmlc-core/archive/808f485387f9a03f78fa9f1159f387d0d91b7a28.zip diff --git a/cmake/external_libs/flatbuffers.cmake b/cmake/external_libs/flatbuffers.cmake index 7d7c74b9e1..18549ed1b5 100644 --- a/cmake/external_libs/flatbuffers.cmake +++ b/cmake/external_libs/flatbuffers.cmake @@ -1,5 +1,8 @@ set(flatbuffers_CXXFLAGS "-D_FORTIFY_SOURCE=2 -O2") set(flatbuffers_CFLAGS "-D_FORTIFY_SOURCE=2 -O2") +if (WIN32) + set(flatbuffers_USE_STATIC_LIBS ON) +endif() mindspore_add_pkg(flatbuffers VER 1.11.0 LIBS flatbuffers diff --git a/cmake/external_libs/gtest.cmake b/cmake/external_libs/gtest.cmake index 5384b48825..df2eaec2cc 100644 --- a/cmake/external_libs/gtest.cmake +++ b/cmake/external_libs/gtest.cmake @@ -9,5 +9,5 @@ mindspore_add_pkg(gtest -DCMAKE_MACOSX_RPATH=TRUE -Dgtest_disable_pthreads=ON) include_directories(${gtest_INC}) add_library(mindspore::gtest ALIAS gtest::gtest) -file(COPY ${gtest_LIBPATH}/libgtest.so DESTINATION ${CMAKE_BINARY_DIR}/googletest/googlemock/gtest) -file(COPY ${gtest_LIBPATH}/libgtest_main.so DESTINATION ${CMAKE_BINARY_DIR}/googletest/googlemock/gtest) +file(COPY ${gtest_LIBPATH}/libgtest${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_BINARY_DIR}/googletest/googlemock/gtest) +file(COPY ${gtest_LIBPATH}/libgtest_main${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_BINARY_DIR}/googletest/googlemock/gtest) diff --git a/cmake/external_libs/jpeg_turbo.cmake b/cmake/external_libs/jpeg_turbo.cmake index 84d6e3006c..6c2c70c709 100644 --- a/cmake/external_libs/jpeg_turbo.cmake +++ b/cmake/external_libs/jpeg_turbo.cmake @@ -1,6 +1,10 @@ - set(jpeg_turbo_USE_STATIC_LIBS ON) -set(jpeg_turbo_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(jpeg_turbo_CFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") +else() + set(jpeg_turbo_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") +endif() + set(jpeg_turbo_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") mindspore_add_pkg(jpeg_turbo VER 2.0.4 diff --git a/cmake/external_libs/libtiff.cmake b/cmake/external_libs/libtiff.cmake index 461b9c4481..4086004e33 100644 --- a/cmake/external_libs/libtiff.cmake +++ b/cmake/external_libs/libtiff.cmake @@ -1,8 +1,18 @@ - -set(tiff_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-unused-result \ +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(tiff_CXXFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -Wno-unused-result \ -Wno-unused-but-set-variable -fPIC -D_FORTIFY_SOURCE=2 -O2") -set(tiff_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-unused-result \ + set(tiff_CFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -Wno-unused-result \ -Wno-unused-but-set-variable -fPIC -D_FORTIFY_SOURCE=2 -O2") +else() + set(tiff_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-unused-result \ + -Wno-unused-but-set-variable -fPIC -D_FORTIFY_SOURCE=2 -O2") + set(tiff_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-unused-result \ + -Wno-unused-but-set-variable -fPIC -D_FORTIFY_SOURCE=2 -O2") + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(tiff_CFLAGS "${tiff_CFLAGS} -Wno-int-to-pointer-cast -Wno-implicit-fallthrough -Wno-pointer-to-int-cast") + endif() +endif() + set(tiff_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") mindspore_add_pkg(tiff diff --git a/cmake/external_libs/mkl_dnn.cmake b/cmake/external_libs/mkl_dnn.cmake index 6f033fa565..4b2c46670a 100644 --- a/cmake/external_libs/mkl_dnn.cmake +++ b/cmake/external_libs/mkl_dnn.cmake @@ -1,11 +1,22 @@ set(onednn_CXXFLAGS "-D_FORTIFY_SOURCE=2 -O2") set(onednn_CFLAGS "-D_FORTIFY_SOURCE=2 -O2") -mindspore_add_pkg(onednn +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + mindspore_add_pkg(onednn + VER 1.1.1 + LIBS dnnl mkldnn + HEAD_ONLY ./ + RELEASE on + URL https://github.com/oneapi-src/oneDNN/releases/download/v1.1.1/dnnl_win_1.1.1_cpu_vcomp.zip + MD5 ecaab9ed549643067699c80e5cea1c23) +else() + mindspore_add_pkg(onednn VER 1.1.2 LIBS dnnl mkldnn URL https://github.com/oneapi-src/oneDNN/archive/v1.1.2.tar.gz MD5 ab40d52230f3ad1d7a6f06ce0f6bc17a CMAKE_OPTION -DDNNL_ARCH_OPT_FLAGS='' -DDNNL_CPU_RUNTIME='SEQ' -DDNNL_BUILD_EXAMPLES=OFF -DDNNL_BUILD_TESTS=OFF) +endif() + include_directories(${onednn_INC}) add_library(mindspore::dnnl ALIAS onednn::dnnl) add_library(mindspore::mkldnn ALIAS onednn::mkldnn) diff --git a/cmake/external_libs/opencv.cmake b/cmake/external_libs/opencv.cmake index e67c3f232f..b4f8d55a9e 100644 --- a/cmake/external_libs/opencv.cmake +++ b/cmake/external_libs/opencv.cmake @@ -1,31 +1,76 @@ +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(opencv_CXXFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_CFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_LDFLAGS "-Wl") +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(opencv_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_CXXFLAGS "${opencv_CXXFLAGS} -Wno-attributes -Wno-unknown-pragmas") + set(opencv_CXXFLAGS "${opencv_CXXFLAGS} -Wno-unused-value -Wno-implicit-fallthrough") +else() + set(opencv_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") + set(opencv_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") +endif() -set(opencv_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") -set(opencv_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -D_FORTIFY_SOURCE=2 -O2") -set(opencv_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") +if (WIN32) + mindspore_add_pkg(opencv + VER 4.2.0 + LIBS libopencv_core420.dll.a libopencv_imgcodecs420.dll.a libopencv_imgproc420.dll.a + LIB_PATH x64/mingw/lib + URL https://github.com/opencv/opencv/archive/4.2.0.tar.gz + MD5 e8cb208ce2723481408b604b480183b6 + CMAKE_OPTION -DCMAKE_BUILD_TYPE=Release -DWITH_PROTOBUF=OFF -DWITH_WEBP=OFF -DWITH_IPP=OFF -DWITH_ADE=OFF + -DBUILD_ZLIB=ON + -DBUILD_JPEG=ON + -DBUILD_PNG=ON + -DBUILD_OPENEXR=ON + -DBUILD_TESTS=OFF + -DBUILD_PERF_TESTS=OFF + -DBUILD_opencv_apps=OFF + -DCMAKE_SKIP_RPATH=TRUE + -DBUILD_opencv_python3=OFF + -DBUILD_opencv_videoio=OFF + -DWITH_FFMPEG=OFF + -DWITH_TIFF=ON + -DBUILD_TIFF=OFF + -DWITH_JASPER=OFF + -DBUILD_JASPER=OFF + -DTIFF_INCLUDE_DIR=${tiff_INC} + -DTIFF_LIBRARY=${tiff_LIB}) +else() + mindspore_add_pkg(opencv + VER 4.2.0 + LIBS opencv_core opencv_imgcodecs opencv_imgproc + URL https://github.com/opencv/opencv/archive/4.2.0.tar.gz + MD5 e8cb208ce2723481408b604b480183b6 + CMAKE_OPTION -DCMAKE_BUILD_TYPE=Release -DWITH_PROTOBUF=OFF -DWITH_WEBP=OFF -DWITH_IPP=OFF -DWITH_ADE=OFF + -DBUILD_ZLIB=ON + -DBUILD_JPEG=ON + -DBUILD_PNG=ON + -DBUILD_OPENEXR=ON + -DBUILD_TESTS=OFF + -DBUILD_PERF_TESTS=OFF + -DBUILD_opencv_apps=OFF + -DCMAKE_SKIP_RPATH=TRUE + -DBUILD_opencv_python3=OFF + -DWITH_FFMPEG=OFF + -DWITH_TIFF=ON + -DBUILD_TIFF=OFF + -DWITH_JASPER=OFF + -DBUILD_JASPER=OFF + -DTIFF_INCLUDE_DIR=${tiff_INC} + -DTIFF_LIBRARY=${tiff_LIB}) +endif() -mindspore_add_pkg(opencv - VER 4.2.0 - LIBS opencv_core opencv_imgcodecs opencv_imgproc - URL https://github.com/opencv/opencv/archive/4.2.0.tar.gz - MD5 e8cb208ce2723481408b604b480183b6 - CMAKE_OPTION -DCMAKE_BUILD_TYPE=Release -DWITH_PROTOBUF=OFF -DWITH_WEBP=OFF -DWITH_IPP=OFF -DWITH_ADE=OFF - -DBUILD_ZLIB=ON - -DBUILD_JPEG=ON - -DBUILD_PNG=ON - -DBUILD_OPENEXR=ON - -DBUILD_TESTS=OFF - -DBUILD_PERF_TESTS=OFF - -DBUILD_opencv_apps=OFF - -DCMAKE_SKIP_RPATH=TRUE - -DBUILD_opencv_python3=OFF - -DWITH_FFMPEG=OFF - -DWITH_TIFF=ON - -DBUILD_TIFF=OFF - -DWITH_JASPER=OFF - -DBUILD_JASPER=OFF - -DTIFF_INCLUDE_DIR=${tiff_INC} - -DTIFF_LIBRARY=${tiff_LIB}) -include_directories(${opencv_INC}/opencv4) -add_library(mindspore::opencv_core ALIAS opencv::opencv_core) -add_library(mindspore::opencv_imgcodecs ALIAS opencv::opencv_imgcodecs) -add_library(mindspore::opencv_imgproc ALIAS opencv::opencv_imgproc) +if (WIN32) + include_directories(${opencv_INC}) + add_library(mindspore::opencv_core ALIAS opencv::libopencv_core420.dll.a) + add_library(mindspore::opencv_imgcodecs ALIAS opencv::libopencv_imgcodecs420.dll.a) + add_library(mindspore::opencv_imgproc ALIAS opencv::libopencv_imgproc420.dll.a) +else() + include_directories(${opencv_INC}/opencv4) + add_library(mindspore::opencv_core ALIAS opencv::opencv_core) + add_library(mindspore::opencv_imgcodecs ALIAS opencv::opencv_imgcodecs) + add_library(mindspore::opencv_imgproc ALIAS opencv::opencv_imgproc) +endif() diff --git a/cmake/external_libs/protobuf.cmake b/cmake/external_libs/protobuf.cmake index c354bcb65d..a574e789db 100644 --- a/cmake/external_libs/protobuf.cmake +++ b/cmake/external_libs/protobuf.cmake @@ -1,22 +1,27 @@ -mindspore_add_pkg(protobuf - VER 3.8.0 - HEAD_ONLY ./ - URL https://github.com/protocolbuffers/protobuf/archive/v3.8.0.tar.gz - MD5 3d9e32700639618a4d2d342c99d4507a) - -set(protobuf_BUILD_TESTS OFF CACHE BOOL "Disable protobuf test") -set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "Gen shared library") +set(protobuf_USE_STATIC_LIBS ON) +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(protobuf_CXXFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -fPIC -fvisibility=hidden -D_FORTIFY_SOURCE=2 -O2") +else() + set(protobuf_CXXFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -fvisibility=hidden -D_FORTIFY_SOURCE=2 -O2") +endif() +set(protobuf_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") set(_ms_tmp_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - +set(CMAKE_CXX_FLAGS ${_ms_tmp_CMAKE_CXX_FLAGS}) string(REPLACE " -Wall" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE " -Werror" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -add_subdirectory(${protobuf_DIRPATH}/cmake ${protobuf_DIRPATH}/build) -set(CMAKE_CXX_FLAGS ${_ms_tmp_CMAKE_CXX_FLAGS}) +mindspore_add_pkg(protobuf + VER 3.8.0 + LIBS protobuf + EXE protoc + URL https://github.com/protocolbuffers/protobuf/archive/v3.8.0.tar.gz + MD5 3d9e32700639618a4d2d342c99d4507a + CMAKE_PATH cmake/ + CMAKE_OPTION -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF) -set(PROTOBUF_LIBRARY protobuf::libprotobuf) -include_directories(${protobuf_DIRPATH}/src) -add_library(mindspore::protobuf ALIAS libprotobuf) +include_directories(${protobuf_INC}) +add_library(mindspore::protobuf ALIAS protobuf::protobuf) +set(CMAKE_CXX_FLAGS ${_ms_tmp_CMAKE_CXX_FLAGS}) function(ms_protobuf_generate c_var h_var) if(NOT ARGN) @@ -72,22 +77,36 @@ function(ms_protobuf_generate_py c_var h_var py_var) list(APPEND ${c_var} "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.cc") list(APPEND ${h_var} "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.h") list(APPEND ${py_var} "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py") - - add_custom_command( - OUTPUT "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.cc" - "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.h" - "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/${rel_path}" - COMMAND protobuf::protoc -I${file_dir} --cpp_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} - COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} - COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} - COMMAND perl -pi -e "s/import (.+_pb2.*)/from . import \\1/" "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" - COMMAND cp "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" "${PROJECT_SOURCE_DIR}/mindspore/train/" - DEPENDS protobuf::protoc ${abs_file} - COMMENT "Running C++ protocol buffer compiler on ${file}" VERBATIM ) + if (WIN32) + add_custom_command( + OUTPUT "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.cc" + "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.h" + "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/${rel_path}" + COMMAND protobuf::protoc -I${file_dir} --cpp_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND perl -pi.bak -e "s/import (.+_pb2.*)/from . import \\1/" "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" "${PROJECT_SOURCE_DIR}/mindspore/train/" + DEPENDS protobuf::protoc ${abs_file} + COMMENT "Running C++ protocol buffer compiler on ${file}" VERBATIM ) + else() + add_custom_command( + OUTPUT "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.cc" + "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}.pb.h" + "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/${rel_path}" + COMMAND protobuf::protoc -I${file_dir} --cpp_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND protobuf::protoc -I${file_dir} --python_out=${CMAKE_BINARY_DIR}/${rel_path} ${abs_file} + COMMAND perl -pi -e "s/import (.+_pb2.*)/from . import \\1/" "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" + COMMAND cp "${CMAKE_BINARY_DIR}/${rel_path}/${file_name}_pb2.py" "${PROJECT_SOURCE_DIR}/mindspore/train/" + DEPENDS protobuf::protoc ${abs_file} + COMMENT "Running C++ protocol buffer compiler on ${file}" VERBATIM ) + endif() endforeach() - set_source_files_properties(${${c_var}} ${${h_var}} ${${py_var}} PROPERTIES GENERATED TRUE) set(${c_var} ${${c_var}} PARENT_SCOPE) set(${h_var} ${${h_var}} PARENT_SCOPE) diff --git a/cmake/external_libs/sqlite.cmake b/cmake/external_libs/sqlite.cmake index 35e48b2d0e..aa6f236917 100644 --- a/cmake/external_libs/sqlite.cmake +++ b/cmake/external_libs/sqlite.cmake @@ -1,15 +1,30 @@ +if (WIN32) + mindspore_add_pkg(sqlite + VER 3.31.1 + LIBS sqlite3 + URL https://sqlite.org/2020/sqlite-amalgamation-3310100.zip + MD5 2b7bfcdd97dc281903a9aee966213fe4 + PATCHES ${CMAKE_SOURCE_DIR}/third_party/patch/sqlite/sqlite.windows.patch001 + CMAKE_OPTION " " + ) -set(sqlite_USE_STATIC_LIBS ON) -set(sqlite_CXXFLAGS) -set(sqlite_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") -set(sqlite_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") - -mindspore_add_pkg(sqlite +else () + set(sqlite_USE_STATIC_LIBS ON) + set(sqlite_CXXFLAGS) + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(sqlite_CFLAGS "-fstack-protector-all -Wno-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") + else() + set(sqlite_CFLAGS "-fstack-protector-all -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -D_FORTIFY_SOURCE=2 -O2") + endif() + set(sqlite_LDFLAGS "-Wl,-z,relro,-z,now,-z,noexecstack") + mindspore_add_pkg(sqlite VER 3.31.1 LIBS sqlite3 URL https://github.com/sqlite/sqlite/archive/version-3.31.1.tar.gz MD5 5f4e7b4016c15f4fb5855615279819da PATCHES ${CMAKE_SOURCE_DIR}/third_party/patch/sqlite/sqlite.patch001 CONFIGURE_COMMAND ./configure --enable-shared=no --disable-tcl --disable-editline --enable-json1) +endif () + include_directories(${sqlite_INC}) -add_library(mindspore::sqlite ALIAS sqlite::sqlite3) \ No newline at end of file +add_library(mindspore::sqlite ALIAS sqlite::sqlite3) diff --git a/cmake/external_libs/tvm_gpu.cmake b/cmake/external_libs/tvm_gpu.cmake index 57a045cb03..2edec52ee1 100644 --- a/cmake/external_libs/tvm_gpu.cmake +++ b/cmake/external_libs/tvm_gpu.cmake @@ -1,8 +1,16 @@ -set(incubator_tvm_gpu_CXXFLAGS "-D_FORTIFY_SOURCE=2 -O2") -set(incubator_tvm_gpu_CFLAGS "-D_FORTIFY_SOURCE=2 -O2") +set(incubator_tvm_gpu_CFLAGS "-pipe -Wall -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2") +set(incubator_tvm_gpu_CXXFLAGS "-std=c++11 -pipe -Wall -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2") +set(USE_CUDA "ON") mindspore_add_pkg(incubator_tvm_gpu VER 0.6.0 - HEAD_ONLY ./ + LIBS tvm URL https://github.com/apache/incubator-tvm/archive/v0.6.0.tar.gz - MD5 9cbbd32545a776023acabbba270449fe) - + MD5 9cbbd32545a776023acabbba270449fe + SUBMODULES ${dlpack_DIRPATH} ${dmlc-core_DIRPATH} ${rang_DIRPATH} + SOURCEMODULES topi/python/topi python/tvm + PATCHES ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/find_library.patch + ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/include.patch + ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/src_pass.patch + CMAKE_OPTION -DBUILD_TESTING=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS=ON) +include_directories(${incubator_tvm_gpu_INC}) +add_library(mindspore::tvm ALIAS incubator_tvm_gpu::tvm) diff --git a/cmake/mind_expression.cmake b/cmake/mind_expression.cmake index af122d4117..7e5e07bdbb 100644 --- a/cmake/mind_expression.cmake +++ b/cmake/mind_expression.cmake @@ -1,6 +1,10 @@ set(SECURE_CXX_FLAGS "") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(SECURE_CXX_FLAGS "-fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack") + if (WIN32) + set(SECURE_CXX_FLAGS "-fstack-protector-all") + else() + set(SECURE_CXX_FLAGS "-fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack") + endif() endif() set(_ms_tmp_CMAKE_CXX_FLAGS_F ${CMAKE_CXX_FLAGS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") diff --git a/cmake/options.cmake b/cmake/options.cmake index 6ec577f312..3e03ed3339 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -19,7 +19,11 @@ option(ENABLE_MPI "enable mpi" OFF) option(ENABLE_AKG "enable akg" OFF) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(OPTION_CXX_FLAGS "${OPTION_CXX_FLAGS} -fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack") + if (WIN32) + set(OPTION_CXX_FLAGS "${OPTION_CXX_FLAGS} -fstack-protector-all") + else() + set(OPTION_CXX_FLAGS "${OPTION_CXX_FLAGS} -fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack") + endif() endif() if (CMAKE_SYSTEM_NAME MATCHES "Darwin") @@ -41,8 +45,8 @@ endif() if (DEBUG_MODE) set(CMAKE_BUILD_TYPE "Debug") -else() add_compile_definitions(MEM_REUSE_DEBUG) +else() set(CMAKE_BUILD_TYPE "Release") endif() @@ -60,6 +64,7 @@ endif() if (ENABLE_GPU) set(ENABLE_GPUQUE ON) + add_compile_definitions(ENABLE_GPU_COLLECTIVE) endif() if (ENABLE_GE) @@ -106,4 +111,4 @@ endif() if(ENABLE_DUMP_E2E) add_compile_definitions(ENABLE_DUMP_E2E) -endif() \ No newline at end of file +endif() diff --git a/cmake/package.cmake b/cmake/package.cmake new file mode 100644 index 0000000000..d35ce0463b --- /dev/null +++ b/cmake/package.cmake @@ -0,0 +1,217 @@ +# include dependency +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +# set package information +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_GENERATOR "External") +set(CPACK_EXTERNAL_PACKAGE_SCRIPT ${CMAKE_SOURCE_DIR}/cmake/package_script.cmake) +set(CPACK_EXTERNAL_ENABLE_STAGING true) +set(CPACK_TEMPORARY_PACKAGE_FILE_NAME ${CMAKE_SOURCE_DIR}/build/package/mindspore) +set(CPACK_TEMPORARY_INSTALL_DIRECTORY ${CMAKE_SOURCE_DIR}/build/package/mindspore) +if (ENABLE_GE) + set(CPACK_MS_BACKEND "ge") + set(CPACK_MS_PACKAGE_NAME "mindspore") +elseif (ENABLE_GPU) + set(CPACK_MS_BACKEND "ms") + set(CPACK_MS_PACKAGE_NAME "mindspore-gpu") +elseif (ENABLE_D) + set(CPACK_MS_BACKEND "ms") + set(CPACK_MS_PACKAGE_NAME "mindspore-ascend") +elseif (ENABLE_CPU) + set(CPACK_MS_BACKEND "ms") + set(CPACK_MS_PACKAGE_NAME "mindspore") +else () + set(CPACK_MS_BACKEND "debug") + set(CPACK_MS_PACKAGE_NAME "mindspore") +endif () +include(CPack) + +# set install path +set(INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries") +set(INSTALL_PY_DIR ".") +set(INSTALL_BASE_DIR ".") + +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + set(INSTALL_LIB_DIR ".") + set(onednn_LIBPATH ${onednn_LIBPATH}/../bin/) + set(glog_LIBPATH ${glog_LIBPATH}/../bin/) + set(opencv_LIBPATH ${opencv_LIBPATH}/../bin/) + set(jpeg_turbo_LIBPATH ${jpeg_turbo_LIBPATH}/../bin/) + set(sqlite_LIBPATH ${sqlite_LIBPATH}/../bin/) +else () + set(INSTALL_LIB_DIR "lib") +endif () + +# set package files +install( + TARGETS _c_expression + DESTINATION ${INSTALL_BASE_DIR} + COMPONENT mindspore +) + +install( + TARGETS mindspore_gvar + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore +) + +if (USE_GLOG) + file(GLOB_RECURSE GLOG_LIB_LIST ${glog_LIBPATH}/libglog*) + install( + FILES ${GLOG_LIB_LIST} + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) +endif () + +if (ENABLE_MINDDATA) + install( + TARGETS _c_dataengine _c_mindrecord + DESTINATION ${INSTALL_BASE_DIR} + COMPONENT mindspore + ) + + file(GLOB_RECURSE OPENCV_LIB_LIST + ${opencv_LIBPATH}/libopencv_core* + ${opencv_LIBPATH}/libopencv_imgcodecs* + ${opencv_LIBPATH}/libopencv_imgproc* + ) + install( + FILES ${OPENCV_LIB_LIST} + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) +endif () + +if (ENABLE_CPU) + if (CMAKE_SYSTEM_NAME MATCHES "Linux") + file(GLOB_RECURSE DNNL_LIB_LIST ${onednn_LIBPATH}/libdnnl${CMAKE_SHARED_LIBRARY_SUFFIX}*) + elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") + file(GLOB_RECURSE DNNL_LIB_LIST ${onednn_LIBPATH}/libdnnl*${CMAKE_SHARED_LIBRARY_SUFFIX}*) + elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") + file(GLOB_RECURSE DNNL_LIB_LIST ${onednn_LIBPATH}/dnnl.dll) + endif () + install( + FILES ${DNNL_LIB_LIST} + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) +endif () + +if (ENABLE_GPU) + if (ENABLE_MPI) + install( + TARGETS _ms_mpi + DESTINATION ${INSTALL_BASE_DIR} + COMPONENT mindspore + ) + install( + TARGETS gpu_collective + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) + endif () + install( + TARGETS gpu_queue + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) +endif () + +if (NOT ENABLE_GE) + if (ENABLE_D) + if (DEFINED ENV{ASCEND_CUSTOM_PATH}) + set(ASCEND_PATH $ENV{ASCEND_CUSTOM_PATH}) + else () + set(ASCEND_PATH /usr/local/Ascend) + endif () + set(ASCEND_DRIVER_PATH ${ASCEND_PATH}/driver/lib64/common) + + install( + FILES + ${CMAKE_BINARY_DIR}/graphengine/src/common/graph/libgraph.so + ${CMAKE_BINARY_DIR}/graphengine/src/ge/common/libge_common.so + ${CMAKE_BINARY_DIR}/graphengine/src/ge/ge_runtime/libge_runtime.so + ${ASCEND_DRIVER_PATH}/libslog.so + ${ASCEND_DRIVER_PATH}/libc_sec.so + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) + elseif (ENABLE_TESTCASES) + install( + FILES + ${CMAKE_BINARY_DIR}/graphengine/src/common/graph/libgraph.so + ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/libslog.so + ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/libc_sec.so + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) + endif () +endif () + +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + get_filename_component(CXX_DIR ${CMAKE_CXX_COMPILER} PATH) + file(GLOB CXX_LIB_LIST ${CXX_DIR}/*.dll) + file(GLOB JPEG_LIB_LIST ${jpeg_turbo_LIBPATH}/*.dll) + file(GLOB SQLITE_LIB_LIST ${sqlite_LIBPATH}/*.dll) + install( + FILES ${CXX_LIB_LIST} ${JPEG_LIB_LIST} ${SQLITE_LIB_LIST} + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) +endif () + +# set python files +file(GLOB MS_PY_LIST ${CMAKE_SOURCE_DIR}/mindspore/*.py) +install( + FILES ${MS_PY_LIST} + DESTINATION ${INSTALL_PY_DIR} + COMPONENT mindspore +) + +install( + DIRECTORY + ${CMAKE_SOURCE_DIR}/mindspore/nn + ${CMAKE_SOURCE_DIR}/mindspore/_extends + ${CMAKE_SOURCE_DIR}/mindspore/parallel + ${CMAKE_SOURCE_DIR}/mindspore/mindrecord + ${CMAKE_SOURCE_DIR}/mindspore/train + ${CMAKE_SOURCE_DIR}/mindspore/model_zoo + ${CMAKE_SOURCE_DIR}/mindspore/common + ${CMAKE_SOURCE_DIR}/mindspore/ops + ${CMAKE_SOURCE_DIR}/mindspore/communication + DESTINATION ${INSTALL_PY_DIR} + COMPONENT mindspore +) + +if (ENABLE_GPU) + install( + DIRECTORY ${CMAKE_SOURCE_DIR}/mindspore/_akg + DESTINATION ${INSTALL_PY_DIR}/../ + COMPONENT mindspore + ) + if (EXISTS ${incubator_tvm_gpu_ROOT}) + file(GLOB_RECURSE GLOG_LIB_LIST ${incubator_tvm_gpu_LIBPATH}/lib*) + install( + FILES ${GLOG_LIB_LIST} + DESTINATION ${INSTALL_LIB_DIR} + COMPONENT mindspore + ) + install( + DIRECTORY + ${incubator_tvm_gpu_ROOT}/topi/python/topi + ${incubator_tvm_gpu_ROOT}/python/tvm + DESTINATION ${INSTALL_PY_DIR}/../_akg + COMPONENT mindspore + ) + endif () +endif () + +if (EXISTS ${CMAKE_SOURCE_DIR}/mindspore/dataset) + install( + DIRECTORY ${CMAKE_SOURCE_DIR}/mindspore/dataset + DESTINATION ${INSTALL_PY_DIR} + COMPONENT mindspore + ) +endif () diff --git a/cmake/package_script.cmake b/cmake/package_script.cmake new file mode 100644 index 0000000000..dcc8ee0ad0 --- /dev/null +++ b/cmake/package_script.cmake @@ -0,0 +1,90 @@ +# find exec +find_package(Python3 3.7 COMPONENTS Interpreter Development) +if (NOT Python3_FOUND) + message("No python3 found.") + return () +endif () + +set(PYTHON ${Python3_EXECUTABLE}) +set(PYTHON_VERSION ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) + +find_package(Git) +if (NOT GIT_FOUND) + message("No git found.") + return () +endif () +set(GIT ${GIT_EXECUTABLE}) + +# set path +set(MS_ROOT_DIR ${CPACK_PACKAGE_DIRECTORY}/../../) +set(MS_PACK_ROOT_DIR ${MS_ROOT_DIR}/build/package) + +# set package file name +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + if (PYTHON_VERSION MATCHES "3.7") + set(PY_TAGS "cp37-cp37m") + else () + message("Could not find 'Python 3.7'") + return() + endif () + string(TOLOWER linux_${CMAKE_HOST_SYSTEM_PROCESSOR} PLATFORM_TAG) +elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") + if (PYTHON_VERSION MATCHES "3.7") + set(PY_TAGS "py37-none") + else () + message("Could not find 'Python 3.7'") + return() + endif () + set(PLATFORM_TAG "any") +elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") + if (PYTHON_VERSION MATCHES "3.7") + set(PY_TAGS "cp37-cp37m") + else () + message("Could not find 'Python 3.7'") + return() + endif () + set(PLATFORM_TAG "win_amd64") +else () + message(FATAL_ERROR "other platform: ${CMAKE_SYSTEM_NAME}") +endif () + +# get git commit id +set(GIT_COMMIT_ID "") +execute_process( + COMMAND ${GIT} log --format='[sha1]:%h,[branch]:%d' -1 + OUTPUT_VARIABLE GIT_COMMIT_ID + WORKING_DIRECTORY ${MS_ROOT_DIR} + ERROR_QUIET) +string(REPLACE " " "" GIT_COMMIT_ID ${GIT_COMMIT_ID}) + +set(ENV{BACKEND_POLICY} ${CPACK_MS_BACKEND}) +set(ENV{MS_PACKAGE_NAME} ${CPACK_MS_PACKAGE_NAME}) +set(ENV{COMMIT_ID} ${GIT_COMMIT_ID}) + +execute_process( + COMMAND ${PYTHON} ${MS_ROOT_DIR}/setup.py "bdist_wheel" + WORKING_DIRECTORY ${MS_PACK_ROOT_DIR} +) + +# finally +set(PACKAGE_NAME ${CPACK_MS_PACKAGE_NAME}) +if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") + string(REPLACE "-" "_" PACKAGE_NAME ${PACKAGE_NAME}) + execute_process( + COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/mindspore/ + COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/${PACKAGE_NAME}.egg-info/ + ) +endif () + +file(GLOB WHL_FILE ${MS_PACK_ROOT_DIR}/dist/*.whl) +get_filename_component(ORIGIN_FILE_NAME ${WHL_FILE} NAME) +string(REPLACE "-" ";" ORIGIN_FILE_NAME ${ORIGIN_FILE_NAME}) +list(GET ORIGIN_FILE_NAME 1 VERSION) +set(NEW_FILE_NAME ${PACKAGE_NAME}-${VERSION}-${PY_TAGS}-${PLATFORM_TAG}.whl) +file(RENAME ${WHL_FILE} ${MS_PACK_ROOT_DIR}/${NEW_FILE_NAME}) +file(REMOVE_RECURSE ${MS_ROOT_DIR}/output) +file(MAKE_DIRECTORY ${MS_ROOT_DIR}/output) +file(COPY ${MS_PACK_ROOT_DIR}/${NEW_FILE_NAME} DESTINATION ${MS_ROOT_DIR}/output/) + +file(SHA256 ${MS_ROOT_DIR}/output/${NEW_FILE_NAME} SHA256_VAR) +file(WRITE ${MS_ROOT_DIR}/output/${NEW_FILE_NAME}.sha256 ${SHA256_VAR} " " ${NEW_FILE_NAME}) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 99c064fdd4..501522a44b 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -1,6 +1,10 @@ include(FetchContent) set(FETCHCONTENT_QUIET OFF) +if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.17.0) + set(CMAKE_FIND_LIBRARY_SUFFIXES .dll ${CMAKE_FIND_LIBRARY_SUFFIXES}) +endif () + function(mindspore_add_submodule_obj des_submodule_objs sub_dir submodule_name_obj) add_subdirectory(${sub_dir}) @@ -103,7 +107,7 @@ function(__download_pkg_with_git pkg_name pkg_url pkg_git_commit pkg_md5) endfunction() -function(__find_pkg_then_add_target pkg_name pkg_exe) +function(__find_pkg_then_add_target pkg_name pkg_exe lib_path) unset(${pkg_name}_LIBS) @@ -129,15 +133,24 @@ function(__find_pkg_then_add_target pkg_name pkg_exe) set(_LIB_TYPE STATIC) endif () set(${_LIB_NAME}_LIB ${_LIB_NAME}_LIB-NOTFOUND) - find_library(${_LIB_NAME}_LIB ${_LIB_SEARCH_NAME} PATHS ${${pkg_name}_BASE_DIR}/lib NO_DEFAULT_PATH) + find_library(${_LIB_NAME}_LIB ${_LIB_SEARCH_NAME} PATHS ${${pkg_name}_BASE_DIR}/${lib_path} NO_DEFAULT_PATH) + if(NOT ${_LIB_NAME}_LIB) return() endif() + add_library(${pkg_name}::${_LIB_NAME} ${_LIB_TYPE} IMPORTED GLOBAL) - set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${${pkg_name}_BASE_DIR}/include" - IMPORTED_LOCATION ${${_LIB_NAME}_LIB} - ) + if (WIN32 AND ${_LIB_TYPE} STREQUAL "SHARED") + set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_IMPLIB_RELEASE ${${_LIB_NAME}_LIB}) + else() + set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${${_LIB_NAME}_LIB}) + endif() + + if (EXISTS ${${pkg_name}_BASE_DIR}/include) + set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${pkg_name}_BASE_DIR}/include") + endif () + list(APPEND ${pkg_name}_LIBS ${pkg_name}::${_LIB_NAME}) message("found ${${_LIB_NAME}_LIB}") STRING( REGEX REPLACE "(.+)/(.+)" "\\1" LIBPATH ${${_LIB_NAME}_LIB}) @@ -192,10 +205,18 @@ set(MS_FIND_NO_DEFAULT_PATH ${MS_FIND_NO_DEFAULT_PATH} PARENT_SCOPE) function(mindspore_add_pkg pkg_name ) set(options ) - set(oneValueArgs URL MD5 GIT_REPOSITORY GIT_TAG VER EXE DIR HEAD_ONLY) - set(multiValueArgs CMAKE_OPTION LIBS PRE_CONFIGURE_COMMAND CONFIGURE_COMMAND BUILD_OPTION INSTALL_INCS INSTALL_LIBS PATCHES) + set(oneValueArgs URL MD5 GIT_REPOSITORY GIT_TAG VER EXE DIR HEAD_ONLY CMAKE_PATH RELEASE LIB_PATH) + set(multiValueArgs CMAKE_OPTION LIBS PRE_CONFIGURE_COMMAND CONFIGURE_COMMAND BUILD_OPTION INSTALL_INCS INSTALL_LIBS PATCHES SUBMODULES SOURCEMODULES) cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + if (NOT PKG_LIB_PATH) + set(PKG_LIB_PATH lib) + endif () + + if(NOT PKG_EXE) + set(PKG_EXE 0) + endif() + set(__FIND_PKG_NAME ${pkg_name}) string(TOLOWER ${pkg_name} pkg_name) message("pkg name:${__FIND_PKG_NAME},${pkg_name}") @@ -223,18 +244,17 @@ function(mindspore_add_pkg pkg_name ) set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/${PKG_HEAD_ONLY} PARENT_SCOPE) add_library(${pkg_name} INTERFACE) target_include_directories(${pkg_name} INTERFACE ${${pkg_name}_INC}) + if (${PKG_RELEASE}) + __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH} ${PKG_LIBS}) + endif () return() endif () - if(NOT PKG_EXE) - set(PKG_EXE 0) - endif() - set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR}) set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR} PARENT_SCOPE) if (PKG_LIBS) - __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIBS}) + __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH} ${PKG_LIBS}) if(${pkg_name}_LIBS) set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE) message("Found libs: ${${pkg_name}_LIBS}") @@ -250,11 +270,21 @@ function(mindspore_add_pkg pkg_name ) endif () if (NOT PKG_DIR) - if (PKG_GIT_REPOSITORY) - __download_pkg_with_git(${pkg_name} ${PKG_GIT_REPOSITORY} ${PKG_GIT_TAG} ${PKG_MD5}) - else() + if (PKG_GIT_REPOSITORY) + __download_pkg_with_git(${pkg_name} ${PKG_GIT_REPOSITORY} ${PKG_GIT_TAG} ${PKG_MD5}) + else() __download_pkg(${pkg_name} ${PKG_URL} ${PKG_MD5}) - endif() + endif() + foreach(_SUBMODULE_FILE ${PKG_SUBMODULES}) + STRING( REGEX REPLACE "(.+)_(.+)" "\\1" _SUBMODEPATH ${_SUBMODULE_FILE}) + STRING( REGEX REPLACE "(.+)/(.+)" "\\2" _SUBMODENAME ${_SUBMODEPATH}) + file(GLOB ${pkg_name}_INSTALL_SUBMODULE ${_SUBMODULE_FILE}/*) + file(COPY ${${pkg_name}_INSTALL_SUBMODULE} DESTINATION ${${pkg_name}_SOURCE_DIR}/3rdparty/${_SUBMODENAME}) + endforeach (_SUBMODULE_FILE) + foreach(_SOURCE_DIR ${PKG_SOURCEMODULES}) + file(GLOB ${pkg_name}_INSTALL_SOURCE ${${pkg_name}_SOURCE_DIR}/${_SOURCE_DIR}/*) + file(COPY ${${pkg_name}_INSTALL_SOURCE} DESTINATION ${${pkg_name}_BASE_DIR}/${_SOURCE_DIR}/) + endforeach (_SUBMODULE_FILE) else() set(${pkg_name}_SOURCE_DIR ${PKG_DIR}) endif () @@ -262,12 +292,16 @@ function(mindspore_add_pkg pkg_name ) message("${pkg_name}_SOURCE_DIR : ${${pkg_name}_SOURCE_DIR}") foreach(_PATCH_FILE ${PKG_PATCHES}) - message("patching ${${pkg_name}_SOURCE_DIR} -p1 < ${_PATCH_FILE}") - execute_process(COMMAND patch -p1 INPUT_FILE ${_PATCH_FILE} + get_filename_component(_PATCH_FILE_NAME ${_PATCH_FILE} NAME) + set(_LF_PATCH_FILE ${CMAKE_BINARY_DIR}/_ms_patch/${_PATCH_FILE_NAME}) + configure_file(${_PATCH_FILE} ${_LF_PATCH_FILE} NEWLINE_STYLE LF) + + message("patching ${${pkg_name}_SOURCE_DIR} -p1 < ${_LF_PATCH_FILE}") + execute_process(COMMAND ${Patch_EXECUTABLE} -p1 INPUT_FILE ${_LF_PATCH_FILE} WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR} RESULT_VARIABLE Result) if(NOT Result EQUAL "0") - message(FATAL_ERROR "Failed patch: ${_PATCH_FILE}") + message(FATAL_ERROR "Failed patch: ${_LF_PATCH_FILE}") endif() endforeach(_PATCH_FILE) @@ -281,8 +315,10 @@ function(mindspore_add_pkg pkg_name ) file(GLOB ${pkg_name}_SOURCE_SUBDIRS ${${pkg_name}_SOURCE_DIR}/*) file(COPY ${${pkg_name}_SOURCE_SUBDIRS} DESTINATION ${${pkg_name}_BASE_DIR}) set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/${PKG_HEAD_ONLY} PARENT_SCOPE) - add_library(${pkg_name} INTERFACE) - target_include_directories(${pkg_name} INTERFACE ${${pkg_name}_INC}) + if (NOT PKG_RELEASE) + add_library(${pkg_name} INTERFACE) + target_include_directories(${pkg_name} INTERFACE ${${pkg_name}_INC}) + endif () elseif (PKG_CMAKE_OPTION) # in cmake @@ -304,7 +340,7 @@ function(mindspore_add_pkg pkg_name ) __exec_cmd(COMMAND ${CMAKE_COMMAND} ${PKG_CMAKE_OPTION} -G ${CMAKE_GENERATOR} ${${pkg_name}_CMAKE_CFLAGS} ${${pkg_name}_CMAKE_CXXFLAGS} ${${pkg_name}_CMAKE_LDFLAGS} - -DCMAKE_INSTALL_PREFIX=${${pkg_name}_BASE_DIR} .. + -DCMAKE_INSTALL_PREFIX=${${pkg_name}_BASE_DIR} ${${pkg_name}_SOURCE_DIR}/${PKG_CMAKE_PATH} WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build) __exec_cmd(COMMAND ${CMAKE_COMMAND} --build . --target install -- -j${THNUM} @@ -353,7 +389,7 @@ function(mindspore_add_pkg pkg_name ) endif() if (PKG_LIBS) - __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIBS}) + __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH} ${PKG_LIBS}) set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE) if(NOT ${pkg_name}_LIBS) message(FATAL_ERROR "Can not find pkg: ${pkg_name}") diff --git a/docker/README.md b/docker/README.md index 76eae12f88..c6851fe531 100644 --- a/docker/README.md +++ b/docker/README.md @@ -7,17 +7,11 @@ This folder hosts all the `Dockerfile` to build MindSpore container images with * CPU ``` - cd mindspore-cpu && docker build . -t mindspore/mindspore-cpu:0.1.0-alpha + cd mindspore-cpu/0.1.0-alpha && docker build . -t mindspore/mindspore-cpu:0.1.0-alpha ``` -* GPU (CUDA 9.2) +* GPU ``` - cd mindspore-cuda9.2 && docker build . -t mindspore/mindspore-cuda9.2:0.1.0-alpha - ``` - -* GPU (CUDA 10.1) - - ``` - cd mindspore-cuda10.1 && docker build . -t mindspore/mindspore-cuda10.1:0.1.0-alpha + cd mindspore-gpu/0.1.0-alpha && docker build . -t mindspore/mindspore-gpu:0.1.0-alpha ``` diff --git a/docker/mindspore-cuda9.2/Dockerfile b/docker/mindspore-cpu/0.1.0-alpha/Dockerfile similarity index 69% rename from docker/mindspore-cuda9.2/Dockerfile rename to docker/mindspore-cpu/0.1.0-alpha/Dockerfile index 6e40106396..c9fb7c2b88 100644 --- a/docker/mindspore-cuda9.2/Dockerfile +++ b/docker/mindspore-cpu/0.1.0-alpha/Dockerfile @@ -1,11 +1,10 @@ -FROM nvidia/cuda:9.2-cudnn7-devel-ubuntu18.04 +FROM ubuntu:18.04 MAINTAINER leonwanghui # Set env ENV PYTHON_ROOT_PATH /usr/local/python-3.7.5 -ENV CMAKE_ROOT_PATH /usr/local/cmake-3.14.1 -ENV PATH ${PYTHON_ROOT_PATH}/bin:${CMAKE_ROOT_PATH}/bin:/usr/local/bin:$PATH +ENV PATH /usr/local/bin:$PATH # Install base tools RUN apt update \ @@ -64,20 +63,5 @@ RUN mkdir -pv /root/.pip \ && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf -# Install pip package -RUN pip install --no-cache-dir \ - numpy \ - wheel \ - nose \ - pytest \ - pytest-xdist - -# Install cmake (v3.14.1) -RUN cd /tmp \ - && wget https://github.com/Kitware/CMake/releases/download/v3.14.1/cmake-3.14.1-Linux-x86_64.sh \ - && mkdir -p ${CMAKE_ROOT_PATH} \ - && bash ./cmake-3.14.1-Linux-x86_64.sh --prefix=${CMAKE_ROOT_PATH} --exclude-subdir --skip-license \ - && rm -f /tmp/cmake-3.14.1-Linux-x86_64.sh - -# Install MindSpore cuda-9.2 whl package -RUN pip install --no-cache-dir https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/gpu/cuda-9.2/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl +# Install MindSpore cpu whl package +RUN pip install --no-cache-dir https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/cpu/ubuntu-x86/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl diff --git a/docker/mindspore-cpu/Dockerfile b/docker/mindspore-cpu/devel/Dockerfile similarity index 86% rename from docker/mindspore-cpu/Dockerfile rename to docker/mindspore-cpu/devel/Dockerfile index d24d23cf6b..77c422ef90 100644 --- a/docker/mindspore-cpu/Dockerfile +++ b/docker/mindspore-cpu/devel/Dockerfile @@ -62,15 +62,8 @@ RUN apt install -y libffi-dev libssl-dev zlib1g-dev libbz2-dev libncurses5-dev \ RUN mkdir -pv /root/.pip \ && echo "[global]" > /root/.pip/pip.conf \ && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ - && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf - -# Install pip package -RUN pip install --no-cache-dir \ - numpy \ - wheel \ - nose \ - pytest \ - pytest-xdist + && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf \ + && pip install --no-cache-dir wheel # Install cmake (v3.14.1) RUN cd /tmp \ @@ -78,6 +71,3 @@ RUN cd /tmp \ && mkdir -p ${CMAKE_ROOT_PATH} \ && bash ./cmake-3.14.1-Linux-x86_64.sh --prefix=${CMAKE_ROOT_PATH} --exclude-subdir --skip-license \ && rm -f /tmp/cmake-3.14.1-Linux-x86_64.sh - -# Install MindSpore cpu whl package -RUN pip install --no-cache-dir https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/cpu/ubuntu-x86/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl diff --git a/docker/mindspore-cpu/runtime/Dockerfile b/docker/mindspore-cpu/runtime/Dockerfile new file mode 100644 index 0000000000..ccf5f297a0 --- /dev/null +++ b/docker/mindspore-cpu/runtime/Dockerfile @@ -0,0 +1,64 @@ +FROM ubuntu:18.04 + +MAINTAINER leonwanghui + +# Set env +ENV PYTHON_ROOT_PATH /usr/local/python-3.7.5 +ENV PATH /usr/local/bin:$PATH + +# Install base tools +RUN apt update \ + && DEBIAN_FRONTEND=noninteractive apt install -y \ + vim \ + wget \ + curl \ + xz-utils \ + net-tools \ + openssh-client \ + git \ + ntpdate \ + tzdata \ + tcl \ + sudo \ + bash-completion + +# Install compile tools +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + gcc \ + g++ \ + zlibc \ + make \ + libgmp-dev \ + patch \ + autoconf \ + libtool \ + automake \ + flex + +# Set bash +RUN echo "dash dash/sh boolean false" | debconf-set-selections +RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash + +# Install python (v3.7.5) +RUN apt install -y libffi-dev libssl-dev zlib1g-dev libbz2-dev libncurses5-dev \ + libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libsqlite3-dev \ + && cd /tmp \ + && wget https://github.com/python/cpython/archive/v3.7.5.tar.gz \ + && tar -xvf v3.7.5.tar.gz \ + && cd /tmp/cpython-3.7.5 \ + && mkdir -p ${PYTHON_ROOT_PATH} \ + && ./configure --prefix=${PYTHON_ROOT_PATH} \ + && make -j4 \ + && make install -j4 \ + && rm -f /usr/local/bin/python \ + && rm -f /usr/local/bin/pip \ + && ln -s ${PYTHON_ROOT_PATH}/bin/python3.7 /usr/local/bin/python \ + && ln -s ${PYTHON_ROOT_PATH}/bin/pip3.7 /usr/local/bin/pip \ + && rm -rf /tmp/cpython-3.7.5 \ + && rm -f /tmp/v3.7.5.tar.gz + +# Set pip source +RUN mkdir -pv /root/.pip \ + && echo "[global]" > /root/.pip/pip.conf \ + && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ + && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf diff --git a/docker/mindspore-gpu/0.1.0-alpha/Dockerfile b/docker/mindspore-gpu/0.1.0-alpha/Dockerfile new file mode 100644 index 0000000000..50ca2b9f08 --- /dev/null +++ b/docker/mindspore-gpu/0.1.0-alpha/Dockerfile @@ -0,0 +1,83 @@ +FROM nvidia/cuda:10.1-cudnn7-runtime-ubuntu18.04 + +MAINTAINER leonwanghui + +# Set env +ENV PYTHON_ROOT_PATH /usr/local/python-3.7.5 +ENV OMPI_ROOT_PATH /usr/local/openmpi-3.1.5 +ENV PATH ${OMPI_ROOT_PATH}/bin:/usr/local/bin:$PATH +ENV LD_LIBRARY_PATH ${OMPI_ROOT_PATH}/lib:$LD_LIBRARY_PATH + +# Install base tools +RUN apt update \ + && DEBIAN_FRONTEND=noninteractive apt install -y \ + vim \ + wget \ + curl \ + xz-utils \ + net-tools \ + openssh-client \ + git \ + ntpdate \ + tzdata \ + tcl \ + sudo \ + bash-completion + +# Install compile tools +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + gcc \ + g++ \ + zlibc \ + make \ + libgmp-dev \ + patch \ + autoconf \ + libtool \ + automake \ + flex \ + libnccl2=2.4.8-1+cuda10.1 \ + libnccl-dev=2.4.8-1+cuda10.1 + +# Set bash +RUN echo "dash dash/sh boolean false" | debconf-set-selections +RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash + +# Install python (v3.7.5) +RUN apt install -y libffi-dev libssl-dev zlib1g-dev libbz2-dev libncurses5-dev \ + libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libsqlite3-dev \ + && cd /tmp \ + && wget https://github.com/python/cpython/archive/v3.7.5.tar.gz \ + && tar -xvf v3.7.5.tar.gz \ + && cd /tmp/cpython-3.7.5 \ + && mkdir -p ${PYTHON_ROOT_PATH} \ + && ./configure --prefix=${PYTHON_ROOT_PATH} \ + && make -j4 \ + && make install -j4 \ + && rm -f /usr/local/bin/python \ + && rm -f /usr/local/bin/pip \ + && ln -s ${PYTHON_ROOT_PATH}/bin/python3.7 /usr/local/bin/python \ + && ln -s ${PYTHON_ROOT_PATH}/bin/pip3.7 /usr/local/bin/pip \ + && rm -rf /tmp/cpython-3.7.5 \ + && rm -f /tmp/v3.7.5.tar.gz + +# Set pip source +RUN mkdir -pv /root/.pip \ + && echo "[global]" > /root/.pip/pip.conf \ + && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ + && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf + +# Install openmpi (v3.1.5) +RUN cd /tmp \ + && wget https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.5.tar.gz \ + && tar -xvf openmpi-3.1.5.tar.gz \ + && cd /tmp/openmpi-3.1.5 \ + && mkdir -p ${OMPI_ROOT_PATH} \ + && ./configure --prefix=${OMPI_ROOT_PATH} \ + && make -j4 \ + && make install -j4 \ + && rm -rf /tmp/openmpi-3.1.5 \ + && rm -f /tmp/openmpi-3.1.5.tar.gz + +# Install MindSpore cuda-10.1 whl package +RUN pip install --no-cache-dir https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/gpu/cuda-10.1/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl diff --git a/docker/mindspore-cuda10.1/Dockerfile b/docker/mindspore-gpu/devel/Dockerfile similarity index 83% rename from docker/mindspore-cuda10.1/Dockerfile rename to docker/mindspore-gpu/devel/Dockerfile index e2a1ee955a..fe88bd9a2c 100644 --- a/docker/mindspore-cuda10.1/Dockerfile +++ b/docker/mindspore-gpu/devel/Dockerfile @@ -5,7 +5,7 @@ MAINTAINER leonwanghui # Set env ENV PYTHON_ROOT_PATH /usr/local/python-3.7.5 ENV CMAKE_ROOT_PATH /usr/local/cmake-3.14.1 -ENV PATH ${PYTHON_ROOT_PATH}/bin:${CMAKE_ROOT_PATH}/bin:/usr/local/bin:$PATH +ENV PATH ${CMAKE_ROOT_PATH}/bin:/usr/local/bin:$PATH # Install base tools RUN apt update \ @@ -36,6 +36,9 @@ RUN DEBIAN_FRONTEND=noninteractive apt install -y \ automake \ flex +# Configure cuDNN (v7.6.5) +RUN ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5 /usr/local/cuda/lib64/libcudnn.so + # Set bash RUN echo "dash dash/sh boolean false" | debconf-set-selections RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash @@ -62,15 +65,8 @@ RUN apt install -y libffi-dev libssl-dev zlib1g-dev libbz2-dev libncurses5-dev \ RUN mkdir -pv /root/.pip \ && echo "[global]" > /root/.pip/pip.conf \ && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ - && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf - -# Install pip package -RUN pip install --no-cache-dir \ - numpy \ - wheel \ - nose \ - pytest \ - pytest-xdist + && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf \ + && pip install --no-cache-dir wheel # Install cmake (v3.14.1) RUN cd /tmp \ @@ -78,6 +74,3 @@ RUN cd /tmp \ && mkdir -p ${CMAKE_ROOT_PATH} \ && bash ./cmake-3.14.1-Linux-x86_64.sh --prefix=${CMAKE_ROOT_PATH} --exclude-subdir --skip-license \ && rm -f /tmp/cmake-3.14.1-Linux-x86_64.sh - -# Install MindSpore cuda-10.1 whl package -RUN pip install --no-cache-dir https://ms-release.obs.cn-north-4.myhuaweicloud.com/0.1.0-alpha/MindSpore/gpu/cuda-10.1/mindspore-0.1.0-cp37-cp37m-linux_x86_64.whl diff --git a/docker/mindspore-gpu/runtime/Dockerfile b/docker/mindspore-gpu/runtime/Dockerfile new file mode 100644 index 0000000000..9e8dabe594 --- /dev/null +++ b/docker/mindspore-gpu/runtime/Dockerfile @@ -0,0 +1,80 @@ +FROM nvidia/cuda:10.1-cudnn7-runtime-ubuntu18.04 + +MAINTAINER leonwanghui + +# Set env +ENV PYTHON_ROOT_PATH /usr/local/python-3.7.5 +ENV OMPI_ROOT_PATH /usr/local/openmpi-3.1.5 +ENV PATH ${OMPI_ROOT_PATH}/bin:/usr/local/bin:$PATH +ENV LD_LIBRARY_PATH ${OMPI_ROOT_PATH}/lib:$LD_LIBRARY_PATH + +# Install base tools +RUN apt update \ + && DEBIAN_FRONTEND=noninteractive apt install -y \ + vim \ + wget \ + curl \ + xz-utils \ + net-tools \ + openssh-client \ + git \ + ntpdate \ + tzdata \ + tcl \ + sudo \ + bash-completion + +# Install compile tools +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + gcc \ + g++ \ + zlibc \ + make \ + libgmp-dev \ + patch \ + autoconf \ + libtool \ + automake \ + flex \ + libnccl2=2.4.8-1+cuda10.1 \ + libnccl-dev=2.4.8-1+cuda10.1 + +# Set bash +RUN echo "dash dash/sh boolean false" | debconf-set-selections +RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash + +# Install python (v3.7.5) +RUN apt install -y libffi-dev libssl-dev zlib1g-dev libbz2-dev libncurses5-dev \ + libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libsqlite3-dev \ + && cd /tmp \ + && wget https://github.com/python/cpython/archive/v3.7.5.tar.gz \ + && tar -xvf v3.7.5.tar.gz \ + && cd /tmp/cpython-3.7.5 \ + && mkdir -p ${PYTHON_ROOT_PATH} \ + && ./configure --prefix=${PYTHON_ROOT_PATH} \ + && make -j4 \ + && make install -j4 \ + && rm -f /usr/local/bin/python \ + && rm -f /usr/local/bin/pip \ + && ln -s ${PYTHON_ROOT_PATH}/bin/python3.7 /usr/local/bin/python \ + && ln -s ${PYTHON_ROOT_PATH}/bin/pip3.7 /usr/local/bin/pip \ + && rm -rf /tmp/cpython-3.7.5 \ + && rm -f /tmp/v3.7.5.tar.gz + +# Set pip source +RUN mkdir -pv /root/.pip \ + && echo "[global]" > /root/.pip/pip.conf \ + && echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf \ + && echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf + +# Install openmpi (v3.1.5) +RUN cd /tmp \ + && wget https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.5.tar.gz \ + && tar -xvf openmpi-3.1.5.tar.gz \ + && cd /tmp/openmpi-3.1.5 \ + && mkdir -p ${OMPI_ROOT_PATH} \ + && ./configure --prefix=${OMPI_ROOT_PATH} \ + && make -j4 \ + && make install -j4 \ + && rm -rf /tmp/openmpi-3.1.5 \ + && rm -f /tmp/openmpi-3.1.5.tar.gz diff --git a/example/Bert_NEZHA_cnwiki/train.py b/example/Bert_NEZHA_cnwiki/train.py index 86e033fc9f..2610542a9a 100644 --- a/example/Bert_NEZHA_cnwiki/train.py +++ b/example/Bert_NEZHA_cnwiki/train.py @@ -39,6 +39,7 @@ import mindspore.dataset.engine.datasets as de import mindspore.dataset.transforms.c_transforms as C from mindspore import context from mindspore.common.tensor import Tensor +import mindspore.common.dtype as mstype from mindspore.train.model import Model from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor from mindspore.model_zoo.Bert_NEZHA import BertNetworkWithLoss, BertTrainOneStepCell @@ -49,9 +50,9 @@ def create_train_dataset(batch_size): """create train dataset""" # apply repeat operations repeat_count = bert_train_cfg.epoch_size - ds = de.StorageDataset([bert_train_cfg.DATA_DIR], bert_train_cfg.SCHEMA_DIR, - columns_list=["input_ids", "input_mask", "segment_ids", "next_sentence_labels", - "masked_lm_positions", "masked_lm_ids", "masked_lm_weights"]) + ds = de.TFRecordDataset([bert_train_cfg.DATA_DIR], bert_train_cfg.SCHEMA_DIR, + columns_list=["input_ids", "input_mask", "segment_ids", "next_sentence_labels", + "masked_lm_positions", "masked_lm_ids", "masked_lm_weights"]) type_cast_op = C.TypeCast(mstype.int32) ds = ds.map(input_columns="masked_lm_ids", operations=type_cast_op) ds = ds.map(input_columns="masked_lm_positions", operations=type_cast_op) diff --git a/example/yolov3_coco2017/dataset.py b/example/yolov3_coco2017/dataset.py index 826fe16c53..9c6a0f362d 100644 --- a/example/yolov3_coco2017/dataset.py +++ b/example/yolov3_coco2017/dataset.py @@ -22,7 +22,6 @@ from PIL import Image from matplotlib.colors import rgb_to_hsv, hsv_to_rgb import mindspore.dataset as de from mindspore.mindrecord import FileWriter -import mindspore.dataset.transforms.vision.py_transforms as P import mindspore.dataset.transforms.vision.c_transforms as C from config import ConfigYOLOV3ResNet18 @@ -301,13 +300,12 @@ def create_yolo_dataset(mindrecord_dir, batch_size=32, repeat_num=10, device_num compose_map_func = (lambda image, annotation: preprocess_fn(image, annotation, is_training)) if is_training: - hwc_to_chw = P.HWC2CHW() + hwc_to_chw = C.HWC2CHW() ds = ds.map(input_columns=["image", "annotation"], output_columns=["image", "bbox_1", "bbox_2", "bbox_3", "gt_box1", "gt_box2", "gt_box3"], columns_order=["image", "bbox_1", "bbox_2", "bbox_3", "gt_box1", "gt_box2", "gt_box3"], operations=compose_map_func, num_parallel_workers=num_parallel_workers) ds = ds.map(input_columns=["image"], operations=hwc_to_chw, num_parallel_workers=num_parallel_workers) - ds = ds.shuffle(buffer_size=256) ds = ds.batch(batch_size, drop_remainder=True) ds = ds.repeat(repeat_num) else: diff --git a/example/yolov3_coco2017/run_distribute_train.sh b/example/yolov3_coco2017/run_distribute_train.sh index 0c43e776b9..201f19ca16 100644 --- a/example/yolov3_coco2017/run_distribute_train.sh +++ b/example/yolov3_coco2017/run_distribute_train.sh @@ -19,6 +19,7 @@ echo "Please run the scipt as: " echo "sh run_distribute_train.sh DEVICE_NUM EPOCH_SIZE MINDRECORD_DIR IMAGE_DIR ANNO_PATH MINDSPORE_HCCL_CONFIG_PATH" echo "for example: sh run_distribute_train.sh 8 100 /data/Mindrecord_train /data /data/train.txt /data/hccl.json" echo "It is better to use absolute path." +echo "The learning rate is 0.005 as default, if you want other lr, please change the value in this script." echo "==============================================================================================================" EPOCH_SIZE=$2 @@ -38,6 +39,11 @@ export RANK_SIZE=$1 for((i=0;i env.log - python ../train.py \ + taskset -c $cmdopt python ../train.py \ --distribute=1 \ + --lr=0.005 \ --device_num=$RANK_SIZE \ --device_id=$DEVICE_ID \ --mindrecord_dir=$MINDRECORD_DIR \ diff --git a/example/yolov3_coco2017/train.py b/example/yolov3_coco2017/train.py index 121e2aa810..c7d28a8350 100644 --- a/example/yolov3_coco2017/train.py +++ b/example/yolov3_coco2017/train.py @@ -67,6 +67,7 @@ if __name__ == '__main__': parser.add_argument("--distribute", type=bool, default=False, help="Run distribute, default is false.") parser.add_argument("--device_id", type=int, default=0, help="Device id, default is 0.") parser.add_argument("--device_num", type=int, default=1, help="Use device nums, default is 1.") + parser.add_argument("--lr", type=float, default=0.001, help="Learning rate, default is 0.001.") parser.add_argument("--mode", type=str, default="sink", help="Run sink mode or not, default is sink") parser.add_argument("--epoch_size", type=int, default=10, help="Epoch size, default is 10") parser.add_argument("--batch_size", type=int, default=32, help="Batch size, default is 32.") @@ -137,8 +138,8 @@ if __name__ == '__main__': ckpt_config = CheckpointConfig(save_checkpoint_steps=dataset_size * args_opt.save_checkpoint_epochs) ckpoint_cb = ModelCheckpoint(prefix="yolov3", directory=None, config=ckpt_config) - lr = Tensor(get_lr(learning_rate=0.001, start_step=0, global_step=args_opt.epoch_size * dataset_size, - decay_step=1000, decay_rate=0.95)) + lr = Tensor(get_lr(learning_rate=args_opt.lr, start_step=0, global_step=args_opt.epoch_size * dataset_size, + decay_step=1000, decay_rate=0.95, steps=True)) opt = nn.Adam(filter(lambda x: x.requires_grad, net.get_parameters()), lr, loss_scale=loss_scale) net = TrainingWrapper(net, opt, loss_scale) diff --git a/graphengine b/graphengine index 71e3e4ac0f..70bb745b45 160000 --- a/graphengine +++ b/graphengine @@ -1 +1 @@ -Subproject commit 71e3e4ac0fd9a1a229f0f07ba273162d27bdbb65 +Subproject commit 70bb745b459ff9a0e7fc1008d15fe4b510f03da7 diff --git a/mindspore/akg/__init__.py b/mindspore/_akg/__init__.py similarity index 88% rename from mindspore/akg/__init__.py rename to mindspore/_akg/__init__.py index a0c0364bd6..e3dceaf35e 100644 --- a/mindspore/akg/__init__.py +++ b/mindspore/_akg/__init__.py @@ -18,7 +18,7 @@ import sys import os def AKGAddPath(): - """akg add path.""" + """_akg add path.""" pwd = os.path.dirname(os.path.realpath(__file__)) tvm_path = os.path.realpath(pwd) if tvm_path not in sys.path: @@ -32,12 +32,12 @@ class AKGMetaPathFinder: """class AKGMetaPath finder.""" def find_module(self, fullname, path=None): - """method akg find module.""" - if fullname.startswith("akg.tvm"): - rname = fullname[4:] + """method _akg find module.""" + if fullname.startswith("_akg.tvm"): + rname = fullname[5:] return AKGMetaPathLoader(rname) - if fullname.startswith("akg.topi"): - rname = fullname[4:] + if fullname.startswith("_akg.topi"): + rname = fullname[5:] return AKGMetaPathLoader(rname) return None diff --git a/mindspore/akg/gpu/__init__.py b/mindspore/_akg/gpu/__init__.py similarity index 83% rename from mindspore/akg/gpu/__init__.py rename to mindspore/_akg/gpu/__init__.py index 86334cfcd3..2ac6d1adb1 100644 --- a/mindspore/akg/gpu/__init__.py +++ b/mindspore/_akg/gpu/__init__.py @@ -26,3 +26,7 @@ from .squeeze_grad import SqueezeGrad, gpu_schedule_SqueezeGrad from .mean import SimpleMean, gpu_schedule_SimpleMean from .mean_grad import SimpleMeanGrad, gpu_schedule_SimpleMeanGrad from .mul import Mul, gpu_schedule_Mul +from .hsigmoid import Hsigmoid, gpu_schedule_Hsigmoid +from .hsigmoid_grad import HsigmoidGrad, gpu_schedule_HsigmoidGrad +from .hswish import Hswish, gpu_schedule_Hswish +from .hswish_grad import HswishGrad, gpu_schedule_HswishGrad diff --git a/mindspore/akg/gpu/cast.py b/mindspore/_akg/gpu/cast.py similarity index 86% rename from mindspore/akg/gpu/cast.py rename to mindspore/_akg/gpu/cast.py index 458772a803..d6b38b6e9b 100644 --- a/mindspore/akg/gpu/cast.py +++ b/mindspore/_akg/gpu/cast.py @@ -14,9 +14,9 @@ """cast""" import logging -import akg.tvm -from akg.ops.math import cast -from akg.topi.generic import schedule_elemwise +import _akg.tvm +from _akg.ops.math import cast +from _akg.topi.generic import schedule_elemwise def Cast(x, dst_type): """cast.""" @@ -34,10 +34,10 @@ def gpu_schedule_Cast(outs): sch (schedule.Schedule): The created schedule. """ device = 'cuda' - ctx = akg.tvm.context(device, 0) + ctx = _akg.tvm.context(device, 0) if not ctx.exist: logging.info("Skip because %s is not enabled", device) return None - with akg.tvm.target.create(device): + with _akg.tvm.target.create(device): sch = schedule_elemwise(outs) return sch diff --git a/mindspore/akg/gpu/default_schedule.py b/mindspore/_akg/gpu/default_schedule.py similarity index 94% rename from mindspore/akg/gpu/default_schedule.py rename to mindspore/_akg/gpu/default_schedule.py index 2e2892c055..811cc2d710 100644 --- a/mindspore/akg/gpu/default_schedule.py +++ b/mindspore/_akg/gpu/default_schedule.py @@ -15,7 +15,7 @@ """default schedule function for GPU""" from queue import Queue -import akg.tvm as tvm +import _akg.tvm as tvm DEFAULT_GPU_THREAD = 1024 @@ -31,7 +31,7 @@ def default_schedule(outs): sch (schedule.Schedule): The created schedule. """ if not isinstance(outs, tvm.tensor.Tensor) and not isinstance(outs, list): - raise ValueError("outs should be list of akg.tvm.tensor.Tensor or akg.tvm.tensor.Tensor") + raise ValueError("outs should be list of _akg.tvm.tensor.Tensor or _akg.tvm.tensor.Tensor") device = 'cuda' ctx = tvm.context(device, 0) if not ctx.exist: diff --git a/mindspore/akg/gpu/equal.py b/mindspore/_akg/gpu/equal.py similarity index 85% rename from mindspore/akg/gpu/equal.py rename to mindspore/_akg/gpu/equal.py index 05dce89622..3321c10b2c 100644 --- a/mindspore/akg/gpu/equal.py +++ b/mindspore/_akg/gpu/equal.py @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. """equal""" -import akg.tvm -from akg.ops.math import equal -from akg.topi.generic import schedule_elemwise +import _akg.tvm +from _akg.ops.math import equal +from _akg.topi.generic import schedule_elemwise def Equal(x, y): """equal.""" @@ -32,9 +32,9 @@ def gpu_schedule_Equal(outs): sch (schedule.Schedule): The created schedule. """ device = 'cuda' - ctx = akg.tvm.context(device, 0) + ctx = _akg.tvm.context(device, 0) if not ctx.exist: raise SystemError("Skip because %s is not enabled" % device) - with akg.tvm.target.create(device): + with _akg.tvm.target.create(device): sch = schedule_elemwise(outs) return sch diff --git a/mindspore/_akg/gpu/hsigmoid.py b/mindspore/_akg/gpu/hsigmoid.py new file mode 100644 index 0000000000..b9d5ea74c9 --- /dev/null +++ b/mindspore/_akg/gpu/hsigmoid.py @@ -0,0 +1,63 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""hsigmoid""" +import _akg.topi as topi +import _akg.tvm as tvm +from _akg.topi import tag + + +@tvm.tag_scope(tag=tag.ELEMWISE) +def topi_nn_hsigmoid(x): + """ + topi hsigmoid + Args: + x: + + Returns: + + """ + return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, + tvm.if_then_else(x(*i) >= 3, 1, + (x(*i) + 3) / 6))) + + +def Hsigmoid(x): + """ + Hsigmoid + Args: + x: + + Returns: + + """ + return topi_nn_hsigmoid(x) + + +def gpu_schedule_Hsigmoid(outs): + """ + gpu schedule Hsigmoid + Args: + outs: + + Returns: + + """ + device = 'cuda' + ctx = tvm.context(device, 0) + if not ctx.exist: + raise SystemError("Skip because %s is not enabled" % device) + with tvm.target.create(device): + sch = topi.cuda.schedule_elemwise(outs) + return sch diff --git a/mindspore/_akg/gpu/hsigmoid_grad.py b/mindspore/_akg/gpu/hsigmoid_grad.py new file mode 100644 index 0000000000..d3e7ac6345 --- /dev/null +++ b/mindspore/_akg/gpu/hsigmoid_grad.py @@ -0,0 +1,51 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Hsigmoid grad""" +import _akg.topi as topi +import _akg.tvm as tvm + + +def HsigmoidGrad(y_grad, x): + """ + HsigmoidGrad + Args: + y_grad: + x: + + Returns: + + """ + return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, + tvm.if_then_else(x(*i) >= 3, 0, + y_grad(*i) / 6))) + + +def gpu_schedule_HsigmoidGrad(outs): + """ + gpu schedule ReLU6Grad + Args: + outs: + + Returns: + + """ + device = 'cuda' + ctx = tvm.context(device, 0) + if not ctx.exist: + raise SystemError("Skip because %s is not enabled" % device) + + with tvm.target.create(device): + sch = topi.cuda.schedule_elemwise(outs) + return sch diff --git a/mindspore/_akg/gpu/hswish.py b/mindspore/_akg/gpu/hswish.py new file mode 100644 index 0000000000..904c38c2a2 --- /dev/null +++ b/mindspore/_akg/gpu/hswish.py @@ -0,0 +1,63 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""hswish""" +import _akg.topi as topi +import _akg.tvm as tvm +from _akg.topi import tag + + +@tvm.tag_scope(tag=tag.ELEMWISE) +def topi_nn_hswish(x): + """ + topi hswish + Args: + x: + + Returns: + + """ + return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, + tvm.if_then_else(x(*i) >= 3, x(*i), + x(*i) * (x(*i) + 3) / 6))) + + +def Hswish(x): + """ + Hswish + Args: + x: + + Returns: + + """ + return topi_nn_hswish(x) + + +def gpu_schedule_Hswish(outs): + """ + gpu schedule Hswish + Args: + outs: + + Returns: + + """ + device = 'cuda' + ctx = tvm.context(device, 0) + if not ctx.exist: + raise SystemError("Skip because %s is not enabled" % device) + with tvm.target.create(device): + sch = topi.cuda.schedule_elemwise(outs) + return sch diff --git a/mindspore/_akg/gpu/hswish_grad.py b/mindspore/_akg/gpu/hswish_grad.py new file mode 100644 index 0000000000..5b38f07c84 --- /dev/null +++ b/mindspore/_akg/gpu/hswish_grad.py @@ -0,0 +1,53 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""HswishGrad""" +import _akg.topi as topi +import _akg.tvm as tvm + + +def HswishGrad(y_grad, x): + """ + HswishGrad + Args: + y_grad: + x: + + Returns: + + """ + shape = x.shape + + res0 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, y_grad(*i) * (2 * x(*i) + 3) / 6)) + res6 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) >= 3, y_grad(*i), res0(*i))) + return res6 + + +def gpu_schedule_HswishGrad(outs): + """ + gpu schedule HswishGrad + Args: + outs: + + Returns: + + """ + device = 'cuda' + ctx = tvm.context(device, 0) + if not ctx.exist: + raise SystemError("Skip because %s is not enabled" % device) + + with tvm.target.create(device): + sch = topi.cuda.schedule_elemwise(outs) + return sch diff --git a/mindspore/akg/gpu/mean.py b/mindspore/_akg/gpu/mean.py similarity index 97% rename from mindspore/akg/gpu/mean.py rename to mindspore/_akg/gpu/mean.py index a68e929409..e9cdb6d551 100644 --- a/mindspore/akg/gpu/mean.py +++ b/mindspore/_akg/gpu/mean.py @@ -13,8 +13,8 @@ # limitations under the License. """mean op compute and schedule""" -import akg.tvm as tvm -from akg.ops.math.mean import mean +import _akg.tvm as tvm +from _akg.ops.math.mean import mean from .default_schedule import DEFAULT_GPU_THREAD def Mean(x, axis=None, keepdims=True): diff --git a/mindspore/akg/gpu/mean_grad.py b/mindspore/_akg/gpu/mean_grad.py similarity index 95% rename from mindspore/akg/gpu/mean_grad.py rename to mindspore/_akg/gpu/mean_grad.py index ef77690a5d..9d91ee3f40 100644 --- a/mindspore/akg/gpu/mean_grad.py +++ b/mindspore/_akg/gpu/mean_grad.py @@ -13,9 +13,9 @@ # limitations under the License. """mean_grad""" -import akg.tvm as tvm -import akg -from akg.ops.math import mean +import _akg.tvm as tvm +import _akg +from _akg.ops.math import mean from .default_schedule import DEFAULT_GPU_THREAD @@ -30,7 +30,7 @@ def mean_ad(head, input_shape, axis, keepdims): if tensor_b.op.name == "mean_output": tensor_b = tensor_b.op.input_tensors[0] - jacs = list(akg.differentiate(tensor_b, [tensor_a], head)) + jacs = list(_akg.differentiate(tensor_b, [tensor_a], head)) return jacs[0] diff --git a/mindspore/akg/gpu/mul.py b/mindspore/_akg/gpu/mul.py similarity index 93% rename from mindspore/akg/gpu/mul.py rename to mindspore/_akg/gpu/mul.py index 975a237837..5c289a62a6 100644 --- a/mindspore/akg/gpu/mul.py +++ b/mindspore/_akg/gpu/mul.py @@ -13,9 +13,9 @@ # limitations under the License. """mul""" -import akg.topi as topi -import akg.tvm as tvm -from akg.ops.math import mul +import _akg.topi as topi +import _akg.tvm as tvm +from _akg.ops.math import mul def Mul(x, y): """mul.""" diff --git a/mindspore/akg/gpu/relu6.py b/mindspore/_akg/gpu/relu6.py similarity index 95% rename from mindspore/akg/gpu/relu6.py rename to mindspore/_akg/gpu/relu6.py index bdcf23f05a..9a0a3d7a45 100644 --- a/mindspore/akg/gpu/relu6.py +++ b/mindspore/_akg/gpu/relu6.py @@ -13,9 +13,9 @@ # limitations under the License. """relu6""" -import akg.topi as topi -import akg.tvm as tvm -from akg.topi import tag +import _akg.topi as topi +import _akg.tvm as tvm +from _akg.topi import tag @tvm.tag_scope(tag=tag.ELEMWISE) def topi_nn_relu6(x): diff --git a/mindspore/akg/gpu/relu6_grad.py b/mindspore/_akg/gpu/relu6_grad.py similarity index 97% rename from mindspore/akg/gpu/relu6_grad.py rename to mindspore/_akg/gpu/relu6_grad.py index e0590cf6ef..62aeabb4c0 100644 --- a/mindspore/akg/gpu/relu6_grad.py +++ b/mindspore/_akg/gpu/relu6_grad.py @@ -13,8 +13,8 @@ # limitations under the License. """relu6 grad""" -import akg.topi as topi -import akg.tvm as tvm +import _akg.topi as topi +import _akg.tvm as tvm def ReLU6Grad(y_grad, x): """ diff --git a/mindspore/akg/gpu/squeeze.py b/mindspore/_akg/gpu/squeeze.py similarity index 96% rename from mindspore/akg/gpu/squeeze.py rename to mindspore/_akg/gpu/squeeze.py index 34fa423b8c..b5f55facaa 100644 --- a/mindspore/akg/gpu/squeeze.py +++ b/mindspore/_akg/gpu/squeeze.py @@ -13,8 +13,8 @@ # limitations under the License. """squeeze""" -import akg.topi as topi -import akg.tvm as tvm +import _akg.topi as topi +import _akg.tvm as tvm def Squeeze(x, axis=None): """ diff --git a/mindspore/akg/gpu/squeeze_grad.py b/mindspore/_akg/gpu/squeeze_grad.py similarity index 98% rename from mindspore/akg/gpu/squeeze_grad.py rename to mindspore/_akg/gpu/squeeze_grad.py index ef6a4242ba..8180ff9638 100644 --- a/mindspore/akg/gpu/squeeze_grad.py +++ b/mindspore/_akg/gpu/squeeze_grad.py @@ -13,7 +13,7 @@ # limitations under the License. """squeeze grad""" -import akg.topi as topi +import _akg.topi as topi def SqueezeGrad(y_grad, x_shape, axis=None): """ diff --git a/mindspore/akg/gpu/tile.py b/mindspore/_akg/gpu/tile.py similarity index 85% rename from mindspore/akg/gpu/tile.py rename to mindspore/_akg/gpu/tile.py index cd3c663f97..1eb6979b09 100644 --- a/mindspore/akg/gpu/tile.py +++ b/mindspore/_akg/gpu/tile.py @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. """tile""" -import akg.tvm -from akg.ops.array import tile -from akg.topi.generic import schedule_elemwise +import _akg.tvm +from _akg.ops.array import tile +from _akg.topi.generic import schedule_elemwise def Tile(x, multiples): """tile.""" @@ -31,9 +31,9 @@ def gpu_schedule_Tile(outs): sch (schedule.Schedule): The created schedule. """ device = 'cuda' - ctx = akg.tvm.context(device, 0) + ctx = _akg.tvm.context(device, 0) if not ctx.exist: raise SystemError("Skip because %s is not enabled" % device) - with akg.tvm.target.create(device): + with _akg.tvm.target.create(device): s = schedule_elemwise(outs) return s diff --git a/mindspore/akg/message.py b/mindspore/_akg/message.py similarity index 94% rename from mindspore/akg/message.py rename to mindspore/_akg/message.py index 86bdf2899c..4528771848 100644 --- a/mindspore/akg/message.py +++ b/mindspore/_akg/message.py @@ -20,9 +20,9 @@ import logging import traceback import os.path from pathlib import Path -import akg.tvm -from akg.utils import validation_check as vc_util -from akg.utils.dsl_create import TensorUtils +import _akg.tvm +from _akg.utils import validation_check as vc_util +from _akg.utils.dsl_create import TensorUtils from . import gpu from . import op_build @@ -67,7 +67,7 @@ def compilewithjson(json_str): tensor_shape = input_desc[0]['shape'] tensor_shape = (1,) if not tensor_shape else tensor_shape vc_util.shape_dtype_max_size_check(tensor_shape) - args[input_desc[0]['name']] = akg.tvm.placeholder( + args[input_desc[0]['name']] = _akg.tvm.placeholder( shape=tensor_shape, name=input_desc[0]['tensor_name'], dtype=input_desc[0]['data_type']) tsr.append(args[input_desc[0]['name']]) else: @@ -76,7 +76,7 @@ def compilewithjson(json_str): tensor_shape = tmp_desc['shape'] tensor_shape = (1,) if not tensor_shape else tensor_shape vc_util.shape_dtype_max_size_check(tensor_shape) - tmp_input.append(akg.tvm.placeholder( + tmp_input.append(_akg.tvm.placeholder( shape=tensor_shape, name=tmp_desc['tensor_name'], dtype=tmp_desc['data_type'])) args[input_desc[0]['name']] = tmp_input tsr = tsr + tmp_input diff --git a/mindspore/akg/op_build.py b/mindspore/_akg/op_build.py similarity index 88% rename from mindspore/akg/op_build.py rename to mindspore/_akg/op_build.py index e3d3ec2b78..44a250bd9e 100644 --- a/mindspore/akg/op_build.py +++ b/mindspore/_akg/op_build.py @@ -19,10 +19,10 @@ import types import typing import logging import traceback -import akg.tvm -import akg -from akg import save_gpu_param as gpu_utils -from akg.utils import validation_check as vc_util +import _akg.tvm +import _akg +from _akg import save_gpu_param as gpu_utils +from _akg.utils import validation_check as vc_util MS_CUDA_KERNEL_PATH = "/tmp/cuda_meta/" @@ -38,21 +38,21 @@ def op_build(opnames, computes, args, custom_schedule, device, kernel_name, attr return None schedule_name = 'gpu_schedule_' + opnames[0] - schedule_func = getattr(akg.gpu, schedule_name) + schedule_func = getattr(_akg.gpu, schedule_name) if not isinstance(schedule_func, (types.FunctionType, typing.Callable)): logging.error("no schedule func found %s", str(schedule_name)) return None ptx_file = os.path.realpath(MS_CUDA_KERNEL_PATH + kernel_name + ".ptx") if os.path.exists(ptx_file): - os.remove(ptx_file) + os.chmod(ptx_file, 0o600) try: with open(ptx_file, 'at') as file: fcntl.flock(file.fileno(), fcntl.LOCK_EX) file.seek(0, 2) if file.tell() == 0: s = schedule_func(computes) - foo = akg.tvm.build(s, args, device, name=kernel_name) + foo = _akg.tvm.build(s, args, device, name=kernel_name) ptx_code = foo.imported_modules[0].get_source("ptx") file.write(ptx_code) json_file = os.path.realpath(MS_CUDA_KERNEL_PATH + kernel_name + ".json") diff --git a/mindspore/akg/ops/__init__.py b/mindspore/_akg/ops/__init__.py similarity index 100% rename from mindspore/akg/ops/__init__.py rename to mindspore/_akg/ops/__init__.py diff --git a/mindspore/akg/ops/array/__init__.py b/mindspore/_akg/ops/array/__init__.py similarity index 100% rename from mindspore/akg/ops/array/__init__.py rename to mindspore/_akg/ops/array/__init__.py diff --git a/mindspore/akg/ops/array/tile.py b/mindspore/_akg/ops/array/tile.py similarity index 84% rename from mindspore/akg/ops/array/tile.py rename to mindspore/_akg/ops/array/tile.py index e60fcc4ffb..2fa485ea36 100644 --- a/mindspore/akg/ops/array/tile.py +++ b/mindspore/_akg/ops/array/tile.py @@ -13,12 +13,12 @@ # limitations under the License. """operator dsl function: tile""" -import akg.tvm -import akg.topi -from akg.utils import validation_check as vc_util +import _akg.tvm +import _akg.topi +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, (list, tuple)) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple)) def tile(data, multiples): """ Repeats the data in the specified dimensions according to the multiples. @@ -32,5 +32,5 @@ def tile(data, multiples): """ vc_util.check_shape(data.shape) vc_util.check_int_list(multiples, "multiples") - output = akg.topi.tile(data, multiples) + output = _akg.topi.tile(data, multiples) return output diff --git a/mindspore/akg/ops/math/__init__.py b/mindspore/_akg/ops/math/__init__.py similarity index 100% rename from mindspore/akg/ops/math/__init__.py rename to mindspore/_akg/ops/math/__init__.py diff --git a/mindspore/akg/ops/math/cast.py b/mindspore/_akg/ops/math/cast.py similarity index 83% rename from mindspore/akg/ops/math/cast.py rename to mindspore/_akg/ops/math/cast.py index 7266fd60c1..78140bfe27 100644 --- a/mindspore/akg/ops/math/cast.py +++ b/mindspore/_akg/ops/math/cast.py @@ -13,12 +13,12 @@ # limitations under the License. """operator dsl function: cast""" -import akg.tvm -import akg.topi -from akg.utils import validation_check as vc_util +import _akg.tvm +import _akg.topi +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, str) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, str) def cast(data, dst_type): """ cast data to target type. @@ -31,6 +31,6 @@ def cast(data, dst_type): tvm.tensor.Tensor, type is dst_type. """ vc_util.check_shape(data.shape) - out = akg.topi.cast(data, dst_type) + out = _akg.topi.cast(data, dst_type) return out diff --git a/mindspore/akg/ops/math/equal.py b/mindspore/_akg/ops/math/equal.py similarity index 63% rename from mindspore/akg/ops/math/equal.py rename to mindspore/_akg/ops/math/equal.py index eb446ac52b..2dbb1ba733 100644 --- a/mindspore/akg/ops/math/equal.py +++ b/mindspore/_akg/ops/math/equal.py @@ -13,13 +13,13 @@ # limitations under the License. """operator dsl function: equal""" -import akg.tvm -import akg.topi -from akg.utils.dsl_create import produce_shapes -from akg.utils import validation_check as vc_util +import _akg.tvm +import _akg.topi +from _akg.utils.dsl_create import produce_shapes +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, akg.tvm.tensor.Tensor) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) def equal(input1, input2): """ check whether input1 equals to input2. @@ -42,13 +42,13 @@ def equal(input1, input2): dtype = input1.dtype # get equal compute - t_value = akg.tvm.compute(shape, lambda *indice: akg.tvm.const(1, dtype), "T") - f_value = akg.tvm.compute(shape, lambda *indice: akg.tvm.const(0, dtype), "F") - - input1_bro = akg.topi.broadcast_to(input1, shape) - input2_bro = akg.topi.broadcast_to(input2, shape) - c_out = akg.tvm.compute(shape, lambda *indice: akg.tvm.expr.Select(input1_bro[indice] == input2_bro[indice], - t_value[indice], f_value[indice]), name="C") - res = akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") + t_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(1, dtype), "T") + f_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(0, dtype), "F") + + input1_bro = _akg.topi.broadcast_to(input1, shape) + input2_bro = _akg.topi.broadcast_to(input2, shape) + c_out = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.expr.Select(input1_bro[indice] == input2_bro[indice], + t_value[indice], f_value[indice]), name="C") + res = _akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") return res diff --git a/mindspore/akg/ops/math/mean.py b/mindspore/_akg/ops/math/mean.py similarity index 82% rename from mindspore/akg/ops/math/mean.py rename to mindspore/_akg/ops/math/mean.py index a26bc29087..8764387d33 100644 --- a/mindspore/akg/ops/math/mean.py +++ b/mindspore/_akg/ops/math/mean.py @@ -13,14 +13,14 @@ # limitations under the License. """operator dsl function: mean""" -import akg.topi -import akg.tvm -from akg.utils import format_transform as ft_util -from akg.utils import validation_check as vc_util -from akg.ops.math import sum +import _akg.topi +import _akg.tvm +from _akg.utils import format_transform as ft_util +from _akg.utils import validation_check as vc_util +from _akg.ops.math import sum -@vc_util.check_input_type(akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) def mean(data, axis=None, keepdims=False): """ Computes the mean of the values of a Tensor over the whole dataset. @@ -42,6 +42,6 @@ def mean(data, axis=None, keepdims=False): for i in axis: count *= shape[i] output, _ = sum.sum_value(data, axis, keepdims) - res = akg.topi.divide(output, count) + res = _akg.topi.divide(output, count) return res diff --git a/mindspore/akg/ops/math/mul.py b/mindspore/_akg/ops/math/mul.py similarity index 86% rename from mindspore/akg/ops/math/mul.py rename to mindspore/_akg/ops/math/mul.py index 8377a63d69..a690089da2 100644 --- a/mindspore/akg/ops/math/mul.py +++ b/mindspore/_akg/ops/math/mul.py @@ -13,11 +13,11 @@ # limitations under the License. """operator dsl function: mul""" -import akg.topi -from akg.utils import validation_check as vc_util +import _akg.topi +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, akg.tvm.tensor.Tensor) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) def mul(l_input, r_input): """ Calculate x * y element-wise. @@ -38,6 +38,6 @@ def mul(l_input, r_input): vc_util.check_shape(shape2) vc_util.auto_broadcast_check(shape1, shape2) vc_util.elemwise_dtype_check(l_input.dtype, r_input.dtype) - output = akg.topi.multiply(l_input, r_input) + output = _akg.topi.multiply(l_input, r_input) return output diff --git a/mindspore/akg/ops/math/sub.py b/mindspore/_akg/ops/math/sub.py similarity index 86% rename from mindspore/akg/ops/math/sub.py rename to mindspore/_akg/ops/math/sub.py index a4a85b0a09..6ae2ee51ef 100644 --- a/mindspore/akg/ops/math/sub.py +++ b/mindspore/_akg/ops/math/sub.py @@ -13,12 +13,12 @@ # limitations under the License. """operator dsl function: sub""" -import akg.topi -import akg.tvm -from akg.utils import validation_check as vc_util +import _akg.topi +import _akg.tvm +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, akg.tvm.tensor.Tensor) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) def sub(data1, data2): """ Computes data1 - data2 elementwise, broadcast is supported. @@ -35,6 +35,6 @@ def sub(data1, data2): vc_util.check_shape(data2.shape) vc_util.auto_broadcast_check(data1.shape, data2.shape) - res = akg.topi.subtract(data1, data2) + res = _akg.topi.subtract(data1, data2) return res diff --git a/mindspore/akg/ops/math/sum.py b/mindspore/_akg/ops/math/sum.py similarity index 79% rename from mindspore/akg/ops/math/sum.py rename to mindspore/_akg/ops/math/sum.py index ea71bab9c4..b9720469a6 100644 --- a/mindspore/akg/ops/math/sum.py +++ b/mindspore/_akg/ops/math/sum.py @@ -14,13 +14,13 @@ """operator dsl function: sum""" -import akg.topi -import akg.tvm -from akg.utils import format_transform as ft_util -from akg.utils import validation_check as vc_util +import _akg.topi +import _akg.tvm +from _akg.utils import format_transform as ft_util +from _akg.utils import validation_check as vc_util -@vc_util.check_input_type(akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) +@vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) def sum_value(inputs, axis=None, keepdims=False): """ Compute the sum of elements across dimensions of a tensor. @@ -38,8 +38,8 @@ def sum_value(inputs, axis=None, keepdims=False): vc_util.check_shape(inputs.shape) if not axis: - output = akg.topi.identity(inputs) + output = _akg.topi.identity(inputs) else: - output = akg.topi.sum(inputs, axis=axis, keepdims=keepdims) + output = _akg.topi.sum(inputs, axis=axis, keepdims=keepdims) return output diff --git a/mindspore/akg/save_gpu_param.py b/mindspore/_akg/save_gpu_param.py similarity index 95% rename from mindspore/akg/save_gpu_param.py rename to mindspore/_akg/save_gpu_param.py index 228bdf32ca..ed2c9fe23a 100644 --- a/mindspore/akg/save_gpu_param.py +++ b/mindspore/_akg/save_gpu_param.py @@ -15,9 +15,9 @@ """save gpu param""" import os import hashlib -import akg.tvm -from akg.tvm import schedule -from akg.utils import validation_check as vc_util +import _akg.tvm +from _akg.tvm import schedule +from _akg.utils import validation_check as vc_util def get_dim(dim, axis=True): @@ -66,7 +66,7 @@ def save_gpu_params(s, args, kernel_info): ptx_code = kernel_info[0] file_name = kernel_info[1] kernel_name = kernel_info[2] - ir = str(akg.tvm.lower(s, args, simple_mode=True)) + ir = str(_akg.tvm.lower(s, args, simple_mode=True)) file_path = os.path.realpath(file_name) if os.path.exists(file_path): os.remove(file_path) diff --git a/mindspore/akg/utils/__init__.py b/mindspore/_akg/utils/__init__.py similarity index 100% rename from mindspore/akg/utils/__init__.py rename to mindspore/_akg/utils/__init__.py diff --git a/mindspore/akg/utils/dsl_create.py b/mindspore/_akg/utils/dsl_create.py similarity index 91% rename from mindspore/akg/utils/dsl_create.py rename to mindspore/_akg/utils/dsl_create.py index aaea913143..9d27039b28 100644 --- a/mindspore/akg/utils/dsl_create.py +++ b/mindspore/_akg/utils/dsl_create.py @@ -13,8 +13,8 @@ # limitations under the License. """dsl create helping function""" -import akg -from akg.utils import format_transform as ft_util +import _akg +from _akg.utils import format_transform as ft_util class TensorUtils: """Class for creating tensor.""" @@ -33,11 +33,11 @@ class TensorUtils: """update tensor attrs.""" tensor_attrs = cls.get_tensor_attrs(tensor) tensor_attrs.update(attrs) - tensor = akg.tvm.compute(tensor.shape, - lambda *indice: tensor[indice], - name=tensor.op.name, - tag=tensor.op.tag, - attrs=tensor_attrs) + tensor = _akg.tvm.compute(tensor.shape, + lambda *indice: tensor[indice], + name=tensor.op.name, + tag=tensor.op.tag, + attrs=tensor_attrs) return tensor @classmethod @@ -61,7 +61,7 @@ class TensorUtils: raise RuntimeError("Shape of the input_tensor and the output_tensor should be equal, " "but got %s and %s"%(input_tensor_shape, output_tensor_shape)) output_tensor = cls.update_tensor_attrs(output_tensor, {cls.CREATE_SCH_ONLY: 1}) - data_buf = akg.tvm.decl_buffer(input_tensor.shape, input_tensor.dtype, name=buffer_name) + data_buf = _akg.tvm.decl_buffer(input_tensor.shape, input_tensor.dtype, name=buffer_name) binds_info = {input_tensor: data_buf, output_tensor: data_buf} return output_tensor, binds_info diff --git a/mindspore/akg/utils/format_transform.py b/mindspore/_akg/utils/format_transform.py similarity index 86% rename from mindspore/akg/utils/format_transform.py rename to mindspore/_akg/utils/format_transform.py index 816cbcaadb..f83130a32a 100644 --- a/mindspore/akg/utils/format_transform.py +++ b/mindspore/_akg/utils/format_transform.py @@ -13,7 +13,7 @@ # limitations under the License. """format transform function""" -import akg +import _akg def refine_reduce_axis(input, axis): """make reduce axis legal.""" @@ -43,11 +43,11 @@ def refine_reduce_axis(input, axis): def get_shape_from_tensor(data): - """translate akg.tvm.shape to list type in python.""" + """translate _akg.tvm.shape to list type in python.""" tvm_shape = data.shape py_shape = [] for i in tvm_shape: - if isinstance(i, akg.tvm.expr.Var): + if isinstance(i, _akg.tvm.expr.Var): py_shape.append(i) else: py_shape.append(i.value) @@ -55,10 +55,10 @@ def get_shape_from_tensor(data): def tvm_shape_to_list(tvm_shape): - """translate akg.tvm.shape to list type in python.""" + """translate _akg.tvm.shape to list type in python.""" py_shape = [] for i in tvm_shape: - if isinstance(i, akg.tvm.expr.Var): + if isinstance(i, _akg.tvm.expr.Var): py_shape.append(i) else: py_shape.append(i.value) @@ -67,9 +67,9 @@ def tvm_shape_to_list(tvm_shape): def get_shape(data): """get shape and save it as list.""" - if isinstance(data, akg.tvm.tensor.Tensor): + if isinstance(data, _akg.tvm.tensor.Tensor): shape = get_shape_from_tensor(data) - elif isinstance(data, akg.tvm.container.Array): + elif isinstance(data, _akg.tvm.container.Array): shape = tvm_shape_to_list(data) elif isinstance(data, int): shape = [data] diff --git a/mindspore/akg/utils/validation_check.py b/mindspore/_akg/utils/validation_check.py similarity index 99% rename from mindspore/akg/utils/validation_check.py rename to mindspore/_akg/utils/validation_check.py index 72494c5281..1231b3110e 100644 --- a/mindspore/akg/utils/validation_check.py +++ b/mindspore/_akg/utils/validation_check.py @@ -14,7 +14,7 @@ """validation check functions""" from functools import wraps, reduce -from akg.utils.format_transform import get_shape +from _akg.utils.format_transform import get_shape MAX_DATA_SIZE = 2 ** 31 diff --git a/mindspore/_checkparam.py b/mindspore/_checkparam.py index d553bcd364..cb3dbc0d50 100644 --- a/mindspore/_checkparam.py +++ b/mindspore/_checkparam.py @@ -300,6 +300,13 @@ class ParamValidator: for arg, value in args.items(): ParamValidator.check_subclass(arg, value, mstype.tensor) + @staticmethod + def check_bool(arg_name, arg_value): + """Check arg isintance of bool""" + if not isinstance(arg_value, bool): + raise ValueError(f'The `{arg_name}` should be isintance of bool, but got {arg_value}.') + return arg_value + @staticmethod def check_type(arg_name, arg_value, valid_types): """Type checking.""" diff --git a/mindspore/_extends/builtin_operations.py b/mindspore/_extends/builtin_operations.py index 087b704719..6fea07425e 100644 --- a/mindspore/_extends/builtin_operations.py +++ b/mindspore/_extends/builtin_operations.py @@ -125,7 +125,7 @@ def list_len(x): return len(x) -# only used in PyNative modes +# only used in PyNative mode def partial(*args): """Implement `partial`.""" func = args[0].__call__ @@ -133,10 +133,14 @@ def partial(*args): return partial_func -# only used in PyNative modes +# only used in PyNative mode def depend(value, expr): return value +# only used in PyNative mode +def make_ref(key, value, ref): + return value + def scalar_cast(x, t): """Implement scalar_cast.""" diff --git a/mindspore/_extends/parallel_compile/multi_compiler.py b/mindspore/_extends/parallel_compile/multi_compiler.py index 542167888b..86e1b684d2 100644 --- a/mindspore/_extends/parallel_compile/multi_compiler.py +++ b/mindspore/_extends/parallel_compile/multi_compiler.py @@ -32,7 +32,7 @@ def _compiletask(platform, *jsons): """ if platform == "AKG": - p = __import__("akg", globals(), locals(), ['ms'], 0) + p = __import__("_akg", globals(), locals(), ['ms'], 0) func = getattr(p.ms, "compilewithjson") for json_item in jsons: res = func(json_item) diff --git a/mindspore/_extends/parse/resources.py b/mindspore/_extends/parse/resources.py index 5dd24ccf80..9fb357597e 100644 --- a/mindspore/_extends/parse/resources.py +++ b/mindspore/_extends/parse/resources.py @@ -83,9 +83,9 @@ convert_object_map = { T.mul: multitype_ops.mul, T.truediv: multitype_ops.div, T.getitem: multitype_ops.getitem, - T.floordiv: NO_IMPLEMENT, - T.mod: F.scalar_mod, - T.pow: F.scalar_pow, + T.floordiv: multitype_ops.floordiv, + T.mod: multitype_ops.mod, + T.pow: multitype_ops.pow_, T.matmul: F.dot, T.lshift: NO_IMPLEMENT, T.rshift: NO_IMPLEMENT, @@ -104,8 +104,8 @@ convert_object_map = { T.ge: multitype_ops.greater_equal, T.is_: F.is_, T.is_not: F.is_not, - T.contains: NO_IMPLEMENT, - T.not_contains: NO_IMPLEMENT, + T.contains: F.in_dict, + T.not_contains: F.not_in_dict, # system function T.len: M.ms_len, diff --git a/mindspore/ccsrc/CMakeLists.txt b/mindspore/ccsrc/CMakeLists.txt index c49c962bdd..8c33b9051c 100644 --- a/mindspore/ccsrc/CMakeLists.txt +++ b/mindspore/ccsrc/CMakeLists.txt @@ -5,6 +5,10 @@ if(ENABLE_CPU) file(GLOB_RECURSE CPU_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "device/cpu/*.cc" ) + if (CMAKE_SYSTEM_NAME MATCHES "Windows") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes -DHAVE_SNPRINTF") + add_compile_definitions(BUILDING_DLL) + endif() endif() if(ENABLE_GPU) @@ -150,17 +154,24 @@ file(GLOB_RECURSE MINDSPORE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "kernel/kash/*.cc" "device/gpu/distribution/collective_init.cc" ) - +if (ENABLE_CPU) + list(REMOVE_ITEM MINDSPORE_SRC_LIST "device/gpu/distribution/collective_init.cc") + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + list(REMOVE_ITEM MINDSPORE_SRC_LIST "kernel/kernel_query.cc") + endif() +endif() +if (NOT ENABLE_GPU) + list(APPEND MINDSPORE_SRC_LIST "device/gpu/distribution/collective_fake_init.cc") +endif() file(GLOB_RECURSE MEM_REUSE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "pre_activate/mem_reuse/*.cc" ) if(NOT ENABLE_DUMP_E2E) list(REMOVE_ITEM MINDSPORE_SRC_LIST "debug/e2e_dump.cc") endif() - file(COPY "${ms_onnx_INC}/onnx/onnx.proto" DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) file(GLOB_RECURSE ONNX_PROTO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/onnx.proto") -message(“onnx proto path is : ${ONNX_PROTO}”) +message("onnx proto path is : ${ONNX_PROTO}") ms_protobuf_generate(ONNX_PROTO_SRCS ONNX_PROTO_HDRS ${ONNX_PROTO}) list(APPEND MINDSPORE_PROTO_LIST ${ONNX_PROTO_SRCS}) @@ -249,6 +260,7 @@ file(GLOB_RECURSE MS_GVAR_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} add_library(mindspore_gvar SHARED ${MS_GVAR_SRC_LIST}) add_library(mindspore STATIC ${MINDSPORE_SRC_LIST}) +add_dependencies(mindspore GENERATED_OUTPUT_DIR) if(ENABLE_D) list(APPEND MINDSPORE_PROTO_LIST ${MINDSPORE_PROTO_AICPU_LIST}) @@ -302,6 +314,7 @@ if(ENABLE_D) set(ASCEND_PATH /usr/local/Ascend) endif() set(ASCEND_DRIVER_PATH ${ASCEND_PATH}/driver/lib64/common) + set(ASCEND_DRIVER_BACK_PATH ${ASCEND_PATH}/driver/lib64/driver) set(ASCEND_RUNTIME_PATH ${ASCEND_PATH}/fwkacllib/lib64) endif() @@ -309,36 +322,52 @@ if(ENABLE_D) find_library(HCCL hccl ${ASCEND_RUNTIME_PATH}) find_library(CCE_LIB cce ${ASCEND_RUNTIME_PATH}) find_library(RUNTIME_LIB runtime ${ASCEND_RUNTIME_PATH}) - find_library(TSDCLIENT tsdclient ${ASCEND_RUNTIME_PATH}) + find_library(TSDCLIENT tsdclient HINTS ${ASCEND_RUNTIME_PATH} ${ASCEND_DRIVER_BACK_PATH}) find_library(PROFILING msprof ${ASCEND_DRIVER_PATH}) target_link_libraries(mindspore ge_runtime ${CCE_LIB} ${RUNTIME_LIB} ${TSDCLIENT} ${PROFILING} ${HCCL} ${TSDCLIENT}) endif() target_link_libraries(mindspore securec) -target_link_libraries(mindspore dl) +if (NOT WIN32) + target_link_libraries(mindspore dl) +endif() target_link_libraries(mindspore mindspore::flatbuffers) # link protobuf if (ENABLE_D) - target_link_libraries(mindspore protobuf::libprotobuf) + target_link_libraries(mindspore mindspore::protobuf) +endif() + +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + target_link_libraries(mindspore ${PYTHON_LIBRARIES} mindspore_gvar) endif() # set c_expression building -set(PYTHON_MODULE_SOURCE +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(PYTHON_MODULE_SOURCE ${MS_GVAR_SRC_LIST} + pipeline/init.cc + kernel/oplib/oplib.cc + ${MINDSPORE_SRC_LIST} ${MS_STEPS_SRC_LIST} ${MS_CCE_SRC_LIST} ${MS_AICPU_SRC_LIST} ${MS_TASKINFO_LIST} ${MS_RT_SRC_LIST} + ${GPU_NCCL_LIST} ${MS_HCCL_SRC_LIST} ${MS_PREDICT_SRC_LIST} ${CPU_SRC_LIST} ${MEM_REUSE_SRC_LIST} ${GPU_KERNEL_SRC_LIST}) +else() + set(PYTHON_MODULE_SOURCE pipeline/init.cc kernel/oplib/oplib.cc - ${MS_STEPS_SRC_LIST} ${MS_CCE_SRC_LIST} ${MS_AICPU_SRC_LIST} ${MS_TASKINFO_LIST} ${MS_RT_SRC_LIST} - ${GPU_NCCL_LIST} ${MS_HCCL_SRC_LIST} ${MS_PREDICT_SRC_LIST} ${CPU_SRC_LIST} ${MEM_REUSE_SRC_LIST} ${GPU_KERNEL_SRC_LIST}) + ${MS_STEPS_SRC_LIST} ${MS_CCE_SRC_LIST} ${MS_AICPU_SRC_LIST} ${MS_TASKINFO_LIST} ${MS_RT_SRC_LIST} + ${GPU_NCCL_LIST} ${MS_HCCL_SRC_LIST} ${MS_PREDICT_SRC_LIST} ${CPU_SRC_LIST} ${MEM_REUSE_SRC_LIST} ${GPU_KERNEL_SRC_LIST}) +endif() set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) pybind11_add_module(_c_expression ${PYTHON_MODULE_SOURCE}) -target_link_options(_c_expression PRIVATE -Wl,-init,mindspore_log_init) MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}") if (CMAKE_SYSTEM_NAME MATCHES "Linux") + target_link_options(_c_expression PRIVATE -Wl,-init,mindspore_log_init) set(ORIGIN_PATH $ORIGIN) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") set_target_properties(_c_expression PROPERTIES MACOSX_RPATH ON) set(ORIGIN_PATH @loader_path) +elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") + set(ORIGIN_PATH $ORIGIN) else () MESSAGE(FATAL_ERROR "other platform: ${CMAKE_SYSTEM_NAME}") endif () @@ -346,125 +375,31 @@ endif () set(ORIGIN_PATH ${ORIGIN_PATH}/lib) set_target_properties(_c_expression PROPERTIES INSTALL_RPATH ${ORIGIN_PATH}) -target_link_libraries(_c_expression PRIVATE - mindspore::pybind11_module - mindspore - mindspore_gvar - ) - -if(ENABLE_GPU) - execute_process(COMMAND bash ${CMAKE_SOURCE_DIR}/third_party/apply_patches.sh - ${CMAKE_BINARY_DIR} - ${dlpack_DIRPATH} - ${dmlc_core_DIRPATH} - ${rang_DIRPATH} - ${incubator_tvm_gpu_DIRPATH}) - set(TVM_DIR "${CMAKE_BINARY_DIR}/incubator-tvm") - # Utility functions - include(${TVM_DIR}/cmake/util/Util.cmake) - include(${TVM_DIR}/cmake/util/FindCUDA.cmake) - - # include directories - include_directories(AFTER "${TVM_DIR}/include") - include_directories(AFTER "${TVM_DIR}/src") - include_directories(AFTER "${TVM_DIR}") - include_directories(AFTER "${TVM_DIR}/src/schedule") - - include_directories(AFTER "${TVM_DIR}/3rdparty/dmlc-core/include") - include_directories(AFTER "${TVM_DIR}/3rdparty/dlpack/include") - include_directories(AFTER "${TVM_DIR}/3rdparty/compiler-rt") - include_directories(AFTER "${TVM_DIR}/3rdparty/rang/include") - - # lib contain dlopen and dlclose - set(TVM_RUNTIME_LINKER_LIBS ${CMAKE_DL_LIBS}) - - # add source group - file(GLOB_RECURSE GROUP_SOURCE "${TVM_DIR}/src/*.cc" "src/*.cc") - file(GLOB_RECURSE GROUP_INCLUDE "${TVM_DIR}/src/*.h" - "${TVM_DIR}/include/*.h" "src/*.h" "include/*.h") - assign_source_group("Source" ${GROUP_SOURCE}) - assign_source_group("Include" ${GROUP_INCLUDE}) - - file(GLOB COMPILER_SRCS - "pre_activate/gpu/*.cc" - ${TVM_DIR}/src/api/*.cc - ${TVM_DIR}/src/arithmetic/*.cc - ${TVM_DIR}/src/autotvm/*.cc - ${TVM_DIR}/src/codegen/*.cc - ${TVM_DIR}/src/lang/*.cc - ${TVM_DIR}/src/pass/*.cc - ${TVM_DIR}/src/op/*.cc - ${TVM_DIR}/src/node/*.cc - ${TVM_DIR}/src/schedule/*.cc - ${TVM_DIR}/src/runtime/*.cc - ${TVM_DIR}/src/runtime/vm/*.cc - ${TVM_DIR}/src/runtime/vm/profiler/*.cc - ${TVM_DIR}/src/codegen/stackvm/*.cc) - - file(GLOB_RECURSE RELAY_SRCS ${TVM_DIR}/src/relay/*.cc) - list(APPEND COMPILER_SRCS ${RELAY_SRCS}) - - file(GLOB DATATYPE_SRCS ${TVM_DIR}/src/codegen/datatype/*.cc) - list(APPEND COMPILER_SRCS ${DATATYPE_SRCS}) - - file(GLOB COMPILER_VERILOG_SRCS ${TVM_DIR}/src/codegen/verilog/*.cc) - list(APPEND COMPILER_SRCS ${COMPILER_VERILOG_SRCS}) - - file(GLOB TOPI_SRCS ${TVM_DIR}/topi/src/*.cc) - - file(GLOB RUNTIME_SRCS - ${TVM_DIR}/src/runtime/*.cc - ${TVM_DIR}/src/runtime/vm/*.cc - ${TVM_DIR}/src/runtime/stub/*.cc - ${TVM_DIR}/src/runtime/stackvm/*.cc) - - - file(GLOB COMPILER_OFF_SRCS - ${TVM_DIR}/src/codegen/opt/build_*_off.cc) - set(USE_CUDA "OFF") - if(ENABLE_GPU) - list(REMOVE_ITEM COMPILER_OFF_SRCS - ${TVM_DIR}/src/codegen/opt/build_cuda_off.cc) - set(USE_CUDA "ON") - endif() - list(APPEND COMPILER_SRCS ${COMPILER_OFF_SRCS}) - # Module rules - include(${TVM_DIR}/cmake/modules/CUDA.cmake) - - set(CMAKE_C_FLAGS_AKG -pipe -Wall -fPIC -fstack-protector-all) - set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -Wl,-z,relro,-z,now,-z,noexecstack) - - set(CMAKE_CXX_FLAGS_AKG -std=c++11 -pipe -Wall -fPIC -fstack-protector-all) - set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -Wl,-z,relro,-z,now,-z,noexecstack) - - if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - message("-- Build in Debug mode") - set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -O0 -g -rdynamic) - set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -O0 -g -rdynamic) - else() - message("-- Build in Release mode") - set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -O2 -Werror) - set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -O2 -Werror) - endif() - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION - VERSION_GREATER 7.0) - set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -faligned-new) - endif() - - add_library(akg OBJECT ${COMPILER_SRCS} ${RUNTIME_SRCS} ${TOPI_SRCS}) +if (WIN32) + target_link_libraries(_c_expression PRIVATE + mindspore::pybind11_module + securec + proto_input + mindspore::flatbuffers + ) +else() + target_link_libraries(_c_expression PRIVATE + mindspore::pybind11_module + mindspore + mindspore_gvar + ) +endif() - target_link_libraries(akg ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS}) - target_compile_options(akg PRIVATE - $<$:${CMAKE_C_FLAGS_AKG}> - $<$:${CMAKE_CXX_FLAGS_AKG}>) - target_include_directories(akg PRIVATE "${TVM_DIR}/topi/include") +if(USE_GLOG) + target_link_libraries(_c_expression PRIVATE mindspore::glog) +endif() - add_dependencies(_c_expression akg) - target_link_libraries(_c_expression PRIVATE akg) +if(ENABLE_GPU) + target_link_libraries(_c_expression PRIVATE mindspore::tvm) endif() if(ENABLE_DUMP_PROTO) - target_link_libraries(_c_expression PRIVATE protobuf::libprotobuf) + target_link_libraries(_c_expression PRIVATE mindspore::protobuf) endif() if(ENABLE_GPU) @@ -473,6 +408,7 @@ if(ENABLE_GPU) gpu_cuda_lib gpu_queue cublas + ${CUDA_PATH}/lib64/libcurand.so ${CUDNN_PATH}/lib64/libcudnn.so ${CUDA_PATH}/lib64/libcudart.so ${CUDA_PATH}/lib64/stubs/libcuda.so) @@ -492,90 +428,3 @@ if(ENABLE_MINDDATA) add_subdirectory(mindrecord) add_subdirectory(dataset) endif() -set(MS_PACK_PATH ${CMAKE_SOURCE_DIR}/build/package/mindspore/) -set(MS_LIB_PATH ${CMAKE_SOURCE_DIR}/build/package/mindspore/lib/) - -add_custom_target(add_ms_lib ALL - COMMAND mkdir -pv ${MS_LIB_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/_c_expression* ${MS_PACK_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/libmindspore_gvar.so ${MS_LIB_PATH} -) -add_dependencies(add_ms_lib _c_expression) - -if (NOT ENABLE_GE) - if (ENABLE_D) - if(DEFINED ENV{ASCEND_CUSTOM_PATH}) - set(ASCEND_PATH $ENV{ASCEND_CUSTOM_PATH}) - else() - set(ASCEND_PATH /usr/local/Ascend) - endif() - set(ASCEND_DRIVER_PATH ${ASCEND_PATH}/driver/lib64/common) - add_custom_target(add_ge_lib ALL - COMMAND cp ${MS_CCSRC_BUILD_PATH}/../../graphengine/src/common/graph/libgraph.so ${MS_LIB_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/../../graphengine/src/ge/common/libge_common.so ${MS_LIB_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/../../graphengine/src/ge/ge_runtime/libge_runtime.so ${MS_LIB_PATH} - COMMAND cp ${ASCEND_DRIVER_PATH}/libslog.so ${MS_LIB_PATH} - COMMAND cp ${ASCEND_DRIVER_PATH}/libc_sec.so ${MS_LIB_PATH} - ) - add_dependencies(add_ge_lib add_ms_lib) - add_dependencies(add_ge_lib graph) - add_dependencies(add_ge_lib ge_runtime) - elseif(ENABLE_TESTCASES) - add_custom_target(add_ge_lib ALL - COMMAND cp ${MS_CCSRC_BUILD_PATH}/../../graphengine/src/common/graph/libgraph.so ${MS_LIB_PATH} - COMMAND cp ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/libslog.so ${MS_LIB_PATH} - COMMAND cp ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/libc_sec.so ${MS_LIB_PATH} - ) - add_dependencies(add_ge_lib add_ms_lib) - add_dependencies(add_ge_lib graph) - endif() -endif() - -if (ENABLE_GPU) - if (ENABLE_MPI) - add_custom_target(add_mpi_lib ALL - COMMAND cp ${MS_CCSRC_BUILD_PATH}/_ms_mpi* ${MS_PACK_PATH} - ) - add_dependencies(add_mpi_lib _ms_mpi) - add_custom_target(add_gpu_collective_lib ALL - COMMAND mkdir -pv ${MS_LIB_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/libgpu_collective* ${MS_LIB_PATH} - ) - add_dependencies(add_gpu_collective_lib gpu_collective) - endif() - add_custom_target(add_gpu_queue_lib ALL - COMMAND cp ${MS_CCSRC_BUILD_PATH}/libgpu_queue* ${MS_LIB_PATH} - ) - add_dependencies(add_gpu_queue_lib add_ms_lib) -endif() - -if (ENABLE_CPU) - add_custom_target(add_cpu_lib ALL - COMMAND cp ${onednn_LIBPATH}/libdnnl.so.1.1 ${MS_LIB_PATH}/libdnnl.so.1 - ) - add_dependencies(add_cpu_lib add_ms_lib) -endif() - -if (ENABLE_MINDDATA) - add_custom_target(add_minddata_lib ALL - COMMAND cp ${MS_CCSRC_BUILD_PATH}/dataset/*.so ${MS_PACK_PATH} - COMMAND cp ${MS_CCSRC_BUILD_PATH}/mindrecord/*.so ${MS_PACK_PATH} - COMMAND cp ${opencv_LIBPATH}/libopencv_core.so.4.2.0 ${MS_LIB_PATH}/libopencv_core.so.4.2 - COMMAND cp ${opencv_LIBPATH}/libopencv_imgcodecs.so.4.2.0 ${MS_LIB_PATH}/libopencv_imgcodecs.so.4.2 - COMMAND cp ${opencv_LIBPATH}/libopencv_imgproc.so.4.2.0 ${MS_LIB_PATH}/libopencv_imgproc.so.4.2 - ) - add_dependencies(add_minddata_lib add_ms_lib) - add_dependencies(add_minddata_lib _c_mindrecord) - add_dependencies(add_minddata_lib _c_dataengine) - - add_dependencies(_c_mindrecord mindspore) - add_dependencies(_c_dataengine mindspore) -endif() - -if (USE_GLOG) - target_link_libraries(_c_expression PRIVATE mindspore::glog) - add_custom_target(add_glog_lib ALL - COMMAND cp ${glog_LIBPATH}/libglog*.so.0 ${MS_LIB_PATH} - ) - add_dependencies(add_glog_lib add_ms_lib) -endif() diff --git a/mindspore/ccsrc/common/trans.cc b/mindspore/ccsrc/common/trans.cc index 380c51bcf9..b4e02c8fe6 100644 --- a/mindspore/ccsrc/common/trans.cc +++ b/mindspore/ccsrc/common/trans.cc @@ -20,6 +20,8 @@ #include #include "./securec.h" #include "common/utils.h" +#include "session/anf_runtime_algorithm.h" +#include "kernel/kernel.h" #include "device/convert_tensor_utils.h" #include "utils/convert_utils.h" #include "utils/log_adapter.h" @@ -27,6 +29,33 @@ namespace mindspore { namespace trans { +namespace { +std::vector PaddingShapeTo4dByDefault(const std::vector &shape) { + std::vector shape_4d(4, 1); + switch (shape.size()) { + case 0: + return shape_4d; + case 1: + shape_4d[1] = shape[0]; + break; + case 2: + shape_4d[1] = shape[0]; + shape_4d[2] = shape[1]; + break; + case 3: + shape_4d[1] = shape[0]; + shape_4d[2] = shape[1]; + shape_4d[3] = shape[2]; + break; + case 4: + std::copy(shape.begin(), shape.end(), shape_4d.begin()); + break; + default: + MS_LOG(EXCEPTION) << "Unexpect shape size = " << shape.size(); + } + return shape_4d; +} +} // namespace const size_t kNchwDims = 4; const std::map type_map = {{kNumberTypeBool, 1}, {kNumberTypeInt, 4}, {kNumberTypeInt8, 1}, {kNumberTypeInt16, 2}, {kNumberTypeInt32, 4}, {kNumberTypeInt64, 8}, @@ -154,38 +183,155 @@ size_t TypeIdSize(const TypeId data_type) { return unsupported_type_error; } -std::vector TransShapeTo4d(const std::vector &shape) { +bool IsNeedPadding(const std::string &format, const size_t shape_size) { + if (shape_size == 0) { + return false; + } + if (format == kOpFormat_DEFAULT || format == kOpFormat_FRAC_NZ) { + return false; + } else if (shape_size < 4) { + return true; + } + return false; +} + +std::vector GetRuntimePaddingShape(const AnfNodePtr &node, size_t index) { + std::vector shape; + std::vector host_shape; + if (node->isa()) { + auto value_node = node->cast(); + auto node_value = value_node->value(); + auto tensor = node_value->cast(); + if (tensor == nullptr) { + MS_LOG(EXCEPTION) << " the node[ " << node->DebugString() << "]'s cannot convert "; + } + auto shape_temp = tensor->shape(); + (void)std::transform(shape_temp.begin(), shape_temp.end(), std::back_inserter(host_shape), IntToSize); + if (host_shape.empty()) { + host_shape.push_back(1); + } + } else { + host_shape = AnfAlgo::GetOutputInferShape(node, index); + } + if (trans::IsNeedPadding(AnfAlgo::GetOutputFormat(node, 0), host_shape.size())) { + host_shape = trans::PaddingShapeTo4d(host_shape, AnfAlgo::GetOutputReshapeType(node, 0)); + } + std::transform(host_shape.begin(), host_shape.end(), std::back_inserter(shape), SizeToInt); + return shape; +} + +std::vector PaddingShapeTo4d(const std::vector &shape, const std::vector &padding_axis) { + if (padding_axis.empty() || shape.size() != padding_axis.size()) { + return PaddingShapeTo4dByDefault(shape); + } std::vector shape_4d(4, 1); - switch (shape.size()) { - case 0: - break; - case 1: - shape_4d[1] = shape[0]; - break; - case 2: - shape_4d[0] = shape[0]; - shape_4d[1] = shape[1]; - break; - case 3: - MS_LOG(EXCEPTION) << "Unexpected shape size = 3,it should has a default format"; - case 4: - for (size_t i = 0; i < 4; ++i) { - shape_4d[i] = shape[i]; - } - break; - default: - MS_LOG(EXCEPTION) << "Unexpected shape size = " << shape.size(); + for (size_t index = 0; index < padding_axis.size(); index++) { + shape_4d[padding_axis[index]] = shape[index]; } return shape_4d; } +namespace { +bool CheckDims(const std::vector &shape) { + if (shape.size() != 4) { + MS_LOG(ERROR) << "Host shape dims shoud be 4"; + return false; + } + return true; +} + +std::vector NchwDeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Check dims failed."; + } + return shape; +} + +std::vector NhwcDeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Ccheck dims failed."; + } + std::vector device_shape; + device_shape.push_back(shape[0]); + device_shape.push_back(shape[2]); + device_shape.push_back(shape[3]); + device_shape.push_back(shape[1]); + return device_shape; +} + +std::vector HwchDeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Check dims failed."; + } + std::vector device_shape; + device_shape.push_back(shape[2]); + device_shape.push_back(shape[3]); + device_shape.push_back(shape[1]); + device_shape.push_back(shape[0]); + return device_shape; +} + +std::vector FracZDeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Check dims failed."; + } + std::vector device_shape; + size_t cout16 = ((shape[0] + kCubeSize - 1) / kCubeSize) * kCubeSize; + size_t cin16 = ((shape[1] + kCubeSize - 1) / kCubeSize) * kCubeSize; + device_shape.push_back(shape[2] * shape[3] * cin16 / kCubeSize); + device_shape.push_back(cout16 / kCubeSize); + device_shape.push_back(kCubeSize); + device_shape.push_back(kCubeSize); + return device_shape; +} + +std::vector Nc1hwc0DeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Check dims failed."; + } + std::vector device_shape; + size_t C1 = (shape[1] + kCubeSize - 1) / kCubeSize; + size_t C0 = kCubeSize; + device_shape.push_back(shape[0]); + device_shape.push_back(C1); + device_shape.push_back(shape[2]); + device_shape.push_back(shape[3]); + device_shape.push_back(C0); + return device_shape; +} + +std::vector C1hwncoc0DeviceShape(const std::vector &shape) { + if (!CheckDims(shape)) { + MS_LOG(EXCEPTION) << "Check dims failed."; + } + std::vector device_shape; + device_shape.push_back((shape[1] - 1) / kCubeSize + 1); + device_shape.push_back(shape[2]); + device_shape.push_back(shape[3]); + device_shape.push_back(shape[0]); + device_shape.push_back(kCubeSize); + device_shape.push_back(kCubeSize); + return device_shape; +} +} // namespace + std::vector TransShapeToDevice(const std::vector &shape, const std::string &format) { + using DeviceShapeTransfer = std::function(const std::vector &)>; + const std::map device_shape_map{ + {kOpFormat_NCHW, NchwDeviceShape}, {kOpFormat_NHWC, NhwcDeviceShape}, + {kOpFormat_HWCN, HwchDeviceShape}, {kOpFormat_FRAC_Z, FracZDeviceShape}, + {kOpFormat_NC1HWC0, Nc1hwc0DeviceShape}, {kOpFormat_C1HWNCoC0, C1hwncoc0DeviceShape}, + }; + + if (format == kOpFormat_ND || format == kOpFormat_DEFAULT) { + return shape; + } + auto temp_shape = shape; std::vector device_shape; if (format == kOpFormat_FRAC_NZ) { if (shape.size() < 2) { - MS_EXCEPTION(NotSupportError) << "Format " << format << " is not support shape " << shape.size(); - } - if (shape.size() > 2) { + MS_LOG(EXCEPTION) << "Format" << format << " is not support shape " << shape.size(); + } else { (void)std::copy(shape.begin(), shape.end() - 2, std::back_inserter(device_shape)); } auto h1 = (shape[shape.size() - 2] - 1) / kCubeSize + 1; @@ -197,39 +343,34 @@ std::vector TransShapeToDevice(const std::vector &shape, const s return device_shape; } if (shape.size() != 4) { - MS_LOG(EXCEPTION) << "shape_4d size should be 4"; - } - if (format == kOpFormat_NC1HWC0) { - size_t C1 = (shape[1] + kCubeSize - 1) / kCubeSize; - size_t C0 = kCubeSize; - device_shape.push_back(shape[0]); - device_shape.push_back(C1); - device_shape.push_back(shape[2]); - device_shape.push_back(shape[3]); - device_shape.push_back(C0); - return device_shape; - } else if (format == kOpFormat_FRAC_Z) { - size_t cout16 = ((shape[0] + kCubeSize - 1) / kCubeSize) * kCubeSize; - size_t cin16 = ((shape[1] + kCubeSize - 1) / kCubeSize) * kCubeSize; - device_shape.push_back(shape[2] * shape[3] * cin16 / kCubeSize); - device_shape.push_back(cout16 / kCubeSize); - device_shape.push_back(kCubeSize); - device_shape.push_back(kCubeSize); - return device_shape; - } else if (format == kOpFormat_NHWC) { - device_shape.push_back(shape[0]); - device_shape.push_back(shape[2]); - device_shape.push_back(shape[3]); - device_shape.push_back(shape[1]); - return device_shape; - } else if (format == kOpFormat_NCHW) { - return shape; - } else if (format == kOpFormat_HWCN) { - return {shape[2], shape[3], shape[1], shape[0]}; + MS_LOG(WARNING) << "Get Device Shape using a shape size is less than 4 ,should be Padding shape by Default firstly"; + temp_shape = PaddingShapeTo4dByDefault(shape); + } + auto iter = device_shape_map.find(format); + if (iter != device_shape_map.end()) { + return iter->second(temp_shape); } MS_LOG(EXCEPTION) << "Unexpected format[" << format << "]"; } +bool CheckArgs(const FormatArgs &args, size_t *size, size_t *total_size) { + if (args.host_shape.size() != kNchwDims) { + MS_LOG(ERROR) << "Invalid host shape, host shape dims:" << args.host_shape.size() << ", expect dims:" << kNchwDims; + return false; + } + *size = TypeIdSize(args.src_data_type); + if (*size < 1) { + MS_LOG(ERROR) << "Illegal dtype."; + return false; + } + *total_size = ShapeSize(args.device_shape) * (*size); + if (*total_size != args.device_size) { + MS_LOG(ERROR) << "Illegal total data size, total_size:" << *total_size << ", device_size:" << args.device_size; + return false; + } + return true; +} + bool TransDataType(const TypeIdArgs &args, void *result) { MS_LOG(DEBUG) << "Begin trans datatype from " << TypeIdLabel(args.host_data_type) << " to " << TypeIdLabel(args.device_data_type); @@ -264,13 +405,14 @@ bool TransFormat(const FormatArgs &args, void *result) { MS_LOG(ERROR) << "Invalid datatype.."; return false; } - if ((args.host_format == kOpFormat_NCHW || args.host_format == kOpFormat_ND) && - args.device_format == kOpFormat_FRAC_Z) { + if (args.device_format == kOpFormat_FRAC_Z) { return NchwToFracZ(args, result); } else if (args.device_format == kOpFormat_FRAC_NZ) { return NchwToFracNz(args, result); } else if (args.device_format == kOpFormat_NC1HWC0) { return NchwToNc1hwc0(args, result); + } else if (args.device_format == kOpFormat_C1HWNCoC0) { + return NchwToC1hwncoc0(args, result); } return true; } @@ -281,13 +423,14 @@ bool TransFormatFromDeviceToHost(const FormatArgs &args, void *result) { MS_LOG(ERROR) << "Invalid datatype.."; return false; } - if ((args.host_format == kOpFormat_NCHW || args.host_format == kOpFormat_ND) && - args.device_format == kOpFormat_FRAC_Z) { + if (args.device_format == kOpFormat_FRAC_Z) { return FracZToNchw(args, result); } else if (args.device_format == kOpFormat_FRAC_NZ) { return FracNzToNchw(args, result); } else if (args.device_format == kOpFormat_NC1HWC0) { return Nc1hwc0ToNchw(args, result); + } else if (args.device_format == kOpFormat_C1HWNCoC0) { + return C1hwncoc0ToNchw(args, result); } return true; } @@ -745,5 +888,99 @@ bool Nc1hwc0ToNchw(const FormatArgs &args, void *result) { } return true; } + +bool NchwToC1hwncoc0(const FormatArgs &args, void *result) { + // trans nchw to c1hwncoc0 + MS_LOG(DEBUG) << "Trans format from nchw to c1hwncoc0."; + MS_EXCEPTION_IF_NULL(result); + size_t size = 0; + size_t total_size = 0; + if (!CheckArgs(args, &size, &total_size)) { + MS_LOG(ERROR) << "Check args failed."; + return false; + } + auto n = args.host_shape[0]; + auto c = args.host_shape[1]; + auto h = args.host_shape[2]; + auto w = args.host_shape[3]; + auto c1 = args.device_shape[0]; + auto co = args.device_shape[4]; + auto c0 = args.device_shape[5]; + for (size_t c1_i = 0; c1_i < c1; c1_i++) { + for (size_t h_i = 0; h_i < h; h_i++) { + for (size_t w_i = 0; w_i < w; w_i++) { + for (size_t n_i = 0; n_i < n; n_i++) { + for (size_t co_i = 0; co_i < co; co_i++) { + for (size_t c0_i = 0; c0_i < c0; c0_i++) { + size_t dst_offset = (c1_i * h * w * n * co * c0 + h_i * w * n * co * c0 + w_i * n * co * c0 + + n_i * co * c0 + co_i * c0 + c0_i) * + size; + size_t protected_size = total_size - dst_offset < static_cast(SECUREC_MEM_MAX_LEN) + ? total_size - dst_offset + : static_cast(SECUREC_MEM_MAX_LEN); + size_t c_i = c0_i + c1_i * c0; + size_t src_offset = (n_i * c * h * w + c_i * h * w + h_i * w + w_i) * size; + errno_t ret; + if (c_i < c && c0_i == co_i) { + ret = memcpy_s(static_cast(result) + dst_offset, protected_size, + static_cast(args.data) + src_offset, size); + } else { + ret = memset_s(static_cast(result) + dst_offset, protected_size, 0, size); + } + if (ret != EOK) { + MS_LOG(ERROR) << "Failed to operate the dst memory, error-code:" << ret; + return false; + } + } + } + } + } + } + } + return true; +} + +bool C1hwncoc0ToNchw(const FormatArgs &args, void *result) { + // trans c1hwncoc0 to nchw + MS_LOG(DEBUG) << "Trans format from c1hwncoc0 to nchw"; + MS_EXCEPTION_IF_NULL(result); + size_t size = 0; + size_t total_size = 0; + if (!CheckArgs(args, &size, &total_size)) { + MS_LOG(ERROR) << "Check args failed."; + return false; + } + auto n = args.host_shape[0]; + auto c = args.host_shape[1]; + auto h = args.host_shape[2]; + auto w = args.host_shape[3]; + auto co = args.device_shape[4]; + auto c0 = args.device_shape[5]; + for (size_t n_i = 0; n_i < n; n_i++) { + for (size_t c_i = 0; c_i < c; c_i++) { + for (size_t h_i = 0; h_i < h; h_i++) { + for (size_t w_i = 0; w_i < w; w_i++) { + size_t dst_offset = (n_i * c * h * w + c_i * h * w + h_i * w + w_i) * size; + size_t c1_i = c_i / kCubeSize; + size_t c0_i = c_i % kCubeSize; + size_t co_i = c0_i; + size_t src_offset = (c1_i * h * w * n * co * c0 + h_i * w * n * co * c0 + w_i * n * co * c0 + n_i * co * c0 + + co_i * c0 + c0_i) * + size; + size_t protected_size = total_size - dst_offset < static_cast(SECUREC_MEM_MAX_LEN) + ? total_size - dst_offset + : static_cast(SECUREC_MEM_MAX_LEN); + auto ret = memcpy_s(static_cast(result) + dst_offset, protected_size, + static_cast(args.data) + src_offset, size); + if (ret != EOK) { + MS_LOG(ERROR) << "Failed to operate the dst memory, error-code:" << ret; + return false; + } + } + } + } + } + return true; +} } // namespace trans } // namespace mindspore diff --git a/mindspore/ccsrc/common/trans.h b/mindspore/ccsrc/common/trans.h index cf815985ff..054fa89a06 100644 --- a/mindspore/ccsrc/common/trans.h +++ b/mindspore/ccsrc/common/trans.h @@ -24,6 +24,7 @@ #include #include #include "ir/dtype.h" +#include "kernel/kernel.h" #include "ir/dtype/type.h" namespace mindspore { @@ -49,7 +50,10 @@ size_t TypeIdSize(const TypeId data_type); size_t ShapeSize(const std::vector &shape); size_t CubeSizeByType(const TypeId data_type); -std::vector TransShapeTo4d(const std::vector &shape); +std::vector PaddingShapeTo4d(const std::vector &shape, + const std::vector &padding_axis = {}); +std::vector GetRuntimePaddingShape(const AnfNodePtr &node, size_t index); +bool IsNeedPadding(const std::string &format, const size_t shape_size); std::vector TransShapeToDevice(const std::vector &shape, const std::string &format); bool TransDataType(const TypeIdArgs &args, void *result); bool TransFormat(const FormatArgs &args, void *result); @@ -59,10 +63,12 @@ bool TransFormatFromDeviceToHost(const FormatArgs &args, void *result); bool NchwToFracZ(const FormatArgs &args, void *result); bool NchwToFracNz(const FormatArgs &args, void *result); bool NchwToNc1hwc0(const FormatArgs &args, void *result); +bool NchwToC1hwncoc0(const FormatArgs &args, void *result); // device to host bool FracZToNchw(const FormatArgs &args, void *result); bool FracNzToNchw(const FormatArgs &args, void *result); bool Nc1hwc0ToNchw(const FormatArgs &args, void *result); +bool C1hwncoc0ToNchw(const FormatArgs &args, void *result); } // namespace trans } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/CMakeLists.txt b/mindspore/ccsrc/dataset/CMakeLists.txt index 477d37051e..0bc4065ac9 100644 --- a/mindspore/ccsrc/dataset/CMakeLists.txt +++ b/mindspore/ccsrc/dataset/CMakeLists.txt @@ -3,10 +3,18 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sequence-point") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-variable") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized") + +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-uninitialized") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized") +endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--image-base -Wl,0x10000000") +endif() ############################# Options ################################ if (ENABLE_GPUQUE) add_definitions(-D ENABLE_GPUQUE) @@ -75,14 +83,19 @@ set_target_properties(_c_dataengine PROPERTIES ###################################################################### ################# Link with external libraries ######################## -target_link_libraries(_c_dataengine PRIVATE mindspore mindspore_gvar) -target_link_libraries(_c_dataengine PRIVATE mindspore::pybind11_module -ldl protobuf::libprotobuf ${SECUREC_LIBRARY}) +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + target_link_libraries(_c_dataengine PRIVATE mindspore) + target_link_libraries(_c_dataengine PRIVATE mindspore::pybind11_module ${PYTHON_LIBRARIES} mindspore::protobuf ${SECUREC_LIBRARY}) +else() + target_link_libraries(_c_dataengine PRIVATE mindspore mindspore_gvar) + target_link_libraries(_c_dataengine PRIVATE mindspore::pybind11_module -ldl mindspore::protobuf ${SECUREC_LIBRARY}) +endif() target_link_libraries(_c_dataengine PUBLIC mindspore::jpeg_turbo mindspore::opencv_core mindspore::opencv_imgcodecs mindspore::opencv_imgproc) if (ENABLE_GPUQUE) target_link_libraries(_c_dataengine PRIVATE gpu_queue ${CUDNN_PATH}/lib64/libcudnn.so - ${CUDA_PATH}/lib64/libcudart.so + ${CUDA_PATH}/lib64/libcudart.so ${CUDA_PATH}/lib64/stubs/libcuda.so) endif () @@ -91,7 +104,12 @@ if (ENABLE_TDTQUE) endif () add_dependencies(_c_dataengine _c_mindrecord) -target_link_libraries(_c_dataengine PRIVATE _c_mindrecord) +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(MINDRECORD_LINK_OBJECT ${CMAKE_BINARY_DIR}/mindspore/ccsrc/mindrecord/CMakeFiles/_c_mindrecord.dir/objects.a) + target_link_libraries(_c_dataengine PRIVATE _c_mindrecord ${MINDRECORD_LINK_OBJECT} mindspore::sqlite) +else() + target_link_libraries(_c_dataengine PRIVATE _c_mindrecord) +endif() if (USE_GLOG) target_link_libraries(_c_dataengine PRIVATE mindspore::glog) diff --git a/mindspore/ccsrc/dataset/api/de_pipeline.cc b/mindspore/ccsrc/dataset/api/de_pipeline.cc index 1812c0421a..5f61c86f06 100644 --- a/mindspore/ccsrc/dataset/api/de_pipeline.cc +++ b/mindspore/ccsrc/dataset/api/de_pipeline.cc @@ -47,12 +47,14 @@ static std::unordered_map g_parse_op_func_ = {{kStorage, &D {kMap, &DEPipeline::ParseMapOp}, {kBatch, &DEPipeline::ParseBatchOp}, {kRepeat, &DEPipeline::ParseRepeatOp}, + {kSkip, &DEPipeline::ParseSkipOp}, {kZip, &DEPipeline::ParseZipOp}, {kRename, &DEPipeline::ParseRenameOp}, {kDeviceQueue, &DEPipeline::ParseDeviceQueueOp}, {kGenerator, &DEPipeline::ParseGeneratorOp}, {kTfReader, &DEPipeline::ParseTFReaderOp}, {kProject, &DEPipeline::ParseProjectOp}, + {kTake, &DEPipeline::ParseTakeOp}, {kImageFolder, &DEPipeline::ParseImageFolderOp}, {kMnist, &DEPipeline::ParseMnistOp}, {kManifest, &DEPipeline::ParseManifestOp}, @@ -422,6 +424,11 @@ Status DEPipeline::ParseMindRecordOp(const py::dict &args, std::shared_ptr(seed)); + } else if (key == "sampler") { + auto create = py::reinterpret_borrow(value).attr("_create_for_minddataset"); + std::shared_ptr sample_op = + create().cast>(); + operators.push_back(sample_op); } } } @@ -506,13 +513,24 @@ Status DEPipeline::ParseRepeatOp(const py::dict &args, std::shared_ptr *ptr) { + if (args["count"].is_none()) { + std::string err_msg = "Error: count is invalid or not set."; + RETURN_STATUS_UNEXPECTED(err_msg); + } + std::shared_ptr op; + RETURN_IF_NOT_OK(SkipOp::Builder(ToInt(args["count"])).Build(&op)); + *ptr = op; + return Status::OK(); +} + Status DEPipeline::ParseGeneratorOp(const py::dict &args, std::shared_ptr *ptr) { std::shared_ptr builder = std::make_shared(); for (auto arg : args) { std::string key = py::str(arg.first); py::handle value = arg.second; if (!value.is_none()) { - if (key == "generator_function") { + if (key == "source") { py::object obj = py::cast(&value); if (!py::isinstance(obj)) { std::string err_msg = "Error: generator is invalid or not set."; @@ -633,7 +651,16 @@ Status DEPipeline::ParseRenameOp(const py::dict &args, std::shared_ptr *ptr) { + if (args["count"].is_none()) { + std::string err_msg = "Error: count is invalid or not set."; + RETURN_STATUS_UNEXPECTED(err_msg); + } + std::shared_ptr op; + RETURN_IF_NOT_OK(TakeOp::Builder(ToInt(args["count"])).Build(&op)); + *ptr = op; + return Status::OK(); +} Status DEPipeline::ParseZipOp(const py::dict &args, std::shared_ptr *ptr) { std::shared_ptr builder = std::make_shared(); diff --git a/mindspore/ccsrc/dataset/api/de_pipeline.h b/mindspore/ccsrc/dataset/api/de_pipeline.h index acffc390cc..6ff7bb091c 100644 --- a/mindspore/ccsrc/dataset/api/de_pipeline.h +++ b/mindspore/ccsrc/dataset/api/de_pipeline.h @@ -42,6 +42,7 @@ enum OpName { kBatch, kCache, kRepeat, + kSkip, kTake, kZip, kMap, @@ -107,13 +108,15 @@ class DEPipeline { Status ParseRepeatOp(const py::dict &args, std::shared_ptr *ptr); + Status ParseSkipOp(const py::dict &args, std::shared_ptr *ptr); + Status ParseBatchOp(const py::dict &args, std::shared_ptr *ptr); Status ParseGeneratorOp(const py::dict &args, std::shared_ptr *ptr); Status ParseRenameOp(const py::dict &args, std::shared_ptr *ptr); - DsOpPtr ParseTakeOp(const py::dict &args) const; + Status ParseTakeOp(const py::dict &args, std::shared_ptr *ptr); Status ParseZipOp(const py::dict &args, std::shared_ptr *ptr); diff --git a/mindspore/ccsrc/dataset/api/python_bindings.cc b/mindspore/ccsrc/dataset/api/python_bindings.cc index e6c2691281..076f2ecc36 100644 --- a/mindspore/ccsrc/dataset/api/python_bindings.cc +++ b/mindspore/ccsrc/dataset/api/python_bindings.cc @@ -19,7 +19,9 @@ #include "dataset/kernels/no_op.h" #include "dataset/kernels/data/one_hot_op.h" #include "dataset/kernels/image/center_crop_op.h" +#if !defined(_WIN32) && !defined(_WIN64) #include "dataset/kernels/image/change_mode_op.h" +#endif #include "dataset/kernels/image/cut_out_op.h" #include "dataset/kernels/image/decode_op.h" #include "dataset/kernels/image/distort_bounding_box_crop_op.h" @@ -54,6 +56,9 @@ #include "dataset/engine/datasetops/source/tf_reader_op.h" #include "dataset/engine/jagged_connector.h" #include "dataset/kernels/data/to_float16_op.h" +#include "dataset/util/random.h" +#include "mindrecord/include/shard_operator.h" +#include "mindrecord/include/shard_sample.h" #include "pybind11/pybind11.h" #include "pybind11/stl.h" #include "pybind11/stl_bind.h" @@ -220,11 +225,13 @@ void bindTensor(py::module *m) { (void)py::class_(*m, "DataType") .def(py::init()) .def(py::self == py::self) - .def("__str__", &DataType::ToString); + .def("__str__", &DataType::ToString) + .def("__deepcopy__", [](py::object &t, py::dict memo) { return t; }); } void bindTensorOps1(py::module *m) { - (void)py::class_>(*m, "TensorOp"); + (void)py::class_>(*m, "TensorOp") + .def("__deepcopy__", [](py::object &t, py::dict memo) { return t; }); (void)py::class_>( *m, "NormalizeOp", "Tensor operation to normalize an image. Takes mean and std.") @@ -276,9 +283,11 @@ void bindTensorOps2(py::module *m) { py::arg("fillG") = RandomCropOp::kDefFillG, py::arg("fillB") = RandomCropOp::kDefFillB); (void)py::class_>(*m, "ChannelSwapOp").def(py::init<>()); +#if !defined(_WIN32) && !defined(_WIN64) (void)py::class_>( *m, "ChangeModeOp", "Tensor operation to change colors from BGR to RGB") .def(py::init<>()); +#endif (void)py::class_>( *m, "OneHotOp", "Tensor operation to apply one hot encoding. Takes number of classes.") @@ -381,7 +390,17 @@ void bindTensorOps4(py::module *m) { } void bindSamplerOps(py::module *m) { - (void)py::class_>(*m, "Sampler"); + (void)py::class_>(*m, "Sampler") + .def("set_num_rows", [](Sampler &self, int64_t rows) { THROW_IF_ERROR(self.SetNumRowsInDataset(rows)); }) + .def("set_num_samples", [](Sampler &self, int64_t samples) { THROW_IF_ERROR(self.SetNumSamples(samples)); }) + .def("initialize", [](Sampler &self) { THROW_IF_ERROR(self.InitSampler()); }) + .def("get_indices", [](Sampler &self) { + py::array ret; + THROW_IF_ERROR(self.GetAllIdsThenReset(&ret)); + return ret; + }); + + (void)py::class_>(*m, "ShardOperator"); (void)py::class_>(*m, "DistributedSampler") .def(py::init(), py::arg("numDev"), py::arg("devId"), py::arg("shuffle"), @@ -399,6 +418,10 @@ void bindSamplerOps(py::module *m) { (void)py::class_>(*m, "SubsetRandomSampler") .def(py::init>(), py::arg("indices")); + (void)py::class_>( + *m, "MindrecordSubsetRandomSampler") + .def(py::init, uint32_t>(), py::arg("indices"), py::arg("seed") = GetSeed()); + (void)py::class_>(*m, "WeightedRandomSampler") .def(py::init, int64_t, bool>(), py::arg("weights"), py::arg("numSamples"), py::arg("replacement")); @@ -406,7 +429,7 @@ void bindSamplerOps(py::module *m) { void bindInfoObjects(py::module *m) { (void)py::class_(*m, "CBatchInfo") - .def(py::init()) + .def(py::init()) .def("get_epoch_num", &BatchOp::CBatchInfo::get_epoch_num) .def("get_batch_num", &BatchOp::CBatchInfo::get_batch_num); } @@ -423,6 +446,7 @@ PYBIND11_MODULE(_c_dataengine, m) { .value("MINDRECORD", OpName::kMindrecord) .value("CACHE", OpName::kCache) .value("REPEAT", OpName::kRepeat) + .value("SKIP", OpName::kSkip) .value("TAKE", OpName::kTake) .value("ZIP", OpName::kZip) .value("MAP", OpName::kMap) diff --git a/mindspore/ccsrc/dataset/core/client.h b/mindspore/ccsrc/dataset/core/client.h index ac289a0e07..b865c54260 100644 --- a/mindspore/ccsrc/dataset/core/client.h +++ b/mindspore/ccsrc/dataset/core/client.h @@ -32,11 +32,13 @@ #include "dataset/engine/datasetops/project_op.h" #include "dataset/engine/datasetops/rename_op.h" #include "dataset/engine/datasetops/repeat_op.h" +#include "dataset/engine/datasetops/skip_op.h" #include "dataset/engine/datasetops/shuffle_op.h" #include "dataset/engine/datasetops/source/generator_op.h" #include "dataset/engine/datasetops/source/mindrecord_op.h" #include "dataset/engine/datasetops/source/storage_op.h" #include "dataset/engine/datasetops/source/tf_reader_op.h" +#include "dataset/engine/datasetops/take_op.h" #include "dataset/engine/datasetops/zip_op.h" #include "dataset/engine/execution_tree.h" #include "dataset/util/status.h" diff --git a/mindspore/ccsrc/dataset/core/tensor.cc b/mindspore/ccsrc/dataset/core/tensor.cc index 8f0eae459a..a566d51f5c 100644 --- a/mindspore/ccsrc/dataset/core/tensor.cc +++ b/mindspore/ccsrc/dataset/core/tensor.cc @@ -85,6 +85,7 @@ Tensor &Tensor::operator=(Tensor &&other) noexcept { shape_ = other.shape(); type_ = other.type(); data_ = other.StartAddr(); + data_end_ = other.data_end_; data_allocator_ = std::move(other.data_allocator_); other.Invalidate(); } @@ -208,11 +209,13 @@ Tensor::~Tensor() { if (data_allocator_ != nullptr) { data_allocator_->deallocate(data_); data_ = nullptr; + data_end_ = nullptr; } else { // If we didn't have an allocator, but data_ is not null then it must // be a stand-alone tensor that used malloc directly. free(data_); data_ = nullptr; + data_end_ = nullptr; } } } @@ -338,8 +341,10 @@ unsigned char *Tensor::StartAddr() { // on the shape and type and allocate it. if (data_allocator_ != nullptr) { data_ = data_allocator_->allocate(this->SizeInBytes()); + data_end_ = data_ + SizeInBytes(); } else { data_ = static_cast(malloc(this->SizeInBytes())); + data_end_ = data_ + SizeInBytes(); if (data_ == nullptr) { return nullptr; } @@ -362,6 +367,7 @@ void Tensor::Invalidate() { shape_ = TensorShape::CreateUnknownRankShape(); type_ = DataType(DataType::DE_UNKNOWN); data_ = nullptr; + data_end_ = nullptr; data_allocator_ = nullptr; } @@ -491,6 +497,8 @@ Status Tensor::GetItemAt(T *o, const std::vector &index) const { // return data as numpy, should return status Status Tensor::GetDataAsNumpy(py::array *data) { + RETURN_UNEXPECTED_IF_NULL(data_); + RETURN_UNEXPECTED_IF_NULL(data); if (type_ == DataType::DE_BOOL) { *data = py::array_t(shape_.AsVector(), reinterpret_cast(data_)); } else if (type_ == DataType::DE_INT8) { diff --git a/mindspore/ccsrc/dataset/core/tensor.h b/mindspore/ccsrc/dataset/core/tensor.h index 2017c2dfab..74da40c293 100644 --- a/mindspore/ccsrc/dataset/core/tensor.h +++ b/mindspore/ccsrc/dataset/core/tensor.h @@ -22,6 +22,10 @@ #include #include "./securec.h" #include "utils/log_adapter.h" +#if defined(_WIN32) || defined(_WIN64) +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#endif #include "pybind11/numpy.h" #include "pybind11/pybind11.h" #include "pybind11/stl.h" @@ -359,7 +363,7 @@ class Tensor { // @return TensorIterator template TensorIterator end() { - return TensorIterator(data_ + SizeInBytes()); + return TensorIterator(data_end_); } protected: @@ -398,6 +402,8 @@ class Tensor { unsigned char *data_; // An allocator for data_ CharAllocPtr data_allocator_; + // pointer to the end of the physical data + unsigned char *data_end_ = nullptr; }; } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/CMakeLists.txt b/mindspore/ccsrc/dataset/engine/datasetops/CMakeLists.txt index d23d6bccb8..655a739ada 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/CMakeLists.txt +++ b/mindspore/ccsrc/dataset/engine/datasetops/CMakeLists.txt @@ -5,12 +5,13 @@ add_library(engine-datasetops OBJECT parallel_op.cc pipeline_op.cc batch_op.cc - batch_op.cc device_queue_op.cc map_op.cc project_op.cc rename_op.cc repeat_op.cc + skip_op.cc + take_op.cc shuffle_op.cc zip_op.cc ) diff --git a/mindspore/ccsrc/dataset/engine/datasetops/batch_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/batch_op.cc index 8778fe1b45..c80078cb44 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/batch_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/batch_op.cc @@ -57,7 +57,7 @@ BatchOp::BatchOp(int32_t batch_size, bool drop, int32_t op_queue_size, int32_t n Status BatchOp::operator()() { RETURN_IF_NOT_OK(LaunchThreadsAndInitOp()); TaskManager::FindMe()->Post(); - int32_t epoch_num = 0, batch_num = 0, cnt = 0; + int64_t epoch_num = 0, batch_num = 0, cnt = 0; TensorRow new_row; std::unique_ptr table = std::make_unique(); child_iterator_ = std::make_unique(this, 0, 0); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/batch_op.h b/mindspore/ccsrc/dataset/engine/datasetops/batch_op.h index 9037b8e94e..32d386e3c9 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/batch_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/batch_op.h @@ -124,17 +124,17 @@ class BatchOp : public ParallelOp { // This struct is used for both internal control and python callback. // This struct is bound to python with read-only access. struct CBatchInfo { - CBatchInfo(int32_t ep, int32_t bat, int32_t cur, batchCtrl ctrl) + CBatchInfo(int64_t ep, int64_t bat, int64_t cur, batchCtrl ctrl) : epoch_num_(ep), batch_num_(bat), total_batch_num_(cur), ctrl_(ctrl) {} - CBatchInfo(int32_t ep, int32_t bat, int32_t cur) : CBatchInfo(ep, bat, cur, batchCtrl::kNoCtrl) {} + CBatchInfo(int64_t ep, int64_t bat, int64_t cur) : CBatchInfo(ep, bat, cur, batchCtrl::kNoCtrl) {} CBatchInfo() : CBatchInfo(0, 0, 0, batchCtrl::kNoCtrl) {} explicit CBatchInfo(batchCtrl ctrl) : CBatchInfo(0, 0, 0, ctrl) {} - int32_t epoch_num_; // i-th epoch. i starts from 0 - int32_t batch_num_; // i-th batch since the start of current epoch. i starts from 0 - int32_t total_batch_num_; // i-th batch since the start of first epoch. i starts from 0 + int64_t epoch_num_; // i-th epoch. i starts from 0 + int64_t batch_num_; // i-th batch since the start of current epoch. i starts from 0 + int64_t total_batch_num_; // i-th batch since the start of first epoch. i starts from 0 batchCtrl ctrl_; // No control=0, EOE=1, EOF=2, Quit=3 - const int32_t get_batch_num() const { return batch_num_; } - const int32_t get_epoch_num() const { return epoch_num_; } + const int64_t get_batch_num() const { return batch_num_; } + const int64_t get_epoch_num() const { return epoch_num_; } }; // BatchOp constructor diff --git a/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.cc index f51c2a1539..5e3ea3dc44 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.cc @@ -109,11 +109,15 @@ void DatasetOp::Print(std::ostream &out, bool show_all) const { // Gets the next buffer from the given child Status DatasetOp::GetNextBuffer(std::unique_ptr *p_buffer, int32_t worker_id, bool retry_if_eoe) { +#if defined(_WIN32) || defined(_WIN64) + RETURN_IF_NOT_OK(out_connector_->PopWithRetry(static_cast(worker_id), p_buffer, retry_if_eoe)); +#else std::unique_ptr next_buff; // pop is a blocked call and will throw an interruption if the whole group shuts down. RETURN_IF_NOT_OK(out_connector_->PopWithRetry(static_cast(worker_id), &next_buff, retry_if_eoe)); *p_buffer = std::move(next_buff); +#endif return Status::OK(); } @@ -161,15 +165,18 @@ Status DatasetOp::EofReceived(int32_t worker_id) { return (out_connector_->Add(static_cast(worker_id), std::move(eof_buffer))); } -// During tree prepare phase, operators may have specific operations to perform depending on +// During tree prepare phase, operators may have specific pre-operations to perform depending on // their role. -Status DatasetOp::PrepareNodeAction() { +Status DatasetOp::PrepareNodePreAction() { + if (BitTest(tree_->PrepareFlags(), ExecutionTree::kDePrepRepeat)) set_control_flag(kDeOpRepeated); + return Status::OK(); +} +// During tree prepare phase, operators may have specific post-operations to perform depending on +// their role. +Status DatasetOp::PrepareNodePostAction() { // If this op does not have any children and it is in a repeat path of the tree... - if (child_.size() == 0 && BitTest(tree_->PrepareFlags(), ExecutionTree::kDePrepRepeat)) { - // Then, flag this operator as a leaf node in a repeat path of tree execution. - BitSet(&op_ctrl_flags_, kDeOpRepeated); - - // Secondly, push ourselves onto the tree repeat stack. Later, the repeat operator + if (child_.empty() && BitTest(op_ctrl_flags_, kDeOpRepeated)) { + // push ourselves onto the tree repeat stack. Later, the repeat operator // above us will consume them. tree_->AddToRepeatStack(shared_from_this()); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.h b/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.h index a7d87c3092..0111f5239a 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/dataset_op.h @@ -150,11 +150,17 @@ class DatasetOp : public std::enable_shared_from_this { return Status::OK(); } - // During tree prepare phase, operators may have specific operations to perform depending on + // During tree prepare phase, operators may have specific pre-operations to perform depending on // their role. // @notes Derived versions of this function should always call it's superclass version first // before providing their own implementations. - virtual Status PrepareNodeAction(); + virtual Status PrepareNodePreAction(); + + // During tree prepare phase, operators may have specific post-operations to perform depending on + // their role. + // @notes Derived versions of this function should always call it's superclass version first + // before providing their own implementations. + virtual Status PrepareNodePostAction(); // Getter function // @return The operator id diff --git a/mindspore/ccsrc/dataset/engine/datasetops/map_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/map_op.cc index b6d603bac9..3f8d70b606 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/map_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/map_op.cc @@ -65,6 +65,9 @@ MapOp::MapOp(const std::vector &in_col_names, const std::vectorGetNextBuffer(&buff, 0)); is_eof = buff->eof(); RETURN_IF_NOT_OK(local_queues_[que_id]->Add(std::move(buff))); +#if defined(_WIN32) || defined(_WIN64) + if (is_eof) { + eof_worker_id_ = que_id; + for (int32_t id = 0; id < num_workers_; id++) { + if (id != eof_worker_id_) { + auto eof_buffer = std::make_unique(0, DataBuffer::kDeBFlagEOF); + RETURN_IF_NOT_OK(local_queues_[id]->Add(std::move(eof_buffer))); + } + } + } +#endif que_id = (que_id + 1) % num_workers_; } } @@ -159,6 +173,14 @@ Status MapOp::WorkerEntry(int32_t worker_id) { continue; } else if (in_buffer->eof()) { // Calling base class EofReceived to forward eof buffer. +#if defined(_WIN32) || defined(_Win64) + if (perf_mode_) { + if (eof_worker_id_ == worker_id) { + RETURN_IF_NOT_OK(EofReceived(worker_id)); + } + break; + } +#endif RETURN_IF_NOT_OK(EofReceived(worker_id)); break; } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/map_op.h b/mindspore/ccsrc/dataset/engine/datasetops/map_op.h index 4c9d27f9c7..5e16bc3fed 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/map_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/map_op.h @@ -193,6 +193,10 @@ class MapOp : public ParallelOp { // cause additional blocking because pop calls to Connector from the threads are synchronized to enforce the order. bool perf_mode_; +#if defined(_WIN32) || defined(_WIN64) + // EOF worker id is only work on Performance mode, to record the worker id of queue which gets EOF + int32_t eof_worker_id_; +#endif // Private function for worker/thread to loop continuously. It comprises the main // logic of MapOp: getting the data from previous Op, validating user specified column names, // applying a list of TensorOps to each of the data, process the results and then diff --git a/mindspore/ccsrc/dataset/engine/datasetops/parallel_op.h b/mindspore/ccsrc/dataset/engine/datasetops/parallel_op.h index ceb7f2c4ac..142ec78360 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/parallel_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/parallel_op.h @@ -64,14 +64,24 @@ class ParallelOp : public DatasetOp { return out; } - // During tree prepare phase, operators may have specific operations to perform depending on + // During tree prepare phase, operators may have specific pre-operations to perform depending on // their role. // @notes Derived versions of this function should always call it's superclass version first // before providing their own implementations. // @return Status - The error return code - Status PrepareNodeAction() override { + Status PrepareNodePreAction() override { // Run common code from super class before adding ParallelOp specific logic - return (DatasetOp::PrepareNodeAction()); + return (DatasetOp::PrepareNodePreAction()); + } + + // During tree prepare phase, operators may have specific post-operations to perform depending on + // their role. + // @notes Derived versions of this function should always call it's superclass version first + // before providing their own implementations. + // @return Status - The error return code + Status PrepareNodePostAction() override { + // Run common code from super class before adding ParallelOp specific logic + return (DatasetOp::PrepareNodePostAction()); } // Override base class reset to provide reset actions specific to the ParallelOp class. diff --git a/mindspore/ccsrc/dataset/engine/datasetops/pipeline_op.h b/mindspore/ccsrc/dataset/engine/datasetops/pipeline_op.h index ee20f1d373..a14279032d 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/pipeline_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/pipeline_op.h @@ -64,13 +64,22 @@ class PipelineOp : public DatasetOp { // @return The number of threads that push data to the output connector int32_t num_producers() const override { return 1; } - // During tree prepare phase, operators may have specific operations to perform depending on + // During tree prepare phase, operators may have specific pre-operations to perform depending on // their role. // @notes Derived versions of this function should always call it's superclass version first // before providing their own implementations. - Status PrepareNodeAction() override { + Status PrepareNodePreAction() override { // Run common code from super class before adding PipelineOp specific logic - return (DatasetOp::PrepareNodeAction()); + return (DatasetOp::PrepareNodePreAction()); + } + + // During tree prepare phase, operators may have specific post-operations to perform depending on + // their role. + // @notes Derived versions of this function should always call it's superclass version first + // before providing their own implementations. + Status PrepareNodePostAction() override { + // Run common code from super class before adding PipelineOp specific logic + return (DatasetOp::PrepareNodePostAction()); } protected: diff --git a/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.cc index 32723a9bd4..33c731c400 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.cc @@ -58,10 +58,10 @@ void RepeatOp::Print(std::ostream &out, bool show_all) const { out << "RepeatOp:" << "\nCurrent repeat count: " << repeat_count_ << "\nMax repeat count: " << max_repeats_ << "\nLeaf Nodes in my execution path:"; - if (!leaf_ops_.empty()) { + if (!eoe_ops_.empty()) { out << "\n"; - for (size_t i = 0; i < leaf_ops_.size(); i++) { - out << " Operator: " << leaf_ops_[i]->id() << "\n"; + for (size_t i = 0; i < eoe_ops_.size(); i++) { + out << " Operator: " << eoe_ops_[i]->id() << "\n"; } } else { out << " kNone."; @@ -71,21 +71,17 @@ void RepeatOp::Print(std::ostream &out, bool show_all) const { // Base-class override for executing specific RepeatOp configurations. This code will be called // during the execution tree prepare phase when it is visiting this operator. -Status RepeatOp::PrepareNodeAction() { +Status RepeatOp::PrepareNodePostAction() { // Run any common code from super class first before adding our own specific logic - RETURN_IF_NOT_OK(PipelineOp::PrepareNodeAction()); + RETURN_IF_NOT_OK(PipelineOp::PrepareNodePostAction()); std::shared_ptr leaf_op = tree_->PopFromRepeatStack(); while (leaf_op != nullptr) { // Track the leaf operators that are under this repeat op. - leaf_ops_.push_back(leaf_op); - - // Special case. If the repeat count is 1, then pre-flag the leaf nodes - // to tell them they are already at their last op: - if (max_repeats_ == 1) { - leaf_op->set_control_flag(kDeOpLastRepeat); - } + eoe_ops_.push_back(leaf_op); leaf_op = tree_->PopFromRepeatStack(); } + // Push ourselves to the stack in case one of our ascendants is repeat too. + tree_->AddToRepeatStack(shared_from_this()); return Status::OK(); } @@ -127,16 +123,20 @@ Status RepeatOp::GetNextBuffer(std::unique_ptr *p_buffer, int32_t wo Status RepeatOp::EoeReceived(int32_t worker_id) { repeat_count_++; MS_LOG(INFO) << "Repeat operator end of epoch message received. Repeat count is now: " << repeat_count_ << "."; - - // If we've reached the requested repeat count, then flag the leaf nodes + bool repeated = BitTest(op_ctrl_flags_, kDeOpRepeated); + bool last_repeat = BitTest(op_ctrl_flags_, kDeOpLastRepeat); + // If we've reached the requested repeat count, then flag the eoe nodes // to tell them they've got one more epoch to perform. When they reach the end - // of the last epoch, they quit rather than loop again. - if (max_repeats_ != kInfiniteRepeat && repeat_count_ == (max_repeats_ - 1)) { - for (size_t i = 0; i < leaf_ops_.size(); i++) { - leaf_ops_[i]->set_control_flag(kDeOpLastRepeat); + // of the last epoch, they quit rather than loop again. This happens in two cases: + // 1- We are also repeated (by another repeat op) and we are at the last repetition. Or, + // 2- We are not repeated + if (max_repeats_ != kInfiniteRepeat && repeat_count_ == (max_repeats_ - 1) && (!repeated || last_repeat)) { + for (auto &eoe_op : eoe_ops_) { + eoe_op->set_control_flag(kDeOpLastRepeat); } } if (repeat_count_ == max_repeats_) { + repeat_count_ = 0; state_ = OpState::kDeOpIdle; return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.h b/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.h index 5cc7ec2efa..8497b4cf3c 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/repeat_op.h @@ -87,8 +87,8 @@ class RepeatOp : public PipelineOp { uint32_t PrepareFlags() const override; // Base-class override for executing specific RepeatOp configurations. This code will be called - // during the execution tree prepare phase when it is visiting this operator. - Status PrepareNodeAction() override; + // during the execution tree post-prepare phase when it is visiting this operator. + Status PrepareNodePostAction() override; // This function returns the buffer that is at the top of our output connector. The caller is // typically our parent node, when the parent is asking us to provide the next buffer of data. @@ -119,9 +119,9 @@ class RepeatOp : public PipelineOp { int32_t num_producers() const override; private: - int32_t max_repeats_; // The number of repeats that the user requested - int32_t repeat_count_; // A counter for the current number of executed repeats - std::vector> leaf_ops_; // List of leaf operators underneath this repeat. + int32_t max_repeats_; // The number of repeats that the user requested + int32_t repeat_count_; // A counter for the current number of executed repeats + std::vector> eoe_ops_; // List of operators that can generate EOE underneath this repeat. }; } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/shuffle_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/shuffle_op.cc index 2afafe2128..bdf39b6a39 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/shuffle_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/shuffle_op.cc @@ -85,7 +85,11 @@ Status ShuffleOp::SelfReset() { if (!reshuffle_each_epoch_) { rng_ = std::mt19937_64(shuffle_seed_); } else { +#if defined(_WIN32) || defined(_WIN64) + std::random_device random_device; +#else std::random_device random_device("/dev/urandom"); +#endif std::uniform_int_distribution distribution(0, std::numeric_limits::max()); shuffle_seed_ = distribution(random_device); rng_ = std::mt19937_64(shuffle_seed_); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/skip_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/skip_op.cc new file mode 100644 index 0000000000..90c160b5bf --- /dev/null +++ b/mindspore/ccsrc/dataset/engine/datasetops/skip_op.cc @@ -0,0 +1,132 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "dataset/engine/data_buffer.h" +#include "dataset/engine/datasetops/skip_op.h" +#include "dataset/engine/db_connector.h" +#include "dataset/engine/execution_tree.h" + +#include "utils/log_adapter.h" + +namespace mindspore { +namespace dataset { +// Builder constructor. Creates the builder object. +SkipOp::Builder::Builder(int32_t count) : build_max_skips_(count) {} + +Status SkipOp::Builder::SanityCheck() const { + if (build_max_skips_ < 0) { + std::string err_msg("Skip count must be positive integer or 0."); + RETURN_STATUS_UNEXPECTED(err_msg); + } + return Status::OK(); +} + +// The builder "build" method creates the final object. +Status SkipOp::Builder::Build(std::shared_ptr *ptr) { + RETURN_IF_NOT_OK(SanityCheck()); + *ptr = std::make_shared(build_max_skips_); + return Status::OK(); +} + +// Constructor of the SkipOp. +SkipOp::SkipOp(int32_t count) : PipelineOp(0), max_skips_(count), skip_count_(0) {} + +// Destructor +SkipOp::~SkipOp() {} + +// A print method typically used for debugging +void SkipOp::Print(std::ostream &out, bool show_all) const { + // Call base class printer first + PipelineOp::Print(out, show_all); + + // Then display our own stuff + out << "SkipOp:" + << "\nCurrent skip count: " << skip_count_ << "\nMax skip count: " << max_skips_; +} + +// Since the buffer may contain multi rows, this function will drop the rows +// that need to skip in it, and then return the buffer. +Status SkipOp::GetNextBuffer(std::unique_ptr *p_buffer, int32_t worker_id, bool retry_if_eoe) { + if (child_.empty()) { + RETURN_STATUS_UNEXPECTED("SkipOp can't be the leaf node."); + } + + std::unique_ptr buf; + // Drop first max_skips_ rows + while (skip_count_ < max_skips_) { + RETURN_IF_NOT_OK(child_[0]->GetNextBuffer(&buf, worker_id, true)); + if (buf->eoe() || buf->eof()) { + break; + } + + // Consider the rows of buffer more than 1 + TensorRow drop_row; + int row_num = buf->NumRows(); + for (int i = 0; i < row_num; i++) { + RETURN_IF_NOT_OK(buf->PopRow(&drop_row)); + if (++skip_count_ == max_skips_) { + break; + } + } + } + + // If buffer is none or the rows of buffer is 0, + // then get a buffer from child. + if (!buf || buf->NumRows() == 0) { + if (buf && buf->eof()) { + *p_buffer = std::move(buf); + return Status::OK(); + } + RETURN_IF_NOT_OK(child_[0]->GetNextBuffer(&buf, worker_id, true)); + } + + // Handling eoe and eof + if (buf->eoe() || buf->eof()) { + RETURN_IF_NOT_OK(EoeReceived(worker_id)); + if (state_ == OpState::kDeOpIdle) { + *p_buffer = std::move(buf); + return Status::OK(); + } + } + + *p_buffer = std::move(buf); + return Status::OK(); +} + +// Base-class override for handling cases when an eoe is received. +Status SkipOp::EoeReceived(int32_t worker_id) { + skip_count_ = 0; + state_ = OpState::kDeOpIdle; + return Status::OK(); +} + +// Class functor operator () override. +// Most dataset ops operate by launching a thread (see ExecutionTree). +// However, the SkipOp is defined as a inlined operator, so it is invalid to +// launch the functor since this op runs inlined inside another operator. The +// function is overloaded to ensure that it is not called by mistake (it will +// generate an error). +Status SkipOp::operator()() { RETURN_STATUS_UNEXPECTED("Logic error. SkipOp is an inlined operator."); } + +// Base-class override for handling cases when an eof is received. +Status SkipOp::EofReceived(int32_t worker_id) { + MS_LOG(INFO) << "Skip operator EOF received, do nothing now."; + return Status::OK(); +} +} // namespace dataset +} // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/skip_op.h b/mindspore/ccsrc/dataset/engine/datasetops/skip_op.h new file mode 100644 index 0000000000..0ae520c3ad --- /dev/null +++ b/mindspore/ccsrc/dataset/engine/datasetops/skip_op.h @@ -0,0 +1,95 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATASET_ENGINE_DATASETOPS_SKIP_OP_H_ +#define DATASET_ENGINE_DATASETOPS_SKIP_OP_H_ + +#include +#include +#include +#include "dataset/engine/datasetops/pipeline_op.h" + +namespace mindspore { +namespace dataset { +class SkipOp : public PipelineOp { + public: + class Builder { + public: + // Builder constructor. Creates the builder object. + // @note No default args + // @param count - The number of skip to do + // @return This is a constructor. + explicit Builder(int32_t count); + + // Default destructor + ~Builder() = default; + + // The builder "build" method creates the final object. + // @return shared_ptr to the new StorageOp object + Status Build(std::shared_ptr *); + + private: + int32_t build_max_skips_; + + Status SanityCheck() const; + }; + + // Constructor of the SkipOp. + // @note The builder class should be used to call it + // @param count - The number of skips to do + explicit SkipOp(int32_t count); + + // Destructor + ~SkipOp(); + + // A print method typically used for debugging + // @param out - The output stream to write output to + // @param show_all - A bool to control if you want to show all info or just a summary + void Print(std::ostream &out, bool show_all) const override; + + // Class functor operator () override. + // Most dataset ops operate by launching a thread (see ExecutionTree). + // However, the SkipOp is defined as a inlined operator, so it is invalid to launch the + // functor since this op runs inlined inside another operator. The function is overloaded to + // ensure that it is not called by mistake (it will generate an error). + // @return Status - The error code return + Status operator()() override; + + // This function returns the buffer that is at the top of our output connector. The caller is + // typically our parent node, when the parent is asking us to provide the next buffer of data. + // Since SkipOp is an inlined op, getting a buffer from us will simply bounce you to get + // a buffer from our child. + // @param p_buffer - output pointer to the buffer that it will fetch. + // @param worker_id - The worker id + // @param retry_if_eoe Set this flag to true to allow calling pop() again after the first pop() returns EOE. + // @return Status - The error code return + Status GetNextBuffer(std::unique_ptr *p_buffer, int32_t worker_id, bool retry_if_eoe) override; + + // Base-class override for handling cases when an eoe is received. + // @param worker_id - The worker id + Status EoeReceived(int32_t worker_id) override; + + // Base-class override for handling cases when an eof is received. + // @param worker_id - The worker id + Status EofReceived(int32_t worker_id) override; + + private: + int32_t max_skips_; // The number of skips that the user requested + int32_t skip_count_; // A counter for the current number of executed skips +}; +} // namespace dataset +} // namespace mindspore + +#endif // DATASET_ENGINE_DATASETOPS_SKIP_OP_H_ diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/CMakeLists.txt b/mindspore/ccsrc/dataset/engine/datasetops/source/CMakeLists.txt index 5a02a2ec31..a7c0dfd725 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/CMakeLists.txt +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/CMakeLists.txt @@ -20,4 +20,4 @@ add_library(engine-datasetops-source OBJECT celeba_op.cc ) -add_dependencies(engine-datasetops-source protobuf::libprotobuf) +add_dependencies(engine-datasetops-source mindspore::protobuf) diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/celeba_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/celeba_op.cc index 0c2e20729e..87a7b3c687 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/celeba_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/celeba_op.cc @@ -100,7 +100,7 @@ Status CelebAOp::LaunchThreadsAndInitOp() { RETURN_IF_NOT_OK(tree_->LaunchWorkers(num_workers_, std::bind(&CelebAOp::WorkerEntry, this, std::placeholders::_1))); TaskManager::FindMe()->Post(); RETURN_IF_NOT_OK(ParseImageAttrInfo()); - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/cifar_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/cifar_op.cc index 3e64c8a3e6..60de5a6bdf 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/cifar_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/cifar_op.cc @@ -240,7 +240,7 @@ Status CifarOp::Reset() { // hand shake with Sampler, allow Sampler to call RandomAccessOp's functions to get NumRows Status CifarOp::InitSampler() { - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/image_folder_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/image_folder_op.cc index f6cf377666..0ac579a865 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/image_folder_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/image_folder_op.cc @@ -258,7 +258,7 @@ Status ImageFolderOp::Reset() { // hand shake with Sampler, allow Sampler to call RandomAccessOp's functions to get NumRows Status ImageFolderOp::InitSampler() { - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/manifest_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/manifest_op.cc index 6907647952..0139af4d9d 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/manifest_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/manifest_op.cc @@ -254,7 +254,7 @@ Status ManifestOp::Reset() { // hand shake with Sampler, allow Sampler to call RandomAccessOp's functions to get NumRows Status ManifestOp::InitSampler() { - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/mnist_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/mnist_op.cc index 3431e58aea..71900f8a91 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/mnist_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/mnist_op.cc @@ -205,7 +205,7 @@ Status MnistOp::Reset() { // hand shake with Sampler, allow Sampler to call RandomAccessOp's functions to get NumRows Status MnistOp::InitSampler() { - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.cc index 28a5705648..5b5a9321df 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.cc @@ -31,8 +31,9 @@ DistributedSampler::DistributedSampler(int64_t num_dev, int64_t dev_id, bool shu num_devices_(num_dev), shuffle_(shuffle) {} -Status DistributedSampler::Init(const RandomAccessOp *op) { - RETURN_IF_NOT_OK(Sampler::Init(op)); +Status DistributedSampler::InitSampler() { + CHECK_FAIL_RETURN_UNEXPECTED(num_samples_ > 0, "num_samples <= 0\n"); + CHECK_FAIL_RETURN_UNEXPECTED(num_rows_ > 0, "num_rows <= 0\n"); CHECK_FAIL_RETURN_UNEXPECTED(device_id_ < num_devices_ && device_id_ >= 0 && num_rows_ > 0 && num_samples_ > 0, "fail to init DistributedSampler"); rnd_.seed(seed_++); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.h index ef25b6bccf..58b469dcc8 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/distributed_sampler.h @@ -41,10 +41,8 @@ class DistributedSampler : public Sampler { // @return - The error code return Status GetNextBuffer(std::unique_ptr *out_buffer) override; - // first handshake between StorageOp and Sampler - // @param op - StorageOp pointer, pass in so Sampler can call GetNumSamples() and get ClassIds() - // @return - Status Init(const RandomAccessOp *) override; + // Init sampler, called by base class or python + Status InitSampler() override; // for next epoch of sampleIds // @return - The error code return diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.cc index 8c8c12fce2..8198204437 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.cc @@ -28,9 +28,7 @@ PKSampler::PKSampler(int64_t val, bool shuffle, int64_t samples_per_buffer) num_pk_samples_(0), samples_per_class_(val) {} -Status PKSampler::Init(const RandomAccessOp *op) { - RETURN_UNEXPECTED_IF_NULL(op); - RETURN_IF_NOT_OK(op->GetClassIds(&label_to_ids_)); +Status PKSampler::InitSampler() { labels_.reserve(label_to_ids_.size()); for (const auto &pair : label_to_ids_) { if (pair.second.empty() == false) { @@ -79,5 +77,13 @@ Status PKSampler::Reset() { rnd_.seed(seed_++); return Status::OK(); } + +Status PKSampler::HandshakeRandomAccessOp(const RandomAccessOp *op) { + RETURN_UNEXPECTED_IF_NULL(op); + RETURN_IF_NOT_OK(op->GetClassIds(&label_to_ids_)); + RETURN_IF_NOT_OK(InitSampler()); + return Status::OK(); +} + } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.h index fa2b4ed0c7..14f598a9ce 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/pk_sampler.h @@ -45,7 +45,10 @@ class PKSampler : public Sampler { // NOT YET FINISHED // first handshake between StorageOp and Sampler // @param op - StorageOp pointer, pass in so Sampler can call GetNumSamples() and get ClassIds() // @return - Status Init(const RandomAccessOp *op) override; + Status HandshakeRandomAccessOp(const RandomAccessOp *op) override; + + // init sampler, to be called by python or Handshake + Status InitSampler() override; // for next epoch of sampleIds // @return - The error code return diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.cc index 216f322052..de8cde409f 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.cc @@ -49,10 +49,9 @@ Status RandomSampler::GetNextBuffer(std::unique_ptr *out_buffer) { return Status::OK(); } -Status RandomSampler::Init(const RandomAccessOp *op) { - RETURN_IF_NOT_OK(Sampler::Init(op)); +Status RandomSampler::InitSampler() { num_samples_ = (user_num_samples_ < num_samples_) ? user_num_samples_ : num_samples_; - CHECK_FAIL_RETURN_UNEXPECTED(num_samples_ > 0 && num_rows_ > 0, "Fail to init RandomSampler"); + CHECK_FAIL_RETURN_UNEXPECTED(num_samples_ > 0 && num_rows_ > 0, "both num_samples & num_rows need to be positive"); samples_per_buffer_ = samples_per_buffer_ > num_samples_ ? num_samples_ : samples_per_buffer_; if (replacement_ == false) { shuffled_ids_.reserve(num_rows_); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.h index 54f26f352b..84a07e9fc6 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/random_sampler.h @@ -42,10 +42,8 @@ class RandomSampler : public Sampler { // @return - The error code return Status GetNextBuffer(std::unique_ptr *out_buffer) override; - // first handshake between StorageOp and Sampler - // @param op - StorageOp pointer, pass in so Sampler can call GetNumSamples() and get ClassIds() - // @return - Status Init(const RandomAccessOp *op) override; + // meant to be called by base class or python + Status InitSampler() override; // for next epoch of sampleIds // @return - The error code return diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.cc index aa3838f8b5..3c3f5f48e8 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.cc @@ -20,12 +20,13 @@ namespace dataset { Sampler::Sampler(int64_t samples_per_buffer) : DatasetOp(0), num_rows_(0), num_samples_(0), samples_per_buffer_(samples_per_buffer), col_desc_(nullptr) {} -Status Sampler::Init(const RandomAccessOp *op) { - CHECK_FAIL_RETURN_UNEXPECTED(op != nullptr && samples_per_buffer_ > 0, "Fail to init Sampler()\n"); +Status Sampler::HandshakeRandomAccessOp(const RandomAccessOp *op) { + CHECK_FAIL_RETURN_UNEXPECTED(op != nullptr, "RandomAccessOp is nullptr\n"); RETURN_IF_NOT_OK(op->GetNumSamples(&num_samples_)); RETURN_IF_NOT_OK(op->GetNumRowsInDataset(&num_rows_)); // It's up to the derived class to check the validity of the two args // Because some sampler only needs one of the arg (weighted_random_sampler) + RETURN_IF_NOT_OK(InitSampler()); // init sampler after callback return Status::OK(); } @@ -42,5 +43,49 @@ Status Sampler::CreateSamplerTensor(std::shared_ptr *sample_ids, int64_t (void)(*sample_ids)->StartAddr(); // allocate memory in case user forgets! return Status::OK(); } + +Status Sampler::GetAllIdsThenReset(py::array *data) { + std::unique_ptr db; + std::shared_ptr sample_ids; + + // check samples_per_buffer is properly set and doesn't overflow + CHECK_FAIL_RETURN_UNEXPECTED(samples_per_buffer_ + 1 > 1, "samples_per_buffer invalid"); + + // A call to derived class to get sample ids wrapped inside a buffer + RETURN_IF_NOT_OK(GetNextBuffer(&db)); + // Get the only tensor inside the buffer that contains the actual SampleIds for the entire epoch + RETURN_IF_NOT_OK(db->GetTensor(&sample_ids, 0, 0)); + // check this buffer is not a ctrl buffer + CHECK_FAIL_RETURN_UNEXPECTED(db->buffer_flags() == DataBuffer::kDeBFlagNone, "ERROR ctrl buffer received"); + { + py::gil_scoped_acquire gil_acquire; + if (Py_IsInitialized() == 0) { + return Status(StatusCode::kPythonInterpreterFailure, "Python Interpreter is finalized"); + } + try { + RETURN_IF_NOT_OK(sample_ids->GetDataAsNumpy(data)); + } catch (const std::runtime_error &e) { + return Status(StatusCode::kPyFuncException, e.what()); + } + } + // perform error checking! Next buffer supposed to be EOE since last one already contains all ids for current epoch + RETURN_IF_NOT_OK(GetNextBuffer(&db)); + CHECK_FAIL_RETURN_UNEXPECTED(db->eoe(), "ERROR Non EOE received"); + // Reset Sampler since this is the end of the epoch + RETURN_IF_NOT_OK(Reset()); + return Status::OK(); +} + +Status Sampler::SetNumSamples(int64_t num_samples) { + CHECK_FAIL_RETURN_UNEXPECTED(num_samples > 0, "num_samples is negative or 0"); + num_samples_ = num_samples; + return Status::OK(); +} + +Status Sampler::SetNumRowsInDataset(int64_t num_rows) { + CHECK_FAIL_RETURN_UNEXPECTED(num_rows > 0, "num_rows is negative or 0"); + num_rows_ = num_rows; + return Status::OK(); +} } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.h index 801565508b..4ea221027a 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sampler.h @@ -78,14 +78,26 @@ class Sampler : public DatasetOp { // @return - The error code return Status GetNextBuffer(std::unique_ptr *out_buffer) override = 0; + // return all ids in one epoch as a numpy array, then call reset + Status GetAllIdsThenReset(py::array *data); + // for next epoch of sampleIds // @return - The error code return Status Reset() override = 0; - // first handshake between StorageOp and Sampler. Base class init will call both GetNumRows and GetNumSamples - // @param op - StorageOp pointer, pass in so Sampler can call GetNumSamples() and get ClassIds() + // setter function for num_rows_ + Status SetNumRowsInDataset(int64_t num_rows); + + // setter function for num_samples_ + Status SetNumSamples(int64_t num_samples); + + // first handshake between StorageOp and Sampler. This func will call getNumRows and getNumSamples + // @param op - StorageOp pointer, pass in so Sampler can call getNumSamples() and get ClassIds() // @return - virtual Status Init(const RandomAccessOp *op); + virtual Status HandshakeRandomAccessOp(const RandomAccessOp *op); + + // initialize sampler and perform checks on certain vars + virtual Status InitSampler() { return Status::OK(); } // Not meant to be called // @return diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.cc index 72131a6de1..a3c4fe2256 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.cc @@ -41,9 +41,7 @@ Status SequentialSampler::GetNextBuffer(std::unique_ptr *out_buffer) return Status::OK(); } -Status SequentialSampler::Init(const RandomAccessOp *op) { - RETURN_UNEXPECTED_IF_NULL(op); - RETURN_IF_NOT_OK(op->GetNumSamples(&num_samples_)); +Status SequentialSampler::InitSampler() { CHECK_FAIL_RETURN_UNEXPECTED(num_samples_ > 0 && samples_per_buffer_ > 0, "Fail to init Sequential Sampler"); samples_per_buffer_ = samples_per_buffer_ > num_samples_ ? num_samples_ : samples_per_buffer_; return Status::OK(); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.h index d119fd8d08..c38a9ed2f9 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/sequential_sampler.h @@ -32,10 +32,8 @@ class SequentialSampler : public Sampler { // Destructor. ~SequentialSampler() = default; - // Initialize the sampler. - // @param op - // @return Status - Status Init(const RandomAccessOp *op) override; + // init sampler, called by python + Status InitSampler() override; // for next epoch of sampleIds // @return - The error code return diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.cc index 16603939b3..c377fddb49 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.cc @@ -31,9 +31,8 @@ SubsetRandomSampler::SubsetRandomSampler(const std::vector &indices, in : Sampler(samples_per_buffer), indices_(indices), sample_id_(0), buffer_id_(0) {} // Initialized this Sampler. -Status SubsetRandomSampler::Init(const RandomAccessOp *op) { - // Calling base class init. - RETURN_IF_NOT_OK(Sampler::Init(op)); +Status SubsetRandomSampler::InitSampler() { + CHECK_FAIL_RETURN_UNEXPECTED(num_rows_ > 0, "num_rows <= 0\n"); // Initialize random generator with seed from config manager rand_gen_.seed(GetSeed()); diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.h index 38fae6b20b..1f4c155748 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/subset_random_sampler.h @@ -38,9 +38,8 @@ class SubsetRandomSampler : public Sampler { ~SubsetRandomSampler() = default; // Initialize the sampler. - // @param op (Not used in this sampler) // @return Status - Status Init(const RandomAccessOp *op) override; + Status InitSampler() override; // Reset the internal variable to the initial state and reshuffle the indices. // @return Status diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.cc index f2957e74be..06afc219e6 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.cc @@ -29,21 +29,21 @@ namespace dataset { // Constructor. WeightedRandomSampler::WeightedRandomSampler(const std::vector &weights, int64_t num_samples, bool replacement, int64_t samples_per_buffer) - : Sampler(samples_per_buffer), weights_(weights), replacement_(replacement), sample_id_(0), buffer_id_(0) { - num_samples_ = num_samples; // this variable is defined in base class sampler -} + : Sampler(samples_per_buffer), + weights_(weights), + replacement_(replacement), + sample_id_(0), + buffer_id_(0), + user_num_samples_(num_samples) {} // Initialized this Sampler. -Status WeightedRandomSampler::Init(const RandomAccessOp *op) { - RETURN_UNEXPECTED_IF_NULL(op); - RETURN_IF_NOT_OK(op->GetNumRowsInDataset(&num_rows_)); - +Status WeightedRandomSampler::InitSampler() { + CHECK_FAIL_RETURN_UNEXPECTED(num_rows_ > 0 && user_num_samples_, "num_samples & num_rows need to be positive"); + CHECK_FAIL_RETURN_UNEXPECTED(samples_per_buffer_ > 0, "samples_per_buffer<=0\n"); // Initialize random generator with seed from config manager rand_gen_.seed(GetSeed()); - samples_per_buffer_ = (samples_per_buffer_ > num_samples_) ? num_samples_ : samples_per_buffer_; - - CHECK_FAIL_RETURN_UNEXPECTED(num_samples_ > 0 && samples_per_buffer_ > 0, "Fail to init WeightedRandomSampler"); + samples_per_buffer_ = (samples_per_buffer_ > user_num_samples_) ? user_num_samples_ : samples_per_buffer_; if (!replacement_) { exp_dist_ = std::make_unique>(1); @@ -65,8 +65,8 @@ void WeightedRandomSampler::InitOnePassSampling() { } // Partial sort the first `numSamples` elements. - std::partial_sort(val_idx.begin(), val_idx.begin() + num_samples_, val_idx.end()); - for (int64_t i = 0; i < num_samples_; i++) { + std::partial_sort(val_idx.begin(), val_idx.begin() + user_num_samples_, val_idx.end()); + for (int64_t i = 0; i < user_num_samples_; i++) { onepass_ids_.push_back(val_idx[i].second); } } @@ -91,11 +91,11 @@ Status WeightedRandomSampler::GetNextBuffer(std::unique_ptr *out_buf "number of samples weights is more than num of rows. Might generate id out of bound OR other errors"); } - if (!replacement_ && (weights_.size() < static_cast(num_samples_))) { + if (!replacement_ && (weights_.size() < static_cast(user_num_samples_))) { RETURN_STATUS_UNEXPECTED("Without replacement, sample weights less than numSamples"); } - if (sample_id_ == num_samples_) { + if (sample_id_ == user_num_samples_) { (*out_buffer) = std::make_unique(buffer_id_++, DataBuffer::kDeBFlagEOE); } else { (*out_buffer) = std::make_unique(buffer_id_++, DataBuffer::kDeBFlagNone); @@ -103,8 +103,8 @@ Status WeightedRandomSampler::GetNextBuffer(std::unique_ptr *out_buf int64_t last_id = sample_id_ + samples_per_buffer_; // Handling the return all samples at once, and when last draw is not a full batch. - if (last_id > num_samples_) { - last_id = num_samples_; + if (last_id > user_num_samples_) { + last_id = user_num_samples_; } // Allocate tensor. diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.h b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.h index bccc9e599d..5381bb64b0 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/sampler/weighted_random_sampler.h @@ -43,7 +43,7 @@ class WeightedRandomSampler : public Sampler { // Initialize the sampler. // @param op (Not used in this sampler) // @return Status - Status Init(const RandomAccessOp *op) override; + Status InitSampler() override; // Reset the internal variable to the initial state and reshuffle the indices. Status Reset() override; @@ -69,6 +69,9 @@ class WeightedRandomSampler : public Sampler { // Random engine and device std::mt19937 rand_gen_; + // num_samples from user + int64_t user_num_samples_; + // Discrete distribution for generating weighted random numbers with replacement. std::unique_ptr> discrete_dist_; diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.cc index 71b4c47cf5..1731ed14ba 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.cc +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.cc @@ -220,7 +220,7 @@ Status VOCOp::ParseImageIds() { } Status VOCOp::InitSampler() { - RETURN_IF_NOT_OK(sampler_->Init(this)); + RETURN_IF_NOT_OK(sampler_->HandshakeRandomAccessOp(this)); return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.h b/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.h index a267ef866a..5751388519 100644 --- a/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.h +++ b/mindspore/ccsrc/dataset/engine/datasetops/source/voc_op.h @@ -201,8 +201,8 @@ class VOCOp : public ParallelOp, public RandomAccessOp { Status Reset() override; bool decode_; - uint64_t row_cnt_; - uint64_t buf_cnt_; + int64_t row_cnt_; + int64_t buf_cnt_; int64_t num_rows_; int64_t num_samples_; std::string folder_path_; diff --git a/mindspore/ccsrc/dataset/engine/datasetops/take_op.cc b/mindspore/ccsrc/dataset/engine/datasetops/take_op.cc new file mode 100644 index 0000000000..d9625b6c26 --- /dev/null +++ b/mindspore/ccsrc/dataset/engine/datasetops/take_op.cc @@ -0,0 +1,146 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "common/utils.h" +#include "dataset/engine/data_buffer.h" +#include "dataset/engine/datasetops/take_op.h" +#include "dataset/engine/db_connector.h" +#include "dataset/engine/execution_tree.h" + +namespace mindspore { +namespace dataset { +// Builder constructor. Creates the builder object. +TakeOp::Builder::Builder(int32_t count) : build_max_takes_(count) {} + +Status TakeOp::Builder::SanityCheck() const { + if (build_max_takes_ <= 0) { + std::string err_msg("Take count must be greater than 0."); + RETURN_STATUS_UNEXPECTED(err_msg); + } + return Status::OK(); +} + +// The builder "build" method creates the final object. +Status TakeOp::Builder::Build(std::shared_ptr *ptr) { + RETURN_IF_NOT_OK(SanityCheck()); + *ptr = std::make_shared(build_max_takes_); + return Status::OK(); +} + +// Constructor of the TakeOp. +TakeOp::TakeOp(int32_t count) : PipelineOp(0), max_takes_(count), take_count_(0) {} + +// A print method typically used for debugging +void TakeOp::Print(std::ostream &out, bool show_all) const { + // Call base class printer first + PipelineOp::Print(out, show_all); + + // Then display our own stuff + out << "TakeOp:" + << "\nCurrent take count: " << take_count_ << "\nMax take count: " << max_takes_; +} + +// This function will be call muti times to returns the buffer, when meet required max take count or meet +// EOF buffer then this will stop. +Status TakeOp::GetNextBuffer(std::unique_ptr *p_buffer, int32_t worker_id, bool retry_if_eoe) { + if (child_.empty()) { + RETURN_STATUS_UNEXPECTED("TakeOp can't be the leaf node."); + } + + std::unique_ptr buf; + + bool last_repeat = !BitTest(op_ctrl_flags_, kDeOpRepeated) || BitTest(op_ctrl_flags_, kDeOpLastRepeat); + if (take_count_ == max_takes_) { + if (state_ == OpState::kDeOpRunning) { + MS_LOG(INFO) << "meet max count and push-back eoe buffer."; + auto eoe_buffer = std::make_unique(0, DataBuffer::kDeBFlagEOE); + *p_buffer = std::move(eoe_buffer); + state_ = OpState::kDeOpIdle; + + // Reset the count and drain + if (!last_repeat) { + take_count_ = 0; + RETURN_IF_NOT_OK(child_[0]->GetNextBuffer(&buf, worker_id, true)); + while (!buf->eoe() && !buf->eof()) { + RETURN_IF_NOT_OK(child_[0]->GetNextBuffer(&buf, worker_id, true)); + } + } + } else { + MS_LOG(INFO) << "meet max count and push-back eof buffer."; + auto eof_buffer = std::make_unique(0, DataBuffer::kDeBFlagEOF); + *p_buffer = std::move(eof_buffer); + take_count_ = 0; + } + return Status::OK(); + } + RETURN_IF_NOT_OK(child_[0]->GetNextBuffer(&buf, worker_id, true)); + // Loop until non EOE is received + if (buf->eoe()) { + take_count_ = 0; + *p_buffer = std::move(buf); + return Status::OK(); + } + + // Check if the last buf is next eof + if (buf->eof()) { + *p_buffer = std::move(buf); + return Status::OK(); + } + + // Get buffer and push back when take_count is still small + if (take_count_ < max_takes_) { + RETURN_IF_NOT_OK(FillBuffer(&buf, p_buffer)); + } + return Status::OK(); +} + +// Function FillBuffer mainly prepare the buffer for returning +Status TakeOp::FillBuffer(std::unique_ptr *buffer, std::unique_ptr *data_buffer) { + int32_t buffer_size = (*buffer)->NumRows(); + if (take_count_ + buffer_size < max_takes_) { + *data_buffer = std::move(*buffer); + take_count_ = take_count_ + buffer_size; + } else { + MS_LOG(INFO) << "In last buffer: Push one buffer."; + std::unique_ptr new_tensor_table = std::make_unique(); + while (take_count_ < max_takes_) { + TensorRow new_row; + RETURN_IF_NOT_OK((*buffer)->PopRow(&new_row)); + take_count_++; + new_tensor_table->push_back(new_row); + } + (*buffer)->set_tensor_table(std::move(new_tensor_table)); + *data_buffer = std::move(*buffer); + } + return Status::OK(); +} + +// Class functor operator () override. +// Most dataset ops operate by launching a thread (see ExecutionTree). +// However, the TakeOp is defined as a inlined operator, so it is invalid to launch the +// functor since this op runs inlined inside another operator. The function is overloaded to +// ensure that it is not called by mistake (it will generate an error). +Status TakeOp::operator()() { RETURN_STATUS_UNEXPECTED("Logic error. TakeOp is an inlined operator."); } + +Status TakeOp::PrepareNodePostAction() { + RETURN_IF_NOT_OK(PipelineOp::PrepareNodePostAction()); + tree_->AddToRepeatStack(shared_from_this()); + return Status::OK(); +} +} // namespace dataset +} // namespace mindspore diff --git a/mindspore/ccsrc/dataset/engine/datasetops/take_op.h b/mindspore/ccsrc/dataset/engine/datasetops/take_op.h new file mode 100644 index 0000000000..02218cf610 --- /dev/null +++ b/mindspore/ccsrc/dataset/engine/datasetops/take_op.h @@ -0,0 +1,107 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATASET_ENGINE_DATASETOPS_TAKE_OP_H_ +#define DATASET_ENGINE_DATASETOPS_TAKE_OP_H_ + +#include +#include +#include +#include "dataset/engine/datasetops/pipeline_op.h" + +namespace mindspore { +namespace dataset { +class TakeOp : public PipelineOp { + public: + // The nested builder class inside of the TakeOp is used to help manage all of the arguments + // for constructing it. This take op is very simple though, so this builder is really just + // provided for a consistent look and feel for creators of Dataset operators overall. + class Builder { + public: + // Builder constructor. Creates the builder object. + // @note No default args + // @param count - The number of takes to do + // @return This is a constructor. + explicit Builder(int32_t count); + + // Default destructor + ~Builder() = default; + + // The builder "build" method creates the final object. + // @return shared_ptr to the new StorageOp object + Status Build(std::shared_ptr *); + + private: + int32_t build_max_takes_; + + Status SanityCheck() const; + }; + + // Constructor of the TakeOp. + // @note The builder class should be used to call it + // @param count - The number of takes to do + explicit TakeOp(int32_t count); + + // Destructor + ~TakeOp() = default; + + // A print method typically used for debugging + // @param out - The output stream to write output to + // @param show_all - A bool to control if you want to show all info or just a summary + void Print(std::ostream &out, bool show_all) const override; + + // << Stream output operator overload + // @notes This allows you to write the debug print info using stream operators + // @param out - reference to the output stream being overloaded + // @param ro - reference to the TakeOp to display + // @return - the output stream must be returned + friend std::ostream &operator<<(std::ostream &out, const TakeOp &ro) { + ro.Print(out, false); + return out; + } + + // Class functor operator () override. + // Most dataset ops operate by launching a thread (see ExecutionTree). + // However, the TakeOp is defined as a inlined operator, so it is invalid to launch the + // functor since this op runs inlined inside another operator. The function is overloaded to + // ensure that it is not called by mistake (it will generate an error). + // @return Status - The error code return + Status operator()() override; + + // Gets a buffer from the child node. The caller is typically our parent node. + // @note This function sets the `retryIfEoe` flag when popping from the child connector. This way, + // this function will retry to pop the connector again and will get the non-EOE buffer if any. + // @param p_buffer - output pointer to the buffer that it will fetch. + // @param worker_id - The worker id + // @param retry_if_eoe Set this flag to true to allow calling pop() again after the first pop() returns EOE. + // @return Status - The error code return + Status GetNextBuffer(std::unique_ptr *p_buffer, int32_t worker_id, bool retry_if_eoe) override; + + // During tree prepare phase, operators may have specific post-operations to perform depending on + // their role. + // @notes Derived versions of this function should always call it's superclass version first + // before providing their own implementations. + Status PrepareNodePostAction() override; + + private: + int32_t max_takes_; // The number of takes that the user requested + int32_t take_count_; // A counter for the current number of executed takes + + Status FillBuffer(std::unique_ptr *buffer, std::unique_ptr *data_buffer); +}; +} // namespace dataset +} // namespace mindspore + +#endif // DATASET_ENGINE_DATASETOPS_TAKE_OP_H_ diff --git a/mindspore/ccsrc/dataset/engine/execution_tree.cc b/mindspore/ccsrc/dataset/engine/execution_tree.cc index 20fcb836c5..ebfa532195 100644 --- a/mindspore/ccsrc/dataset/engine/execution_tree.cc +++ b/mindspore/ccsrc/dataset/engine/execution_tree.cc @@ -162,30 +162,25 @@ Status ExecutionTree::Prepare() { // Recursive function used during prepare phase to visit a node and drive any pre- and post- // node actions during a tree walk. Status ExecutionTree::PrepareNode(const std::shared_ptr &dataset_op) { - int32_t num_children = dataset_op->child_.size(); + // execute PreAction + RETURN_IF_NOT_OK(dataset_op->PrepareNodePreAction()); - // Before going down into children, make any prepare flags updates based on this - // operator. + // Before going down into children, make any prepare flags updates based on this operator. uint32_t op_prep_flags = dataset_op->PrepareFlags(); - // Sanity check. In future we can support nested repeats. for now it's not allowed. - // If somebody above us already set the repeat flag, and now we are another repeat... - if (BitTest(op_prep_flags, kDePrepRepeat) && BitTest(prepare_flags_, kDePrepRepeat)) { - std::string err_msg("Nested RepeatOp detected! This is not supported yet."); - RETURN_STATUS_UNEXPECTED(err_msg); - } BitSet(&prepare_flags_, op_prep_flags); // Now, descend to children - for (int32_t i = 0; i < num_children; ++i) { - RETURN_IF_NOT_OK(this->PrepareNode(dataset_op->child_[i])); + for (const auto &i : dataset_op->child_) { + RETURN_IF_NOT_OK(this->PrepareNode(i)); } - // No more children, now we execute any prepare actions before going back up the - // the tree on recursive function exit - RETURN_IF_NOT_OK(dataset_op->PrepareNodeAction()); - // Then clear the flags from this op now that we have prepared it. BitClear(&prepare_flags_, op_prep_flags); + + // No more children, now we execute any prepare actions before going back up the + // the tree on recursive function + RETURN_IF_NOT_OK(dataset_op->PrepareNodePostAction()); + return Status::OK(); } diff --git a/mindspore/ccsrc/dataset/engine/tdt/CMakeLists.txt b/mindspore/ccsrc/dataset/engine/tdt/CMakeLists.txt index 4a2adff310..9c6ec4b388 100644 --- a/mindspore/ccsrc/dataset/engine/tdt/CMakeLists.txt +++ b/mindspore/ccsrc/dataset/engine/tdt/CMakeLists.txt @@ -4,4 +4,4 @@ add_library(engine-tdt OBJECT ${FEATURE_SRCS} ) -add_dependencies(engine-tdt protobuf::libprotobuf) +add_dependencies(engine-tdt mindspore::protobuf) diff --git a/mindspore/ccsrc/dataset/kernels/image/CMakeLists.txt b/mindspore/ccsrc/dataset/kernels/image/CMakeLists.txt index 7a6240d173..23a26d5214 100644 --- a/mindspore/ccsrc/dataset/kernels/image/CMakeLists.txt +++ b/mindspore/ccsrc/dataset/kernels/image/CMakeLists.txt @@ -1,22 +1,46 @@ -add_library(kernels-image OBJECT - center_crop_op.cc - change_mode_op.cc - cut_out_op.cc - decode_op.cc - distort_bounding_box_crop_op.cc - hwc_to_chw_op.cc - image_utils.cc - normalize_op.cc - pad_op.cc - random_color_adjust_op.cc - random_crop_decode_resize_op.cc - random_crop_and_resize_op.cc - random_crop_op.cc - random_horizontal_flip_op.cc - random_resize_op.cc - random_rotation_op.cc - random_vertical_flip_op.cc - rescale_op.cc - resize_bilinear_op.cc - resize_op.cc - ) +if (WIN32) + add_library(kernels-image OBJECT + center_crop_op.cc + cut_out_op.cc + decode_op.cc + distort_bounding_box_crop_op.cc + hwc_to_chw_op.cc + image_utils.cc + normalize_op.cc + pad_op.cc + random_color_adjust_op.cc + random_crop_decode_resize_op.cc + random_crop_and_resize_op.cc + random_crop_op.cc + random_horizontal_flip_op.cc + random_resize_op.cc + random_rotation_op.cc + random_vertical_flip_op.cc + rescale_op.cc + resize_bilinear_op.cc + resize_op.cc + ) +else() + add_library(kernels-image OBJECT + center_crop_op.cc + change_mode_op.cc + cut_out_op.cc + decode_op.cc + distort_bounding_box_crop_op.cc + hwc_to_chw_op.cc + image_utils.cc + normalize_op.cc + pad_op.cc + random_color_adjust_op.cc + random_crop_decode_resize_op.cc + random_crop_and_resize_op.cc + random_crop_op.cc + random_horizontal_flip_op.cc + random_resize_op.cc + random_rotation_op.cc + random_vertical_flip_op.cc + rescale_op.cc + resize_bilinear_op.cc + resize_op.cc + ) +endif() diff --git a/mindspore/ccsrc/dataset/kernels/image/image_utils.cc b/mindspore/ccsrc/dataset/kernels/image/image_utils.cc index 8735cf7a05..63c9bb2641 100644 --- a/mindspore/ccsrc/dataset/kernels/image/image_utils.cc +++ b/mindspore/ccsrc/dataset/kernels/image/image_utils.cc @@ -186,7 +186,11 @@ void JpegSetSource(j_decompress_ptr cinfo, const void *data, int64_t datasize) { (*cinfo->mem->alloc_small)(reinterpret_cast(cinfo), JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr))); cinfo->src->init_source = JpegInitSource; cinfo->src->fill_input_buffer = JpegFillInputBuffer; +#if defined(_WIN32) || defined(_WIN64) + cinfo->src->skip_input_data = reinterpret_cast(JpegSkipInputData); +#else cinfo->src->skip_input_data = JpegSkipInputData; +#endif cinfo->src->resync_to_restart = jpeg_resync_to_restart; cinfo->src->term_source = JpegTermSource; cinfo->src->bytes_in_buffer = datasize; diff --git a/mindspore/ccsrc/dataset/kernels/image/image_utils.h b/mindspore/ccsrc/dataset/kernels/image/image_utils.h index a4ddef40d6..51090fb9ea 100644 --- a/mindspore/ccsrc/dataset/kernels/image/image_utils.h +++ b/mindspore/ccsrc/dataset/kernels/image/image_utils.h @@ -22,6 +22,10 @@ #include #include #include +#if defined(_WIN32) || defined(_WIN64) +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#endif #include "./jpeglib.h" #include "./jerror.h" #include diff --git a/mindspore/ccsrc/dataset/util/path.cc b/mindspore/ccsrc/dataset/util/path.cc index dd72f80766..24c8db5b9c 100644 --- a/mindspore/ccsrc/dataset/util/path.cc +++ b/mindspore/ccsrc/dataset/util/path.cc @@ -27,7 +27,7 @@ namespace mindspore { namespace dataset { #ifdef _WIN32 -char Path::_separator = '\\'; +char Path::separator_ = '\\'; #else char Path::separator_ = '/'; #endif @@ -129,7 +129,11 @@ bool Path::IsDirectory() { Status Path::CreateDirectory() { if (!Exists()) { +#if defined(_WIN32) || defined(_WIN64) + int rc = mkdir(common::SafeCStr(path_)); +#else int rc = mkdir(common::SafeCStr(path_), 0700); +#endif if (rc) { std::ostringstream oss; oss << "Unable to create directory " << path_ << ". Errno = " << errno; diff --git a/mindspore/ccsrc/dataset/util/random.cc b/mindspore/ccsrc/dataset/util/random.cc index e4bab6094c..2a0762c920 100644 --- a/mindspore/ccsrc/dataset/util/random.cc +++ b/mindspore/ccsrc/dataset/util/random.cc @@ -32,7 +32,11 @@ namespace dataset { uint32_t GetSeed() { uint32_t seed = GlobalContext::config_manager()->seed(); if (seed == std::mt19937::default_seed) { +#if defined(_WIN32) || defined(_WIN64) + std::random_device random_device; +#else std::random_device random_device("/dev/urandom"); +#endif std::uniform_int_distribution distribution(0, std::numeric_limits::max()); seed = distribution(random_device); } diff --git a/mindspore/ccsrc/dataset/util/services.cc b/mindspore/ccsrc/dataset/util/services.cc index 7dcb5b14c9..ea7b11014c 100644 --- a/mindspore/ccsrc/dataset/util/services.cc +++ b/mindspore/ccsrc/dataset/util/services.cc @@ -16,7 +16,9 @@ #include "dataset/util/services.h" #include +#if !defined(_WIN32) && !defined(_WIN64) #include +#endif #include #include #include "dataset/util/circular_pool.h" @@ -28,6 +30,7 @@ namespace dataset { std::unique_ptr Services::instance_ = nullptr; std::once_flag Services::init_instance_flag_; +#if !defined(_WIN32) && !defined(_WIN64) std::string Services::GetUserName() { char user[LOGIN_NAME_MAX]; (void)getlogin_r(user, sizeof(user)); @@ -41,10 +44,15 @@ std::string Services::GetHostName() { } int Services::GetLWP() { return syscall(SYS_gettid); } +#endif std::string Services::GetUniqueID() { const std::string kStr = "abcdefghijklmnopqrstuvwxyz0123456789"; +#if defined(_WIN32) || defined(_WIN64) + std::mt19937 gen{std::random_device{}()}; +#else std::mt19937 gen{std::random_device{"/dev/urandom"}()}; +#endif std::uniform_int_distribution<> dist(0, kStr.size() - 1); char buffer[UNIQUEID_LEN]; for (int i = 0; i < UNIQUEID_LEN; i++) { diff --git a/mindspore/ccsrc/dataset/util/services.h b/mindspore/ccsrc/dataset/util/services.h index 65a302af91..5e81c4816e 100644 --- a/mindspore/ccsrc/dataset/util/services.h +++ b/mindspore/ccsrc/dataset/util/services.h @@ -62,11 +62,13 @@ class Services { std::shared_ptr GetServiceMemPool() { return pool_; } +#if !defined(_WIN32) && !defined(_WIN64) static std::string GetUserName(); static std::string GetHostName(); static int GetLWP(); +#endif static std::string GetUniqueID(); diff --git a/mindspore/ccsrc/dataset/util/sig_handler.cc b/mindspore/ccsrc/dataset/util/sig_handler.cc index 1b6a3701c3..644a633066 100644 --- a/mindspore/ccsrc/dataset/util/sig_handler.cc +++ b/mindspore/ccsrc/dataset/util/sig_handler.cc @@ -16,13 +16,16 @@ #include "dataset/util/sig_handler.h" #include #include +#if !defined(_WIN32) && !defined(_WIN64) #include +#endif #include #include "dataset/util/task_manager.h" namespace mindspore { namespace dataset { // Register the custom signal handlers +#if !defined(_WIN32) && !defined(_WIN64) void RegisterHandlers() { struct sigaction new_int_action; @@ -40,5 +43,6 @@ extern void IntHandler(int sig_num, // The signal that was raised // Wake up the watchdog which is designed as async-signal-safe. TaskManager::WakeUpWatchDog(); } +#endif } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/dataset/util/sig_handler.h b/mindspore/ccsrc/dataset/util/sig_handler.h index 6c5e1f015c..af40738feb 100644 --- a/mindspore/ccsrc/dataset/util/sig_handler.h +++ b/mindspore/ccsrc/dataset/util/sig_handler.h @@ -22,12 +22,14 @@ namespace mindspore { namespace dataset { // Register the custom signal handlers +#if !defined(_WIN32) && !defined(_WIN64) extern void RegisterHandlers(); // A signal handler for SIGINT. Drives interrupt to watchdog extern void IntHandler(int sig_num, // The signal that was raised siginfo_t *sig_info, // The siginfo structure. void *context); // context info +#endif } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/debug/anf_ir_dump.cc b/mindspore/ccsrc/debug/anf_ir_dump.cc index 9eb0a376cc..e977084ab8 100644 --- a/mindspore/ccsrc/debug/anf_ir_dump.cc +++ b/mindspore/ccsrc/debug/anf_ir_dump.cc @@ -14,6 +14,9 @@ * limitations under the License. */ #include "debug/anf_ir_dump.h" +#if defined(_WIN32) || defined(_WIN64) +#include +#endif #include #include #include @@ -94,7 +97,7 @@ struct SubGraphIRInfo { OrderedMap local_var_map; }; -void DumpGrobalInfoEntry(const FuncGraphPtr &graph, std::ostringstream &buffer) { +void DumpGlobalInfoEntry(const FuncGraphPtr &graph, std::ostringstream &buffer) { if (graph == nullptr) { return; } @@ -434,9 +437,15 @@ void DumpIR(const std::string &filename, const FuncGraphPtr &graph, bool dump_fu return; } char real_path[PATH_MAX] = {0}; +#if defined(_WIN32) || defined(_WIN64) + if (_fullpath(real_path, filename.c_str(), PATH_MAX) == nullptr) { + MS_LOG(DEBUG) << "dir " << filename << " does not exit."; + } +#else if (nullptr == realpath(filename.c_str(), real_path)) { MS_LOG(DEBUG) << "Dir " << filename << " does not exit."; } +#endif OrderedMap para_map; std::string path_string = real_path; @@ -452,7 +461,7 @@ void DumpIR(const std::string &filename, const FuncGraphPtr &graph, bool dump_fu auto nodes = TopoSort(graph->get_return(), SuccDeeperSimple, AlwaysInclude); // dump global info - DumpGrobalInfoEntry(graph, buffer); + DumpGlobalInfoEntry(graph, buffer); DumpParams(graph, buffer, ¶_map); OrderedMap> sub_graphs; diff --git a/mindspore/ccsrc/debug/anf_ir_utils.cc b/mindspore/ccsrc/debug/anf_ir_utils.cc index c25ad862df..8e626d6f9a 100644 --- a/mindspore/ccsrc/debug/anf_ir_utils.cc +++ b/mindspore/ccsrc/debug/anf_ir_utils.cc @@ -48,9 +48,15 @@ std::string GetMsIrPath(void) { if (path_ptr != nullptr) { path = path_ptr; char real_path[PATH_MAX] = {0}; +#if defined(_WIN32) || defined(_WIN64) + if (path.size() > PATH_MAX || _fullpath(real_path, path.c_str(), PATH_MAX) == nullptr) { + MS_LOG(EXCEPTION) << "MS IR Path error, " << path_ptr; + } +#else if (path.size() > PATH_MAX || nullptr == realpath(path.c_str(), real_path)) { MS_LOG(EXCEPTION) << "MS IR path error, " << path_ptr; } +#endif path = real_path; } return path; @@ -2247,8 +2253,14 @@ void DumpIRProto(const FuncGraphPtr& func_graph, const std::string& suffix) { return; } char real_path[PATH_MAX] = {0}; - if (nullptr == realpath(file_path.c_str(), real_path)) { - MS_LOG(DEBUG) << "Dir " << file_path << " does not exit."; + char* real_path_ret = nullptr; +#if defined(_WIN32) || defined(_WIN64) + real_path_ret = _fullpath(real_path, file_path.c_str(), PATH_MAX); +#else + real_path_ret = realpath(file_path.c_str(), real_path); +#endif + if (nullptr == real_path_ret) { + MS_LOG(DEBUG) << "dir " << file_path << " does not exit."; } else { std::string path_string = real_path; if (chmod(common::SafeCStr(path_string), S_IRUSR | S_IWUSR) == -1) { diff --git a/mindspore/ccsrc/debug/info.cc b/mindspore/ccsrc/debug/info.cc index 5c1fc372c5..3c43bfa9b1 100644 --- a/mindspore/ccsrc/debug/info.cc +++ b/mindspore/ccsrc/debug/info.cc @@ -53,10 +53,15 @@ std::string Location::ToString(SourceLineTip tip) { } char path[PATH_MAX + 1] = {0x00}; +#if defined(_WIN32) || defined(_WIN64) + if (file_name_.size() > PATH_MAX || _fullpath(path, file_name_.c_str(), PATH_MAX) == nullptr) { + return debug_info_ss.str(); + } +#else if (file_name_.size() > PATH_MAX || realpath(file_name_.c_str(), path) == nullptr) { return debug_info_ss.str(); } - +#endif auto src_path = std::string(path); std::ifstream file(src_path); if (!file.is_open()) { diff --git a/mindspore/ccsrc/debug/label.cc b/mindspore/ccsrc/debug/label.cc index 794151b952..f0e16e831e 100644 --- a/mindspore/ccsrc/debug/label.cc +++ b/mindspore/ccsrc/debug/label.cc @@ -66,7 +66,7 @@ NameWithTrace RootName(const DebugInfoPtr& debug_info, TraceLabelType trace_labe return trace_name; } -std::string CombineTraceTypes(const std::string& root_name, std::vector trace_labels) { +std::string CombineTraceTypes(const std::string& root_name, const std::vector& trace_labels) { std::string tags = ""; for (auto& itr : trace_labels) { std::string symbol = itr; diff --git a/mindspore/ccsrc/device/ascend/ascend_device_address.cc b/mindspore/ccsrc/device/ascend/ascend_device_address.cc index 93f039af0e..79241df612 100644 --- a/mindspore/ccsrc/device/ascend/ascend_device_address.cc +++ b/mindspore/ccsrc/device/ascend/ascend_device_address.cc @@ -114,8 +114,11 @@ bool AscendDeviceAddress::SyncDeviceToHost(const std::vector &shape, size_t return false; } } - } else if (format_ == kOpFormat_NC1HWC0 || format_ == kOpFormat_FRAC_Z || format_ == kOpFormat_FRAC_NZ) { - sync_ok = SyncDeviceToHostAndConvertFormat(shape, size, type, host_ptr); + } else { + auto iter = kNeedTransFormatSet.find(format_); + if (iter != kNeedTransFormatSet.end()) { + sync_ok = SyncDeviceToHostAndConvertFormat(shape, size, type, host_ptr); + } } if (!sync_ok) { MS_LOG(ERROR) << "Not support to trans, dev_format:" << format_ << ", dev_type:" << TypeIdLabel(type_id_) @@ -141,7 +144,7 @@ bool AscendDeviceAddress::SyncDeviceToHostAndConvertFormat(const std::vector &shape, size_t } SyncMemory(ptr_, host_tmp.data(), size_, RT_MEMCPY_HOST_TO_DEVICE); } - } else if (format_ == kOpFormat_NC1HWC0 || format_ == kOpFormat_FRAC_Z || format_ == kOpFormat_FRAC_NZ) { - sync_ok = ConvertFormatAndSyncHostToDevice(shape, size, type, host_ptr); + } else { + auto iter = kNeedTransFormatSet.find(format_); + if (iter != kNeedTransFormatSet.end()) { + sync_ok = ConvertFormatAndSyncHostToDevice(shape, size, type, host_ptr); + } } if (!sync_ok) { MS_LOG(ERROR) << "Not support to trans, dev_format:" << format_ << ", dev_type:" << TypeIdLabel(type_id_) @@ -224,7 +230,7 @@ bool AscendDeviceAddress::ConvertFormatAndSyncHostToDevice(const std::vector(ret) << "]"; } - MS_EXCEPTION_IF_NULL(mem_manager_); - mem_manager_->FreeDeviceMemory(); + if (mem_manager_ != nullptr) { + mem_manager_->FreeDeviceMemory(); + } + (void)DestroyHccl(); (void)ResetDevice(); (void)ProfilingManager::GetInstance().StopProfiling(); @@ -148,14 +151,18 @@ void DumpOutput(mindspore::session::KernelGraph *graph, const string &dump_path, auto output_size = AnfAlgo::GetOutputTensorNum(node); for (size_t j = 0; j < output_size; ++j) { auto addr = AnfAlgo::GetOutputAddr(node, j); - auto shape = AnfAlgo::GetOutputInferShape(node, j); + std::vector int_shapes; + if (trans_flag) { + int_shapes = trans::GetRuntimePaddingShape(node, j); + } else { + auto shape = AnfAlgo::GetOutputDeviceShape(node, j); + (void)std::transform(shape.begin(), shape.end(), std::back_inserter(int_shapes), + [](size_t inner_item) { return SizeToInt(inner_item); }); + } auto type = AnfAlgo::GetOutputInferDataType(node, j); auto format = kOpFormat_DEFAULT; string filepath = dump_path + '/' + kernel_name + '_' + "output_" + std::to_string(j); auto ascend_addr = dynamic_cast(addr); - std::vector int_shapes; - (void)std::transform(shape.begin(), shape.end(), std::back_inserter(int_shapes), - [](size_t inner_item) { return SizeToInt(inner_item); }); auto ret = ascend_addr->DumpMemToFile(trans_flag, filepath, format, int_shapes, type); if (!ret) { MS_LOG(ERROR) << "DumpMemToFile Failed: flag:" << trans_flag << ", path:" << filepath @@ -179,14 +186,18 @@ void DumpParameters(mindspore::session::KernelGraph *graph, const string &dump_p continue; } auto addr = AnfAlgo::GetOutputAddr(item, PRAMATER_OUTPUT_INDEX); - auto shape = AnfAlgo::GetOutputInferShape(item, PRAMATER_OUTPUT_INDEX); + std::vector int_shapes; + if (trans_flag) { + int_shapes = trans::GetRuntimePaddingShape(item, PRAMATER_OUTPUT_INDEX); + } else { + auto shape = AnfAlgo::GetOutputDeviceShape(item, PRAMATER_OUTPUT_INDEX); + (void)std::transform(shape.begin(), shape.end(), std::back_inserter(int_shapes), + [](size_t inner_item) { return SizeToInt(inner_item); }); + } auto type = AnfAlgo::GetOutputInferDataType(item, PRAMATER_OUTPUT_INDEX); auto format = kOpFormat_DEFAULT; string filepath = dump_path + '/' + parameter_name + '_' + "output_0"; auto ascend_addr = dynamic_cast(addr); - std::vector int_shapes; - (void)std::transform(shape.begin(), shape.end(), std::back_inserter(int_shapes), - [](size_t inner_item) { return SizeToInt(inner_item); }); auto ret = ascend_addr->DumpMemToFile(trans_flag, filepath, format, int_shapes, type); if (!ret) { MS_LOG(ERROR) << "DumpMemToFile Failed: flag:" << trans_flag << ", path:" << filepath @@ -238,6 +249,10 @@ DeviceAddressPtr AscendKernelRuntime::CreateDeviceAddress(void *device_ptr, size } bool AscendKernelRuntime::GenTask(const session::KernelGraph *graph) { + if (graph == nullptr) { + MS_EXCEPTION(NotExistsError) << "session::KernelGraph is NULL!"; + } + MS_LOG(INFO) << "GenTask start. GraphId:" << graph->graph_id(); auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); bool is_task_sink = context_ptr->enable_task_sink(); @@ -250,13 +265,22 @@ bool AscendKernelRuntime::GenTask(const session::KernelGraph *graph) { mindspore::memreuse::MemReuseChecker::GetInstance().CheckNormalIR(graph); } #endif - if (graph == nullptr) { - MS_EXCEPTION(NotExistsError) << "session::KernelGraph is NULL!"; - } vector> task_info_list; auto anf_node_list = graph->execution_order(); TaskGenerator::GenTasks(anf_node_list, &task_info_list, graph->graph_id()); + // Store the task_info_list + auto insert_ret = task_map_.insert(std::make_pair(graph->graph_id(), task_info_list)); + if (!insert_ret.second) { + MS_LOG(EXCEPTION) << "Duplicate GraphId! Please check in ascend_session."; + } + + // Graph may have no compute node, such TensorAddGrad. + if (task_info_list.empty()) { + MS_LOG(WARNING) << "graph " << graph->graph_id() << " have no compute node"; + return true; + } + AscendStreamAssign &assign_instance = AscendStreamAssign::GetInstance(); // the streams' flag not HEAD_STREAM std::vector wait_active_stream_list = assign_instance.GetWaitStreams(); @@ -272,29 +296,19 @@ bool AscendKernelRuntime::GenTask(const session::KernelGraph *graph) { task_info_list, empty_list, empty_list, empty_list, empty_list, wait_active_stream_list, force_copy_stream_list, 0, 0, 0, 0, 0, 0, assign_instance.GetTotalStreamNum(), 1, assign_instance.GetTotalEventNum(), 0); - graph_model_map_[graph] = model; - graph_model_id_map_[graph] = graph->graph_id(); + auto ret = graph_model_map_.insert(std::make_pair(graph->graph_id(), model)); + if (!ret.second) { + MS_LOG(EXCEPTION) << "Duplicate GraphId! Please check in ascend_session."; + } MS_LOG(INFO) << "TaskGenerator GetTaskInfo end..."; - - // Store the task_info_list - task_map_.insert(std::make_pair(graph, task_info_list)); - return true; } -uint32_t AscendKernelRuntime::GetGraphModelId(const session::KernelGraph *kernel_graph) { - MS_EXCEPTION_IF_NULL(kernel_graph); - auto iter = graph_model_id_map_.find(kernel_graph); - if (iter == graph_model_id_map_.end()) { - MS_LOG(EXCEPTION) << "graph not in the map"; - } - return iter->second; -} - bool AscendKernelRuntime::LoadTask(const session::KernelGraph *graph) { if (graph == nullptr) { MS_EXCEPTION(NotExistsError) << "Null pointer graph, LoadTask failed. "; } + MS_LOG(INFO) << "LoadTask start. GraphId:" << graph->graph_id(); auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); bool is_task_sink = context_ptr->enable_task_sink(); @@ -302,23 +316,27 @@ bool AscendKernelRuntime::LoadTask(const session::KernelGraph *graph) { return true; } - auto task_iter = graph_model_map_.find(graph); - if (task_iter == graph_model_map_.end()) { - MS_LOG(ERROR) << "task not exist"; + if (GraphWithEmptyTaskList(graph)) { + MS_LOG(WARNING) << "LoadTask end, task list is empty"; + return true; + } + + auto model_iter = graph_model_map_.find(graph->graph_id()); + if (model_iter == graph_model_map_.end()) { + MS_LOG(ERROR) << "GraphId:" << graph->graph_id() << " Invalid! Graph LoadTask without GenTask."; return false; } - auto model_id = GetGraphModelId(graph); std::shared_ptr listener; - MS_LOG(INFO) << "LoadDavinciModel mode_id:" << model_id; - bool status = - ge::model_runner::ModelRunner::Instance().LoadDavinciModel(device_id_, 0, model_id, task_iter->second, listener); + MS_LOG(INFO) << "LoadDavinciModel mode_id:" << model_iter->first; + bool status = ge::model_runner::ModelRunner::Instance().LoadDavinciModel(device_id_, 0, model_iter->first, + model_iter->second, listener); if (!status) { - MS_LOG(INFO) << "load task failed"; + MS_LOG(ERROR) << "load task failed"; return false; } if (ProfilingManager::GetInstance().IsProfiling()) { - std::vector task_ids = ge::model_runner::ModelRunner::Instance().GetTaskIdList(model_id); + std::vector task_ids = ge::model_runner::ModelRunner::Instance().GetTaskIdList(model_iter->first); ProfilingUtils::ReportProfilingData(graph->graph_id(), task_ids); } return true; @@ -326,12 +344,23 @@ bool AscendKernelRuntime::LoadTask(const session::KernelGraph *graph) { bool AscendKernelRuntime::RunTask(const session::KernelGraph *graph) { MS_EXCEPTION_IF_NULL(graph); + MS_LOG(INFO) << "RunTask start. GraphId:" << graph->graph_id(); + auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); ge::InputData input_tensors = ge::InputData(); ge::OutputData *output_tensors = nullptr; - auto model_id = GetGraphModelId(graph); - bool status = ge::model_runner::ModelRunner::Instance().RunModel(model_id, input_tensors, output_tensors); + if (GraphWithEmptyTaskList(graph)) { + MS_LOG(WARNING) << "RunTask end, no task info found"; + return true; + } + + if (!CheckGraphIdValid(graph->graph_id())) { + MS_LOG(ERROR) << "GraphId:" << graph->graph_id() << " Invalid! Graph RunTask without GenTask."; + return false; + } + + bool status = ge::model_runner::ModelRunner::Instance().RunModel(graph->graph_id(), input_tensors, output_tensors); if (!status) { MS_LOG(INFO) << "run task failed"; return false; @@ -465,6 +494,18 @@ bool AscendKernelRuntime::DestroyHccl() { context_ptr->set_enable_hccl(false); return true; } + +bool AscendKernelRuntime::GraphWithEmptyTaskList(const session::KernelGraph *graph) const { + auto iter = task_map_.find(graph->graph_id()); + if (iter == task_map_.end()) { + MS_LOG(EXCEPTION) << "Unknown graph ptr"; + } + return iter->second.empty(); +} + +bool AscendKernelRuntime::CheckGraphIdValid(GraphId graph_id) const { + return task_map_.find(graph_id) != task_map_.end() && graph_model_map_.find(graph_id) != graph_model_map_.end(); +} } // namespace ascend } // namespace device } // namespace mindspore diff --git a/mindspore/ccsrc/device/ascend/ascend_kernel_runtime.h b/mindspore/ccsrc/device/ascend/ascend_kernel_runtime.h index 0eedad3d2b..5d0f61d0a6 100644 --- a/mindspore/ccsrc/device/ascend/ascend_kernel_runtime.h +++ b/mindspore/ccsrc/device/ascend/ascend_kernel_runtime.h @@ -23,6 +23,7 @@ #include "runtime/context.h" #include "framework/ge_runtime/davinci_model.h" #include "device/kernel_runtime_manager.h" +#include "session/session_basic.h" using ge::model_runner::TaskInfo; using std::unordered_map; @@ -54,12 +55,13 @@ class AscendKernelRuntime : public KernelRuntime { void ClearGraphModelMap(); void ReleaseDeviceRes() override; - uint32_t GetGraphModelId(const session::KernelGraph *kernel_graph); + bool GraphWithEmptyTaskList(const session::KernelGraph *graph) const; + bool CheckGraphIdValid(GraphId graph_id) const; + rtContext_t rt_context_{nullptr}; bool initialized_{false}; - unordered_map>> task_map_; - unordered_map> graph_model_map_; - unordered_map graph_model_id_map_; + unordered_map>> task_map_; + unordered_map> graph_model_map_; }; MS_REG_KERNEL_RUNTIME(kAscendDevice, AscendKernelRuntime); diff --git a/mindspore/ccsrc/device/ascend/ascend_memory_manager.h b/mindspore/ccsrc/device/ascend/ascend_memory_manager.h index dea88ac10a..90c8b2dfca 100644 --- a/mindspore/ccsrc/device/ascend/ascend_memory_manager.h +++ b/mindspore/ccsrc/device/ascend/ascend_memory_manager.h @@ -23,7 +23,7 @@ namespace ascend { class AscendMemoryManager : public MemoryManager { public: AscendMemoryManager() = default; - virtual ~AscendMemoryManager() = default; + ~AscendMemoryManager() override = default; void MallocDeviceMemory() override; void FreeDeviceMemory() override; diff --git a/mindspore/ccsrc/device/ascend/ascend_memory_pool.h b/mindspore/ccsrc/device/ascend/ascend_memory_pool.h index c2a29725f4..a02bd453b2 100644 --- a/mindspore/ccsrc/device/ascend/ascend_memory_pool.h +++ b/mindspore/ccsrc/device/ascend/ascend_memory_pool.h @@ -26,6 +26,8 @@ namespace ascend { class AscendMemoryPool : public DynamicMemPoolBestFit { public: ~AscendMemoryPool() override = default; + AscendMemoryPool(const AscendMemoryPool&) = delete; + AscendMemoryPool& operator=(const AscendMemoryPool&) = delete; size_t AllocDeviceMem(size_t size, DeviceMemPtr* addr) override; bool FreeDeviceMem(const DeviceMemPtr& addr) override; @@ -51,13 +53,11 @@ class AscendMemoryPool : public DynamicMemPoolBestFit { private: AscendMemoryPool() = default; - AscendMemoryPool(const AscendMemoryPool&) = delete; - AscendMemoryPool& operator=(const AscendMemoryPool&) = delete; bool has_malloc_{false}; uint8_t* device_mem_pool_base_{nullptr}; uint64_t device_mem_pool_size_{0}; - size_t free_mem_size_; - size_t total_mem_size_; + size_t free_mem_size_{0}; + size_t total_mem_size_{0}; }; } // namespace ascend } // namespace device diff --git a/mindspore/ccsrc/device/ascend/kernel_select_ascend.cc b/mindspore/ccsrc/device/ascend/kernel_select_ascend.cc index d05b9fafa1..36c622cbc5 100644 --- a/mindspore/ccsrc/device/ascend/kernel_select_ascend.cc +++ b/mindspore/ccsrc/device/ascend/kernel_select_ascend.cc @@ -31,12 +31,13 @@ namespace mindspore { namespace device { namespace ascend { namespace { +const float kWegihtBaseScore = 1; +const float kFeatureMapBaseScore = 10; enum MatchCountPriority : int { MATCH_COUNT_PRIORITY_BEGIN = 0, MATCH_DTYPE_COUNT = MATCH_COUNT_PRIORITY_BEGIN, MATCH_FORMAT_COUNT, MATCH_SPECIAL_FORMAT_COUNT, - MATCH_5D_FORMAT_COUNT, MATCH_OUTPUT_DTYPE_COUNT, MATCH_COUNT_PRIORITY_END }; @@ -44,82 +45,11 @@ enum MatchCountPriority : int { const size_t kMaxCount = 0xffffffff; const int kUnSupportMixedDataTypeIndex = -1; -const std::set kOpFormatList = { - kOpFormat_DEFAULT, kOpFormat_NC1KHKWHWC0, kOpFormat_ND, kOpFormat_NCHW, kOpFormat_NHWC, - kOpFormat_HWCN, kOpFormat_NC1HWC0, kOpFormat_FRAC_Z, kOpFormat_C1HWNCoC0, kOpFormat_FRAC_NZ}; - -bool IsShapeMatchFormat(const std::vector &shape, const std::string &format) { - // if format is default, it remarkes support all format - if (kOpFormatList.find(format) == kOpFormatList.end()) { - MS_LOG(EXCEPTION) << "got the unknown format " << format; - } - if (format == kOpFormat_DEFAULT) { - return true; - } - // if shape size is 0, the shape will be a scalar - if (shape.empty()) { - return true; - } - if (shape.size() > kShapeSupportFormatMap.size()) { - return false; - } - if (format == kOpFormat_FRAC_NZ && shape.size() >= 2) { - return true; - } - return !(kShapeSupportFormatMap[shape.size() - 1].find(format) == kShapeSupportFormatMap[shape.size() - 1].end()); -} - -bool IsValidKernelInfo(const std::shared_ptr &kernel_node, const kernel::KernelBuildInfo &kernel_build_info) { - MS_EXCEPTION_IF_NULL(kernel_node); - auto check_function = [](const std::vector &shape, const std::string &format) -> bool { - if (!IsShapeMatchFormat(shape, format)) { - return false; - } - for (auto shape_value : shape) { - if (shape_value == 0) { - MS_LOG(EXCEPTION) << "dimension size of the tensor shape should be a positive integer, but got " << shape_value; - } - } - return true; - }; - if (AnfAlgo::GetCNodeName(kernel_node) == prim::kPrimCast->name()) { - return AnfAlgo::GetOutputInferDataType(kernel_node, 0) == kernel_build_info.GetOutputDeviceType(0) && - AnfAlgo::GetPrevNodeOutputInferDataType(kernel_node, 0) == kernel_build_info.GetInputDeviceType(0); - } - for (size_t index = 0; index < kernel_build_info.GetOutputNum(); ++index) { - auto output_shape = AnfAlgo::GetOutputInferShape(kernel_node, index); - if (!check_function(output_shape, kernel_build_info.GetOutputFormat(index))) { - return false; - } - } - for (size_t index = 0; index < kernel_build_info.GetInputNum(); ++index) { - auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, index); - if (!check_function(input_shape, kernel_build_info.GetInputFormat(index))) { - return false; - } - } - return true; -} - bool MatchInferOutputDataType(const CNodePtr &cnode, const kernel::KernelBuildInfo &kernel_build_info) { MS_EXCEPTION_IF_NULL(cnode); // Check input data type for (size_t input_index = 0; input_index < kernel_build_info.GetInputNum(); ++input_index) { - AnfNodePtr cur_input = AnfAlgo::GetInputNode(cnode, input_index); - MS_EXCEPTION_IF_NULL(cur_input); - TypeId input_origin_type; - if (cur_input->isa() && AnfAlgo::IsParameterWeight(cur_input->cast())) { - // weight - input_origin_type = AnfAlgo::GetOutputDeviceDataType(cur_input, 0); - } else if (cur_input->isa()) { - input_origin_type = AnfAlgo::GetOutputDeviceDataType(cur_input, 0); - } else { - // feature map - input_origin_type = AnfAlgo::GetPrevNodeOutputInferDataType(cnode, input_index); - } - if (input_origin_type == kTypeUnknown) { - continue; - } + TypeId input_origin_type = AnfAlgo::GetPrevNodeOutputInferDataType(cnode, input_index); if (kernel_build_info.GetInputDeviceType(input_index) != input_origin_type) { return false; } @@ -133,6 +63,29 @@ bool MatchInferOutputDataType(const CNodePtr &cnode, const kernel::KernelBuildIn return true; } +string GetPriorityMatchFormat(const CNodePtr &cnode) { + string priority_matched_format = kOpFormat_NC1HWC0; + bool is_init = false; + bool need_change_nd = false; + for (size_t index = 0; index < AnfAlgo::GetInputTensorNum(cnode); ++index) { + auto pre_output_format = AnfAlgo::GetPrevNodeOutputFormat(cnode, index); + if (AnfAlgo::IsFeatureMapInput(cnode, index) && + kNeedTransFormatSet.find(pre_output_format) != kNeedTransFormatSet.end()) { + priority_matched_format = !is_init ? priority_matched_format : pre_output_format; + is_init = true; + } + // feature map has two or more special format; + if (priority_matched_format != pre_output_format && pre_output_format != kOpFormat_DEFAULT) { + priority_matched_format = kOpFormat_DEFAULT; + } + auto input_shape_size = AnfAlgo::GetPrevNodeOutputInferShape(cnode, index).size(); + need_change_nd = (need_change_nd || (input_shape_size != 4 && input_shape_size > 1)); + } + if (need_change_nd) { + priority_matched_format = kOpFormat_DEFAULT; + } + return priority_matched_format; +} /** * compare two vector by priority, select a better vector, like compare two num, first compare highest num location, * if equal then next num location @@ -165,34 +118,18 @@ void UpdateCurMatchCounts(const kernel::KernelBuildInfo &kernel_build_info, cons if (cur_kernelinfo_match_counts->size() < MATCH_COUNT_PRIORITY_END) { MS_LOG(EXCEPTION) << "Out of range cur_kernelinfo_match_counts " << MATCH_COUNT_PRIORITY_END; } + auto pri_match_format = GetPriorityMatchFormat(kernel_node); for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(kernel_node); ++input_index) { - AnfNodePtr input_anf_node = AnfAlgo::GetInputNode(kernel_node, input_index); - MS_EXCEPTION_IF_NULL(input_anf_node); - // if a input parameter is a weight with default format, the input shouldn't participate the judge - if (input_anf_node->isa()) { - auto para = input_anf_node->cast(); - if (AnfAlgo::IsParameterWeight(para) && AnfAlgo::GetOutputDeviceDataType(para, 0) == kTypeUnknown) { - continue; - } - } + auto base_score = AnfAlgo::IsFeatureMapInput(kernel_node, input_index) ? kFeatureMapBaseScore : kWegihtBaseScore; if (kernel_build_info.GetInputFormat(input_index) == AnfAlgo::GetPrevNodeOutputFormat(kernel_node, input_index)) { - if (AnfAlgo::IsFeatureMapInput(kernel_node, input_index) && - kSpecialFormatSet.find(kernel_build_info.GetInputFormat(input_index)) != kSpecialFormatSet.end()) { - (*cur_kernelinfo_match_counts)[MATCH_SPECIAL_FORMAT_COUNT]++; - } - (*cur_kernelinfo_match_counts)[MATCH_FORMAT_COUNT]++; + (*cur_kernelinfo_match_counts)[MATCH_FORMAT_COUNT] += base_score; } if (kernel_build_info.GetInputDeviceType(input_index) == AnfAlgo::GetPrevNodeOutputDeviceDataType(kernel_node, input_index)) { - (*cur_kernelinfo_match_counts)[MATCH_DTYPE_COUNT]++; + (*cur_kernelinfo_match_counts)[MATCH_DTYPE_COUNT] += base_score; } - if (kernel_build_info.GetInputFormat(input_index) == kOpFormat_NC1HWC0) { - // input is from a feature map & this input's shape is not 4d - if (AnfAlgo::IsFeatureMapInput(kernel_node, input_index) && - AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, input_index).size() != kShape4dDims) { - continue; - } - (*cur_kernelinfo_match_counts)[MATCH_5D_FORMAT_COUNT]++; + if (kernel_build_info.GetInputFormat(input_index) == pri_match_format) { + (*cur_kernelinfo_match_counts)[MATCH_SPECIAL_FORMAT_COUNT] += base_score; } } @@ -200,22 +137,25 @@ void UpdateCurMatchCounts(const kernel::KernelBuildInfo &kernel_build_info, cons // cal count of same output dtype between abstract and kernel info if (kernel_build_info.GetOutputDeviceType(output_index) == AnfAlgo::GetOutputInferDataType(kernel_node, output_index)) { - (*cur_kernelinfo_match_counts)[MATCH_OUTPUT_DTYPE_COUNT]++; + (*cur_kernelinfo_match_counts)[MATCH_OUTPUT_DTYPE_COUNT] += 1; } } -} // namespace +} void SetTensorDeviceInfo(const kernel::KernelBuildInfo &selected_kernel_info, const CNodePtr &kernel_node) { MS_EXCEPTION_IF_NULL(kernel_node); for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(kernel_node); ++input_index) { auto input_kernel_node = AnfAlgo::GetInputNode(kernel_node, input_index); MS_EXCEPTION_IF_NULL(input_kernel_node); - if (AnfAlgo::IsFeatureMapInput(kernel_node, input_index)) { - continue; - } auto input_with_index = AnfAlgo::VisitKernel(input_kernel_node, 0); MS_EXCEPTION_IF_NULL(input_with_index.first); auto real_input_node = input_with_index.first; + if (real_input_node->isa()) { + continue; + } + if (real_input_node->isa() && !AnfAlgo::IsParameterWeight(real_input_node->cast())) { + continue; + } std::shared_ptr builder = std::make_shared(); // we set special device info of a input tensor. @@ -461,6 +401,29 @@ int PrecisionReduce(const std::vector &node_mix_precision_datatype_index, // raise precision int selected_index = RaiseDataTypePrecisionSelect(node_mix_precision_datatype_index, node_mix_precision_datatype, kernel_support_datatype, kernel_match_datatype_idx); + if (selected_index != -1) { + int max_match = 0; + auto iter = kernel_match_datatype_idx->begin(); + int match_count = 0; + while (iter != kernel_match_datatype_idx->end()) { + auto kernel_datatypes = kernel_support_datatype.find(iter->first); + if (kernel_datatypes == kernel_support_datatype.end()) { + MS_LOG(EXCEPTION) << "Can not find kernel index" << iter->first << "'s datatype."; + } + if (kernel_datatypes->second.size() < node_mix_precision_datatype.size()) { + MS_LOG(EXCEPTION) << "Kernel datatype size is not equal to node datatype size!"; + } + for (size_t i = 0; i < node_mix_precision_datatype.size(); ++i) { + if (node_mix_precision_datatype[i] == kernel_datatypes->second[i]) { + ++match_count; + } + } + if (match_count > max_match) { + selected_index = SizeToInt(iter->first); + } + ++iter; + } + } if (selected_index == -1 && context_ptr->enable_reduce_precision()) { selected_index = RaiseOrReduceDataTypePrecisionSelect(node_mix_precision_datatype_index, node_mix_precision_datatype, @@ -507,28 +470,22 @@ void SelectKernelInfo(const CNodePtr &kernel_node) { std::vector> kernel_info_list; MS_EXCEPTION_IF_NULL(kernel_node); kernel::KernelQuery(kernel_node, &kernel_info_list); - std::vector most_match_counts = {-1, -1, -1, -1, -1}; + std::vector most_match_counts = {-1, -1, -1, -1}; int selected_index = -1; - auto context_ptr = MsContext::GetInstance(); - MS_EXCEPTION_IF_NULL(context_ptr); - bool auto_mixed_precision = context_ptr->auto_mixed_precision_flag(); std::unordered_map> kernel_match_datatype_idx; std::unordered_map> kernel_support_datatype; std::vector node_mix_precision_datatype_index; std::vector node_mix_precision_datatype; for (size_t info_index = 0; info_index < kernel_info_list.size(); ++info_index) { - std::vector cur_kernel_info_match_counts = {0, 0, 0, 0, 0}; + std::vector cur_kernel_info_match_counts = {0, 0, 0, 0}; auto kernel_build_info = *(kernel_info_list[info_index]); - if (!IsValidKernelInfo(kernel_node, kernel_build_info)) { - continue; - } std::vector support_indexes; std::vector support_datatypes; AddNodeAndKernelDataType(kernel_node, kernel_build_info, &support_indexes, &node_mix_precision_datatype, &support_datatypes, &node_mix_precision_datatype_index); kernel_match_datatype_idx[info_index] = support_indexes; kernel_support_datatype[info_index] = support_datatypes; - if (!auto_mixed_precision && !MatchInferOutputDataType(kernel_node, kernel_build_info)) { + if (!MatchInferOutputDataType(kernel_node, kernel_build_info)) { continue; } std::shared_ptr kernel_info_ptr = kernel_info_list[info_index]; diff --git a/mindspore/ccsrc/device/cpu/cpu_resource_manager.cc b/mindspore/ccsrc/device/cpu/cpu_resource_manager.cc index 97df7d4487..45b9ea5bed 100644 --- a/mindspore/ccsrc/device/cpu/cpu_resource_manager.cc +++ b/mindspore/ccsrc/device/cpu/cpu_resource_manager.cc @@ -60,6 +60,7 @@ void CPUResourceManager::MemMalloc(const session::KernelGraph *graph) { void *CPUResourceManager::MemMalloc(size_t mem_size) { void *ptr = malloc(mem_size); if (ptr != nullptr) { + memset_s(ptr, mem_size, 0, mem_size); dynamic_mem_[ptr] = mem_size; return ptr; } else { diff --git a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_cpu_kernel.cc b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_cpu_kernel.cc index f7527c4750..5d63aee6cd 100644 --- a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_cpu_kernel.cc +++ b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_cpu_kernel.cc @@ -35,8 +35,22 @@ void Conv2dCPUKernel::InitKernel(const CNodePtr &kernel_node) { dnnl::memory::desc dst_desc = GetDefaultMemDesc(dst_shape); int kernel_size = SizeToInt(weight_shape[3]); - int stride = AnfAlgo::GetNodeAttr(kernel_node, STRIDE); - int dilation = AnfAlgo::GetNodeAttr(kernel_node, DILATION); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, STRIDE); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, DILATION); + if (stride_ori.size() != 4 || stride_ori[2] != stride_ori[3]) { + MS_LOG(EXCEPTION) << "conv2d only support equal stride, and stride must be 4d!"; + } + if (stride_ori[0] != 1 || stride_ori[1] != 1) { + MS_LOG(EXCEPTION) << "conv2d stride only support 1 in N axis and C axis!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != 1 || dilation_ori[3] != 1) { + MS_LOG(EXCEPTION) << "conv2d dilation only support 1, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "conv2d dilation only support 1 in N axis and C axis!"; + } + int stride = stride_ori[2]; + int dilation = dilation_ori[2]; dnnl::memory::dims strides{stride, stride}; dnnl::memory::dims dilates{dilation - 1, dilation - 1}; diff --git a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_filter_cpu_kernel.cc b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_filter_cpu_kernel.cc index f4c0e58350..1a7c10a531 100644 --- a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_filter_cpu_kernel.cc +++ b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_filter_cpu_kernel.cc @@ -35,8 +35,19 @@ void Conv2dGradFilterCPUKernel::InitKernel(const CNodePtr &kernel_node) { dnnl::memory::desc dst_desc = GetDefaultMemDesc(dst_shape); int kernel_size = SizeToInt(weight_shape[3]); - int stride = AnfAlgo::GetNodeAttr(kernel_node, STRIDE); - int dilation = AnfAlgo::GetNodeAttr(kernel_node, DILATION); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, STRIDE); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, DILATION); + if (stride_ori.size() != 2 || stride_ori[0] != stride_ori[1]) { + MS_LOG(EXCEPTION) << "Conv2dGradFilterCPUKernel only support equal stride, and stride must be 2d!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != 1 || dilation_ori[3] != 1) { + MS_LOG(EXCEPTION) << "Conv2dGradFilterCPUKernel dilation only support 1, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "Conv2dGradFilterCPUKernel dilation only support 1 in N axis and C axis!"; + } + int stride = stride_ori[0]; + int dilation = dilation_ori[2]; dnnl::memory::dims strides{stride, stride}; dnnl::memory::dims dilates{dilation - 1, dilation - 1}; diff --git a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_input_cpu_kernel.cc b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_input_cpu_kernel.cc index 492e2d6280..04dda20acd 100644 --- a/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_input_cpu_kernel.cc +++ b/mindspore/ccsrc/device/cpu/kernel/mkldnn/conv2d_grad_input_cpu_kernel.cc @@ -35,8 +35,19 @@ void Conv2dGradInputCPUKernel::InitKernel(const CNodePtr &kernel_node) { dnnl::memory::desc dst_desc = GetDefaultMemDesc(dst_shape); int kernel_size = SizeToInt(weight_shape[3]); - int stride = AnfAlgo::GetNodeAttr(kernel_node, STRIDE); - int dilation = AnfAlgo::GetNodeAttr(kernel_node, DILATION); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, STRIDE); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, DILATION); + if (stride_ori.size() != 2 || stride_ori[0] != stride_ori[1]) { + MS_LOG(EXCEPTION) << "Conv2dGradInputCPUKernel only support equal stride, and stride must be 2d!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != 1 || dilation_ori[3] != 1) { + MS_LOG(EXCEPTION) << "Conv2dGradInputCPUKernel dilation only support 1, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "Conv2dGradInputCPUKernel dilation only support 1 in N axis and C axis!"; + } + int stride = stride_ori[0]; + int dilation = dilation_ori[2]; dnnl::memory::dims strides{stride, stride}; dnnl::memory::dims dilates{dilation - 1, dilation - 1}; std::vector int_padding_l; diff --git a/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.cc b/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.cc new file mode 100644 index 0000000000..e4b3f03f58 --- /dev/null +++ b/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.cc @@ -0,0 +1,74 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "device/cpu/kernel/one_hot_cpu_kernel.h" +#include "device/cpu/cpu_device_address.h" + +namespace mindspore { +namespace device { +namespace cpu { +void OneHotCPUKernel::InitKernel(const CNodePtr &kernel_node) { + MS_EXCEPTION_IF_NULL(kernel_node); + auto output_shape = AnfAlgo::GetOutputInferShape(kernel_node, 0); + if (output_shape.size() < 2) { + MS_LOG(EXCEPTION) << "invalid output shape size: " << output_shape.size(); + } + int axis = AnfAlgo::GetNodeAttr(kernel_node, AXIS); + if (axis != -1 && IntToSize(axis) >= output_shape.size()) { + MS_LOG(EXCEPTION) << "invalid axis: " << axis; + } + if (axis == -1) { + axis_ = output_shape.size() - 1; + } else { + axis_ = IntToSize(axis); + } + depth_ = output_shape[axis_]; + stride_ = 1; + for (size_t i = axis_ + 1; i < output_shape.size(); ++i) { + stride_ *= output_shape[i]; + } +} + +bool OneHotCPUKernel::Launch(const std::vector &inputs, + const std::vector & /*workspace*/, + const std::vector &outputs) { + if (inputs.size() < 3 || outputs.empty()) { + MS_LOG(EXCEPTION) << "input or output invalid!"; + } + auto indices = reinterpret_cast(inputs[0]->addr); + auto on_value = reinterpret_cast(inputs[1]->addr)[0]; + auto off_value = reinterpret_cast(inputs[2]->addr)[0]; + auto output = reinterpret_cast(outputs[0]->addr); + size_t elem_num = inputs[0]->size / sizeof(int); + + for (size_t i = 0; i < elem_num; i++) { + size_t stride_num = i / stride_; + size_t output_index = stride_num * depth_ * stride_ + i % stride_; + size_t index = IntToSize(indices[i]); + for (size_t j = 0; j < depth_; j++) { + if (index == j) { + output[output_index] = on_value; + } else { + output[output_index] = off_value; + } + output_index += stride_; + } + } + + return true; +} +} // namespace cpu +} // namespace device +} // namespace mindspore diff --git a/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.h b/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.h new file mode 100644 index 0000000000..f41ac63265 --- /dev/null +++ b/mindspore/ccsrc/device/cpu/kernel/one_hot_cpu_kernel.h @@ -0,0 +1,47 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_DEVICE_CPU_ONE_HOT_CPU_KERNEL_H_ +#define MINDSPORE_CCSRC_DEVICE_CPU_ONE_HOT_CPU_KERNEL_H_ +#include +#include +#include "device/cpu/cpu_kernel.h" +#include "device/cpu/cpu_kernel_factory.h" + +namespace mindspore { +namespace device { +namespace cpu { +class OneHotCPUKernel : public CPUKernel { + public: + OneHotCPUKernel() = default; + ~OneHotCPUKernel() override = default; + + void InitKernel(const CNodePtr &kernel_node) override; + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs) override; + + private: + size_t depth_; + size_t stride_; + size_t axis_; +}; + +MS_REG_CPU_KERNEL(OneHot, OneHotCPUKernel); +} // namespace cpu +} // namespace device +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_DEVICE_CPU_ONE_HOT_CPU_KERNEL_H_ diff --git a/mindspore/ccsrc/device/cpu/kernel/reshape_cpu_kernel.h b/mindspore/ccsrc/device/cpu/kernel/reshape_cpu_kernel.h index 908c3df2d9..d371e3a7ac 100644 --- a/mindspore/ccsrc/device/cpu/kernel/reshape_cpu_kernel.h +++ b/mindspore/ccsrc/device/cpu/kernel/reshape_cpu_kernel.h @@ -35,6 +35,8 @@ class ReshapeCPUKernel : public CPUKernel { }; MS_REG_CPU_KERNEL(Reshape, ReshapeCPUKernel); +MS_REG_CPU_KERNEL(Flatten, ReshapeCPUKernel); +MS_REG_CPU_KERNEL(ExpandDims, ReshapeCPUKernel); } // namespace cpu } // namespace device } // namespace mindspore diff --git a/mindspore/ccsrc/device/gpu/cuda_driver.cc b/mindspore/ccsrc/device/gpu/cuda_driver.cc index 3693157d2b..3b265a4d5e 100644 --- a/mindspore/ccsrc/device/gpu/cuda_driver.cc +++ b/mindspore/ccsrc/device/gpu/cuda_driver.cc @@ -96,7 +96,7 @@ size_t CudaDriver::free_mem_size() { } bool CudaDriver::CreateStream(DeviceStream *stream) { - auto ret = cudaStreamCreate(reinterpret_cast(stream)); + auto ret = cudaStreamCreateWithFlags(reinterpret_cast(stream), cudaStreamNonBlocking); if (ret != cudaSuccess) { MS_LOG(ERROR) << "cudaStreamCreate failed, ret[" << static_cast(ret) << "], " << cudaGetErrorString(ret); return false; diff --git a/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.cc b/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.cc new file mode 100644 index 0000000000..06497a2e82 --- /dev/null +++ b/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.cc @@ -0,0 +1,28 @@ +/** + * Copyright 2019 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "device/gpu/distribution/collective_fake_init.h" +#include "utils/log_adapter.h" + +namespace mindspore { +namespace device { +namespace gpu { +void CollectiveFakeInitializer::InitCollective() { MS_LOG(EXCEPTION) << "build without enable gpu!"; } + +void CollectiveFakeInitializer::FinalizeCollective() { MS_LOG(EXCEPTION) << "build without enable gpu!"; } +} // namespace gpu +} // namespace device +} // namespace mindspore diff --git a/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.h b/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.h new file mode 100644 index 0000000000..65467139c0 --- /dev/null +++ b/mindspore/ccsrc/device/gpu/distribution/collective_fake_init.h @@ -0,0 +1,37 @@ +/** + * Copyright 2019 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_DEVICE_GPU_DISTRIBUTION_COLLECTIVE_FAKE_INIT_H_ +#define MINDSPORE_CCSRC_DEVICE_GPU_DISTRIBUTION_COLLECTIVE_FAKE_INIT_H_ + +namespace mindspore { +namespace device { +namespace gpu { + +class CollectiveFakeInitializer { + public: + CollectiveFakeInitializer() = default; + ~CollectiveFakeInitializer() = default; + CollectiveFakeInitializer(CollectiveFakeInitializer const &) = delete; + CollectiveFakeInitializer &operator=(const CollectiveFakeInitializer &) = delete; + static void InitCollective(); + static void FinalizeCollective(); +}; +} // namespace gpu +} // namespace device +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_DEVICE_GPU_DISTRIBUTION_COLLECTIVE_FAKE_INIT_H_ diff --git a/mindspore/ccsrc/device/gpu/gpu_device_manager.cc b/mindspore/ccsrc/device/gpu/gpu_device_manager.cc index 59c8fde5a2..b25ba2906b 100644 --- a/mindspore/ccsrc/device/gpu/gpu_device_manager.cc +++ b/mindspore/ccsrc/device/gpu/gpu_device_manager.cc @@ -25,7 +25,7 @@ namespace device { namespace gpu { void GPUDeviceManager::InitDevice() { CHECK_OP_RET_WITH_EXCEPT(CudaDriver::set_current_device(SizeToInt(cur_dev_id_)), "Failed to set current device id"); - CHECK_OP_RET_WITH_EXCEPT(CudaDriver::CreateStream(&stream_), "Failed to create CUDA stream."); + CHECK_OP_RET_WITH_EXCEPT(CreateStream(&default_stream_), "Failed to create CUDA stream."); CHECK_CUDNN_RET_WITH_EXCEPT(cudnnCreate(&cudnn_handle_), "Failed to create cuDNN handle"); CHECK_CUDNN_RET_WITH_EXCEPT(cudnnSetStream(cudnn_handle_, reinterpret_cast(default_stream())), "Failed to set stream for cuDNN handle."); @@ -36,19 +36,27 @@ void GPUDeviceManager::InitDevice() { } void GPUDeviceManager::ReleaseDevice() { - if (stream_ != nullptr) { - CHECK_OP_RET_WITH_ERROR(CudaDriver::DestroyStream(stream_), "Failed to destroy cuda stream."); + for (DeviceStream stream : gpu_streams_) { + if (stream != nullptr) { + CHECK_OP_RET_WITH_ERROR(CudaDriver::DestroyStream(stream), "Failed to destroy CUDA stream."); + } } if (cudnn_handle_ != nullptr) { - CHECK_CUDNN_RET_WITH_ERROR(cudnnDestroy(cudnn_handle_), "Failed to destroy cudnn handle"); + CHECK_CUDNN_RET_WITH_ERROR(cudnnDestroy(cudnn_handle_), "Failed to destroy cuDNN handle"); } if (cublas_handle_ != nullptr) { - CHECK_CUBLAS_RET_WITH_ERROR(cublasDestroy(cublas_handle_), "Failed to destroy cublas handle."); + CHECK_CUBLAS_RET_WITH_ERROR(cublasDestroy(cublas_handle_), "Failed to destroy cuBLAS handle."); } CHECK_OP_RET_WITH_ERROR(GPUMemoryAllocator::GetInstance().Finalize(), "Failed to destroy gpu memory allocator"); } -const DeviceStream& GPUDeviceManager::default_stream() const { return stream_; } +bool GPUDeviceManager::CreateStream(DeviceStream* stream) { + CHECK_OP_RET_WITH_EXCEPT(CudaDriver::CreateStream(stream), "Failed to create CUDA stream"); + gpu_streams_.emplace_back(*stream); + return true; +} + +const DeviceStream& GPUDeviceManager::default_stream() const { return default_stream_; } int GPUDeviceManager::device_count() const { return CudaDriver::device_count(); } diff --git a/mindspore/ccsrc/device/gpu/gpu_device_manager.h b/mindspore/ccsrc/device/gpu/gpu_device_manager.h index 6bfaf85673..3b3d2aecb5 100644 --- a/mindspore/ccsrc/device/gpu/gpu_device_manager.h +++ b/mindspore/ccsrc/device/gpu/gpu_device_manager.h @@ -19,6 +19,7 @@ #include #include +#include #include #include "device/gpu/cuda_driver.h" #include "device/gpu/gpu_memory_allocator.h" @@ -36,13 +37,15 @@ class GPUDeviceManager { uint32_t cur_device_id() const; bool is_device_id_init() const; + bool CreateStream(DeviceStream* stream); + bool SyncStream(const DeviceStream& stream) const; const DeviceStream& default_stream() const; + const cudnnHandle_t& GetCudnnHandle() const; const cublasHandle_t& GetCublasHandle() const; bool CopyDeviceMemToHost(const HostMemPtr& dst, const DeviceMemPtr& src, size_t size) const; bool CopyHostMemToDevice(const DeviceMemPtr& dst, const void* src, size_t size) const; - bool SyncStream(const DeviceStream& stream) const; static GPUDeviceManager& GetInstance() { static GPUDeviceManager instance; @@ -55,13 +58,16 @@ class GPUDeviceManager { GPUDeviceManager(const GPUDeviceManager&) = delete; GPUDeviceManager& operator=(const GPUDeviceManager&) = delete; - // default cuda stream used for all the kernels. - DeviceStream stream_{nullptr}; + // default CUDA stream used for all the kernels. + DeviceStream default_stream_{nullptr}; + + // all gpu CUDA streams including default_stream_. + std::vector gpu_streams_; - // handle used for cudnn kernels. + // handle used for cuDNN kernels. cudnnHandle_t cudnn_handle_{nullptr}; - // handle used for cublas kernels. + // handle used for cuBLAS kernels. cublasHandle_t cublas_handle_{nullptr}; bool dev_id_init_; diff --git a/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.cc b/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.cc index 2ec1a5df29..11b8bdc162 100644 --- a/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.cc +++ b/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.cc @@ -101,8 +101,9 @@ void GPUKernelRuntime::ReleaseDeviceRes() { CHECK_OP_RET_WITH_EXCEPT(GpuBufferMgr::GetInstance().Destroy(), "Could not destroy gpu data queue."); } GPUDeviceManager::GetInstance().ReleaseDevice(); - MS_EXCEPTION_IF_NULL(mem_manager_); - mem_manager_->FreeDeviceMemory(); + if (mem_manager_ != nullptr) { + mem_manager_->FreeDeviceMemory(); + } } void GPUKernelRuntime::AssignMemory(session::KernelGraph *graph) { @@ -126,9 +127,10 @@ bool GPUKernelRuntime::Run(session::KernelGraph *graph) { auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); bool is_enable_dynamic_mem = context_ptr->enable_dynamic_mem_pool(); + bool is_enable_pynative_infer = context_ptr->enable_pynative_infer(); struct timeval start_time, end_time; (void)gettimeofday(&start_time, nullptr); - if (is_enable_dynamic_mem) { + if (is_enable_dynamic_mem && !is_enable_pynative_infer) { ret = LaunchKernelDynamic(graph); } else { ret = LaunchKernel(graph); @@ -151,9 +153,10 @@ void GPUKernelRuntime::InitKernelRefCount(const session::KernelGraph *graph) { } mem_reuse_util_ptr->SetKernelDefMap(); mem_reuse_util_ptr->SetReuseRefCount(); - // Can't free the device address of graph output, so set the reference count of graph output specially, + // Can't free the device address of graph output, so set the reference count of graph output specially. mem_reuse_util_ptr->SetGraphOutputRefCount(); - mem_reuse_util_ptr_ = mem_reuse_util_ptr; + auto graph_id = graph->graph_id(); + mem_reuse_util_map_[graph_id] = mem_reuse_util_ptr; } void GPUKernelRuntime::InitKernelOutputAddress(const session::KernelGraph *graph) { @@ -177,6 +180,7 @@ void GPUKernelRuntime::InitKernelOutputAddress(const session::KernelGraph *graph bool GPUKernelRuntime::LaunchKernelDynamic(const session::KernelGraph *graph) { MS_EXCEPTION_IF_NULL(graph); + auto graph_id = graph->graph_id(); // The inputs and outputs memory of communication kernel are special, so separate processing. AllocCommunicationOpDynamicRes(graph); @@ -192,7 +196,7 @@ bool GPUKernelRuntime::LaunchKernelDynamic(const session::KernelGraph *graph) { MS_LOG(ERROR) << "Launch kernel failed."; return false; } - FreeKernelDynamicRes(kernel, kernel_workspaces); + FreeKernelDynamicRes(kernel, kernel_workspaces, graph_id); } if (!SyncStream()) { @@ -339,34 +343,46 @@ void GPUKernelRuntime::AllocCommunicationOpOutputDynamicRes(const mindspore::Anf } void GPUKernelRuntime::FreeKernelDynamicRes(const mindspore::AnfNodePtr &kernel, - const AddressPtrList &kernel_workspaces) { + const AddressPtrList &kernel_workspaces, uint32_t graph_id) { MS_EXCEPTION_IF_NULL(kernel); MS_EXCEPTION_IF_NULL(mem_manager_); + auto mem_reuse_util_ptr = mem_reuse_util_map_[graph_id]; + MS_EXCEPTION_IF_NULL(mem_reuse_util_ptr); auto cnode = kernel->cast(); MS_EXCEPTION_IF_NULL(cnode); // Free the input of kernel by reference count. for (size_t i = 0; i < AnfAlgo::GetInputTensorNum(kernel); ++i) { - auto kernel_ref_count_ptr = mem_reuse_util_ptr_->GetKernelInputRef(cnode, i); + auto kernel_ref_count_ptr = mem_reuse_util_ptr->GetKernelInputRef(cnode, i); if (kernel_ref_count_ptr == nullptr) { continue; } + // Can't free the output of graph. + if (kernel_ref_count_ptr->ref_count_dynamic_use_ == memreuse::kMaxRefCount) { + continue; + } kernel_ref_count_ptr->ref_count_dynamic_use_--; if (kernel_ref_count_ptr->ref_count_dynamic_use_ == 0) { // Reset the reference count. kernel_ref_count_ptr->ref_count_dynamic_use_ = kernel_ref_count_ptr->ref_count_; bool is_communication_op = false; - // The inputs and outputs memory of communication kernel are special, so separate processing. FreeCommunicationOpDynamicRes(kernel, i, &is_communication_op); if (!is_communication_op) { auto device_address = AnfAlgo::GetPrevNodeMutableOutputAddr(kernel, i); - MS_EXCEPTION_IF_NULL(device_address); - MS_EXCEPTION_IF_NULL(device_address->ptr_); - mem_manager_->FreeMemFromMemPool(device_address->ptr_); - device_address->ptr_ = nullptr; + mem_manager_->FreeMemFromMemPool(device_address); } } } - + // Free the output of kernel, if output has no reference. + for (size_t i = 0; i < AnfAlgo::GetOutputTensorNum(kernel); ++i) { + auto kernel_ref_count_ptr = mem_reuse_util_ptr->GetRef(cnode, i); + if (kernel_ref_count_ptr == nullptr) { + continue; + } + if (kernel_ref_count_ptr->ref_count_dynamic_use_ == 0) { + auto device_address = AnfAlgo::GetMutableOutputAddr(kernel, i); + mem_manager_->FreeMemFromMemPool(device_address); + } + } // Free the workspace of kernel. for (size_t i = 0; i < kernel_workspaces.size(); ++i) { auto workspace = kernel_workspaces[i]; @@ -387,10 +403,7 @@ void GPUKernelRuntime::FreeCommunicationOpDynamicRes(const mindspore::AnfNodePtr communication_op_input_ref_count_--; if (communication_op_input_ref_count_ == 0) { auto device_address = AnfAlgo::GetPrevNodeMutableOutputAddr(kernel, 0); - MS_EXCEPTION_IF_NULL(device_address); - MS_EXCEPTION_IF_NULL(device_address->ptr_); - mem_manager_->FreeMemFromMemPool(device_address->ptr_); - device_address->ptr_ = nullptr; + mem_manager_->FreeMemFromMemPool(device_address); } *is_communication_op = true; return; @@ -409,10 +422,7 @@ void GPUKernelRuntime::FreeCommunicationOpDynamicRes(const mindspore::AnfNodePtr communication_op_output_ref_count_--; if (communication_op_output_ref_count_ == 0) { auto device_address = AnfAlgo::GetMutableOutputAddr(kernel_input.first, 0); - MS_EXCEPTION_IF_NULL(device_address); - MS_EXCEPTION_IF_NULL(device_address->ptr_); - mem_manager_->FreeMemFromMemPool(device_address->ptr_); - device_address->ptr_ = nullptr; + mem_manager_->FreeMemFromMemPool(device_address); } *is_communication_op = true; } diff --git a/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.h b/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.h index 6f761342d3..e0eb2dc3f1 100644 --- a/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.h +++ b/mindspore/ccsrc/device/gpu/gpu_kernel_runtime.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "device/kernel_runtime.h" #include "device/kernel_runtime_manager.h" @@ -57,11 +58,12 @@ class GPUKernelRuntime : public KernelRuntime { void AllocCommunicationOpDynamicRes(const session::KernelGraph *graph); void AllocCommunicationOpInputDynamicRes(const mindspore::AnfNodePtr &kernel); void AllocCommunicationOpOutputDynamicRes(const mindspore::AnfNodePtr &kernel); - void FreeKernelDynamicRes(const mindspore::AnfNodePtr &kernel, const AddressPtrList &kernel_workspaces); + void FreeKernelDynamicRes(const mindspore::AnfNodePtr &kernel, const AddressPtrList &kernel_workspaces, + uint32_t graph_id); void FreeCommunicationOpDynamicRes(const mindspore::AnfNodePtr &kernel, size_t input_idx, bool *is_communication_op); size_t communication_op_input_ref_count_{0}; size_t communication_op_output_ref_count_{0}; - MemReuseUtilPtr mem_reuse_util_ptr_{nullptr}; + std::unordered_map mem_reuse_util_map_; }; MS_REG_KERNEL_RUNTIME(kGPUDevice, GPUKernelRuntime); } // namespace gpu diff --git a/mindspore/ccsrc/device/gpu/gpu_memory_manager.cc b/mindspore/ccsrc/device/gpu/gpu_memory_manager.cc index 7d042264b6..8bb65963d8 100644 --- a/mindspore/ccsrc/device/gpu/gpu_memory_manager.cc +++ b/mindspore/ccsrc/device/gpu/gpu_memory_manager.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/mindspore/ccsrc/device/gpu/gpu_stream_assign.cc b/mindspore/ccsrc/device/gpu/gpu_stream_assign.cc new file mode 100644 index 0000000000..2550b543ec --- /dev/null +++ b/mindspore/ccsrc/device/gpu/gpu_stream_assign.cc @@ -0,0 +1,185 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "device/gpu/gpu_common.h" +#include "device/gpu/kernel_info_setter.h" +#include "device/gpu/gpu_device_manager.h" +#include "device/gpu/gpu_stream_assign.h" + +namespace mindspore { +namespace device { +namespace gpu { +void AssignGpuStream(const std::shared_ptr &kernel_graph) { + MS_EXCEPTION_IF_NULL(kernel_graph); + std::vector allreduce_kernels; + auto execution_kernels = kernel_graph->execution_order(); + for (auto kernel_node : execution_kernels) { + std::string kernel_name = AnfAlgo::GetCNodeName(kernel_node); + if (kernel_name == kAllReduceOpName) { + allreduce_kernels.emplace_back(kernel_node); + } else { + DeviceStream compute_stream = GPUDeviceManager::GetInstance().default_stream(); + AnfAlgo::SetNodeAttr("stream_id", MakeValue(reinterpret_cast(compute_stream)), kernel_node); + } + } + if (allreduce_kernels.size() > 1) { + DeviceStream comm_stream = nullptr; + GPUDeviceManager::GetInstance().CreateStream(&comm_stream); + std::transform( + allreduce_kernels.begin(), allreduce_kernels.end(), allreduce_kernels.begin(), [&](CNodePtr allreduce_kernel) { + AnfAlgo::SetNodeAttr("stream_id", MakeValue(reinterpret_cast(comm_stream)), allreduce_kernel); + return allreduce_kernel; + }); + + std::vector send_recv_pairs; + FindAllReduceStreamSwitchPos(kernel_graph, &send_recv_pairs); + InsertStreamSwitchNode(kernel_graph, send_recv_pairs); + } +} + +void FindAllReduceStreamSwitchPos(const std::shared_ptr &kernel_graph, + std::vector *send_recv_pairs) { + auto execution_kernels = kernel_graph->execution_order(); + std::vector::iterator iter, iter_begin; + iter = iter_begin = execution_kernels.begin(); + std::vector::iterator iter_end = execution_kernels.end(); + for (; iter != execution_kernels.end(); ++iter) { + std::string kernel_name = AnfAlgo::GetCNodeName(*iter); + if (kernel_name == kAllReduceOpName) { + // Find AllReduce node's last input node. + std::vector::iterator mock_send_node_iter = + FindSendNodePos(iter_begin, iter + 1, *iter, kAllReduceStreamSwitch); + if (mock_send_node_iter == iter + 1) { + MS_LOG(WARNING) << "Can't find send node place before AllReduce node."; + continue; + } + SendRecvPair pair1 = {kAllReduceStreamSwitch, *mock_send_node_iter, *iter, + IntToSize(mock_send_node_iter - iter_begin + 1), IntToSize(iter - iter_begin)}; + send_recv_pairs->push_back(pair1); + // Find node which uses AllReduce as input[0]. + std::vector::iterator mock_recv_node_iter = + FindRecvNodePos(iter, iter_end, *iter, kAllReduceStreamSwitch); + if (mock_recv_node_iter == iter_end) { + MS_LOG(WARNING) << "Can't find send node place before AllReduce node."; + continue; + } + SendRecvPair pair2 = {kAllReduceStreamSwitch, *iter, *mock_recv_node_iter, IntToSize(iter - iter_begin + 1), + IntToSize(mock_recv_node_iter - iter_begin)}; + send_recv_pairs->push_back(pair2); + } + } +} + +std::vector::iterator FindSendNodePos(std::vector::iterator begin, + std::vector::iterator end, const CNodePtr mock_recv_node, + StreamSwitchType stream_switch_type) { + MS_EXCEPTION_IF_NULL(mock_recv_node); + if (stream_switch_type == kAllReduceStreamSwitch) { + for (auto iter = begin; iter != end; iter++) { + if (*(iter + 1) == mock_recv_node) { + return iter; + } + } + } + return end; +} + +std::vector::iterator FindRecvNodePos(std::vector::iterator begin, + std::vector::iterator end, const CNodePtr mock_send_node, + StreamSwitchType stream_switch_type) { + MS_EXCEPTION_IF_NULL(mock_send_node); + for (auto iter = begin; iter != end; iter++) { + auto node = *iter; + if (stream_switch_type == kAllReduceStreamSwitch) { + for (auto input : node->inputs()) { + if (mock_send_node == AnfAlgo::VisitKernel(input, 0).first) { + return iter; + } + } + } + } + return end; +} + +void InsertStreamSwitchNode(const std::shared_ptr &kernel_graph, + const std::vector &send_recv_pairs) { + std::set ordered_stream_switch_nodes; + for (SendRecvPair pair : send_recv_pairs) { + StreamSwitchType stream_switch_type = pair.stream_switch_type; + CNodePtr mock_send_node = pair.mock_send_node; + CNodePtr mock_recv_node = pair.mock_recv_node; + size_t send_node_offset = pair.send_node_offset; + size_t recv_node_offset = pair.recv_node_offset; + CNodePtr send_node = nullptr; + CNodePtr recv_node = nullptr; + // Step 1: generate Send and Recv CNodes. + if (stream_switch_type == kAllReduceStreamSwitch) { + if (!GenSendRecvCNodesForAllReduce(kernel_graph, mock_send_node, mock_recv_node, &send_node, &recv_node)) { + MS_LOG(EXCEPTION) << "Generating CNodes for send and recv failed. Stream switch type: kAllReduceStreamSwitch"; + } + } + // Step 2: sort send and recv CNodes by offset. + ordered_stream_switch_nodes.insert({send_node_offset, send_node}); + ordered_stream_switch_nodes.insert({recv_node_offset, recv_node}); + } + // Step 3: insert stream switch CNodes into execution kernel list. + auto execution_kernels = kernel_graph->execution_order(); + for (auto node = ordered_stream_switch_nodes.rbegin(); node != ordered_stream_switch_nodes.rend(); node++) { + execution_kernels.insert(execution_kernels.begin() + node->offset, node->cnode); + } + kernel_graph->set_execution_order(execution_kernels); +} + +bool GenSendRecvCNodesForAllReduce(const std::shared_ptr &kernel_graph, + const CNodePtr &mock_send_node, const CNodePtr &mock_recv_node, CNodePtr *send_node, + CNodePtr *recv_node) { + *send_node = CreateStreamSwitchNode(kernel_graph, kSendOpName); + MS_EXCEPTION_IF_NULL(*send_node); + *recv_node = CreateStreamSwitchNode(kernel_graph, kRecvOpName); + MS_EXCEPTION_IF_NULL(*recv_node); + + cudaEvent_t event = nullptr; + CHECK_CUDA_RET_WITH_EXCEPT(cudaEventCreate(&event, cudaEventDisableTiming), "Creating cuda event failed."); + AnfAlgo::SetNodeAttr("record_event", MakeValue(reinterpret_cast(event)), *send_node); + AnfAlgo::SetNodeAttr("wait_event", MakeValue(reinterpret_cast(event)), *recv_node); + + uintptr_t send_stream = AnfAlgo::GetNodeAttr(mock_send_node, "stream_id"); + AnfAlgo::SetNodeAttr("record_event_stream", MakeValue(send_stream), *send_node); + uintptr_t recv_stream = AnfAlgo::GetNodeAttr(mock_recv_node, "stream_id"); + AnfAlgo::SetNodeAttr("wait_event_stream", MakeValue(recv_stream), *recv_node); + return true; +} + +CNodePtr CreateStreamSwitchNode(const std::shared_ptr &kernel_graph, const std::string &name) { + auto op = std::make_shared(name); + auto apply = std::make_shared(op); + std::vector input_list = {apply}; + CNodePtr node = kernel_graph->NewCNode(input_list); + MS_EXCEPTION_IF_NULL(node); + kernel::KernelBuildInfo::KernelBuildInfoBuilder selected_kernel_builder; + AnfAlgo::SetSelectKernelBuildInfo(selected_kernel_builder.Build(), node.get()); + auto abstract_none = std::make_shared(); + node->set_abstract(abstract_none); + SetKernelInfo(node); + return node; +} +} // namespace gpu +} // namespace device +} // namespace mindspore diff --git a/mindspore/ccsrc/device/gpu/gpu_stream_assign.h b/mindspore/ccsrc/device/gpu/gpu_stream_assign.h new file mode 100644 index 0000000000..e3d98d68da --- /dev/null +++ b/mindspore/ccsrc/device/gpu/gpu_stream_assign.h @@ -0,0 +1,73 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_DEVICE_GPU_GPU_STREAM_ASSIGN_H_ +#define MINDSPORE_CCSRC_DEVICE_GPU_GPU_STREAM_ASSIGN_H_ + +#include +#include +#include +#include "session/kernel_graph.h" +#include "session/anf_runtime_algorithm.h" + +namespace mindspore { +namespace device { +namespace gpu { +enum StreamSwitchType { kAllReduceStreamSwitch, kStreamSwitchInvalidType = 255 }; +struct SendRecvPair { + StreamSwitchType stream_switch_type; + CNodePtr mock_send_node; + CNodePtr mock_recv_node; + size_t send_node_offset; + size_t recv_node_offset; +}; +struct StreamSwitchNode { + size_t offset; + CNodePtr cnode; + bool operator<(const StreamSwitchNode &n) const { + if (offset < n.offset) { + return true; + } else if (offset == n.offset) { + return AnfAlgo::GetCNodeName(cnode) == kSendOpName ? true : false; + } else { + return false; + } + } +}; +void AssignGpuStream(const std::shared_ptr &kernel_graph); +void FindAllReduceStreamSwitchPos(const std::shared_ptr &kernel_graph, + std::vector *send_recv_pairs); +// Find Send node position according to "mock" recv node. +// "mock" recv node is a gpu kernel node after a real Recv node, e.g. AllReduce node. +std::vector::iterator FindSendNodePos(std::vector::iterator begin, + std::vector::iterator end, const CNodePtr mock_recv_node, + StreamSwitchType stream_switch_type); +// Find Recv node position according to "mock" send node. +// "mock" send node is a gpu kernel node before a real send node, e.g. AllReduce node. +std::vector::iterator FindRecvNodePos(std::vector::iterator begin, + std::vector::iterator end, const CNodePtr mock_send_node, + StreamSwitchType stream_switch_type); +void InsertStreamSwitchNode(const std::shared_ptr &kernel_graph, + const std::vector &send_recv_pairs); +bool GenSendRecvCNodesForAllReduce(const std::shared_ptr &kernel_graph, + const CNodePtr &mock_send_node, const CNodePtr &mock_recv_node, CNodePtr *send_node, + CNodePtr *recv_node); +CNodePtr CreateStreamSwitchNode(const std::shared_ptr &kernel_graph, const std::string &name); +} // namespace gpu +} // namespace device +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_DEVICE_GPU_GPU_STREAM_ASSIGN_H_ diff --git a/mindspore/ccsrc/device/kernel_adjust.cc b/mindspore/ccsrc/device/kernel_adjust.cc index 9a6f48025f..c1588d7d53 100644 --- a/mindspore/ccsrc/device/kernel_adjust.cc +++ b/mindspore/ccsrc/device/kernel_adjust.cc @@ -25,6 +25,7 @@ #include "session/anf_runtime_algorithm.h" #include "utils/context/ms_context.h" +#include "common/trans.h" #include "utils/config_manager.h" #include "common/utils.h" #include "kernel/kernel_build_info.h" @@ -391,7 +392,8 @@ bool KernelAdjust::StepLoadCtrlInputs(const std::shared_ptr &c auto device_address = AnfAlgo::GetMutableOutputAddr(pk_node, 0); MS_EXCEPTION_IF_NULL(device_address); tensor->set_device_address(device_address); - if (!device_address->SyncHostToDevice(tensor->shape(), LongToSize(tensor->data().nbytes()), tensor->data_type(), + if (!device_address->SyncHostToDevice(trans::GetRuntimePaddingShape(pk_node, 0), + LongToSize(tensor->data().nbytes()), tensor->data_type(), tensor->data_c(false))) { MS_LOG(INFO) << "SyncHostToDevice failed."; return false; diff --git a/mindspore/ccsrc/device/kernel_info.h b/mindspore/ccsrc/device/kernel_info.h index 9352158774..33ddda83c9 100644 --- a/mindspore/ccsrc/device/kernel_info.h +++ b/mindspore/ccsrc/device/kernel_info.h @@ -31,6 +31,7 @@ class KernelInfo { public: KernelInfo() { kernel_mod_ = nullptr; + is_feature_map_ = false; select_kernel_build_info_ = nullptr; output_address_list_ = {}; workspace_address_list_ = {}; @@ -45,6 +46,7 @@ class KernelInfo { void set_select_kernel_build_info(const kernel::KernelBuildInfoPtr &select_kernel_build_info) { select_kernel_build_info_ = select_kernel_build_info; } + void SetFeatureMapFlag(bool flag) { is_feature_map_ = flag; } const DeviceAddress *GetOutputAddr(size_t index) const; DeviceAddressPtr GetMutableOutputAddr(size_t index) const; bool OutputAddrExist(size_t index) const; @@ -63,8 +65,10 @@ class KernelInfo { void set_graph_id(uint32_t graph_id) { graph_id_ = graph_id; } uint32_t graph_id() const { return graph_id_; } bool operator==(const KernelInfo &other) const; + bool is_feature_map() const { return is_feature_map_; } private: + bool is_feature_map_; kernel::KernelBuildInfoPtr select_kernel_build_info_; std::vector> output_address_list_; std::vector> workspace_address_list_; diff --git a/mindspore/ccsrc/device/kernel_runtime.cc b/mindspore/ccsrc/device/kernel_runtime.cc index eebc650347..7f3d31d8d0 100644 --- a/mindspore/ccsrc/device/kernel_runtime.cc +++ b/mindspore/ccsrc/device/kernel_runtime.cc @@ -44,19 +44,29 @@ bool KernelRuntime::Run(session::KernelGraph *graph) { bool ret = false; auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); +#if defined(_WIN32) || defined(_WIN64) + auto start_time = std::chrono::steady_clock::now(); +#else struct timeval start_time, end_time; (void)gettimeofday(&start_time, nullptr); +#endif bool is_task_sink = context_ptr->enable_task_sink(); if (is_task_sink) { ret = RunTask(graph); } else { ret = LaunchKernel(graph); } +#if defined(_WIN32) || defined(_WIN64) + auto end_time = std::chrono::steady_clock::now(); + std::chrono::duration> cost = end_time - start_time; + MS_LOG(INFO) << "Call MS Run Success in " << cost.count() << " us"; +#else (void)gettimeofday(&end_time, nullptr); const uint64_t kUSecondInSecond = 1000000; uint64_t cost = kUSecondInSecond * static_cast(end_time.tv_sec - start_time.tv_sec); cost += static_cast(end_time.tv_usec - start_time.tv_usec); MS_LOG(INFO) << "Call MS Run Success in " << cost << " us"; +#endif return ret; } @@ -105,7 +115,7 @@ size_t KernelRuntime::CountNodeDeviceMemorySize(const mindspore::AnfNodePtr &nod std::vector shape = AnfAlgo::GetOutputDeviceShape(node, output_index); auto format = AnfAlgo::GetOutputFormat(node, output_index); if (shape.empty() && format != kOpFormat_DEFAULT) { - shape = trans::TransShapeTo4d(shape); + shape = trans::PaddingShapeTo4d(shape, AnfAlgo::GetOutputReshapeType(node, output_index)); shape = trans::TransShapeToDevice(shape, format); } // scalar's output shape is a empty vector @@ -250,7 +260,7 @@ void KernelRuntime::AssignStaticMemoryOutput(const session::KernelGraph *graph) MS_EXCEPTION_IF_NULL(graph); auto nodes = AnfAlgo::GetAllOutput(graph->output(), {prim::kPrimTupleGetItem}); for (const auto &node : nodes) { - auto item_with_index = AnfAlgo::VisitKernelWithReturnType(node, 0); + auto item_with_index = AnfAlgo::VisitKernelWithReturnType(node, 0, true); MS_EXCEPTION_IF_NULL(item_with_index.first); if (!item_with_index.first->isa() || !AnfAlgo::IsRealKernel(item_with_index.first)) { continue; @@ -355,6 +365,10 @@ void KernelRuntime::AssignNodeOutputMem(int flag, const AnfNodePtr &node, int in AssignCommunicationNodeOutputMem(flag, node); return; } + if (AnfAlgo::IsGetNext(NOT_NULL(node)) && flag == kReuseDynamicMem) { + MS_LOG(INFO) << "GetNext disable mem_reuse"; + flag = kDynamicMem; + } auto kernel_mod = AnfAlgo::GetKernelMod(node); MS_EXCEPTION_IF_NULL(kernel_mod); auto output_sizes = kernel_mod->GetOutputSizeList(); @@ -401,8 +415,9 @@ void KernelRuntime::AssignValueNodeTensor(const ValueNodePtr &value_node, const auto address = CreateDeviceAddress(ptr, node_size, AnfAlgo::GetOutputFormat(value_node, output_idx), output_type_id); MS_EXCEPTION_IF_NULL(address); AnfAlgo::SetOutputAddr(address, output_idx, value_node.get()); - if (!address->SyncHostToDevice(tensor->shape(), tensor_size, tensor->data_type(), tensor->data_c(false))) { - MS_EXCEPTION(NotExistsError) << "kValueNode SyncHostToDevice fail!" << value_node->DebugString() << "node format is" + if (!address->SyncHostToDevice(trans::GetRuntimePaddingShape(value_node, 0), tensor_size, tensor->data_type(), + tensor->data_c(false))) { + MS_EXCEPTION(NotExistsError) << "ValueNode SyncHostToDevice fail!" << value_node->DebugString() << "node format is" << AnfAlgo::GetOutputFormat(value_node, output_idx) << "node dtype is " << AnfAlgo::GetOutputInferDataType(value_node, output_idx); } @@ -421,19 +436,6 @@ void KernelRuntime::AssignStaticMemoryValueNode(session::KernelGraph *graph) { MS_EXCEPTION_IF_NULL(node_value); if (node_value->isa()) { AssignValueNodeTensor(value_node, node_value, 0); - } else if (node_value->isa()) { - auto value_tuple = node_value->cast(); - if (value_tuple == nullptr) { - MS_LOG(WARNING) << "value_tuple is null"; - continue; - } - size_t i = 0; - auto value_list = value_tuple->value(); - for (auto value_ptr : value_list) { - if (value_ptr->isa()) { - AssignValueNodeTensor(value_node, value_ptr, i++); - } - } } else if (node_value->isa()) { auto value = GetValue(node_value); size_t tensor_size = value.size(); @@ -474,7 +476,7 @@ void KernelRuntime::AssignWorkSpaceMem(int flag, const AnfNodePtr &node) { MS_EXCEPTION_IF_NULL(kernel_mod); size_t index = 0; for (auto &size : kernel_mod->GetWorkspaceSizeList()) { - auto ptr = mem_manager_->MallocWorkSpaceMem(node, flag, index, size); + auto ptr = mem_manager_->MallocWorkSpaceMem(node, index, flag, size); AnfAlgo::SetWorkspaceAddr(CreateDeviceAddress(ptr, size, "", kTypeUnknown), index, node.get()); index++; } @@ -569,8 +571,12 @@ bool KernelRuntime::LaunchKernelMod(const session::KernelGraph &graph) { AddressPtrList kernel_workspaces; AddressPtrList kernel_outputs; GenLaunchArgs(*kernel_mod, kernel, &kernel_inputs, &kernel_workspaces, &kernel_outputs); +#if defined(_WIN32) || defined(_WIN64) + auto start_time = std::chrono::steady_clock::now(); +#else struct timeval start_time, end_time; (void)gettimeofday(&start_time, nullptr); +#endif auto ret = kernel_mod->Launch(kernel_inputs, kernel_workspaces, kernel_outputs, reinterpret_cast(stream_)); if (!ret) { @@ -580,11 +586,17 @@ bool KernelRuntime::LaunchKernelMod(const session::KernelGraph &graph) { if (AnfAlgo::GetKernelType(kernel) == TBE_KERNEL && !SyncStream()) { MS_LOG(EXCEPTION) << "SyncStream failed."; } +#if defined(_WIN32) || defined(_WIN64) + auto end_time = std::chrono::steady_clock::now(); + std::chrono::duration> cost = end_time - start_time; + MS_LOG(DEBUG) << "d " << kernel->fullname_with_scope() << " in " << cost.count() << " us"; +#else (void)gettimeofday(&end_time, nullptr); const uint64_t kUSecondInSecond = 1000000; uint64_t cost = kUSecondInSecond * static_cast(end_time.tv_sec - start_time.tv_sec); cost += static_cast(end_time.tv_usec - start_time.tv_usec); MS_LOG(DEBUG) << "d " << kernel->fullname_with_scope() << " in " << cost << " us"; +#endif } } return true; diff --git a/mindspore/ccsrc/device/memory_manager.cc b/mindspore/ccsrc/device/memory_manager.cc index 6977628eb1..2fad5fc10e 100644 --- a/mindspore/ccsrc/device/memory_manager.cc +++ b/mindspore/ccsrc/device/memory_manager.cc @@ -155,6 +155,13 @@ void *MemoryManager::MallocMemFromMemPool(size_t size) { return nullptr; } +void MemoryManager::FreeMemFromMemPool(const DeviceAddressPtr address) { + MS_EXCEPTION_IF_NULL(address); + MS_EXCEPTION_IF_NULL(address->ptr_); + FreeMemFromMemPool(address->ptr_); + address->ptr_ = nullptr; +} + void MemoryManager::FreeMemFromMemPool(void *device_ptr) { if (device_ptr == nullptr) { MS_LOG(ERROR) << "FreeMemFromMemPool device_ptr is null."; diff --git a/mindspore/ccsrc/device/memory_manager.h b/mindspore/ccsrc/device/memory_manager.h index 82c22f4548..c90ffc380e 100644 --- a/mindspore/ccsrc/device/memory_manager.h +++ b/mindspore/ccsrc/device/memory_manager.h @@ -47,6 +47,7 @@ class MemoryManager { virtual void MallocMemFromMemPool(const DeviceAddressPtr address, size_t size); virtual void *MallocMemFromMemPool(size_t size); + virtual void FreeMemFromMemPool(const DeviceAddressPtr address); virtual void FreeMemFromMemPool(void *device_ptr); size_t GetCommonAlignSize(size_t input_size) const; diff --git a/mindspore/ccsrc/ir/anf.cc b/mindspore/ccsrc/ir/anf.cc index 924453a7a6..658fb578b7 100644 --- a/mindspore/ccsrc/ir/anf.cc +++ b/mindspore/ccsrc/ir/anf.cc @@ -103,7 +103,8 @@ std::string CNode::fullname_with_scope() { return fullname_with_scope_; } - if (IsApply(prim::kPrimScalarSummary) || IsApply(prim::kPrimTensorSummary) || IsApply(prim::kPrimImageSummary)) { + if (IsApply(prim::kPrimScalarSummary) || IsApply(prim::kPrimTensorSummary) || IsApply(prim::kPrimImageSummary) || + IsApply(prim::kPrimHistogramSummary)) { std::string tag = GetValue(GetValueNode(input(1))); if (tag == "") { MS_LOG(EXCEPTION) << "The tag name is null, should be valid string"; @@ -111,10 +112,12 @@ std::string CNode::fullname_with_scope() { std::string name; if (IsApply(prim::kPrimScalarSummary)) { name = tag + "[:Scalar]"; - } else if (IsApply(prim::kPrimTensorSummary)) { - name = tag + "[:Tensor]"; - } else { + } else if (IsApply(prim::kPrimImageSummary)) { name = tag + "[:Image]"; + } else if (IsApply(prim::kPrimHistogramSummary)) { + name = tag + "[:Histogram]"; + } else { + name = tag + "[:Tensor]"; } fullname_with_scope_ = name; } else { diff --git a/mindspore/ccsrc/ir/dtype.h b/mindspore/ccsrc/ir/dtype.h index 11099e460e..e3e2099b5e 100644 --- a/mindspore/ccsrc/ir/dtype.h +++ b/mindspore/ccsrc/ir/dtype.h @@ -51,7 +51,7 @@ class String : public Object { TypeId generic_type_id() const override { return kObjectTypeString; } TypePtr DeepCopy() const override { return std::make_shared(); } - std::string ToString() const override { return std::string("String:"); } + std::string ToString() const override { return std::string("String"); } std::string ToReprString() const override { return "string"; } std::string DumpText() const override { return "String"; } }; diff --git a/mindspore/ccsrc/ir/func_graph.cc b/mindspore/ccsrc/ir/func_graph.cc index 7404db4af0..93fd9c0936 100644 --- a/mindspore/ccsrc/ir/func_graph.cc +++ b/mindspore/ccsrc/ir/func_graph.cc @@ -640,8 +640,8 @@ FuncGraphPtr FuncGraph::GenerateGraph(const AbstractBasePtrList& args_spec_list) void FuncGraph::add_parameter_obj_node(const AnfNodePtr& p) { paramter_obj_nodes_.push_back(p); } -std::list FuncGraph::GetOrderedCnodes(bool force_use_topo_sort) { - if (has_flag(GRAPH_FLAG_HAS_EFFECT) && !force_use_topo_sort) { +std::list FuncGraph::GetOrderedCnodes() { + if (has_flag(GRAPH_FLAG_HAS_EFFECT)) { MS_LOG(DEBUG) << "Return ordered cnodes."; return order_; } else { @@ -703,14 +703,14 @@ void FuncGraph::CheckOrder() { } } } - auto topo_sort = GetOrderedCnodes(true); - if (topo_sort.size() != order_.size()) { - DumpCNodeList(); - DumpIR(ToString(), shared_from_base()); - MS_LOG(INFO) << "Dump graph: " << ToString() << "."; - DumpFuncGraph(ToString()); - MS_LOG(EXCEPTION) << "CNode order size " << order_.size() << " is not equal to topo sort list size " - << topo_sort.size() << "."; + auto mng = manager_.lock(); + if (mng != nullptr) { + const auto& nodes = mng->nodes()[shared_from_base()]; + if (nodes.size() != (order_.size() + parameters_.size())) { + DumpCNodeList(); + MS_LOG(EXCEPTION) << "CNode order size " << order_.size() << " is not equal to managed node size " + << nodes.size() - parameters_.size() << "."; + } } MS_LOG(DEBUG) << "Check order okay."; } diff --git a/mindspore/ccsrc/ir/func_graph.h b/mindspore/ccsrc/ir/func_graph.h index 1d58c90755..9c3752cd81 100644 --- a/mindspore/ccsrc/ir/func_graph.h +++ b/mindspore/ccsrc/ir/func_graph.h @@ -258,7 +258,7 @@ class FuncGraph : public FuncGraphBase { std::map parameter_default_value_; std::unordered_map make_ref_params_; - std::list GetOrderedCnodes(bool force_use_topo_sort = false); + std::list GetOrderedCnodes(); void EraseUnusedNodeInOrder(const AnfNodePtr &n); void EraseUnusedNodeInOrder(); void CheckOrder(); diff --git a/mindspore/ccsrc/ir/manager.cc b/mindspore/ccsrc/ir/manager.cc index c1459014bb..889a091711 100644 --- a/mindspore/ccsrc/ir/manager.cc +++ b/mindspore/ccsrc/ir/manager.cc @@ -985,40 +985,14 @@ void ParentComputer::RealRecompute(FuncGraphPtr fg) { } } -// children include: -// A. func graphs which use variables in fg as free variables; (child_direct_) -// B. func graphs which call func func graph in A. (all_users_) -FuncGraphSetPtr ChildrenComputer::SeekChildren(const FuncGraphPtr& fg, const FuncGraphSetPtr& path) { - if (path == nullptr || path->contains(fg)) { - return std::make_shared(); - } - std::shared_ptr children = std::make_shared(); - auto& deps = *child_direct_; - auto& users = *all_users_; - MS_LOG(DEBUG) << "" << fg->ToString() << " start func graph dep size:" << deps[fg].size(); - for (auto& dep : deps[fg]) { - FuncGraphPtr child = dep.first; - children->add(child); - path->add(child); - MS_LOG(DEBUG) << "Child func graph:" << fg->ToString() << " child " << child->ToString(); - for (auto& user : users[child]) { - auto user_func_graph = user.first; - MS_LOG(DEBUG) << "Func graph:" << fg->ToString() << " user " << user_func_graph->ToString(); - children->add(user_func_graph); - path->add(user_func_graph); - } - children->update(SeekChildren(child, path)); - } - (void)children->erase(fg); - MS_LOG(DEBUG) << "End in children: " << children->size(); - return children; -} - void ChildrenComputer::RealRecompute(FuncGraphPtr fg) { MS_EXCEPTION_IF_NULL(manager_); - child_direct_ = &manager_->func_graph_child_direct(); - all_users_ = &manager_->func_graph_users(); - children_analysis_[fg].update(SeekChildren(fg)); + auto used_fg_total = manager_->func_graphs_used_total(fg); + for (auto& used_fg : used_fg_total) { + if (manager_->parent(used_fg) == fg) { + children_analysis_[fg].add(used_fg); + } + } } void ScopeComputer::RealRecompute(FuncGraphPtr fg) { diff --git a/mindspore/ccsrc/ir/manager.h b/mindspore/ccsrc/ir/manager.h index dc8f656ae7..aaf5a0aa5f 100644 --- a/mindspore/ccsrc/ir/manager.h +++ b/mindspore/ccsrc/ir/manager.h @@ -398,11 +398,8 @@ class ParentComputer final : public DepComputer { // graph's children graph except self class ChildrenComputer final : public DepComputer { public: - explicit ChildrenComputer(const FuncGraphManager* m) : DepComputer(m), all_users_(nullptr), child_direct_(nullptr) {} - ~ChildrenComputer() override { - all_users_ = nullptr; - child_direct_ = nullptr; - } + explicit ChildrenComputer(const FuncGraphManager* m) : DepComputer(m) {} + ~ChildrenComputer() override = default; FuncGraphToFuncGraphSetMap& children_analysis() { return children_analysis_; } @@ -414,13 +411,6 @@ class ChildrenComputer final : public DepComputer { void ExtraReset() override { children_analysis_.clear(); } void RealRecompute(FuncGraphPtr fg) override; - - private: - FuncGraphSetPtr SeekChildren(const FuncGraphPtr& fg, const FuncGraphSetPtr& path = std::make_shared()); - // when SeekChildren calls itself recursively, it can access these variables by class member - // other than pass by formal parameters, it can save 2 parameters for SeekChildren(). - FuncGraphToFuncGraphCounterMap* all_users_; - FuncGraphToFuncGraphCounterMap* child_direct_; }; // graph's children graph include self diff --git a/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_build.cc b/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_build.cc index cf23779415..808e87edc0 100644 --- a/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_build.cc +++ b/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_build.cc @@ -39,8 +39,6 @@ namespace mindspore { namespace kernel { using FNodeAttrHandle = std::function &anf_node, mindspore::NodeDef *proto)>; -const std::vector local_framework_op_vec = {kInitData, kGetNext, kDropoutGenMask, kPrint}; - bool SetIOIputSize(const std::shared_ptr &anf_node, const size_t &input_num, std::vector *input_size_list) { MS_EXCEPTION_IF_NULL(anf_node); @@ -298,19 +296,12 @@ KernelModPtr AicpuOpBuild(const std::shared_ptr &anf_node) { MS_EXCEPTION_IF_NULL(kernel_mod_ptr); kernel_mod_ptr->SetAnfNode(anf_node); kernel_mod_ptr->SetNodeName(op_name); - auto iter = std::find(local_framework_op_vec.begin(), local_framework_op_vec.end(), op_name); - if (iter != local_framework_op_vec.end()) { - if (!CreateNodeDefBytes(anf_node, kernel_mod_ptr)) { - MS_LOG(EXCEPTION) << "Create nodeDefBytes faild!"; - } - } else { - MS_LOG(EXCEPTION) << "Aicpu don't support node [" << op_name << "]"; + if (!CreateNodeDefBytes(anf_node, kernel_mod_ptr)) { + MS_LOG(EXCEPTION) << "Create nodeDefBytes faild!"; } - if (!SetIOSize(anf_node, kernel_mod_ptr)) { MS_LOG(EXCEPTION) << "Set input output size list failed."; } - return kernel_mod_ptr; } } // namespace kernel diff --git a/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_metadata.cc b/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_metadata.cc index 6675051069..e8636ffa2e 100644 --- a/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_metadata.cc +++ b/mindspore/ccsrc/kernel/aicpu/aicpu_kernel_metadata.cc @@ -34,16 +34,18 @@ void AicpuMetadataInfo(const CNodePtr &kernel_node, std::vector inputs_format; - std::vector inputs_type; - for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(kernel_node); ++input_index) { - inputs_format.emplace_back(kOpFormat_DEFAULT); - inputs_type.push_back(AnfAlgo::GetPrevNodeOutputInferDataType(kernel_node, input_index)); + if (op_name == kPrint || op_name == kGetNext) { + std::vector inputs_format{}; + std::vector inputs_type{}; + if (op_name == kPrint) { + for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(kernel_node); ++input_index) { + inputs_format.emplace_back(kOpFormat_DEFAULT); + inputs_type.push_back(AnfAlgo::GetPrevNodeOutputInferDataType(kernel_node, input_index)); + } } std::vector outputs_format; std::vector outputs_type; diff --git a/mindspore/ccsrc/kernel/common_utils.cc b/mindspore/ccsrc/kernel/common_utils.cc index 137ae65414..5abaff412e 100644 --- a/mindspore/ccsrc/kernel/common_utils.cc +++ b/mindspore/ccsrc/kernel/common_utils.cc @@ -89,13 +89,13 @@ bool IsAtomicNode(const CNodePtr &kernel_node) { parameters_indexs.push_back(0); } } - std::vector clean_output_indexs; + std::vector clean_output_indexs; // in parameters data sort as input->workspace->output size_t index = 0; while (index < output_num) { if (parameters_indexs[input_num + workspace_num + index] == 1) { atomic_flag = true; - clean_output_indexs.push_back(index); + clean_output_indexs.push_back(SizeToInt(index)); } index++; } @@ -117,7 +117,11 @@ bool IsAtomicNode(const CNodePtr &kernel_node) { bool KernelMeta::ReadIndex(const std::string &bin_dir) { DIR *dir = opendir(bin_dir.c_str()); if (dir == nullptr) { +#if defined(_WIN32) || defined(_WIN64) + auto ret = mkdir(bin_dir.c_str()); +#else auto ret = mkdir(bin_dir.c_str(), S_IRWXG | S_IRWXU); +#endif if (ret != 0) { MS_LOG(INFO) << "kernel dir not exist[" << bin_dir << "]."; return false; @@ -500,10 +504,17 @@ void SaveJsonInfo(const std::string &json_name, const std::string &info) { } filewrite << info << std::endl; filewrite.close(); +#if defined(_WIN32) || defined(_WIN64) + if (nullptr == _fullpath(real_path, path.c_str(), PATH_MAX)) { + MS_LOG(DEBUG) << "dir " << path << " does not exit."; + return; + } +#else if (nullptr == realpath(path.c_str(), real_path)) { MS_LOG(DEBUG) << "dir " << path << " does not exit."; return; } +#endif MS_LOG(INFO) << "real path is :" << real_path; if (chmod(real_path, S_IRUSR) == -1) { MS_LOG(DEBUG) << "modify file:" << real_path << " to read only fail."; diff --git a/mindspore/ccsrc/kernel/common_utils.h b/mindspore/ccsrc/kernel/common_utils.h index 6e3635d904..07f191cc7b 100644 --- a/mindspore/ccsrc/kernel/common_utils.h +++ b/mindspore/ccsrc/kernel/common_utils.h @@ -37,7 +37,7 @@ constexpr auto kProcessorCuda = "cuda"; constexpr auto kJsonSuffix = ".json"; constexpr auto kInfoSuffix = ".info"; constexpr unsigned int AUTODIFF_COMPILE_OVERTIME = 600; -constexpr auto kAkgModule = "akg"; +constexpr auto kAkgModule = "_akg"; constexpr auto kArgDataformat = "data_format"; const std::vector support_devices = {"aicore", "aicpu", "cuda"}; diff --git a/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.cc new file mode 100644 index 0000000000..41c9c2243f --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.cc @@ -0,0 +1,43 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/arrays/select_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(Select, + KernelAttr() + .AddInputAttr(kNumberTypeBool) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32), + SelectGpuKernel, float) +MS_REG_GPU_KERNEL_ONE(Select, + KernelAttr() + .AddInputAttr(kNumberTypeBool) + .AddInputAttr(kNumberTypeFloat16) + .AddInputAttr(kNumberTypeFloat16) + .AddOutputAttr(kNumberTypeFloat16), + SelectGpuKernel, half) +MS_REG_GPU_KERNEL_ONE(Select, + KernelAttr() + .AddInputAttr(kNumberTypeBool) + .AddInputAttr(kNumberTypeInt32) + .AddInputAttr(kNumberTypeInt32) + .AddOutputAttr(kNumberTypeInt32), + SelectGpuKernel, int) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.h new file mode 100644 index 0000000000..ba0bea4dee --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/arrays/select_gpu_kernel.h @@ -0,0 +1,95 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_SELECT_GPU_KERNEL_H +#define MINDSPORE_CCSRC_KERNEL_GPU_SELECT_GPU_KERNEL_H + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/select_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class SelectGpuKernel : public GpuKernel { + public: + SelectGpuKernel() : input_size_(0), output_size_(0) {} + ~SelectGpuKernel() override = default; + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &, + const std::vector &outputs, uintptr_t stream_ptr) override { + bool *input_cond = GetDeviceAddress(inputs, 0); + T *input_x = GetDeviceAddress(inputs, 1); + T *input_y = GetDeviceAddress(inputs, 2); + T *output = GetDeviceAddress(outputs, 0); + CalSelect(output_size_ / sizeof(T), input_cond, input_x, input_y, output, + reinterpret_cast(stream_ptr)); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + if (!CheckParam(kernel_node)) { + return false; + } + auto shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + input_size_ = sizeof(bool); + output_size_ = sizeof(T); + for (size_t x : shape) { + input_size_ = input_size_ * x; + output_size_ = output_size_ * x; + } + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + input_size_list_.push_back(input_size_); + input_size_list_.push_back(output_size_); + input_size_list_.push_back(output_size_); + output_size_list_.push_back(output_size_); + } + + private: + bool CheckParam(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 3) { + MS_LOG(ERROR) << "Input number is " << input_num << ", but SelectGpuKernel needs 3 output."; + return false; + } + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(ERROR) << "Output number is " << output_num << ", but SelectGpuKernel needs 1 output."; + return false; + } + return true; + } + + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + size_t input_size_; + size_t output_size_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_SELECT_GPU_KERNEL_H diff --git a/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.cc new file mode 100644 index 0000000000..5468aa6500 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.cc @@ -0,0 +1,23 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/control/recv_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_REGULAR(Recv, KernelAttr(), RecvGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.h new file mode 100644 index 0000000000..206eac5bd9 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/control/recv_gpu_kernel.h @@ -0,0 +1,66 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_RECV_GPU_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_RECV_GPU_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class RecvGpuKernel : public GpuKernel { + public: + RecvGpuKernel() {} + ~RecvGpuKernel() override = default; + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &, const std::vector &, const std::vector &, + uintptr_t) override { + CHECK_CUDA_RET_WITH_EXCEPT(cudaStreamWaitEvent(wait_stream_, wait_event_, 0), "Waiting cuda event failed."); + return true; + } + bool Init(const CNodePtr &kernel_node) override { + wait_stream_ = reinterpret_cast(GetAttr(kernel_node, "wait_event_stream")); + wait_event_ = reinterpret_cast(GetAttr(kernel_node, "wait_event")); + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + input_size_list_.clear(); + output_size_list_.clear(); + workspace_size_list_.clear(); + return; + } + + private: + cudaStream_t wait_stream_{nullptr}; + cudaEvent_t wait_event_{nullptr}; + + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_RECV_GPU_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.cc new file mode 100644 index 0000000000..c417c30bb3 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.cc @@ -0,0 +1,23 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/control/send_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_REGULAR(Send, KernelAttr(), SendGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.h new file mode 100644 index 0000000000..156ec4160d --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/control/send_gpu_kernel.h @@ -0,0 +1,66 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_SEND_GPU_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_SEND_GPU_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class SendGpuKernel : public GpuKernel { + public: + SendGpuKernel() {} + ~SendGpuKernel() override = default; + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &, const std::vector &, const std::vector &, + uintptr_t) override { + CHECK_CUDA_RET_WITH_EXCEPT(cudaEventRecord(record_event_, record_stream_), "Recording cuda event failed."); + return true; + } + bool Init(const CNodePtr &kernel_node) override { + record_stream_ = reinterpret_cast(GetAttr(kernel_node, "record_event_stream")); + record_event_ = reinterpret_cast(GetAttr(kernel_node, "record_event")); + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + input_size_list_.clear(); + output_size_list_.clear(); + workspace_size_list_.clear(); + return; + } + + private: + cudaStream_t record_stream_{nullptr}; + cudaEvent_t record_event_{nullptr}; + + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CONTROL_SEND_GPU_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cu new file mode 100644 index 0000000000..3ef856e00a --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cu @@ -0,0 +1,169 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "batchnorm_fold2_impl.cuh" +#include "batchnorm_fold_impl.cuh" +#include "include/cuda_runtime.h" + + +template +__global__ void BatchNormFold2Kernel(const T *x, const T *beta, const T *gamma, const T *batch_std, const T *batch_mean, + const T *running_std, const T *running_mean, const int *global_step, T *y, + int freeze_bn, size_t N, size_t C, size_t H, size_t W) { + int c = 0; + size_t num_count = N * C * H * W; + if (*global_step < freeze_bn) { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < num_count; i += blockDim.x * gridDim.x) { + c = i / (H * W) % C; + y[i] = x[i] * running_std[c] / batch_std[c] + beta[c] - gamma[c] * batch_mean[c] / batch_std[c]; + } + } else { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < num_count; i += blockDim.x * gridDim.x) { + c = i / (H * W) % C; + y[i] = x[i] + beta[c] - gamma[c] * running_mean[c] / running_std[c]; + } + } +} + +template +__global__ void BatchNormFold2GradReduce1(const T *dout, T *tmp, const T *x, T *tmp2, size_t N, size_t C, size_t HW) { + int n = 0; + int c = 0; + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < N * C; i += blockDim.x * gridDim.x) { + n = i / C; + c = i % C; + tmp[c * N + n] = thrust::reduce(thrust::seq, dout + i * HW, dout + (i + 1) * HW, 0.f, thrust::plus()); + tmp2[c * N + n] = thrust::reduce(thrust::seq, x + i * HW, x + (i + 1) * HW, 0.f, thrust::plus()); + } +} + +template +__global__ void BatchNormFold2GradReduce2(const T *tmp, T *d_beta, const T *tmp2, T *reduce_x, size_t N, size_t C) { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < C; i += blockDim.x * gridDim.x) { + d_beta[i] = thrust::reduce(thrust::seq, tmp + i * N, tmp + (i + 1) * N, 0.f, thrust::plus()); + reduce_x[i] = thrust::reduce(thrust::seq, tmp2 + i * N, tmp2 + (i + 1) * N, 0.f, thrust::plus()); + } +} + +template +__global__ void BatchNormFold2GradNotFreeze(const T *d_beta, const T *reduce_x, const T *batch_mean, const T *batch_std, + const T *running_mean, const T *running_std, const T *gamma, T *d_gamma, + T *d_batch_mean, T *d_batch_std, size_t C) { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < C; i += blockDim.x * gridDim.x) { + d_gamma[i] = -d_beta[i] * batch_mean[i] / batch_std[i]; + d_batch_mean[i] = -d_beta[i] * gamma[i] / batch_std[i]; + d_batch_std[i] = + (d_beta[i] * gamma[i] * batch_mean[i] - reduce_x[i] * running_std[i]) / batch_std[i] / batch_std[i]; + } +} + +template +__global__ void BatchNormFold2GradFreeze(const T *d_beta, const T *running_mean, const T *running_std, T *d_gamma, + size_t C) { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < C; i += blockDim.x * gridDim.x) { + d_gamma[i] = -d_beta[i] * running_mean[i] / running_std[i]; + } +} + +template +__global__ void BatchNormFold2GradMul(const T *dout, const T *x, T *tmp_x, size_t NCHW) { + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < NCHW; i += blockDim.x * gridDim.x) { + tmp_x[i] = dout[i] * x[i]; + } +} + +template +__global__ void DxMul(size_t N, size_t C, size_t HW, const T *batch_std, const T *running_std, T *d_x) { + int c = 0; + size_t num_count = N * C * HW; + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < num_count; i += blockDim.x * gridDim.x) { + c = (i / HW) % C; + d_x[i] = d_x[i] * running_std[c] / batch_std[c]; + } +} + +template +void BatchNormFold2Forward(const T *x, const T *beta, const T *gamma, const T *batch_std, const T *batch_mean, + const T *running_std, const T *running_mean, const int *global_step, T *y, int freeze_bn, + size_t N, size_t C, size_t H, size_t W, cudaStream_t cuda_stream) { + auto num_count = N * C * H * W; + BatchNormFold2Kernel<<>>( + x, beta, gamma, batch_std, batch_mean, running_std, running_mean, global_step, y, freeze_bn, N, C, H, W); +} + +template void BatchNormFold2Forward(const float *x, const float *beta, const float *gamma, + const float *batch_std, const float *batch_mean, const float *running_std, + const float *running_mean, const int *global_step, float *y, int freeze_bn, + size_t N, size_t C, size_t H, size_t W, cudaStream_t cuda_stream); + +template +void BatchNormFold2GradReduce(const T *dout, const T *x, T *d_beta, T *tmp, T *reduce_x, T *tmp2, T *tmp_x, size_t N, + size_t C, size_t H, size_t W, cudaStream_t cuda_stream) { + auto hw = H * W; + auto num_count = N * C * H * W; + BatchNormFold2GradMul<<>>(dout, x, tmp_x, num_count); + BatchNormFold2GradReduce1<<>>(dout, tmp, tmp_x, tmp2, N, C, hw); + BatchNormFold2GradReduce2<<>>(tmp, d_beta, tmp2, reduce_x, N, C); +} + +template void BatchNormFold2GradReduce(const float *dout, const float *x, float *d_beta, float *tmp, + float *reduce_x, float *tmp2, float *tmp_x, size_t N, size_t C, size_t H, + size_t W, cudaStream_t cuda_stream); + +template +void CalBatchNormFold2GradNotFreeze(const T *d_beta, const T *reduce_x, const T *batch_mean, const T *batch_std, + const T *running_mean, const T *running_std, const T *gamma, T *d_gamma, + T *d_batch_mean, T *d_batch_std, size_t C, cudaStream_t cuda_stream) { + BatchNormFold2GradNotFreeze<<>>( + d_beta, reduce_x, batch_mean, batch_std, running_mean, running_std, gamma, d_gamma, d_batch_mean, d_batch_std, C); +} + +template void CalBatchNormFold2GradNotFreeze(const float *d_beta, const float *reduce_x, const float *batch_mean, + const float *batch_std, const float *running_mean, + const float *running_std, const float *gamma, float *d_gamma, + float *d_batch_mean, float *d_batch_std, size_t C, + cudaStream_t cuda_stream); + +template +void CalBatchNormFold2GradFreeze(const T *d_beta, const T *reduce_x, const T *batch_mean, const T *batch_std, + const T *running_mean, const T *running_std, const T *gamma, T *d_gamma, + T *d_batch_mean, T *d_batch_std, size_t C, cudaStream_t cuda_stream) { + BatchNormFold2GradFreeze<<>>(d_beta, running_mean, running_std, d_gamma, + C); + ThrustFillWith(d_batch_mean, C, (T)0.f, cuda_stream); + ThrustFillWith(d_batch_std, C, (T)0.f, cuda_stream); +} + +template void CalBatchNormFold2GradFreeze(const float *d_beta, const float *reduce_x, const float *batch_mean, + const float *batch_std, const float *running_mean, + const float *running_std, const float *gamma, float *d_gamma, + float *d_batch_mean, float *d_batch_std, size_t C, + cudaStream_t cuda_stream); + +template +void CalBatchNormFold2GradNotFreezeDxMul(const T *batch_std, const T *running_std, T *d_x, size_t N, size_t C, size_t H, + size_t W, cudaStream_t cuda_stream) { + DxMul<<>>(N, C, H * W, batch_std, running_std, d_x); +} + +template void CalBatchNormFold2GradNotFreezeDxMul(const float *batch_std, const float *running_std, float *d_x, + size_t N, size_t C, size_t H, size_t W, + cudaStream_t cuda_stream); diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cuh new file mode 100644 index 0000000000..c3ce08dfd0 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold2_impl.cuh @@ -0,0 +1,40 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_BATCHNORMFOLD2_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_BATCHNORMFOLD2_H_ + +#include "device/gpu/cuda_common.h" +template +void BatchNormFold2Forward(const T *x, const T *beta, const T *gamma, const T *batch_std, const T *batch_mean, + const T *running_std, const T *running_mean, const int *global_step, T *y, int freeze_bn, + size_t N, size_t C, size_t H, size_t W, cudaStream_t cuda_stream); +template +void CalBatchNormFold2GradNotFreeze(const T *d_beta, const T *reduce_x, const T *batch_mean, const T *batch_std, + const T *running_mean, const T *running_std, const T *gamma, T *d_gamma, + T *d_batch_mean, T *d_batch_std, size_t C, cudaStream_t cuda_stream); +template +void CalBatchNormFold2GradFreeze(const T *d_beta, const T *reduce_x, const T *batch_mean, const T *batch_std, + const T *running_mean, const T *running_std, const T *gamma, T *d_gamma, + T *d_batch_mean, T *d_batch_std, size_t C, cudaStream_t cuda_stream); +template +void BatchNormFold2GradReduce(const T *dout, const T *x, T *d_beta, T *tmp, T *reduce_x, T *tmp2, T *tmp_x, size_t N, + size_t C, size_t H, size_t W, cudaStream_t cuda_stream); + +template +void CalBatchNormFold2GradNotFreezeDxMul(const T *batch_std, const T *running_std, T *d_x, size_t N, size_t C, size_t H, + size_t W, cudaStream_t cuda_stream); +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_BATCHNORMFOLD2_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cu new file mode 100755 index 0000000000..ddc2803f56 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cu @@ -0,0 +1,88 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "batchnorm_fold_impl.cuh" +#include "device/gpu/cuda_common.h" + +template +__global__ void UpdateRunningStd(int channel_size, const double epsilon, T* running_std) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < channel_size; i += blockDim.x * gridDim.x) { + running_std[i] = sqrtf(running_std[i] + epsilon); + } + return; +} + +template +__global__ void UpdateBatchStd(int channel_size, T* batch_std) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < channel_size; i += blockDim.x * gridDim.x) { + batch_std[i] = 1 / batch_std[i]; + } + return; +} + +template +__global__ void CalDx(const T* d_batch_mean, const T* d_batch_std, const T* x, const T* batch_mean, const T* batch_std, + int batch_size, int channel_size, int height, int width, T* dx) { + int n = batch_size * channel_size * height * width; + int normal_size = batch_size * height * width; + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < n; i += blockDim.x * gridDim.x) { + int channel_index = i / (height * width) % channel_size; + dx[i] = d_batch_mean[channel_index] / normal_size + + d_batch_std[channel_index] * (x[i] - batch_mean[channel_index]) / batch_std[channel_index] / normal_size; + } + return; +} + +template +void CalUpdateRunningStd(int channel_size, double epsilon, T* running_std, cudaStream_t cuda_stream) { + UpdateRunningStd<<>>(channel_size, epsilon, running_std); + return; +} + +template void CalUpdateRunningStd(int channel_size, double epsilon, float* running_std, + cudaStream_t cuda_stream); + +template +void CalUpdateBatchStd(int channel_size, T* batch_std, cudaStream_t cuda_stream) { + UpdateBatchStd<<>>(channel_size, batch_std); + return; +} + +template void CalUpdateBatchStd(int channel_size, float* batch_std, cudaStream_t cuda_stream); + +template +void CalBatchNormFoldGrad(const T* d_batch_mean, const T* d_batch_std, const T* x, const T* batch_mean, + const T* batch_std, int batch_size, int channel_size, int height, int width, T* dx, + cudaStream_t cuda_stream) { + CalDx<<>>( + d_batch_mean, d_batch_std, x, batch_mean, batch_std, batch_size, channel_size, height, width, dx); +} + +template void CalBatchNormFoldGrad(const float* d_batch_mean, const float* d_batch_std, const float* x, + const float* batch_mean, const float* batch_std, int batch_size, + int channel_size, int height, int width, float* dx, cudaStream_t cuda_stream); + +template +void ThrustFillWith(T* array, int size, T tofill, cudaStream_t cuda_stream) { + thrust::device_ptr dev_ptr(array); + thrust::fill(thrust::cuda::par.on(cuda_stream), dev_ptr, dev_ptr + size, tofill); +} + +template void ThrustFillWith(float* array, int size, float tofill, cudaStream_t cuda_stream); + diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cuh new file mode 100755 index 0000000000..d7ad76c5ad --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/batchnorm_fold_impl.cuh @@ -0,0 +1,32 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_BATCHNORM_FOLD_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_BATCHNORM_FOLD_H_ + +template +void CalUpdateRunningStd(int channel_size, double epsilon, T* running_std, cudaStream_t cuda_stream); + +template +void CalUpdateBatchStd(int channel_size, T* batch_std, cudaStream_t cuda_stream); + +template +void CalBatchNormFoldGrad(const T* d_batch_mean, const T* d_batch_std, const T* x, const T* batch_mean, + const T* batch_std, int batch_size, int channel_size, int height, int width, T* dx, + cudaStream_t cuda_stream); +template +void ThrustFillWith(T* array, int size, T tofill, cudaStream_t cuda_stream); +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_BATCHNORM_FOLD_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/concatv2_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/concatv2_impl.cu index ed330f6e0a..fa10494d9c 100755 --- a/mindspore/ccsrc/kernel/gpu/cuda_impl/concatv2_impl.cu +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/concatv2_impl.cu @@ -41,3 +41,4 @@ template void CalConcatV2(const size_t size, const int w1, const int w2, const i int* output, cudaStream_t cuda_stream); template void CalConcatV2(const size_t size, const int w1, const int w2, const half* input_1, const half* input_2, half* output, cudaStream_t cuda_stream); + diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cu new file mode 100755 index 0000000000..ac2f99ed9a --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cu @@ -0,0 +1,66 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "correction_mul_impl.cuh" +#include "device/gpu/cuda_common.h" + +template +__global__ void CorrectionMul(const T* weight, const T* gamma, const T* running_std, const int batchsize, const int chw, + T* output) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < batchsize * chw; i += blockDim.x * gridDim.x) { + int n = i / chw; + output[i] = weight[i] * gamma[n] / running_std[n]; + } + return; +} + +template +__global__ void Mul(int N, const T* a, const T* b, T* c) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < N; i += blockDim.x * gridDim.x) { + c[i] = a[i] * b[i]; + } + return; +} + +template +__global__ void Reduce(int N, int CHW, const T* tmp, const T* running_std, T* d_gamma) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < N; i += blockDim.x * gridDim.x) { + d_gamma[i] = thrust::reduce(thrust::seq, tmp + i * CHW, tmp + (i + 1) * CHW, 0.f, thrust::plus()); + d_gamma[i] = d_gamma[i] / running_std[i]; + } + return; +} + +template +void CalCorrectionMul(const T* weight, const T* gamma, const T* running_std, int N, int C, int H, int W, T* output, + cudaStream_t cuda_stream) { + CorrectionMul<<>>(weight, gamma, running_std, N, C * H * W, + output); +} + +template void CalCorrectionMul(const float* weight, const float* gamma, const float* running_std, int N, int C, + int H, int W, float* output, cudaStream_t cuda_stream); + +template +void CalCorrectionMulGrad(const T* d_out, const T* weight, const T* running_std, int N, int C, int H, int W, T* d_gamma, + T* tmp, cudaStream_t cuda_stream) { + Mul<<>>(N * C * H * W, d_out, weight, tmp); + Reduce<<>>(N, C * H * W, tmp, running_std, d_gamma); +} + +template void CalCorrectionMulGrad(const float* d_out, const float* weight, const float* running_std, int N, + int C, int H, int W, float* d_gamma, float* tmp, cudaStream_t cuda_stream); diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cuh new file mode 100644 index 0000000000..176c063dc8 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/correction_mul_impl.cuh @@ -0,0 +1,27 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_CORRECTIONMUL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_CORRECTIONMUL_H_ + +template +void CalCorrectionMul(const T* weight, const T* gamma, const T* running_std, int batch_size, int channel_size, + int height, int width, T* output, cudaStream_t cuda_stream); + +template +void CalCorrectionMulGrad(const T* d_out, const T* weight, const T* running_std, int batch_size, int channel_size, + int height, int width, T* d_gamma, T* tmp, cudaStream_t cuda_stream); +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_CORRECTIONMUL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cu new file mode 100644 index 0000000000..a3d2e3558c --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cu @@ -0,0 +1,47 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cross_entropy_cuda_impl.cuh" +#include "include/cuda_runtime.h" + +__global__ void CalCrossEntropyWithGradKernel(const float *softmax_logits, const float *log_softmax_logits, + const float *labels, const int batch_size, const int num_classes, + float *loss, float *dx) { + extern __shared__ float loss_shared[]; + const float mean_scale = 1.0f / static_cast(batch_size); + + loss_shared[threadIdx.x] = 0; + for (int i = threadIdx.x * num_classes; i < (threadIdx.x + 1) * num_classes; ++i) { + loss_shared[threadIdx.x] -= log_softmax_logits[i] * labels[i]; + dx[i] = (softmax_logits[i] - labels[i]) * mean_scale; + } + __syncthreads(); + if (threadIdx.x == 0) { + *loss = 0; + for (int i = 0; i < batch_size; i++) { + *loss += loss_shared[i]; + } + *loss *= mean_scale; + } +} + +void CalCrossEntropyWithGrad(const float *softmax_logits, const float *log_softmax_logits, const float *labels, + const int batch_size, const int num_classes, float *loss, float *dx, + cudaStream_t cuda_stream) { + CalCrossEntropyWithGradKernel<<<1, batch_size, batch_size * sizeof(float), cuda_stream>>>( + softmax_logits, log_softmax_logits, labels, batch_size, num_classes, loss, dx); +} diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cuh new file mode 100644 index 0000000000..25b1624a46 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/cross_entropy_cuda_impl.cuh @@ -0,0 +1,26 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_CROSSENTROPYCUDAIMPL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_CROSSENTROPYCUDAIMPL_H_ + +#include "device/gpu/cuda_common.h" + +void CalCrossEntropyWithGrad(const float *softmax_logits, const float *log_softmax_logits, const float *labels, + const int batch_size, const int num_classes, float *loss, float *dx, + cudaStream_t cuda_stream); + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_CROSSENTROPYCUDAIMPL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cu new file mode 100644 index 0000000000..bffa73fb76 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cu @@ -0,0 +1,47 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "dropout_impl.cuh" +#include "include/cuda_runtime.h" + +__global__ void DropoutForwardKernel(const float *input, float *mask, float *output, size_t num_count, + float drop_prob) { + float scale = 1.f / (1.f - drop_prob); + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < num_count; i += blockDim.x * gridDim.x) { + mask[i] = mask[i] > drop_prob; + output[i] = scale * input[i] * mask[i]; + } +} + +void DropoutForward(const float *input, float *mask, float *output, size_t num_count, float drop_prob, + cudaStream_t cuda_stream) { + DropoutForwardKernel<<>>(input, mask, output, num_count, + drop_prob); +} + +__global__ void DropoutBackwardKernel(const float *dy, const float *mask, float *dx, size_t num_count, + float drop_prob) { + float scale = 1.f / (1.f - drop_prob); + for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < num_count; i += blockDim.x * gridDim.x) { + dx[i] = scale * dy[i] * mask[i]; + } +} + +void DropoutBackward(const float *dy, const float *mask, float *dx, size_t num_count, float drop_prob, + cudaStream_t cuda_stream) { + DropoutBackwardKernel<<>>(dy, mask, dx, num_count, drop_prob); +} diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cuh new file mode 100644 index 0000000000..9aa05d6a08 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/dropout_impl.cuh @@ -0,0 +1,26 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_DROPOUT_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_DROPOUT_H_ + +#include "device/gpu/cuda_common.h" +void DropoutForward(const float *input, float *mask, float *output, size_t num_count, float drop_prob, + cudaStream_t cuda_stream); +void DropoutBackward(const float *dy, const float *mask, float *dx, size_t num_count, float drop_prob, + cudaStream_t cuda_stream); + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_DROPOUT_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cu new file mode 100644 index 0000000000..7b09256e1d --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cu @@ -0,0 +1,133 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "device/gpu/cuda_common.h" +#include "fake_quant_impl.cuh" + +__global__ void FakeQuantize(const float* input, float* output, const int size, const float* nudge_min, + const float* nudge_max, const float* scale, bool symmetric) { + float input_x = 0.f; + int nudge_input = 0; + + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < size; i += blockDim.x * gridDim.x) { + input_x = input[i]; + // clamp input x + if (input_x < nudge_min[0]) { + input_x = nudge_min[0]; + } + if (input_x > nudge_max[0]) { + input_x = nudge_max[0]; + } + // clamp shift + nudge_input = floor((input_x - nudge_min[0]) / scale[0] + 0.5f); + + // quantize + output[i] = nudge_input * scale[0] + nudge_min[0]; + } + return; +} + +__global__ void FakeQuantizeGrad(const float* input, const float* gradient, float* output, const int size, + const float* nudge_min, const float* nudge_max) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < size; i += blockDim.x * gridDim.x) { + if (input[i] < nudge_min[0] || input[i] > nudge_max[0]) { + output[i] = 0; + } else { + output[i] = gradient[i]; + } + } + return; +} + +__global__ void NudgeMinMax(const float* input_min, const float* input_max, const float quant_min, + const float quant_max, float* nudge_min, float* nudge_max, float* scale) { + float zp_from_min = 0.f; + if ((quant_max - quant_min) == 0 || (*input_max - *input_min) == 0) { + *scale = 0.f; + zp_from_min = 0.f; + } else { + *scale = (*input_max - *input_min) / (quant_max - quant_min); + zp_from_min = quant_min - *input_min / *scale; + } + + float nudge_zp = 0.f; + if (zp_from_min <= quant_min) { + nudge_zp = quant_min; + } else if (zp_from_min >= quant_max) { + nudge_zp = quant_max; + } else { + nudge_zp = round(zp_from_min); + } + + *nudge_min = (quant_min - nudge_zp) * (*scale); + *nudge_max = (quant_max - nudge_zp) * (*scale); + return; +} + +__global__ void UpdateInputMinMaxWithEMA(float* input_min, float* input_max, const float min, const float max, + const float decay) { + *input_min = decay * (min) + (1 - decay) * (*input_min); + *input_min = *input_min > 0 ? 0 : *input_min; + *input_max = decay * (max) + (1 - decay) * (*input_max); + *input_max = *input_max < 0 ? 0 : *input_max; + return; +} + +__global__ void UpdateInputMinMax(float* input_min, float* input_max, const float min, const float max) { + *input_min = min; + *input_max = max; +} + +void CalFakeQuantize(const float* input, float* output, const int size, const float* nudge_min, const float* nudge_max, + const float* scale, bool symmetric, cudaStream_t cuda_stream) { + FakeQuantize<<>>(input, output, size, nudge_min, nudge_max, scale, + symmetric); + return; +} + +void CalFakeQuantizeGrad(const float* input, const float* gradient, float* output, const int size, + const float* nudge_min, const float* nudge_max, cudaStream_t cuda_stream) { + FakeQuantizeGrad<<>>(input, gradient, output, size, nudge_min, + nudge_max); + return; +} + +void CalNudge(const float* input_min, const float* input_max, const float quant_min, const float quant_max, + float* nudge_min, float* nudge_max, float* scale, cudaStream_t cuda_stream) { + NudgeMinMax<<<1, 1>>>(input_min, input_max, quant_min, quant_max, nudge_min, nudge_max, scale); + return; +} + +void CalMinMax(float* input, float* input_min, float* input_max, const int size, const float ema_decay, const bool ema, + cudaStream_t cuda_stream) { + float minel = 0.f; + float maxel = 0.f; + thrust::pair, thrust::device_ptr> tuple; + tuple = thrust::minmax_element(thrust::device_pointer_cast(input), thrust::device_pointer_cast(input) + size); + minel = tuple.first[0]; + maxel = tuple.second[0]; + + if (ema) { + UpdateInputMinMaxWithEMA<<<1, 1>>>(input_min, input_max, minel, maxel, ema_decay); + } else { + UpdateInputMinMax<<<1, 1>>>(input_min, input_max, minel, maxel); + } + return; +} + diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cuh new file mode 100644 index 0000000000..c88c1f79e2 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_impl.cuh @@ -0,0 +1,32 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ + +void CalFakeQuantize(const float* input, float* output, const int size, const float* nudge_min, const float* nudge_max, + const float* scale, bool symmetric, cudaStream_t cuda_stream); + +void CalFakeQuantizeGrad(const float* input, const float* gradient, float* output, const int size, + const float* nudge_min, const float* nudge_max, cudaStream_t cuda_stream); + +void CalNudge(const float* input_min, const float* input_max, const float quant_min, const float quant_max, + float* nudge_min, float* nudge_max, float* scale, cudaStream_t cuda_stream); + +void CalMinMax(float* input, float* input_min, float* input_max, const int size, const float ema_decay, const bool ema, + cudaStream_t cuda_stream); + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cu new file mode 100644 index 0000000000..09153bf28f --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cu @@ -0,0 +1,174 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "fake_quant_per_channel_impl.cuh" +#include "device/gpu/cuda_common.h" + +/** + * Find the nudge min, max and scale value as output. + * @param input_min array + * @param input_max array + * @param quant_min 1 << bit -1 + * @param quant_max 0 + * @param nudge_min array + * @param nudge_max array + * @param scale array + * @param channel_num + * @return + */ +__global__ void NudgeMinMaxPerChannel(const float* input_min, const float* input_max, const float quant_min, + const float quant_max, float* nudge_min, float* nudge_max, float* scale, + int channel_num) { + float zp_from_min = 0.f; + float nudge_zp = 0.f; + + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < channel_num; i += blockDim.x * gridDim.x) { + if ((quant_max - quant_min) == 0 || (input_max[i] - input_min[i]) == 0) { + scale[i] = 0.f; + zp_from_min = 0.f; + } else { + scale[i] = (input_max[i] - input_min[i]) / (quant_max - quant_min); + zp_from_min = quant_min - input_min[i] / scale[i]; + } + + if (zp_from_min <= quant_min) { + nudge_zp = quant_min; + } else if (zp_from_min >= quant_max) { + nudge_zp = quant_max; + } else { + nudge_zp = round(zp_from_min); + } + + nudge_min[i] = (quant_min - nudge_zp) * (scale[i]); + nudge_max[i] = (quant_max - nudge_zp) * (scale[i]); + } +} + +void CalNudgePerChannel(const float* input_min, const float* input_max, const float quant_min, const float quant_max, + float* nudge_min, float* nudge_max, float* scale, const int channel_num, + cudaStream_t cuda_stream) { + NudgeMinMaxPerChannel<<>>( + input_min, input_max, quant_min, quant_max, nudge_min, nudge_max, scale, channel_num); +} + +/** + * Calulate fake quant output accroding by nudge min, nudge max, nudge scale. + * @param input - array + * @param output - array + * @param total_size - int, purpose for cal the per chanel number in filters + * @param channel_size - int, purpose for cal the per channel number in filters + * @param nudge_min - array + * @param nudge_max - array + * @param scale - array + * @return + */ +__global__ void FakeQuantizePerChannel(const float* input, float* output, const int total_size, const int channel_size, + const float* nudge_min, const float* nudge_max, const float* scale, + bool symmetric) { + float input_x = 0.f; + int nudge_input = 0; + int channel_idx = 0; + int per_channel_num = total_size / channel_size; + + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < total_size; i += blockDim.x * gridDim.x) { + input_x = input[i]; + channel_idx = floor(static_cast(i) / static_cast(per_channel_num)); + // clamp input x + if (input_x < nudge_min[channel_idx]) { + input_x = nudge_min[channel_idx]; + } + if (input_x > nudge_max[channel_idx]) { + input_x = nudge_max[channel_idx]; + } + // clamp shift + nudge_input = floor((input_x - nudge_min[channel_idx]) / scale[channel_idx] + 0.5f); + + // quantize + output[i] = nudge_input * scale[channel_idx] + nudge_min[channel_idx]; + } +} + +void CalFakeQuantizePerChannel(const float* input, float* output, const int total_size, const int channel_size, + const float* nudge_min, const float* nudge_max, const float* scale, bool symmetric, + cudaStream_t cuda_stream) { + FakeQuantizePerChannel<<>>( + input, output, total_size, channel_size, nudge_min, nudge_max, scale, symmetric); +} + +/** + * UpdateInputMinMaxPerChannel or UpdateInputMinMaxPerChannel With EMA. + * @param input_min + * @param input_max + * @param min + * @param max + * @return + */ +__global__ void UpdateInputMinMaxPerChannel(float* input_min, float* input_max, float* input, int channels, + int per_channel_nums, bool ema, float ema_decay) { + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < channels; i += blockDim.x * gridDim.x) { + thrust::pair sum = + thrust::minmax_element(thrust::device, input + i * per_channel_nums, input + per_channel_nums * (i + 1)); + if (ema) { + input_min[i] = ema_decay * sum.first[0] + (1 - ema_decay) * input_min[i]; + input_max[i] = ema_decay * sum.second[0] + (1 - ema_decay) * input_max[i]; + } else { + input_min[i] = sum.first[0]; + input_max[i] = sum.second[0]; + } + } +} + +__global__ void UpdateInputMinMaxPerChannelWithEMA(float* input_min, float* input_max, float min, float max, + const float decay) { + *input_min = decay * (min) + (1 - decay) * (*input_min); + *input_max = decay * (max) + (1 - decay) * (*input_max); +} + +void CalMinMaxPerChannel(float* input, float* input_min, float* input_max, const int total_size, const int channel_size, + const float ema_decay, const bool ema, cudaStream_t cuda_stream) { + int per_channel_num = total_size / channel_size; + UpdateInputMinMaxPerChannel<<>>( + input_min, input_max, input, channel_size, per_channel_num, ema, ema_decay); +} + +__global__ void FakeQuantizePerChannelGrad(const float* input, const float* gradient, float* output, + const int total_size, const int channel_size, const float* nudge_min, + const float* nudge_max) { + int channel_idx = 0; + int per_channel_num = total_size / channel_size; + + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < total_size; i += blockDim.x * gridDim.x) { + channel_idx = floor(static_cast(i) / static_cast(per_channel_num)); + if (input[i] < nudge_min[channel_idx] || input[i] > nudge_max[channel_idx]) { + output[i] = 0; + } else { + output[i] = gradient[i]; + } + } +} + +void CalFakeQuantizePerChannelGrad(const float* input, const float* gradient, float* output, const int total_num, + const int channel_num, const float* nudge_min, const float* nudge_max, + cudaStream_t cuda_stream) { + FakeQuantizePerChannelGrad<<>>( + input, gradient, output, total_num, channel_num, nudge_min, nudge_max); +} + diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cuh new file mode 100644 index 0000000000..3dff7156a7 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cuh @@ -0,0 +1,35 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ + +void CalNudgePerChannel(const float* input_min, const float* input_max, const float quant_min, const float quant_max, + float* nudge_min, float* nudge_max, float* scale, const int channel_num, + cudaStream_t cuda_stream); + +void CalFakeQuantizePerChannel(const float* input, float* output, const int total_num, const int channel_num, + const float* nudge_min, const float* nudge_max, const float* scale, bool symmetric, + cudaStream_t cuda_stream); + +void CalMinMaxPerChannel(float* input, float* input_min, float* input_max, const int total_num, const int channel_num, + const float ema_decay, const bool ema, cudaStream_t cuda_stream); + +void CalFakeQuantizePerChannelGrad(const float* input, const float* gradient, float* output, const int total_num, + const int channel_num, const float* nudge_min, const float* nudge_max, + cudaStream_t cuda_stream); + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMP_FAKEQUANTIZE_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/gather.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/gather.cuh old mode 100755 new mode 100644 index dae2115a91..a2aab89fb1 --- a/mindspore/ccsrc/kernel/gpu/cuda_impl/gather.cuh +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/gather.cuh @@ -16,7 +16,7 @@ #ifndef MINDSPORE_GATHER_GPU_CU_H #define MINDSPORE_GATHER_GPU_CU_H -template +template void Gather(T *input, S *indices, T *output, size_t output_dim0, size_t output_dim1, size_t output_dim2, size_t input_dim1, cudaStream_t stream); diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cu new file mode 100644 index 0000000000..f07a820e75 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cu @@ -0,0 +1,42 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "kernel/gpu/cuda_impl/select_impl.cuh" + +template +__global__ void Select(const size_t size, const bool* cond, const T* input_x, const T* input_y, T* output) { + for (size_t pos = blockIdx.x * blockDim.x + threadIdx.x; pos < (size); pos += blockDim.x * gridDim.x) { + output[pos] = cond[pos] ? input_x[pos] : input_y[pos]; + } + return; +} + +template +void CalSelect(const size_t size, const bool* cond, const T* input_x, const T* input_y, T* output, + cudaStream_t cuda_stream) { + Select<<>>(size, cond, input_x, input_y, output); + return; +} + +template void CalSelect(const size_t size, const bool* cond, const float* input_X, const float* input_y, + float* output, cudaStream_t cuda_stream); +template void CalSelect(const size_t size, const bool* cond, const int* input_X, const int* input_y, int* output, + cudaStream_t cuda_stream); +template void CalSelect(const size_t size, const bool* cond, const half* input_X, const half* input_y, + half* output, cudaStream_t cuda_stream); diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cuh new file mode 100644 index 0000000000..da2d7d9a7f --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/select_impl.cuh @@ -0,0 +1,25 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SELECT_IMPL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SELECT_IMPL_H_ + +#include "device/gpu/cuda_common.h" + +template +void CalSelect(const size_t size, const bool* cond, const T* input_x, const T* input_y, T* output, + cudaStream_t cuda_stream); +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SELECT_IMPL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cu b/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cu new file mode 100755 index 0000000000..b549c5bd4e --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cu @@ -0,0 +1,77 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "sparse_cross_entropy_cuda_impl.cuh" +#include "include/cuda_runtime.h" + +template +__global__ void CalCrossEntropyKernel(const float *logits, T *labels, const int batch_size, const int class_num, + float *loss) { + float total_loss = 0.0; + float epsilon = 1e-6; + for (int i = 0; i < batch_size; ++i) { + float logit = logits[i * class_num + labels[i]]; + if (logit <= 0) { + logit += epsilon; + } + float single_loss = -logf(logit); + total_loss += single_loss; + } + + total_loss /= batch_size; + loss[0] = total_loss; + return; +} + +template +__global__ void CalCrossEntropyGradKernel(const float *logits, T *labels, const int batch_size, const int class_num, + float *grad) { + for (int i = 0; i < batch_size; i++) { + for (int j = blockIdx.x * blockDim.x + threadIdx.x; j < class_num; j += blockDim.x * gridDim.x) { + if (labels[i] == j) { + grad[i * class_num + j] = (logits[i * class_num + j] - 1) / batch_size; + } else { + grad[i * class_num + j] = logits[i * class_num + j] / batch_size; + } + } + } + return; +} + +template +void CalCrossEntropy(const float *logits, T *labels, const int batch_size, const int class_num, float *loss, + cudaStream_t cuda_stream) { + CalCrossEntropyKernel<<<1, 1, 0, cuda_stream>>>(logits, labels, batch_size, class_num, loss); + return; +} + +template +void CalCrossEntropyGrad(const float *logits, T *labels, const int batch_size, const int class_num, float *grad, + cudaStream_t cuda_stream) { + CalCrossEntropyGradKernel<<>>(logits, labels, batch_size, + class_num, grad); + return; +} + +template void CalCrossEntropy(const float *logits, int *labels, const int batch_size, const int class_num, + float *loss, cudaStream_t cuda_stream); +template void CalCrossEntropy(const float *logits, uint64_t *labels, const int batch_size, + const int class_num, float *loss, cudaStream_t cuda_stream); +template void CalCrossEntropyGrad(const float *logits, int *labels, const int batch_size, const int class_num, + float *grad, cudaStream_t cuda_stream); +template void CalCrossEntropyGrad(const float *logits, uint64_t *labels, const int batch_size, + const int class_num, float *grad, cudaStream_t cuda_stream); diff --git a/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cuh b/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cuh new file mode 100755 index 0000000000..d16131470c --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/cuda_impl/sparse_cross_entropy_cuda_impl.cuh @@ -0,0 +1,30 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SPARSECROSSENTROPYCUDAIMPL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SPARSECROSSENTROPYCUDAIMPL_H_ + +#include "device/gpu/cuda_common.h" + +template +void CalCrossEntropy(const float *logits, T *labels, const int batch_size, const int class_num, float *loss, + cudaStream_t cuda_stream); + +template +void CalCrossEntropyGrad(const float *logits, T *labels, const int batch_size, const int class_num, float *grad, + cudaStream_t cuda_stream); + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CUDA_IMPL_SPARSECROSSENTROPYCUDAIMPL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/nccl/nccl_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/nccl/nccl_gpu_kernel.h index 54e4eb9213..4ea332784d 100644 --- a/mindspore/ccsrc/kernel/gpu/nccl/nccl_gpu_kernel.h +++ b/mindspore/ccsrc/kernel/gpu/nccl/nccl_gpu_kernel.h @@ -52,7 +52,8 @@ class NcclGpuKernel : public GpuKernel { nccl_reduce_type_(ncclSum), input_size_(0), output_size_(0), - collective_handle_(nullptr) {} + collective_handle_(nullptr), + comm_stream_(nullptr) {} ~NcclGpuKernel() override = default; const std::vector &GetInputSizeList() const override { return input_size_list_; } @@ -63,34 +64,33 @@ class NcclGpuKernel : public GpuKernel { T *input_addr = GetDeviceAddress(inputs, 0); T *output_addr = GetDeviceAddress(outputs, 0); + cudaStream_t stream = comm_stream_ ? comm_stream_ : reinterpret_cast(stream_ptr); switch (nccl_kernel_type_) { case NCCL_ALL_REDUCE: { auto all_reduce_funcptr = reinterpret_cast(dlsym(const_cast(collective_handle_), "AllReduce")); MS_EXCEPTION_IF_NULL(all_reduce_funcptr); - CHECK_NCCL_RET_WITH_EXCEPT( - (*all_reduce_funcptr)(input_addr, output_addr, output_size_ / sizeof(T), nccl_data_type_, nccl_reduce_type_, - reinterpret_cast(stream_ptr)), - "ncclAllReduce failed"); + CHECK_NCCL_RET_WITH_EXCEPT((*all_reduce_funcptr)(input_addr, output_addr, output_size_ / sizeof(T), + nccl_data_type_, nccl_reduce_type_, stream), + "ncclAllReduce failed"); break; } case NCCL_ALL_GATHER: { auto all_gather_funcptr = reinterpret_cast(dlsym(const_cast(collective_handle_), "AllGather")); MS_EXCEPTION_IF_NULL(all_gather_funcptr); - CHECK_NCCL_RET_WITH_EXCEPT((*all_gather_funcptr)(input_addr, output_addr, input_size_ / sizeof(T), - nccl_data_type_, reinterpret_cast(stream_ptr)), - "ncclAllGather failed"); + CHECK_NCCL_RET_WITH_EXCEPT( + (*all_gather_funcptr)(input_addr, output_addr, input_size_ / sizeof(T), nccl_data_type_, stream), + "ncclAllGather failed"); break; } case NCCL_REDUCE_SCATTER: { auto reduce_scatter_funcptr = reinterpret_cast(dlsym(const_cast(collective_handle_), "ReduceScatter")); MS_EXCEPTION_IF_NULL(reduce_scatter_funcptr); - CHECK_NCCL_RET_WITH_EXCEPT( - (*reduce_scatter_funcptr)(input_addr, output_addr, output_size_ / sizeof(T), nccl_data_type_, - nccl_reduce_type_, reinterpret_cast(stream_ptr)), - "ncclReduceScatter failed"); + CHECK_NCCL_RET_WITH_EXCEPT((*reduce_scatter_funcptr)(input_addr, output_addr, output_size_ / sizeof(T), + nccl_data_type_, nccl_reduce_type_, stream), + "ncclReduceScatter failed"); break; } default: { @@ -124,6 +124,12 @@ class NcclGpuKernel : public GpuKernel { InferCommType(kernel_node); collective_handle_ = device::gpu::CollectiveInitializer::instance().collective_handle(); MS_EXCEPTION_IF_NULL(collective_handle_); + + auto comm_stream_attr = AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stream_id"); + if (comm_stream_attr) { + comm_stream_ = reinterpret_cast(GetValue(comm_stream_attr)); + MS_EXCEPTION_IF_NULL(comm_stream_); + } return true; } @@ -167,6 +173,7 @@ class NcclGpuKernel : public GpuKernel { std::vector output_size_list_; std::vector workspace_size_list_; const void *collective_handle_; + cudaStream_t comm_stream_; }; } // namespace kernel } // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/nn/conv2d_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/nn/conv2d_gpu_kernel.h index 7a4adff970..75b2a97cf8 100644 --- a/mindspore/ccsrc/kernel/gpu/nn/conv2d_gpu_kernel.h +++ b/mindspore/ccsrc/kernel/gpu/nn/conv2d_gpu_kernel.h @@ -113,9 +113,24 @@ class Conv2dGpuFwdKernel : public GpuKernel { CHECK_CUDNN_RET_WITH_EXCEPT(cudnnSetConvolutionGroupCount(conv_desc_, group_), "cudnnSetConvGroupCount failed"); pad_height_ = GetAttr(kernel_node, "pad"); pad_width_ = pad_height_; - stride_ = GetAttr(kernel_node, "stride"); - dilation_ = GetAttr(kernel_node, "dilation"); pad_mode_ = GetAttr(kernel_node, "pad_mode"); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, "stride"); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, "dilation"); + if (stride_ori.size() != 4 || stride_ori[2] != stride_ori[3]) { + MS_LOG(EXCEPTION) << "conv2d only support equal stride, and stride must be 4d!"; + } + if (stride_ori[0] != 1 || stride_ori[1] != 1) { + MS_LOG(EXCEPTION) << "conv2d stride only support 1 in N axis and C axis!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != dilation_ori[3]) { + MS_LOG(EXCEPTION) << "conv2d only support equal dilation, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "conv2d dilation only support 1 in N axis and C axis!"; + } + stride_ = stride_ori[2]; + dilation_ = dilation_ori[2]; + cudnnTensorDescriptor_t input_descriptor_real = nullptr; if (pad_mode_ == kSamePadModeUpperCase || pad_mode_ == kSamePadModeLowerCase) { SetPad(in_shape, kernel_node); diff --git a/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_filter_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_filter_gpu_kernel.h index f8afad4f84..e481fd448e 100644 --- a/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_filter_gpu_kernel.h +++ b/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_filter_gpu_kernel.h @@ -116,9 +116,20 @@ class ConvGradFilterGpuBkwKernel : public GpuKernel { pad_height_ = GetAttr(kernel_node, "pad"); pad_width_ = pad_height_; - stride_ = GetAttr(kernel_node, "stride"); - dilation_ = GetAttr(kernel_node, "dilation"); pad_mode_ = GetAttr(kernel_node, "pad_mode"); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, "stride"); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, "dilation"); + if (stride_ori.size() != 2 || stride_ori[0] != stride_ori[1]) { + MS_LOG(EXCEPTION) << "ConvGradFilterGpuBkwKernel only support equal stride, and stride must be 2d!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != dilation_ori[3]) { + MS_LOG(EXCEPTION) << "ConvGradFilterGpuBkwKernel only support equal dilation, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "ConvGradFilterGpuBkwKernel dilation only support 1 in N axis and C axis!"; + } + stride_ = stride_ori[0]; + dilation_ = dilation_ori[2]; cudnnTensorDescriptor_t x_desc_real = nullptr; if (pad_mode_ == kSamePadModeUpperCase || pad_mode_ == kSamePadModeLowerCase) { SetPad(in_shape, kernel_node); diff --git a/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_input_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_input_gpu_kernel.h index be7739981d..008abcc658 100644 --- a/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_input_gpu_kernel.h +++ b/mindspore/ccsrc/kernel/gpu/nn/conv2d_grad_input_gpu_kernel.h @@ -117,9 +117,20 @@ class ConvGradInputGpuBkwKernel : public GpuKernel { pad_height_ = GetAttr(kernel_node, "pad"); pad_width_ = pad_height_; - stride_ = GetAttr(kernel_node, "stride"); - dilation_ = GetAttr(kernel_node, "dilation"); pad_mode_ = GetAttr(kernel_node, "pad_mode"); + auto stride_ori = AnfAlgo::GetNodeAttr>(kernel_node, "stride"); + auto dilation_ori = AnfAlgo::GetNodeAttr>(kernel_node, "dilation"); + if (stride_ori.size() != 2 || stride_ori[0] != stride_ori[1]) { + MS_LOG(EXCEPTION) << "ConvGradInputGpuBkwKernel only support equal stride, and stride must be 2d!"; + } + if (dilation_ori.size() != 4 || dilation_ori[2] != dilation_ori[3]) { + MS_LOG(EXCEPTION) << "ConvGradInputGpuBkwKernel only support equal dilation, and dilation must be 4d!"; + } + if (dilation_ori[0] != 1 || dilation_ori[1] != 1) { + MS_LOG(EXCEPTION) << "ConvGradInputGpuBkwKernel dilation only support 1 in N axis and C axis!"; + } + stride_ = stride_ori[0]; + dilation_ = dilation_ori[2]; cudnnTensorDescriptor_t dx_desc_real = nullptr; if (pad_mode_ == kSamePadModeUpperCase || pad_mode_ == kSamePadModeLowerCase) { SetPad(input_shape, kernel_node); diff --git a/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.cc new file mode 100644 index 0000000000..937f38137f --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.cc @@ -0,0 +1,100 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/nn/dropout_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/dropout_impl.cuh" + +namespace mindspore { +namespace kernel { +DropoutGpuFwdKernel::DropoutGpuFwdKernel() + : cudnn_handle_(nullptr), + is_null_input_(false), + num_count_(0), + drop_prob_(0.0), + states_init_(false), + mask_generator_(nullptr) {} + +DropoutGpuFwdKernel::~DropoutGpuFwdKernel() { DestroyResource(); } + +const std::vector &DropoutGpuFwdKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &DropoutGpuFwdKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &DropoutGpuFwdKernel::GetWorkspaceSizeList() const { return workspace_size_list_; } + +bool DropoutGpuFwdKernel::Init(const CNodePtr &kernel_node) { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 1) { + MS_LOG(EXCEPTION) << "Argument number is " << input_num << ", but DropoutGpuFwdKernel needs 1."; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + is_null_input_ = CHECK_NULL_INPUT(input_shape); + if (is_null_input_) { + InitSizeLists(); + return true; + } + + num_count_ = 1; + for (size_t x : input_shape) { + num_count_ *= x; + } + drop_prob_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("drop_prob")); + + InitSizeLists(); + return true; +} + +void DropoutGpuFwdKernel::InitResource() { + cudnn_handle_ = device::gpu::GPUDeviceManager::GetInstance().GetCudnnHandle(); +} + +void DropoutGpuFwdKernel::DestroyResource() noexcept {} + +void DropoutGpuFwdKernel::InitSizeLists() { + size_t input_size = num_count_ * sizeof(float); + size_t workspace_size = 0; + input_size_list_.push_back(input_size); + output_size_list_.push_back(input_size); // output size: the same with input size + output_size_list_.push_back(input_size); // mask size: the same with input size + workspace_size_list_.push_back(workspace_size); +} + +bool DropoutGpuFwdKernel::Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + if (is_null_input_) { + return true; + } + + auto *input = reinterpret_cast(inputs[0]->addr); + auto *output = reinterpret_cast(outputs[0]->addr); + auto *mask = reinterpret_cast(outputs[1]->addr); + + if (!states_init_) { + curandCreateGenerator(&mask_generator_, CURAND_RNG_PSEUDO_DEFAULT); + curandSetPseudoRandomGeneratorSeed(mask_generator_, time(NULL)); + states_init_ = true; + } + + curandGenerateUniform(mask_generator_, mask, num_count_); + DropoutForward(input, mask, output, num_count_, drop_prob_, reinterpret_cast(stream_ptr)); + + return true; +} +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.h new file mode 100644 index 0000000000..2b0d84a40c --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/nn/dropout_gpu_kernel.h @@ -0,0 +1,67 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GPU_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GPU_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "include/curand.h" + +namespace mindspore { +namespace kernel { +class DropoutGpuFwdKernel : public GpuKernel { + public: + DropoutGpuFwdKernel(); + + ~DropoutGpuFwdKernel() override; + + const std::vector &GetInputSizeList() const override; + + const std::vector &GetOutputSizeList() const override; + + const std::vector &GetWorkspaceSizeList() const override; + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + + bool Init(const CNodePtr &kernel_node) override; + + protected: + void InitResource() override; + + void InitSizeLists() override; + + private: + void DestroyResource() noexcept; + + cudnnHandle_t cudnn_handle_; + bool is_null_input_; + size_t num_count_; + float drop_prob_; + bool states_init_; + curandGenerator_t mask_generator_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; + +MS_REG_GPU_KERNEL(Dropout, DropoutGpuFwdKernel) +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GPU_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.cc b/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.cc new file mode 100644 index 0000000000..42c3d279c4 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.cc @@ -0,0 +1,92 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/nn/dropout_grad_kernel.h" +#include "kernel/gpu/cuda_impl/dropout_impl.cuh" + +namespace mindspore { +namespace kernel { +DropoutGradGpuFwdKernel::DropoutGradGpuFwdKernel() + : cudnn_handle_(nullptr), is_null_input_(false), num_count_(0), drop_prob_(0.0) {} + +DropoutGradGpuFwdKernel::~DropoutGradGpuFwdKernel() { DestroyResource(); } + +const std::vector &DropoutGradGpuFwdKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &DropoutGradGpuFwdKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &DropoutGradGpuFwdKernel::GetWorkspaceSizeList() const { return workspace_size_list_; } + +bool DropoutGradGpuFwdKernel::Init(const CNodePtr &kernel_node) { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 2) { + MS_LOG(ERROR) << "Argument number is " << input_num << ", but DropoutGradGpuFwdKernel needs 2."; + return false; + } + + auto input_shape = AnfAlgo::GetOutputInferShape(kernel_node, 0); + is_null_input_ = CHECK_NULL_INPUT(input_shape); + if (is_null_input_) { + InitSizeLists(); + return true; + } + + num_count_ = 1; + for (size_t x : input_shape) { + num_count_ *= x; + } + drop_prob_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("drop_prob")); + + InitSizeLists(); + return true; +} + +void DropoutGradGpuFwdKernel::InitResource() { + cudnn_handle_ = device::gpu::GPUDeviceManager::GetInstance().GetCudnnHandle(); +} + +void DropoutGradGpuFwdKernel::DestroyResource() noexcept {} + +void DropoutGradGpuFwdKernel::InitSizeLists() { + size_t dy_size = num_count_ * sizeof(float); + size_t mask_size = dy_size; + size_t dx_size = dy_size; + size_t workspace_size = 0; + + input_size_list_.push_back(dy_size); + input_size_list_.push_back(mask_size); + output_size_list_.push_back(dx_size); + workspace_size_list_.push_back(workspace_size); +} + +bool DropoutGradGpuFwdKernel::Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + if (is_null_input_) { + return true; + } + + auto *dy = reinterpret_cast(inputs[0]->addr); + auto *mask = reinterpret_cast(inputs[1]->addr); + auto *dx = reinterpret_cast(outputs[0]->addr); + + DropoutBackward(dy, mask, dx, num_count_, drop_prob_, reinterpret_cast(stream_ptr)); + + return true; +} +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.h b/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.h new file mode 100644 index 0000000000..b59b5d2670 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/nn/dropout_grad_kernel.h @@ -0,0 +1,58 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GRAD_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GRAD_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class DropoutGradGpuFwdKernel : public GpuKernel { + public: + DropoutGradGpuFwdKernel(); + ~DropoutGradGpuFwdKernel() override; + + const std::vector &GetInputSizeList() const override; + const std::vector &GetOutputSizeList() const override; + const std::vector &GetWorkspaceSizeList() const override; + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + bool Init(const CNodePtr &kernel_node) override; + + protected: + void InitResource() override; + void InitSizeLists() override; + + private: + void DestroyResource() noexcept; + + cudnnHandle_t cudnn_handle_; + bool is_null_input_; + size_t num_count_; + float drop_prob_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; + +MS_REG_GPU_KERNEL(DropoutGrad, DropoutGradGpuFwdKernel) +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_NN_DROPOUT_GRAD_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.cc new file mode 100644 index 0000000000..0f3e0c95f4 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.cc @@ -0,0 +1,33 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/other/assign_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE( + Assign, + KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), + AssignGpuKernel, float) +MS_REG_GPU_KERNEL_ONE( + Assign, + KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16), + AssignGpuKernel, half) +MS_REG_GPU_KERNEL_ONE( + Assign, KernelAttr().AddInputAttr(kNumberTypeInt32).AddInputAttr(kNumberTypeInt32).AddOutputAttr(kNumberTypeInt32), + AssignGpuKernel, int) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.h new file mode 100644 index 0000000000..1c1cde4fd4 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/other/assign_gpu_kernel.h @@ -0,0 +1,93 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_ASSIGN_GPU_KERNEL_H +#define MINDSPORE_CCSRC_KERNEL_GPU_ASSIGN_GPU_KERNEL_H + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +template +class AssignGpuKernel : public GpuKernel { + public: + AssignGpuKernel() : input_size_(0) {} + ~AssignGpuKernel() override = default; + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &, + const std::vector &outputs, uintptr_t stream_ptr) override { + T *var = GetDeviceAddress(inputs, 0); + T *value = GetDeviceAddress(inputs, 1); + T *output = GetDeviceAddress(outputs, 0); + CHECK_CUDA_RET_WITH_EXCEPT( + cudaMemcpyAsync(var, value, input_size_, cudaMemcpyDeviceToDevice, reinterpret_cast(stream_ptr)), + "cudaMemxcpyAsync failed."); + CHECK_CUDA_RET_WITH_EXCEPT( + cudaMemcpyAsync(output, value, input_size_, cudaMemcpyDeviceToDevice, reinterpret_cast(stream_ptr)), + "cudaMemxcpyAsync failed."); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + if (!CheckParam(kernel_node)) { + return false; + } + auto shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + input_size_ = sizeof(T); + for (size_t x : shape) { + input_size_ = input_size_ * x; + } + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + input_size_list_.push_back(input_size_); + input_size_list_.push_back(input_size_); + output_size_list_.push_back(input_size_); + } + + private: + bool CheckParam(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 2) { + MS_LOG(ERROR) << "Input number is " << input_num << ", but AssignGpuKernel needs 2 output."; + return false; + } + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(ERROR) << "Output number is " << output_num << ", but AssignGpuKernel needs 1 output."; + return false; + } + return true; + } + + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + size_t input_size_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_ASSIGN_GPU_KERNEL_H diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.cc new file mode 100644 index 0000000000..af95767407 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.cc @@ -0,0 +1,34 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/batchnorm_fold2_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(BatchNormFold2, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeInt32) + .AddOutputAttr(kNumberTypeFloat32), + BatchNormFold2GpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.h new file mode 100644 index 0000000000..beeeb12a9a --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_gpu_kernel.h @@ -0,0 +1,138 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GPU_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GPU_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/batchnorm_fold2_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class BatchNormFold2GpuKernel : public GpuKernel { + public: + BatchNormFold2GpuKernel() + : cudnn_handle_(nullptr), + is_null_input_(false), + batch_size_(0), + channel_(0), + height_(0), + width_(0), + freeze_bn_(0) {} + + ~BatchNormFold2GpuKernel() override { DestroyResource(); } + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + if (is_null_input_) { + return true; + } + + auto *input = GetDeviceAddress(inputs, 0); + auto *beta = GetDeviceAddress(inputs, 1); + auto *gamma = GetDeviceAddress(inputs, 2); + auto *batch_std = GetDeviceAddress(inputs, 3); + auto *batch_mean = GetDeviceAddress(inputs, 4); + auto *running_std = GetDeviceAddress(inputs, 5); + auto *running_mean = GetDeviceAddress(inputs, 6); + auto *global_step = GetDeviceAddress(inputs, 7); + auto *output = GetDeviceAddress(outputs, 0); + + BatchNormFold2Forward(input, beta, gamma, batch_std, batch_mean, running_std, running_mean, global_step, output, + freeze_bn_, batch_size_, channel_, height_, width_, + reinterpret_cast(stream_ptr)); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 8) { + MS_LOG(ERROR) << "Argument number is " << input_num << ", but BatchNormFold2GpuKernel needs 8."; + return false; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + is_null_input_ = CHECK_NULL_INPUT(input_shape); + if (is_null_input_) { + MS_LOG(WARNING) << "BatchNormFold2GpuKernel input is null"; + InitSizeLists(); + return true; + } + + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "BatchNormFold2GpuKernel input shape needs (N,C,H,W)."; + return false; + } + batch_size_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + freeze_bn_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("freeze_bn")); + + InitSizeLists(); + return true; + } + + protected: + void InitResource() override { cudnn_handle_ = device::gpu::GPUDeviceManager::GetInstance().GetCudnnHandle(); } + + void InitSizeLists() override { + size_t input_size = batch_size_ * channel_ * height_ * width_ * sizeof(T); + size_t weight_size = channel_ * sizeof(T); + input_size_list_.push_back(input_size); + input_size_list_.push_back(weight_size); // beta + input_size_list_.push_back(weight_size); // gamma + input_size_list_.push_back(weight_size); // batch_std + input_size_list_.push_back(weight_size); // batch_mean + input_size_list_.push_back(weight_size); // running_std + input_size_list_.push_back(weight_size); // running_mean + input_size_list_.push_back(sizeof(int32_t)); // global_step + + output_size_list_.push_back(input_size); + + size_t workspace_size = 0; + workspace_size_list_.push_back(workspace_size); + } + + private: + void DestroyResource() noexcept {} + + cudnnHandle_t cudnn_handle_; + bool is_null_input_; + size_t batch_size_; + size_t channel_; + size_t height_; + size_t width_; + size_t freeze_bn_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GPU_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.cc new file mode 100644 index 0000000000..93862aeedd --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.cc @@ -0,0 +1,38 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(BatchNormFold2Grad, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeInt32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32), + BatchNormFold2GradGpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.h new file mode 100644 index 0000000000..099960e7fa --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold2_grad_gpu_kernel.h @@ -0,0 +1,167 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GRAD_GPU_KERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GRAD_GPU_KERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/batchnorm_fold2_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class BatchNormFold2GradGpuKernel : public GpuKernel { + public: + BatchNormFold2GradGpuKernel() + : cudnn_handle_(nullptr), + is_null_input_(false), + batch_size_(0), + channel_(0), + height_(0), + width_(0), + freeze_bn_(0) {} + + ~BatchNormFold2GradGpuKernel() override { DestroyResource(); } + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + if (is_null_input_) { + return true; + } + + auto *dout = GetDeviceAddress(inputs, 0); + auto *x = GetDeviceAddress(inputs, 1); + auto *gamma = GetDeviceAddress(inputs, 2); + auto *batch_std = GetDeviceAddress(inputs, 3); + auto *batch_mean = GetDeviceAddress(inputs, 4); + auto *running_std = GetDeviceAddress(inputs, 5); + auto *running_mean = GetDeviceAddress(inputs, 6); + auto *global_step = GetDeviceAddress(inputs, 7); + auto *d_batch_std = GetDeviceAddress(outputs, 0); + auto *d_batch_mean = GetDeviceAddress(outputs, 1); + auto *d_beta = GetDeviceAddress(outputs, 2); + auto *d_gamma = GetDeviceAddress(outputs, 3); + auto *d_x = GetDeviceAddress(outputs, 4); + auto *tmp = GetDeviceAddress(workspace, 0); + auto *tmp2 = GetDeviceAddress(workspace, 1); + auto *reduce_x = GetDeviceAddress(workspace, 2); + auto *tmp_x = GetDeviceAddress(workspace, 3); + + int32_t current_step_host[1]; + size_t x_size = batch_size_ * channel_ * height_ * width_ * sizeof(T); + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(current_step_host, global_step, sizeof(int32_t), cudaMemcpyDeviceToHost), + "Failed to copy gpu memory."); + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(d_x, dout, x_size, cudaMemcpyDeviceToDevice), "Failed to copy gpu memory."); + + BatchNormFold2GradReduce(dout, x, d_beta, tmp, reduce_x, tmp2, tmp_x, batch_size_, channel_, height_, width_, + reinterpret_cast(stream_ptr)); + if (current_step_host[0] < freeze_bn_) { + CalBatchNormFold2GradNotFreezeDxMul(batch_std, running_std, d_x, batch_size_, channel_, height_, width_, + reinterpret_cast(stream_ptr)); + CalBatchNormFold2GradNotFreeze(d_beta, reduce_x, batch_mean, batch_std, running_mean, running_std, gamma, d_gamma, + d_batch_mean, d_batch_std, channel_, reinterpret_cast(stream_ptr)); + } else { + CalBatchNormFold2GradFreeze(d_beta, reduce_x, batch_mean, batch_std, running_mean, running_std, gamma, d_gamma, + d_batch_mean, d_batch_std, channel_, reinterpret_cast(stream_ptr)); + } + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 8) { + MS_LOG(ERROR) << "Argument number is " << input_num << ", but BatchNormFold2GradGpuKernel needs 8."; + return false; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + is_null_input_ = CHECK_NULL_INPUT(input_shape); + if (is_null_input_) { + MS_LOG(WARNING) << "BatchNormFold2GradGpuKernel input is null"; + InitSizeLists(); + return true; + } + + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "BatchNormFold2GradGpuKernel input shape needs (N,C,H,W)."; + return false; + } + batch_size_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + freeze_bn_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("freeze_bn")); + + InitSizeLists(); + return true; + } + + protected: + void InitResource() override { cudnn_handle_ = device::gpu::GPUDeviceManager::GetInstance().GetCudnnHandle(); } + + void InitSizeLists() override { + size_t input_size = batch_size_ * channel_ * height_ * width_ * sizeof(T); + size_t weight_size = channel_ * sizeof(T); + size_t workspace_size = batch_size_ * channel_ * sizeof(T); + input_size_list_.push_back(input_size); // dout + input_size_list_.push_back(input_size); // x + input_size_list_.push_back(weight_size); // gamma + input_size_list_.push_back(weight_size); // batch_std + input_size_list_.push_back(weight_size); // batch_mean + input_size_list_.push_back(weight_size); // running_std + input_size_list_.push_back(weight_size); // running_mean + input_size_list_.push_back(sizeof(int32_t)); // global_step + + output_size_list_.push_back(weight_size); // d_batch_std + output_size_list_.push_back(weight_size); // d_batch_mean + output_size_list_.push_back(weight_size); // d_beta + output_size_list_.push_back(weight_size); // d_gamma + output_size_list_.push_back(input_size); // d_x + + workspace_size_list_.push_back(workspace_size); // tmp + workspace_size_list_.push_back(workspace_size); // tmp2 + workspace_size_list_.push_back(weight_size); // reduce_x + workspace_size_list_.push_back(input_size); // tmp_x + } + + private: + void DestroyResource() noexcept {} + + cudnnHandle_t cudnn_handle_; + bool is_null_input_; + size_t batch_size_; + size_t channel_; + size_t height_; + size_t width_; + int32_t freeze_bn_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_NN_BATCHNORMFOLD2_GRAD_GPU_KERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.cc new file mode 100644 index 0000000000..4f968a0fa3 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.cc @@ -0,0 +1,33 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/batchnorm_fold_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(BatchNormFold, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeInt32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32), + BatchNormFoldGpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.h new file mode 100644 index 0000000000..3e8c1ca52b --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_gpu_kernel.h @@ -0,0 +1,208 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/kernel_constants.h" +#include "kernel/gpu/cuda_impl/batchnorm_fold_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class BatchNormFoldGpuKernel : public GpuKernel { + public: + BatchNormFoldGpuKernel() + : input_size_(0), + output_size_(0), + exp_avg_factor_(0.9), + epsilon_(1e-12), + is_training_(true), + freeze_bn_(0), + batch_(0), + channel_(0), + height_(0), + width_(0), + mode_(CUDNN_BATCHNORM_SPATIAL), + x_desc_(nullptr), + scale_bias_mean_var_desc_(nullptr), + handle_(nullptr) {} + + ~BatchNormFoldGpuKernel() override { DestroyResource(); } + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + (void)workspace; + auto x = reinterpret_cast(inputs[0]->addr); + auto mean = reinterpret_cast(inputs[1]->addr); + auto variance = reinterpret_cast(inputs[2]->addr); + int *current_step = reinterpret_cast(inputs[3]->addr); + int current_step_host[1]; + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(current_step_host, current_step, sizeof(int), cudaMemcpyDeviceToHost), + "Copy gpu memoy failed."); + if (x == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGpuKernel x is null."; + return false; + } + if (mean == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGpuKernel mean is null."; + return false; + } + if (variance == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGpuKernel variance is null."; + return false; + } + if (current_step == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGpuKernel current_step is null."; + return false; + } + auto batch_mean = reinterpret_cast(outputs[0]->addr); + auto batch_std = reinterpret_cast(outputs[1]->addr); + auto running_mean = reinterpret_cast(outputs[2]->addr); + auto running_std = reinterpret_cast(outputs[3]->addr); + auto y = reinterpret_cast(workspace[0]->addr); + + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(running_mean, mean, output_size_, cudaMemcpyDeviceToDevice), + "Failed to copy gpu memory."); + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(running_std, variance, output_size_, cudaMemcpyDeviceToDevice), + "Failed to copy gpu memory."); + CalUpdateRunningStd(channel_, epsilon_, running_std, reinterpret_cast(stream_ptr)); + if (!is_training_ || current_step_host[0] >= freeze_bn_) { + CHECK_CUDA_RET_WITH_ERROR(cudaMemset(batch_mean, 0, output_size_), "Failed to set gpu memory."); + ThrustFillWith(batch_std, channel_, 1.f, reinterpret_cast(stream_ptr)); + return true; + } + const T alpha = 1; + const T beta = 0; + CHECK_CUDNN_RET_WITH_EXCEPT(cudnnBatchNormalizationForwardTraining( + handle_, mode_, &alpha, &beta, x_desc_, x, x_desc_, y, scale_bias_mean_var_desc_, + mean, mean, exp_avg_factor_, mean, variance, epsilon_, batch_mean, batch_std), + "Failed to launch kernel.") + CalUpdateBatchStd(channel_, batch_std, reinterpret_cast(stream_ptr)); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + InitResource(); + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 4) { + MS_LOG(ERROR) << "Input number is " << input_num << " but BatchNormFold GpuKernel OP needs 4 input."; + return false; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 4) { + MS_LOG(ERROR) << "Output number is " << output_num << ", but BatchNormFold GpuKernel OP needs 4 output."; + return false; + } + + T momentum = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("momentum")); + exp_avg_factor_ = 1.0 - momentum; + epsilon_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("epsilon")); + is_training_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("is_training")); + freeze_bn_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("freeze_bn")); + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "Input shape is " << input_shape.size() + << ", but BatchNormFold GpuKernel OP needs 4DTensor input."; + return false; + } + batch_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + + input_size_ = sizeof(T) * batch_ * channel_ * height_ * width_; + output_size_ = sizeof(T) * channel_; + + cudnnDataType_t cudnnDataType = kCudnnDtypeMap[TypeIdLabel(AnfAlgo::GetInputDeviceDataType(kernel_node, 0))]; + CHECK_CUDNN_RET_WITH_EXCEPT( + cudnnSetTensor4dDescriptor(x_desc_, CUDNN_TENSOR_NCHW, cudnnDataType, batch_, channel_, height_, width_), + "Set x desc failed"); + + CHECK_CUDNN_RET_WITH_EXCEPT( + cudnnSetTensor4dDescriptor(scale_bias_mean_var_desc_, CUDNN_TENSOR_NCHW, cudnnDataType, 1, channel_, 1, 1), + "Set para desc failed"); + + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + // x, mean, variance, current_step + input_size_list_.push_back(input_size_); + input_size_list_.push_back(output_size_); + input_size_list_.push_back(output_size_); + input_size_list_.push_back(sizeof(int)); + + // batch_mean, batch_std, running_mean, running_std + output_size_list_.push_back(output_size_); + output_size_list_.push_back(output_size_); + output_size_list_.push_back(output_size_); + output_size_list_.push_back(output_size_); + + // store y + workspace_size_list_.push_back(input_size_); + } + + void InitResource() override { + handle_ = device::gpu::GPUDeviceManager::GetInstance().GetCudnnHandle(); + CHECK_CUDNN_RET_WITH_EXCEPT(cudnnCreateTensorDescriptor(&x_desc_), "Create x desc failed"); + CHECK_CUDNN_RET_WITH_EXCEPT(cudnnCreateTensorDescriptor(&scale_bias_mean_var_desc_), "Create para desc failed"); + } + + private: + void DestroyResource() noexcept { + CHECK_CUDNN_RET_WITH_ERROR(cudnnDestroyTensorDescriptor(x_desc_), "Destroy x desc failed"); + CHECK_CUDNN_RET_WITH_ERROR(cudnnDestroyTensorDescriptor(scale_bias_mean_var_desc_), "Destroy para desc failed"); + } + + size_t input_size_; + size_t output_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + double exp_avg_factor_; + double epsilon_; + bool is_training_; + int freeze_bn_; + int batch_; + int channel_; + int height_; + int width_; + + cudnnBatchNormMode_t mode_; + cudnnTensorDescriptor_t x_desc_; + cudnnTensorDescriptor_t scale_bias_mean_var_desc_; + + cudnnHandle_t handle_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.cc new file mode 100644 index 0000000000..93ea66258d --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.cc @@ -0,0 +1,32 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(BatchNormFoldGrad, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeInt32) + .AddOutputAttr(kNumberTypeFloat32), + BatchNormFoldGradGpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.h new file mode 100644 index 0000000000..ec845fbb9e --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/batchnorm_fold_grad_gpu_kernel.h @@ -0,0 +1,169 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GRAD_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GRAD_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/batchnorm_fold_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class BatchNormFoldGradGpuKernel : public GpuKernel { + public: + BatchNormFoldGradGpuKernel() + : input_size_(0), + channel_size_(0), + workspace_size_(0), + momentum_(0.1), + epsilon_(1e-12), + is_training_(true), + freeze_bn_(0), + current_step_(0), + batch_(0), + channel_(0), + height_(0), + width_(0) {} + ~BatchNormFoldGradGpuKernel() = default; + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + (void)workspace; + // 'd_batch_mean', 'd_batch_std', 'x', 'batch_mean', 'batch_std', 'current_step' + T *d_batch_mean = GetDeviceAddress(inputs, 0); + T *d_batch_std = GetDeviceAddress(inputs, 1); + T *x = GetDeviceAddress(inputs, 2); + T *batch_mean = GetDeviceAddress(inputs, 3); + T *batch_std = GetDeviceAddress(inputs, 4); + int *current_step = GetDeviceAddress(inputs, 5); + int current_step_host[1]; + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(current_step_host, current_step, sizeof(int), cudaMemcpyDeviceToHost), + "Copy gpu memoy failed."); + if (d_batch_mean == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel d_batch_mean is null."; + return false; + } + if (d_batch_std == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel d_batch_std is null."; + return false; + } + if (x == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel x is null."; + return false; + } + if (batch_mean == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel batch_mean is null."; + return false; + } + if (batch_std == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel batch_std is null."; + return false; + } + if (current_step == nullptr) { + MS_LOG(ERROR) << "BatchNormFoldGradGpuKernel current_step is null."; + return false; + } + T *dx = reinterpret_cast(outputs[0]->addr); + + if (!is_training_ || current_step_host[0] >= freeze_bn_) { + ThrustFillWith(dx, batch_ * channel_ * height_ * width_, 0.f, reinterpret_cast(stream_ptr)); + return true; + } + CalBatchNormFoldGrad(d_batch_mean, d_batch_std, x, batch_mean, batch_std, batch_, channel_, height_, width_, dx, + reinterpret_cast(stream_ptr)); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 6) { + MS_LOG(ERROR) << "Input number is " << input_num << ", but BatchNormFoldGrad GpuKernel OP needs 6 input."; + return false; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(ERROR) << "Output number is " << output_num << ", but BatchNormFoldGrad GpuKernel OP needs 4 output."; + return false; + } + + epsilon_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("epsilon")); + is_training_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("is_training")); + freeze_bn_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("freeze_bn")); + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 2); + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "Input shape is " << input_shape.size() + << ", but BatchNormFoldGrad GpuKernel OP needs 4DTensor input."; + return false; + } + batch_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + + input_size_ = sizeof(T) * batch_ * channel_ * height_ * width_; + channel_size_ = sizeof(T) * channel_; + + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + // 'd_batch_mean', 'd_batch_std', 'x', 'batch_mean', 'batch_std', 'current_step' + input_size_list_.push_back(channel_size_); + input_size_list_.push_back(channel_size_); + input_size_list_.push_back(input_size_); + input_size_list_.push_back(channel_size_); + input_size_list_.push_back(channel_size_); + input_size_list_.push_back(sizeof(int)); + + // 'dx' + output_size_list_.push_back(input_size_); + + workspace_size_list_.push_back(workspace_size_); + } + + private: + size_t input_size_; + size_t channel_size_; + size_t workspace_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + T momentum_; + T epsilon_; + bool is_training_; + int freeze_bn_; + int current_step_; + int batch_; + int channel_; + int height_; + int width_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_BATCHNORM_FOLD_GRAD_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.cc new file mode 100644 index 0000000000..a914b6ec14 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.cc @@ -0,0 +1,29 @@ +/** + * Copyright 2020、 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/correction_mul_gpu_kernel.h" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(CorrectionMul, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32), + CorrectionMulGpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.h new file mode 100644 index 0000000000..eeab872ab3 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_gpu_kernel.h @@ -0,0 +1,97 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMUL_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMUL_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/correction_mul_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class CorrectionMulGpuKernel : public GpuKernel { + public: + CorrectionMulGpuKernel() : batch_size_(0), channel_(0), height_(0), width_(0) {} + ~CorrectionMulGpuKernel() override { DestroyResource(); } + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + auto *weight = GetDeviceAddress(inputs, 0); + auto *gamma = GetDeviceAddress(inputs, 1); + auto *running_std = GetDeviceAddress(inputs, 2); + auto *output = GetDeviceAddress(outputs, 0); + + CalCorrectionMul(weight, gamma, running_std, batch_size_, channel_, height_, width_, output, + reinterpret_cast(stream_ptr)); + return true; + } + bool Init(const CNodePtr &kernel_node) override { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 3) { + MS_LOG(ERROR) << "Argument number is " << input_num << ", but CorrectionMulGpuKernel needs 3."; + return false; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "CorrectionMulGpuKernel input shape needs (N,C,H,W)."; + return false; + } + batch_size_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + size_t input_size = batch_size_ * channel_ * height_ * width_ * sizeof(T); + size_t weight_size = batch_size_ * sizeof(T); + input_size_list_.push_back(input_size); // weight + input_size_list_.push_back(weight_size); // gamma + input_size_list_.push_back(weight_size); // running_std + size_t workspace_size = 0; + output_size_list_.push_back(input_size); + workspace_size_list_.push_back(workspace_size); + } + void InitResource() override {} + + private: + void DestroyResource() noexcept {} + + size_t batch_size_; + size_t channel_; + size_t height_; + size_t width_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMUL_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.cc new file mode 100644 index 0000000000..28b5d56e68 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.cc @@ -0,0 +1,32 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/correction_mul_grad_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/correction_mul_impl.cuh" + +namespace mindspore { +namespace kernel { +MS_REG_GPU_KERNEL_ONE(CorrectionMulGrad, + KernelAttr() + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddInputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32) + .AddOutputAttr(kNumberTypeFloat32), + CorrectionMulGradGpuKernel, float) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.h new file mode 100644 index 0000000000..29aeb3be13 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/correction_mul_grad_gpu_kernel.h @@ -0,0 +1,105 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMULGRAD_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMULGRAD_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" +#include "kernel/gpu/cuda_impl/correction_mul_impl.cuh" + +namespace mindspore { +namespace kernel { +template +class CorrectionMulGradGpuKernel : public GpuKernel { + public: + CorrectionMulGradGpuKernel() : batch_size_(0), channel_(0), height_(0), width_(0) {} + ~CorrectionMulGradGpuKernel() override { DestroyResource(); } + + const std::vector &GetInputSizeList() const override { return input_size_list_; } + const std::vector &GetOutputSizeList() const override { return output_size_list_; } + const std::vector &GetWorkspaceSizeList() const override { return workspace_size_list_; } + + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override { + auto *d_out = GetDeviceAddress(inputs, 0); + auto *weight = GetDeviceAddress(inputs, 1); + auto *gamma = GetDeviceAddress(inputs, 2); + auto *running_std = GetDeviceAddress(inputs, 3); + auto *d_weight = GetDeviceAddress(outputs, 0); + auto *d_gamma = GetDeviceAddress(outputs, 1); + auto *tmp = GetDeviceAddress(workspace, 0); + + CalCorrectionMul(d_out, gamma, running_std, batch_size_, channel_, height_, width_, d_weight, + reinterpret_cast(stream_ptr)); + CalCorrectionMulGrad(d_out, weight, running_std, batch_size_, channel_, height_, width_, d_gamma, tmp, + reinterpret_cast(stream_ptr)); + return true; + } + + bool Init(const CNodePtr &kernel_node) override { + InitResource(); + + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 4) { + MS_LOG(ERROR) << "Argument number is " << input_num << ", but CorrectionMulGradGpuKernel needs 4."; + return false; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + if (input_shape.size() != 4) { + MS_LOG(ERROR) << "CorrectionMulGradGpuKernel input shape needs (N,C,H,W)."; + return false; + } + batch_size_ = input_shape[0]; + channel_ = input_shape[1]; + height_ = input_shape[2]; + width_ = input_shape[3]; + + InitSizeLists(); + return true; + } + + protected: + void InitSizeLists() override { + size_t input_size = batch_size_ * channel_ * height_ * width_ * sizeof(T); + size_t weight_size = batch_size_ * sizeof(T); + input_size_list_.push_back(input_size); // d_out + input_size_list_.push_back(input_size); // weight + input_size_list_.push_back(weight_size); // gamma + input_size_list_.push_back(weight_size); // running_std + output_size_list_.push_back(input_size); // d_weight + output_size_list_.push_back(weight_size); // d_gamma + workspace_size_list_.push_back(input_size); // tmp d_out * weight + } + void InitResource() override {} + + private: + void DestroyResource() noexcept {} + + size_t batch_size_; + size_t channel_; + size_t height_; + size_t width_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_CORRECTIONMULGRAD_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.cc new file mode 100644 index 0000000000..f4e2c74aac --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.cc @@ -0,0 +1,176 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/fake_quant_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/fake_quant_impl.cuh" +#include +#include +#include +#include + +namespace mindspore { +namespace kernel { +FakeQuantGpuKernel::FakeQuantGpuKernel() + : input_size_(0), + min_size_(0), + max_size_(0), + output_size_(0), + workspace_size_(0), + num_bits_(0), + quant_min_(0), + quant_max_(0), + quant_num_(0), + quant_delay_(0), + ema_(false), + ema_decay_(0), + global_step_(0), + training_(false), + narrow_range_(false), + symmetric_(false) {} + +const std::vector &FakeQuantGpuKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &FakeQuantGpuKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &FakeQuantGpuKernel::GetWorkspaceSizeList() const { return workspace_size_list_; } + +bool FakeQuantGpuKernel::Init(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 3) { + MS_LOG(EXCEPTION) << "Input number is " << input_num << ", but FakeQuant GpuKernel OP needs 3 output."; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(EXCEPTION) << "Output number is " << output_num << ", but FakeQuant GpuKernel OP needs 1 output."; + } + + num_bits_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("num_bits")); + ema_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("ema")); + ema_decay_ = 1.0 - GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("ema_decay")); + training_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("training")); + + if (num_bits_ <= 2 || num_bits_ >= 16) { + MS_LOG(EXCEPTION) << "Attr \'num_bits\' " << num_bits_ << " is out of range, expected between 2 and 16."; + } + + quant_delay_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("quant_delay")); + if (quant_delay_ < 0) { + MS_LOG(EXCEPTION) << "Attr \'quant_delay\' " << num_bits_ << "is less then 0, require larger than 0."; + } + + symmetric_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("symmetric")); + if (symmetric_) { + quant_min_ = 0 - (1 << (num_bits_ - 1)); + quant_max_ = (1 << (num_bits_ - 1)) - 1; + } else { + quant_min_ = 0; + quant_max_ = (1 << num_bits_) - 1; + } + + narrow_range_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("narrow_range")); + if (narrow_range_) { + quant_min_++; + } + + if (quant_num_ == 0) { + quant_num_ = 1; + } + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + for (size_t i = 0; i < input_shape.size(); ++i) { + quant_num_ *= SizeToInt(input_shape[i]); + } + + input_size_ = sizeof(float); + min_size_ = sizeof(float); + max_size_ = sizeof(float); + for (size_t i = 0; i < input_shape.size(); i++) { + input_size_ *= input_shape[i]; + } + output_size_ = input_size_; + InitSizeLists(); + return true; +} + +void FakeQuantGpuKernel::InitSizeLists() { + input_size_list_.push_back(input_size_); // input + input_size_list_.push_back(min_size_); // min + input_size_list_.push_back(max_size_); // max + output_size_list_.push_back(output_size_); + workspace_size_list_.push_back(workspace_size_); +} + +bool FakeQuantGpuKernel::Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + (void)workspace; + float *output = GetDeviceAddress(outputs, 0); + float *input = GetDeviceAddress(inputs, 0); + float *input_min = GetDeviceAddress(inputs, 1); + float *input_max = GetDeviceAddress(inputs, 2); + + if (input == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGpuKernel input x is null."; + } + if (input_min == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGpuKernel input min is null."; + } + if (input_max == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGpuKernel input max is null."; + } + + // Allocate space for device copies + int size = sizeof(float); + float *d_scale = nullptr; + float *d_nudge_min = nullptr; + float *d_nudge_max = nullptr; + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_scale), size), "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_min), size), "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_max), size), "Malloc gpu memory failed"); + + if (training_) { + // calculate the input min and max according by the parameter ema and ema_decay. + CalMinMax(input, input_min, input_max, quant_num_, ema_decay_, ema_, reinterpret_cast(stream_ptr)); + // control flow for quant_delay + if (global_step_ >= quant_delay_) { + // real launch + CalNudge(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, + reinterpret_cast(stream_ptr)); + CalFakeQuantize(input, output, quant_num_, d_nudge_min, d_nudge_max, d_scale, symmetric_, + reinterpret_cast(stream_ptr)); + } else { + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(output, input, input_size_, cudaMemcpyDeviceToDevice), + "Copy gpu memory failed"); + } + global_step_++; + } else { + // real launch + CalNudge(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, + reinterpret_cast(stream_ptr)); + CalFakeQuantize(input, output, quant_num_, d_nudge_min, d_nudge_max, d_scale, symmetric_, + reinterpret_cast(stream_ptr)); + } + + // Cleanup + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_scale), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_min), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_max), "Free gpu memory failed"); + + return true; +} + +MS_REG_GPU_KERNEL(FakeQuantWithMinMax, FakeQuantGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.h new file mode 100755 index 0000000000..b14268ed62 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_gpu_kernel.h @@ -0,0 +1,66 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class FakeQuantGpuKernel : public GpuKernel { + public: + FakeQuantGpuKernel(); + ~FakeQuantGpuKernel() = default; + + const std::vector &GetInputSizeList() const override; + const std::vector &GetOutputSizeList() const override; + const std::vector &GetWorkspaceSizeList() const override; + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + bool Init(const CNodePtr &kernel) override; + + protected: + void InitSizeLists() override; + + private: + size_t input_size_; + size_t min_size_; + size_t max_size_; + size_t output_size_; + size_t workspace_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + int num_bits_; + float quant_min_; + float quant_max_; + int quant_num_; + int quant_delay_; + bool ema_; + float ema_decay_; + int global_step_; + bool training_; + bool narrow_range_; + bool symmetric_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.cc new file mode 100644 index 0000000000..4746e8e8e0 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.cc @@ -0,0 +1,145 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/fake_quant_grad_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/fake_quant_impl.cuh" + +namespace mindspore { +namespace kernel { +FakeQuantGradGpuKernel::FakeQuantGradGpuKernel() + : input_size_(0), + min_size_(0), + max_size_(0), + output_size_(0), + workspace_size_(0), + num_bits_(0), + quant_min_(0), + quant_max_(0), + quant_size_(0), + quant_delay_(0), + global_step_(0) {} + +const std::vector &FakeQuantGradGpuKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &FakeQuantGradGpuKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &FakeQuantGradGpuKernel::GetWorkspaceSizeList() const { return workspace_size_list_; } + +bool FakeQuantGradGpuKernel::Init(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 4) { + MS_LOG(EXCEPTION) << "Input number is " << input_num << ", but FakeQuantGrad GpuKernel OP needs 4 output."; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(EXCEPTION) << "Output number is " << output_num << ", but FakeQuantGrad GpuKernel OP needs 1 output."; + } + + num_bits_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("num_bits")); + if (num_bits_ <= 2 || num_bits_ >= 16) { + MS_LOG(EXCEPTION) << "Attr \'num_bits\' " << num_bits_ << " is out of range, expected between 2 and 16."; + } + + quant_delay_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("quant_delay")); + if (quant_delay_ < 0) { + MS_LOG(EXCEPTION) << "Attr \'quant_delay_\' " << quant_delay_ << " is less then 0, require larger than 0."; + } + + quant_min_ = 0; + quant_max_ = (1 << num_bits_) - 1; + + if (quant_size_ == 0) { + quant_size_ = 1; + } + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + for (size_t i = 0; i < input_shape.size(); ++i) { + quant_size_ *= SizeToInt(input_shape[i]); + } + + input_size_ = sizeof(float); + min_size_ = sizeof(float); + max_size_ = sizeof(float); + for (size_t i = 0; i < input_shape.size(); i++) { + input_size_ *= input_shape[i]; + } + output_size_ = input_size_; + + InitSizeLists(); + return true; +} + +void FakeQuantGradGpuKernel::InitSizeLists() { + input_size_list_.push_back(input_size_); // gradient + input_size_list_.push_back(input_size_); // input + input_size_list_.push_back(min_size_); // min + input_size_list_.push_back(max_size_); // max + output_size_list_.push_back(output_size_); + workspace_size_list_.push_back(workspace_size_); +} + +bool FakeQuantGradGpuKernel::Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + (void)workspace; + float *output = GetDeviceAddress(outputs, 0); + float *gradient = GetDeviceAddress(inputs, 0); + float *input = GetDeviceAddress(inputs, 1); + float *input_min = GetDeviceAddress(inputs, 2); + float *input_max = GetDeviceAddress(inputs, 3); + + if (gradient == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGradGpuKernel gradient is null"; + } + if (input == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGradGpuKernel input is null."; + } + if (input_min == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGradGpuKernel input min is null."; + } + if (input_max == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantGradGpuKernel input max is null."; + } + + if (global_step_ >= quant_delay_) { + float *d_scale = nullptr; + float *d_nudge_min = nullptr; + float *d_nudge_max = nullptr; + int size = sizeof(float); + // Allocate space for device copies + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_scale), size), "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_min), size), "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_max), size), "Malloc gpu memory failed"); + + CalNudge(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, + reinterpret_cast(stream_ptr)); + CalFakeQuantizeGrad(input, gradient, output, quant_size_, d_nudge_min, d_nudge_max, + reinterpret_cast(stream_ptr)); + + // Cleanup + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_scale), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_min), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_max), "Free gpu memory failed"); + } else { + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(output, gradient, input_size_, cudaMemcpyDeviceToDevice), + "Copy gpu memory failed."); + } + global_step_++; + return true; +} + +MS_REG_GPU_KERNEL(FakeQuantWithMinMaxGrad, FakeQuantGradGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.h new file mode 100644 index 0000000000..cd0f9a4680 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_grad_gpu_kernel.h @@ -0,0 +1,61 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GRAD_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GRAD_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class FakeQuantGradGpuKernel : public GpuKernel { + public: + FakeQuantGradGpuKernel(); + ~FakeQuantGradGpuKernel() = default; + + const std::vector &GetInputSizeList() const override; + const std::vector &GetOutputSizeList() const override; + const std::vector &GetWorkspaceSizeList() const override; + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + bool Init(const CNodePtr &kernel_node) override; + + protected: + void InitSizeLists() override; + + private: + size_t input_size_; + size_t min_size_; + size_t max_size_; + size_t output_size_; + size_t workspace_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + int num_bits_; + float quant_min_; + float quant_max_; + int quant_size_; + int quant_delay_; + int global_step_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_GRAD_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.cc new file mode 100644 index 0000000000..1da9f457a1 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.cc @@ -0,0 +1,189 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cuh" +#include +#include +#include +#include + +namespace mindspore { +namespace kernel { +FakeQuantPerChannelGpuKernel::FakeQuantPerChannelGpuKernel() + : input_size_(0), + min_size_(0), + max_size_(0), + output_size_(0), + workspace_size_(0), + num_bits_(0), + quant_min_(0), + quant_max_(0), + quant_delay_(0), + ema_(false), + ema_decay_(0), + global_step_(0), + training_(false), + channel_out_(0), + narrow_range_(false), + symmetric_(false) {} + +const std::vector &FakeQuantPerChannelGpuKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &FakeQuantPerChannelGpuKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &FakeQuantPerChannelGpuKernel::GetWorkspaceSizeList() const { return workspace_size_list_; } + +bool FakeQuantPerChannelGpuKernel::Init(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 3) { + MS_LOG(EXCEPTION) << "Input number is " << input_num << ", but FakeQuant GpuKernel OP needs 3 input."; + return false; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(EXCEPTION) << "Output number is " << output_num << " but FakeQuant GpuKernel OP needs 1 output."; + return false; + } + + num_bits_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("num_bits")); + ema_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("ema")); + ema_decay_ = 1.0 - GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("ema_decay")); + + if (num_bits_ <= 2 || num_bits_ >= 16) { + MS_LOG(EXCEPTION) << "Attr \'num_bits\' " << num_bits_ << "is out of range, expected between 2 and 16."; + return false; + } + + quant_delay_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("quant_delay")); + if (quant_delay_ < 0) { + MS_LOG(EXCEPTION) << "Attr \'quant_delay\' " << num_bits_ << " is less then 0, require larger than 0."; + return false; + } + + training_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("training")); + + symmetric_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("symmetric")); + if (symmetric_) { + quant_min_ = 0 - (1 << (num_bits_ - 1)); + quant_max_ = (1 << (num_bits_ - 1)) - 1; + } else { + quant_min_ = 0; + quant_max_ = (1 << num_bits_) - 1; + } + + narrow_range_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("narrow_range")); + if (narrow_range_) { + quant_min_++; + } + + // shape info for gpu + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + channel_out_ = SizeToInt(input_shape[0]); + min_size_ = sizeof(float) * channel_out_; + max_size_ = sizeof(float) * channel_out_; + input_size_ = sizeof(float); + for (size_t i = 0; i < input_shape.size(); i++) { + input_size_ *= input_shape[i]; + } + output_size_ = input_size_; + + InitSizeLists(); + return true; +} + +void FakeQuantPerChannelGpuKernel::InitSizeLists() { + input_size_list_.push_back(input_size_); // input + input_size_list_.push_back(min_size_); // min + input_size_list_.push_back(max_size_); // max + output_size_list_.push_back(output_size_); + workspace_size_list_.push_back(workspace_size_); +} + +void FakeQuantPerChannelGpuKernel::CalFakeQuantizeForTraining(float *input, float *output, float *input_min, + float *input_max, float *d_nudge_min, float *d_nudge_max, + float *d_scale, uintptr_t stream_ptr) { + // calculate the input min and max according by the parameter ema and ema_decay. + CalMinMaxPerChannel(input, input_min, input_max, input_size_ / sizeof(float), channel_out_, ema_decay_, ema_, + reinterpret_cast(stream_ptr)); + // control flow for quant_delay + if (global_step_ >= quant_delay_) { + // real launch + CalNudgePerChannel(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, channel_out_, + reinterpret_cast(stream_ptr)); + CalFakeQuantizePerChannel(input, output, input_size_ / sizeof(float), channel_out_, d_nudge_min, d_nudge_max, + d_scale, symmetric_, reinterpret_cast(stream_ptr)); + } else { + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(output, input, input_size_, cudaMemcpyDeviceToDevice), + "Copy gpu memory failed."); + } + global_step_++; +} + +void FakeQuantPerChannelGpuKernel::CalFakeQuantizeForInfer(float *input, float *output, float *input_min, + float *input_max, float *d_nudge_min, float *d_nudge_max, + float *d_scale, uintptr_t stream_ptr) { + // real launch + CalNudgePerChannel(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, channel_out_, + reinterpret_cast(stream_ptr)); + CalFakeQuantizePerChannel(input, output, input_size_ / sizeof(float), channel_out_, d_nudge_min, d_nudge_max, d_scale, + symmetric_, reinterpret_cast(stream_ptr)); +} + +bool FakeQuantPerChannelGpuKernel::Launch(const std::vector &inputs, + const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + (void)workspace; + float *output = GetDeviceAddress(outputs, 0); + float *input = GetDeviceAddress(inputs, 0); + float *input_min = GetDeviceAddress(inputs, 1); + float *input_max = GetDeviceAddress(inputs, 2); + + if (input == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGpuKernel input is null."; + } + if (input_min == nullptr || input_max == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGpuKernel input min or max is null."; + } + + // Allocate space for device copies + float *d_scale = nullptr; + float *d_nudge_min = nullptr; + float *d_nudge_max = nullptr; + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_scale), sizeof(float) * channel_out_), + "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_min), sizeof(float) * channel_out_), + "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_max), sizeof(float) * channel_out_), + "Malloc gpu memory failed"); + + if (training_) { + CalFakeQuantizeForTraining(input, output, input_min, input_max, d_nudge_min, d_nudge_max, d_scale, stream_ptr); + } else { + CalFakeQuantizeForInfer(input, output, input_min, input_max, d_nudge_min, d_nudge_max, d_scale, stream_ptr); + } + + // Cleanup + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_scale), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_min), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_max), "Free gpu memory failed"); + return true; +} + +MS_REG_GPU_KERNEL(FakeQuantWithMinMaxPerChannel, FakeQuantPerChannelGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.h new file mode 100755 index 0000000000..8a1bb7293a --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_gpu_kernel.h @@ -0,0 +1,71 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class FakeQuantPerChannelGpuKernel : public GpuKernel { + public: + FakeQuantPerChannelGpuKernel(); + ~FakeQuantPerChannelGpuKernel() = default; + + const std::vector &GetInputSizeList() const override; + const std::vector &GetOutputSizeList() const override; + const std::vector &GetWorkspaceSizeList() const override; + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + bool Init(const CNodePtr &kernel) override; + + protected: + void InitSizeLists() override; + + private: + void CalFakeQuantizeForTraining(float *input, float *output, float *input_min, float *input_max, float *d_nudge_min, + float *d_nudge_max, float *d_scale, uintptr_t stream_ptr); + void CalFakeQuantizeForInfer(float *input, float *output, float *input_min, float *input_max, float *d_nudge_min, + float *d_nudge_max, float *d_scale, uintptr_t stream_ptr); + + size_t input_size_; + size_t min_size_; + size_t max_size_; + size_t output_size_; + size_t workspace_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + int num_bits_; + float quant_min_; + float quant_max_; + int quant_delay_; + bool ema_; + float ema_decay_; + int global_step_; + bool training_; + int channel_out_; + bool narrow_range_; + bool symmetric_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.cc b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.cc new file mode 100644 index 0000000000..3184132121 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.cc @@ -0,0 +1,158 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.h" +#include "kernel/gpu/cuda_impl/fake_quant_per_channel_impl.cuh" + +namespace mindspore { +namespace kernel { +FakeQuantPerChannelGradGpuKernel::FakeQuantPerChannelGradGpuKernel() + : input_size_(0), + min_size_(0), + max_size_(0), + output_size_(0), + workspace_size_(0), + num_bits_(0), + quant_min_(0), + quant_max_(0), + channel_out_(0), + quant_delay_(0), + global_step_(0), + narrow_range_(false), + symmetric_(false) {} + +const std::vector &FakeQuantPerChannelGradGpuKernel::GetInputSizeList() const { return input_size_list_; } + +const std::vector &FakeQuantPerChannelGradGpuKernel::GetOutputSizeList() const { return output_size_list_; } + +const std::vector &FakeQuantPerChannelGradGpuKernel::GetWorkspaceSizeList() const { + return workspace_size_list_; +} + +bool FakeQuantPerChannelGradGpuKernel::Init(const CNodePtr &kernel_node) { + size_t input_num = AnfAlgo::GetInputTensorNum(kernel_node); + if (input_num != 4) { + MS_LOG(EXCEPTION) << "Input number is " << input_num << ", but FakeQuantGrad GpuKernel OP needs 4 output."; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(kernel_node); + if (output_num != 1) { + MS_LOG(EXCEPTION) << "Output number is " << output_num << ", but FakeQuantGrad GpuKernel OP needs 1 output."; + } + + num_bits_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("num_bits")); + if (num_bits_ <= 2 || num_bits_ >= 16) { + MS_LOG(EXCEPTION) << "Attr \'num_bits\' " << num_bits_ << " is out of range, expected between 2 and 16."; + } + + quant_delay_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("quant_delay")); + if (quant_delay_ < 0) { + MS_LOG(EXCEPTION) << "Attr \'quant_delay_\' " << quant_delay_ << " is less then 0, require larger than 0."; + } + + symmetric_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("symmetric")); + if (symmetric_) { + quant_min_ = 0 - (1 << (num_bits_ - 1)); + quant_max_ = (1 << (num_bits_ - 1)) - 1; + } else { + quant_min_ = 0; + quant_max_ = (1 << num_bits_) - 1; + } + + narrow_range_ = GetValue(AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("narrow_range")); + if (narrow_range_) { + quant_min_++; + } + + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); + channel_out_ = SizeToInt(input_shape[0]); + min_size_ = sizeof(float) * channel_out_; + max_size_ = sizeof(float) * channel_out_; + input_size_ = sizeof(float); + for (size_t i = 0; i < input_shape.size(); i++) { + input_size_ *= input_shape[i]; + } + output_size_ = input_size_; + + InitSizeLists(); + return true; +} + +void FakeQuantPerChannelGradGpuKernel::InitSizeLists() { + input_size_list_.push_back(input_size_); // gradient + input_size_list_.push_back(input_size_); // input + input_size_list_.push_back(min_size_); // min + input_size_list_.push_back(max_size_); // max + output_size_list_.push_back(output_size_); + workspace_size_list_.push_back(workspace_size_); +} + +bool FakeQuantPerChannelGradGpuKernel::Launch(const std::vector &inputs, + const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) { + (void)workspace; + float *output = GetDeviceAddress(outputs, 0); + float *gradient = GetDeviceAddress(inputs, 0); + float *input = GetDeviceAddress(inputs, 1); + float *input_min = GetDeviceAddress(inputs, 2); + float *input_max = GetDeviceAddress(inputs, 3); + + if (gradient == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGradGpuKernel gradient is null"; + } + if (input == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGradGpuKernel input is null"; + } + if (input_min == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGradGpuKernel input min is null"; + } + if (input_max == nullptr) { + MS_LOG(EXCEPTION) << "FakeQuantPerChannelGradGpuKernel input max is null"; + } + + int total_size = input_size_ / sizeof(float); + if (global_step_ >= quant_delay_) { + float *d_scale = nullptr; + float *d_nudge_min = nullptr; + float *d_nudge_max = nullptr; + // Allocate space for device copies + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_scale), channel_out_ * sizeof(float)), + "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_min), channel_out_ * sizeof(float)), + "Malloc gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaMalloc(reinterpret_cast(&d_nudge_max), channel_out_ * sizeof(float)), + "Malloc gpu memory failed"); + + CalNudgePerChannel(input_min, input_max, quant_min_, quant_max_, d_nudge_min, d_nudge_max, d_scale, channel_out_, + reinterpret_cast(stream_ptr)); + CalFakeQuantizePerChannelGrad(input, gradient, output, total_size, channel_out_, d_nudge_min, d_nudge_max, + reinterpret_cast(stream_ptr)); + + // Cleanup + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_scale), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_min), "Free gpu memory failed"); + CHECK_CUDA_RET_WITH_ERROR(cudaFree(d_nudge_max), "Free gpu memory failed"); + } else { + CHECK_CUDA_RET_WITH_ERROR(cudaMemcpy(output, gradient, input_size_, cudaMemcpyDeviceToDevice), + "Copy gpu memory failed."); + } + global_step_++; + return true; +} + +MS_REG_GPU_KERNEL(FakeQuantWithMinMaxPerChannelGrad, FakeQuantPerChannelGradGpuKernel) +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.h b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.h new file mode 100644 index 0000000000..c210f4cc81 --- /dev/null +++ b/mindspore/ccsrc/kernel/gpu/quant/fake_quant_per_channel_grad_gpu_kernel.h @@ -0,0 +1,63 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GRAD_GPUKERNEL_H_ +#define MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GRAD_GPUKERNEL_H_ + +#include +#include "kernel/gpu/gpu_kernel.h" +#include "kernel/gpu/gpu_kernel_factory.h" + +namespace mindspore { +namespace kernel { +class FakeQuantPerChannelGradGpuKernel : public GpuKernel { + public: + FakeQuantPerChannelGradGpuKernel(); + ~FakeQuantPerChannelGradGpuKernel() = default; + + const std::vector &GetInputSizeList() const override; + const std::vector &GetOutputSizeList() const override; + const std::vector &GetWorkspaceSizeList() const override; + bool Launch(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, uintptr_t stream_ptr) override; + bool Init(const CNodePtr &kernel_node) override; + + protected: + void InitSizeLists() override; + + private: + size_t input_size_; + size_t min_size_; + size_t max_size_; + size_t output_size_; + size_t workspace_size_; + std::vector input_size_list_; + std::vector output_size_list_; + std::vector workspace_size_list_; + + int num_bits_; + float quant_min_; + float quant_max_; + int channel_out_; + int quant_delay_; + int global_step_; + bool narrow_range_; + bool symmetric_; +}; +} // namespace kernel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_KERNEL_GPU_FAKEQUANT_PER_CHANNEL_GRAD_GPUKERNEL_H_ diff --git a/mindspore/ccsrc/kernel/hccl/hccl_kernel_metadata.cc b/mindspore/ccsrc/kernel/hccl/hccl_kernel_metadata.cc index 80e87b0c6d..dc26045374 100755 --- a/mindspore/ccsrc/kernel/hccl/hccl_kernel_metadata.cc +++ b/mindspore/ccsrc/kernel/hccl/hccl_kernel_metadata.cc @@ -27,7 +27,7 @@ void HcclMetadataInfo(const CNodePtr &kernel_node, std::vector *reshape_type) const { - MS_EXCEPTION_IF_NULL(reshape_type); - reshape_type->clear(); +std::vector KernelBuildInfo::GetInputReshapeType(size_t input_index) const { if (input_index >= input_reshape_type_.size()) { - MS_LOG(WARNING) << "The index [" << input_index << "] is exceed the number of input node size " - << input_reshape_type_.size(); - return false; + MS_LOG(EXCEPTION) << "The index [" << input_index << "] is exceed the number of input node size " + << input_reshape_type_.size(); } - (void)std::copy(input_reshape_type_[input_index].begin(), input_reshape_type_[input_index].end(), - std::inserter(*reshape_type, (*reshape_type).begin())); - return true; + return input_reshape_type_[input_index]; } -bool KernelBuildInfo::GetOutputReshapeType(size_t output_index, std::vector *reshape_type) const { - MS_EXCEPTION_IF_NULL(reshape_type); - reshape_type->clear(); +std::vector KernelBuildInfo::GetOutputReshapeType(size_t output_index) const { if (output_index >= output_reshape_type_.size()) { - MS_LOG(WARNING) << "The index [" << output_index << "] is exceed the number of output node dixr" - << output_reshape_type_.size(); - return false; + MS_LOG(EXCEPTION) << "The index [" << output_index << "] is exceed the number of output node size " + << output_reshape_type_.size(); } - (void)std::copy(output_reshape_type_[output_index].begin(), output_reshape_type_[output_index].end(), - std::inserter(*reshape_type, (*reshape_type).begin())); - return true; + return output_reshape_type_[output_index]; } std::string KernelBuildInfo::ToString() const { @@ -115,6 +105,10 @@ bool KernelBuildInfo::operator==(const KernelBuildInfo &other) const { return !(inputs_device_type_ != other.inputs_device_type_ || outputs_device_type_ != other.outputs_device_type_); } +bool KernelBuildInfo::IsInputDefaultPadding() const { return output_reshape_type_.empty(); } + +bool KernelBuildInfo::IsOutputDefaultPadding() const { return input_reshape_type_.empty(); } + void KernelBuildInfo::KernelBuildInfoBuilder::SetKernelType(const KernelType &kernel_type) { MS_EXCEPTION_IF_NULL(kernel_build_info_); kernel_build_info_->kernel_type_ = kernel_type; diff --git a/mindspore/ccsrc/kernel/kernel_build_info.h b/mindspore/ccsrc/kernel/kernel_build_info.h index 24552e0341..76ebc7a572 100644 --- a/mindspore/ccsrc/kernel/kernel_build_info.h +++ b/mindspore/ccsrc/kernel/kernel_build_info.h @@ -54,9 +54,13 @@ class KernelBuildInfo { TypeId GetOutputDeviceType(size_t output_index) const; - bool GetInputReshapeType(size_t input_index, std::vector *reshape_type) const; + std::vector GetInputReshapeType(size_t input_index) const; - bool GetOutputReshapeType(size_t input_index, std::vector *reshape_type) const; + bool IsInputDefaultPadding() const; + + bool IsOutputDefaultPadding() const; + + std::vector GetOutputReshapeType(size_t input_index) const; std::vector GetAllInputFormats() const; diff --git a/mindspore/ccsrc/kernel/mng/rt_kernel_info.cc b/mindspore/ccsrc/kernel/mng/rt_kernel_info.cc index 9bd22712d9..a87bb4d514 100755 --- a/mindspore/ccsrc/kernel/mng/rt_kernel_info.cc +++ b/mindspore/ccsrc/kernel/mng/rt_kernel_info.cc @@ -60,7 +60,7 @@ void GetRtKelInfo(const CNodePtr &kernel_node, MS_EXCEPTION_IF_NULL(ker_desc_ptr); auto kernel_info = ker_desc_ptr->GetKernelInfo(); if (kernel_info.empty()) { - MS_LOG(WARNING) << "Rt dose not has op[" << opNameLower << "]."; + MS_LOG(DEBUG) << "Rt dose not have op [" << opNameLower << "]."; return; } *kernel_info_list = kernel_info; diff --git a/mindspore/ccsrc/kernel/oplib/oplib.cc b/mindspore/ccsrc/kernel/oplib/oplib.cc index d2464bce47..c8cc1530ce 100644 --- a/mindspore/ccsrc/kernel/oplib/oplib.cc +++ b/mindspore/ccsrc/kernel/oplib/oplib.cc @@ -94,6 +94,20 @@ bool OpLib::RegOp(const std::string& json_string, const std::string& impl_path) return ret; } +void OpLib::DecodeTBESpecificInfo(const nlohmann::json& obj, const std::shared_ptr& op_info) { + op_info->set_async_flag(obj.at(kAsyncFlag)); + op_info->set_binfile_name(obj.at(kBinfileName)); + op_info->set_compute_cost(obj.at(kComputeCost)); + op_info->set_kernel_name(obj.at(kKernelName)); + op_info->set_partial_flag(obj.at(kPartialFlag)); + if (obj.find(kOpPattern) != obj.end()) { + op_info->set_op_pattern(obj.at(kOpPattern)); + } + if (obj.find(kDynamicFormat) != obj.end()) { + op_info->set_dynamic_format(obj.at(kDynamicFormat)); + } +} + bool OpLib::DecodeOpInfo(const nlohmann::json& obj, const mindspore::kernel::OpImplyType imply_type, const std::string& impl_path) { std::shared_ptr op_info = std::make_shared(); @@ -103,17 +117,7 @@ bool OpLib::DecodeOpInfo(const nlohmann::json& obj, const mindspore::kernel::OpI op_info->set_imply_type(imply_type); op_info->set_fusion_type(obj.at(kFusionType)); if (imply_type == kTBE) { - op_info->set_async_flag(obj.at(kAsyncFlag)); - op_info->set_binfile_name(obj.at(kBinfileName)); - op_info->set_compute_cost(obj.at(kComputeCost)); - op_info->set_kernel_name(obj.at(kKernelName)); - op_info->set_partial_flag(obj.at(kPartialFlag)); - if (obj.find(kOpPattern) != obj.end()) { - op_info->set_op_pattern(obj.at(kOpPattern)); - } - if (obj.find(kDynamicFormat) != obj.end()) { - op_info->set_dynamic_format(obj.at(kDynamicFormat)); - } + DecodeTBESpecificInfo(obj, op_info); } auto attrs = obj.at(kAttr); for (const auto& attr : attrs) { diff --git a/mindspore/ccsrc/kernel/oplib/oplib.h b/mindspore/ccsrc/kernel/oplib/oplib.h index a4c5e04bb1..0e11e28d58 100644 --- a/mindspore/ccsrc/kernel/oplib/oplib.h +++ b/mindspore/ccsrc/kernel/oplib/oplib.h @@ -40,6 +40,7 @@ class OpLib { const std::shared_ptr& op_info); static bool DecodeDtypeFormat(const nlohmann::json& dtype_format, const std::shared_ptr& op_io, size_t index); + static void DecodeTBESpecificInfo(const nlohmann::json& obj, const std::shared_ptr& op_info); static bool DecodeInputOutput(const nlohmann::json& obj, const OpImplyType imply_type, const OpIOType io_type, const std::shared_ptr& op_info, const nlohmann::json& dtype_format); static bool GetRefInfo(const std::shared_ptr& op_info); diff --git a/mindspore/ccsrc/kernel/tbe/tbe_adapter.cc b/mindspore/ccsrc/kernel/tbe/tbe_adapter.cc index 229a3eb34a..3fda554759 100644 --- a/mindspore/ccsrc/kernel/tbe/tbe_adapter.cc +++ b/mindspore/ccsrc/kernel/tbe/tbe_adapter.cc @@ -30,6 +30,8 @@ namespace mindspore { namespace kernel { namespace tbe { static std::map tbe_func_adapter_map = { + {"re_lu6", "relu6"}, + {"re_lu6_grad", "relu6_grad"}, {"re_lu", "relu"}, {"tensor_add", "add"}, {"reduce_mean", "reduce_mean_d"}, @@ -37,7 +39,9 @@ static std::map tbe_func_adapter_map = { {"reduce_min", "reduce_min_d"}, {"conv2d_backprop_filter", "conv2d_backprop_filter_d"}, {"conv2d_backprop_input", "conv2d_backprop_input_d"}, - {"top_kv2", "top_k"}, + {"depthwise_conv2d_native", "depthwise_conv2d"}, + {"depthwise_conv2d_native_backprop_filter", "depthwise_conv2d_backprop_filter_d"}, + {"depthwise_conv2d_native_backprop_input", "depthwise_conv2d_backprop_input_d"}, {"scatter_nd", "scatter_nd_d"}, {"tile", "tile_d"}, {"gather_v2", "gather_v2_d"}, @@ -148,9 +152,6 @@ void TbeAdapter::InputOrderPass(const std::string &op_name, std::vector TbeAdapter::build_json_attr_pass_map_ = { - {"Conv2D", TbeAdapter::Conv2DAttrJsonPass}, - {"Conv2DBackpropFilter", TbeAdapter::Conv2DBackpropFilterAttrJsonPass}, - {"Conv2DBackpropInput", TbeAdapter::Conv2DBackpropInputAttrJsonPass}, {"MaximumGrad", TbeAdapter::MaximumGradAttrJsonPass}, {"MinimumGrad", TbeAdapter::MinimumGradAttrJsonPass}, {"Cast", TbeAdapter::CastAttrJsonPass}}; @@ -168,135 +169,6 @@ bool TbeAdapter::RunAttrPass(const mindspore::AnfNodePtr &anf_node, return false; } -void TbeAdapter::Conv2DAttrJsonPass(const mindspore::AnfNodePtr &anf_node, - const std::vector> &op_info_attrs, - nlohmann::json *attrs_json) { - MS_EXCEPTION_IF_NULL(anf_node); - MS_EXCEPTION_IF_NULL(attrs_json); - auto attr_num = op_info_attrs.size(); - auto primitive = AnfAlgo::GetCNodePrimitive(anf_node); - MS_EXCEPTION_IF_NULL(primitive); - for (size_t i = 0; i < attr_num; i++) { - nlohmann::json attr_obj; - MS_EXCEPTION_IF_NULL(op_info_attrs[i]); - std::string attr_name = op_info_attrs[i]->name(); - std::vector attr_value; - if (primitive->GetAttr(attr_name) != nullptr) { - auto value = primitive->GetAttr(attr_name); - int data = GetValue(value); - size_t list_int_size = 0; - if (attr_name == "stride") { - list_int_size = 4; - } else if (attr_name == "dilation") { - list_int_size = 4; - } else if (attr_name == "pad") { - value = primitive->GetAttr("pad_list"); - attr_value = GetValue>(value); - } - for (size_t j = 0; j < list_int_size; j++) { - attr_value.push_back(data); - } - attr_obj["value"] = attr_value; - } else { - attr_obj["value"] = 0; - } - attr_obj["name"] = attr_name; - attr_obj["valid"] = true; - (*attrs_json).push_back(attr_obj); - } - MS_LOG(INFO) << "Conv2DAttrPass done."; -} - -void TbeAdapter::Conv2DBackpropFilterAttrJsonPass( - const mindspore::AnfNodePtr &anf_node, const std::vector> &op_info_attrs, - nlohmann::json *attrs_json) { - MS_EXCEPTION_IF_NULL(anf_node); - MS_EXCEPTION_IF_NULL(attrs_json); - auto attr_num = op_info_attrs.size(); - auto primitive = AnfAlgo::GetCNodePrimitive(anf_node); - MS_EXCEPTION_IF_NULL(primitive); - for (size_t i = 0; i < attr_num; i++) { - nlohmann::json attr_obj; - MS_EXCEPTION_IF_NULL(op_info_attrs[i]); - std::string attr_name = op_info_attrs[i]->name(); - if (primitive->GetAttr(attr_name) != nullptr) { - auto value = primitive->GetAttr(attr_name); - if (attr_name == "pad_mode") { - std::string attr_value = GetValue(value); - (void)transform(attr_value.begin(), attr_value.end(), attr_value.begin(), ::toupper); - attr_obj["value"] = attr_value; - } else if (attr_name == "filter_sizes") { - std::vector attr_value = GetValue>(value); - attr_obj["value"] = attr_value; - } else { - std::vector attr_value; - int data = GetValue(value); - size_t list_int_size = 0; - if (attr_name == "stride") { - list_int_size = 2; - } else if (attr_name == "dilation") { - list_int_size = 4; - } - for (size_t j = 0; j < list_int_size; j++) { - attr_value.push_back(data); - } - attr_obj["value"] = attr_value; - } - attr_obj["valid"] = true; - } else { - attr_obj["valid"] = false; - } - attr_obj["name"] = attr_name; - attrs_json->push_back(attr_obj); - } - MS_LOG(INFO) << "Conv2DBackpropFilterAttrJsonPass done."; -} - -void TbeAdapter::Conv2DBackpropInputAttrJsonPass( - const mindspore::AnfNodePtr &anf_node, const std::vector> &op_info_attrs, - nlohmann::json *attrs_json) { - MS_EXCEPTION_IF_NULL(anf_node); - MS_EXCEPTION_IF_NULL(attrs_json); - auto attr_num = op_info_attrs.size(); - auto primitive = AnfAlgo::GetCNodePrimitive(anf_node); - MS_EXCEPTION_IF_NULL(primitive); - for (size_t i = 0; i < attr_num; i++) { - nlohmann::json attr_obj; - MS_EXCEPTION_IF_NULL(op_info_attrs[i]); - std::string attr_name = op_info_attrs[i]->name(); - if (primitive->GetAttr(attr_name) != nullptr) { - auto value = primitive->GetAttr(attr_name); - if (attr_name == "pad_mode") { - std::string attr_value = GetValue(value); - (void)transform(attr_value.begin(), attr_value.end(), attr_value.begin(), ::toupper); - attr_obj["value"] = attr_value; - } else if (attr_name == "input_sizes") { - std::vector attr_value = GetValue>(value); - attr_obj["value"] = attr_value; - } else { - std::vector attr_value; - int data = GetValue(value); - size_t list_int_size = 0; - if (attr_name == "stride") { - list_int_size = 2; - } else if (attr_name == "dilation") { - list_int_size = 4; - } - for (size_t j = 0; j < list_int_size; j++) { - attr_value.push_back(data); - } - attr_obj["value"] = attr_value; - } - attr_obj["valid"] = true; - } else { - attr_obj["valid"] = false; - } - attr_obj["name"] = attr_name; - attrs_json->push_back(attr_obj); - } - MS_LOG(INFO) << "Conv2DBackpropInputAttrJsonPass done."; -} - void TbeAdapter::MaximumGradAttrJsonPass(const mindspore::AnfNodePtr &anf_node, const std::vector> &op_info_attrs, nlohmann::json *attrs_json) { diff --git a/mindspore/ccsrc/kernel/tbe/tbe_adapter.h b/mindspore/ccsrc/kernel/tbe/tbe_adapter.h index 3997318c86..27f6d315f6 100644 --- a/mindspore/ccsrc/kernel/tbe/tbe_adapter.h +++ b/mindspore/ccsrc/kernel/tbe/tbe_adapter.h @@ -45,12 +45,6 @@ class TbeAdapter { std::vector *input_list, kCreaterType creater_type); private: - static void MaxPoolWithArgmaxAttrJsonPass(const AnfNodePtr &anf_node, - const std::vector> &op_info_attrs, - nlohmann::json *attrs_json); - static void MaxPoolGradWithArgmaxAttrJsonPass(const AnfNodePtr &anf_node, - const std::vector> &op_info_attrs, - nlohmann::json *attrs_json); static void Conv2DAttrJsonPass(const AnfNodePtr &anf_node, const std::vector> &op_info_attrs, nlohmann::json *attrs_json); static void Conv2DBackpropFilterAttrJsonPass(const AnfNodePtr &anf_node, diff --git a/mindspore/ccsrc/kernel/tbe/tbe_convert_utils.cc b/mindspore/ccsrc/kernel/tbe/tbe_convert_utils.cc index 025ff935e2..1159bd888d 100644 --- a/mindspore/ccsrc/kernel/tbe/tbe_convert_utils.cc +++ b/mindspore/ccsrc/kernel/tbe/tbe_convert_utils.cc @@ -51,7 +51,7 @@ const std::map type_id_str_maps = { const std::map type_str_maps = { {"Float32", "float32"}, {"Float16", "float16"}, {"Int8", "int8"}, {"Int16", "int16"}, {"UInt16", "uint16"}, {"UInt8", "uint8"}, {"Int32", "int32"}, {"UInt32", "uint32"}, - {"Int64", "int64"}, {"UInt64", "uint64"}, {"Bool_", "int8"}, {"Float64", "double"}, + {"Int64", "int64"}, {"UInt64", "uint64"}, {"Bool_", "int8"}, {"Float64", "float64"}, }; const std::unordered_map type_nbyte_maps = { diff --git a/mindspore/ccsrc/kernel/tbe/tbe_kernel_select.cc b/mindspore/ccsrc/kernel/tbe/tbe_kernel_select.cc index 92798aa6bc..127451851e 100644 --- a/mindspore/ccsrc/kernel/tbe/tbe_kernel_select.cc +++ b/mindspore/ccsrc/kernel/tbe/tbe_kernel_select.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include "session/anf_runtime_algorithm.h" #include "kernel/oplib/oplib.h" @@ -510,6 +511,64 @@ bool ParseMetadata(const CNodePtr &kernel_node, const std::shared_ptr &shape, const std::string &format) { + const std::set kOpFormatList = {kOpFormat_DEFAULT, kOpFormat_NC1KHKWHWC0, kOpFormat_ND, + kOpFormat_NCHW, kOpFormat_NHWC, kOpFormat_HWCN, + kOpFormat_NC1HWC0, kOpFormat_FRAC_Z, kOpFormat_C1HWNCoC0, + kOpFormat_FRAC_NZ, kOpFormat_NC1HWC0_C04}; + + // if format is default, it remarkes support all format + if (kOpFormatList.find(format) == kOpFormatList.end()) { + MS_LOG(EXCEPTION) << "Got the unknown format " << format; + } + if (format == kOpFormat_DEFAULT) { + return true; + } + // if shape size is 0, the shape will be a scalar + if (shape.empty()) { + return true; + } + if (shape.size() > kShapeSupportFormatMap.size()) { + return false; + } + if (format == kOpFormat_FRAC_NZ && shape.size() >= 2) { + return true; + } + return !(kShapeSupportFormatMap[shape.size() - 1].find(format) == kShapeSupportFormatMap[shape.size() - 1].end()); +} + +bool IsValidKernelInfo(const std::shared_ptr &kernel_node, const kernel::KernelBuildInfo &kernel_build_info) { + MS_EXCEPTION_IF_NULL(kernel_node); + auto check_function = [](const std::vector &shape, const std::string &format) -> bool { + if (!IsShapeMatchFormat(shape, format)) { + return false; + } + for (auto shape_value : shape) { + if (shape_value == 0) { + MS_LOG(EXCEPTION) << "Dimension size of the tensor shape should be a positive integer, but got " << shape_value; + } + } + return true; + }; + for (size_t index = 0; index < kernel_build_info.GetOutputNum(); ++index) { + auto output_shape = AnfAlgo::GetOutputInferShape(kernel_node, index); + if (!check_function(output_shape, kernel_build_info.GetOutputFormat(index))) { + return false; + } + } + for (size_t index = 0; index < kernel_build_info.GetInputNum(); ++index) { + auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, index); + if (!check_function(input_shape, kernel_build_info.GetInputFormat(index))) { + return false; + } + } + if (AnfAlgo::GetCNodeName(kernel_node) == prim::kPrimCast->name()) { + return AnfAlgo::GetOutputInferDataType(kernel_node, 0) == kernel_build_info.GetOutputDeviceType(0) && + AnfAlgo::GetPrevNodeOutputInferDataType(kernel_node, 0) == kernel_build_info.GetInputDeviceType(0); + } + return true; +} + void TbeMetadataInfo(const CNodePtr &kernel_node, std::vector> *kernel_info_list) { MS_EXCEPTION_IF_NULL(kernel_node); MS_EXCEPTION_IF_NULL(kernel_info_list); @@ -534,7 +593,7 @@ void TbeMetadataInfo(const CNodePtr &kernel_node, std::vectorexecution_mode() == kPynativeMode) { kernel_info_list->push_back(parse_info); } else { - if (CheckSupported(kernel_node, parse_info)) { + if (IsValidKernelInfo(kernel_node, *(parse_info)) && CheckSupported(kernel_node, parse_info)) { kernel_info_list->push_back(parse_info); } else { MS_LOG(INFO) << "CheckSupported Failed for TBE op" << op_name << " kernel info."; @@ -542,7 +601,7 @@ void TbeMetadataInfo(const CNodePtr &kernel_node, std::vectorempty()) { - MS_LOG(DEBUG) << "Tbe dose not has metadata of op[" << op_name << "]."; + MS_LOG(DEBUG) << "Tbe dose not have op [" << op_name << "]."; } } } // namespace kernel diff --git a/mindspore/ccsrc/mindrecord/CMakeLists.txt b/mindspore/ccsrc/mindrecord/CMakeLists.txt index eb1c1fb591..fdd648a50f 100644 --- a/mindspore/ccsrc/mindrecord/CMakeLists.txt +++ b/mindspore/ccsrc/mindrecord/CMakeLists.txt @@ -26,7 +26,11 @@ set_target_properties(_c_mindrecord PROPERTIES ) # add link library -target_link_libraries(_c_mindrecord PRIVATE mindspore::sqlite ${PYTHON_LIB} ${SECUREC_LIBRARY} mindspore mindspore_gvar protobuf::libprotobuf) +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + target_link_libraries(_c_mindrecord PRIVATE mindspore::sqlite mindspore mindspore::protobuf) +else() + target_link_libraries(_c_mindrecord PRIVATE mindspore::sqlite ${PYTHON_LIB} ${SECUREC_LIBRARY} mindspore mindspore_gvar mindspore::protobuf) +endif() if (USE_GLOG) target_link_libraries(_c_mindrecord PRIVATE mindspore::glog) diff --git a/mindspore/ccsrc/mindrecord/common/shard_utils.cc b/mindspore/ccsrc/mindrecord/common/shard_utils.cc index ca4bb8a261..51de0c5f64 100644 --- a/mindspore/ccsrc/mindrecord/common/shard_utils.cc +++ b/mindspore/ccsrc/mindrecord/common/shard_utils.cc @@ -65,6 +65,15 @@ std::pair GetFileName(const std::string &path) { return {FAILED, ""}; } char tmp[PATH_MAX] = {0}; +#if defined(_WIN32) || defined(_WIN64) + if (_fullpath(tmp, dirname(&(buf[0])), PATH_MAX) == nullptr) { + MS_LOG(ERROR) << "Invalid file path, path: " << buf; + return {FAILED, ""}; + } + if (_fullpath(real_path, common::SafeCStr(path), PATH_MAX) == nullptr) { + MS_LOG(DEBUG) << "Path: " << common::SafeCStr(path) << "check successfully"; + } +#else if (realpath(dirname(&(buf[0])), tmp) == nullptr) { MS_LOG(ERROR) << "Invalid file path, path: " << buf; return {FAILED, ""}; @@ -72,6 +81,7 @@ std::pair GetFileName(const std::string &path) { if (realpath(common::SafeCStr(path), real_path) == nullptr) { MS_LOG(DEBUG) << "Path: " << path << "check successfully"; } +#endif std::string s = real_path; char sep = '/'; size_t i = s.rfind(sep, s.length()); @@ -91,6 +101,15 @@ std::pair GetParentDir(const std::string &path) { return {FAILED, ""}; } char tmp[PATH_MAX] = {0}; +#if defined(_WIN32) || defined(_WIN64) + if (_fullpath(tmp, dirname(&(buf[0])), PATH_MAX) == nullptr) { + MS_LOG(ERROR) << "Invalid file path, path: " << buf; + return {FAILED, ""}; + } + if (_fullpath(real_path, common::SafeCStr(path), PATH_MAX) == nullptr) { + MS_LOG(DEBUG) << "Path: " << common::SafeCStr(path) << "check successfully"; + } +#else if (realpath(dirname(&(buf[0])), tmp) == nullptr) { MS_LOG(ERROR) << "Invalid file path, path: " << buf; return {FAILED, ""}; @@ -98,6 +117,7 @@ std::pair GetParentDir(const std::string &path) { if (realpath(common::SafeCStr(path), real_path) == nullptr) { MS_LOG(DEBUG) << "Path: " << path << "check successfully"; } +#endif std::string s = real_path; if (s.rfind('/') + 1 <= s.size()) { return {SUCCESS, s.substr(0, s.rfind('/') + 1)}; @@ -144,6 +164,9 @@ bool IsLegalFile(const std::string &path) { } std::pair GetDiskSize(const std::string &str_dir, const DiskSizeType &disk_type) { +#if defined(_WIN32) || defined(_WIN64) + return {SUCCESS, 100}; +#else uint64_t ll_count = 0; struct statfs disk_info; if (statfs(common::SafeCStr(str_dir), &disk_info) == -1) { @@ -166,6 +189,7 @@ std::pair GetDiskSize(const std::string &str_dir, const Dis } return {SUCCESS, ll_count}; +#endif } uint32_t GetMaxThreadNum() { diff --git a/mindspore/ccsrc/mindrecord/include/common/shard_utils.h b/mindspore/ccsrc/mindrecord/include/common/shard_utils.h index c452b49fbc..d31037c8ad 100644 --- a/mindspore/ccsrc/mindrecord/include/common/shard_utils.h +++ b/mindspore/ccsrc/mindrecord/include/common/shard_utils.h @@ -21,8 +21,10 @@ #include #include #include +#if !defined(_WIN32) && !defined(_WIN64) #include #include +#endif #include #include #include @@ -33,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +70,8 @@ enum ShardType { kCV = 1, }; +enum SamplerType { kCustomTopNSampler, kCustomTopPercentSampler, kSubsetRandomSampler, kPKSampler }; + const double kEpsilon = 1e-7; const int kThreadNumber = 14; @@ -117,6 +122,12 @@ const char kPoint = '.'; // field type used by check schema validation const std::set kFieldTypeSet = {"bytes", "string", "int32", "int64", "float32", "float64"}; +// can be searched field list +const std::set kScalarFieldTypeSet = {"string", "int32", "int64", "float32", "float64"}; + +// number field list +const std::set kNumberFieldTypeSet = {"int32", "int64", "float32", "float64"}; + /// \brief split a string using a character /// \param[in] field target string /// \param[in] separator a character for spliting diff --git a/mindspore/ccsrc/mindrecord/include/shard_category.h b/mindspore/ccsrc/mindrecord/include/shard_category.h index 08e5ac9c2e..b8a7611540 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_category.h +++ b/mindspore/ccsrc/mindrecord/include/shard_category.h @@ -32,7 +32,7 @@ class ShardCategory : public ShardOperator { const std::vector> &get_categories() const; - MSRStatus operator()(ShardTask &tasks) override; + MSRStatus execute(ShardTask &tasks) override; private: std::vector> categories_; diff --git a/mindspore/ccsrc/mindrecord/include/shard_index_generator.h b/mindspore/ccsrc/mindrecord/include/shard_index_generator.h index 1febd28fc2..f91d0f17a7 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_index_generator.h +++ b/mindspore/ccsrc/mindrecord/include/shard_index_generator.h @@ -42,11 +42,11 @@ class ShardIndexGenerator { ~ShardIndexGenerator() {} - /// \brief fetch value in json by field path - /// \param[in] field_path - /// \param[in] schema - /// \return the vector of value - static std::vector GetField(const std::string &field_path, json schema); + /// \brief fetch value in json by field name + /// \param[in] field + /// \param[in] input + /// \return pair + std::pair GetValueByField(const string &field, json input); /// \brief fetch field type in schema n by field path /// \param[in] field_path diff --git a/mindspore/ccsrc/mindrecord/include/shard_operator.h b/mindspore/ccsrc/mindrecord/include/shard_operator.h index 9d00fb7628..9f302e5321 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_operator.h +++ b/mindspore/ccsrc/mindrecord/include/shard_operator.h @@ -24,7 +24,25 @@ namespace mindrecord { class ShardOperator { public: virtual ~ShardOperator() = default; - virtual MSRStatus operator()(ShardTask &tasks) = 0; + + MSRStatus operator()(ShardTask &tasks) { + if (SUCCESS != this->pre_execute(tasks)) { + return FAILED; + } + if (SUCCESS != this->execute(tasks)) { + return FAILED; + } + if (SUCCESS != this->suf_execute(tasks)) { + return FAILED; + } + return SUCCESS; + } + + virtual MSRStatus pre_execute(ShardTask &tasks) { return SUCCESS; } + + virtual MSRStatus execute(ShardTask &tasks) = 0; + + virtual MSRStatus suf_execute(ShardTask &tasks) { return SUCCESS; } }; } // namespace mindrecord } // namespace mindspore diff --git a/mindspore/ccsrc/mindrecord/include/shard_reader.h b/mindspore/ccsrc/mindrecord/include/shard_reader.h index c114b17951..5548473cd7 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_reader.h +++ b/mindspore/ccsrc/mindrecord/include/shard_reader.h @@ -19,7 +19,9 @@ #include #include +#if !defined(_WIN32) && !defined(_WIN64) #include +#endif #include #include #include diff --git a/mindspore/ccsrc/mindrecord/include/shard_sample.h b/mindspore/ccsrc/mindrecord/include/shard_sample.h index f6b074a65d..15353fd0ff 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_sample.h +++ b/mindspore/ccsrc/mindrecord/include/shard_sample.h @@ -17,8 +17,12 @@ #ifndef MINDRECORD_INCLUDE_SHARD_SAMPLE_H_ #define MINDRECORD_INCLUDE_SHARD_SAMPLE_H_ +#include +#include #include +#include #include "mindrecord/include/shard_operator.h" +#include "mindrecord/include/shard_shuffle.h" namespace mindspore { namespace mindrecord { @@ -30,17 +34,23 @@ class ShardSample : public ShardOperator { ShardSample(int num, int den, int par); + ShardSample(const std::vector &indices, uint32_t seed); + ~ShardSample() override{}; const std::pair get_partitions() const; - MSRStatus operator()(ShardTask &tasks) override; + MSRStatus execute(ShardTask &tasks) override; + MSRStatus suf_execute(ShardTask &tasks) override; private: int numerator_; int denominator_; int no_of_samples_; int partition_id_; + std::vector indices_; + SamplerType sampler_type_; + std::shared_ptr shuffle_op_; }; } // namespace mindrecord } // namespace mindspore diff --git a/mindspore/ccsrc/mindrecord/include/shard_shuffle.h b/mindspore/ccsrc/mindrecord/include/shard_shuffle.h index a9992ab4bc..464881aa7a 100644 --- a/mindspore/ccsrc/mindrecord/include/shard_shuffle.h +++ b/mindspore/ccsrc/mindrecord/include/shard_shuffle.h @@ -28,7 +28,7 @@ class ShardShuffle : public ShardOperator { ~ShardShuffle() override{}; - MSRStatus operator()(ShardTask &tasks) override; + MSRStatus execute(ShardTask &tasks) override; private: uint32_t shuffle_seed_; diff --git a/mindspore/ccsrc/mindrecord/io/shard_index_generator.cc b/mindspore/ccsrc/mindrecord/io/shard_index_generator.cc index c0108241a1..5a5cd7cbf3 100644 --- a/mindspore/ccsrc/mindrecord/io/shard_index_generator.cc +++ b/mindspore/ccsrc/mindrecord/io/shard_index_generator.cc @@ -38,7 +38,7 @@ ShardIndexGenerator::ShardIndexGenerator(const std::string &file_path, bool appe MSRStatus ShardIndexGenerator::Build() { ShardHeader header = ShardHeader(); if (header.Build(file_path_) != SUCCESS) { - MS_LOG(ERROR) << "Build shard schema failed"; + MS_LOG(ERROR) << "Build shard schema failed."; return FAILED; } shard_header_ = header; @@ -46,35 +46,49 @@ MSRStatus ShardIndexGenerator::Build() { return SUCCESS; } -std::vector ShardIndexGenerator::GetField(const string &field_path, json schema) { - std::vector field_name = StringSplit(field_path, kPoint); - std::vector res; - if (schema.empty()) { - res.emplace_back("null"); - return res; +std::pair ShardIndexGenerator::GetValueByField(const string &field, json input) { + if (field.empty()) { + MS_LOG(ERROR) << "The input field is None."; + return {FAILED, ""}; } - for (uint64_t i = 0; i < field_name.size(); i++) { - // Check if field is part of an array of objects - auto &child = schema.at(field_name[i]); - if (child.is_array() && !child.empty() && child[0].is_object()) { - schema = schema[field_name[i]]; - std::string new_field_path; - for (uint64_t j = i + 1; j < field_name.size(); j++) { - if (j > i + 1) new_field_path += '.'; - new_field_path += field_name[j]; - } - // Return multiple field data since multiple objects in array - for (auto &single_schema : schema) { - auto child_res = GetField(new_field_path, single_schema); - res.insert(res.end(), child_res.begin(), child_res.end()); - } - return res; + + if (input.empty()) { + MS_LOG(ERROR) << "The input json is None."; + return {FAILED, ""}; + } + + // parameter input does not contain the field + if (input.find(field) == input.end()) { + MS_LOG(ERROR) << "The field " << field << " is not found in parameter " << input; + return {FAILED, ""}; + } + + // schema does not contain the field + auto schema = shard_header_.get_schemas()[0]->GetSchema()["schema"]; + if (schema.find(field) == schema.end()) { + MS_LOG(ERROR) << "The field " << field << " is not found in schema " << schema; + return {FAILED, ""}; + } + + // field should be scalar type + if (kScalarFieldTypeSet.find(schema[field]["type"]) == kScalarFieldTypeSet.end()) { + MS_LOG(ERROR) << "The field " << field << " type is " << schema[field]["type"] << ", it is not retrievable"; + return {FAILED, ""}; + } + + if (kNumberFieldTypeSet.find(schema[field]["type"]) != kNumberFieldTypeSet.end()) { + auto schema_field_options = schema[field]; + if (schema_field_options.find("shape") == schema_field_options.end()) { + return {SUCCESS, input[field].dump()}; + } else { + // field with shape option + MS_LOG(ERROR) << "The field " << field << " shape is " << schema[field]["shape"] << " which is not retrievable"; + return {FAILED, ""}; } - schema = schema.at(field_name[i]); } - // Return vector of one field data (not array of objects) - return std::vector{schema.dump()}; + // the field type is string in here + return {SUCCESS, input[field].get()}; } std::string ShardIndexGenerator::TakeFieldType(const string &field_path, json schema) { @@ -304,6 +318,7 @@ MSRStatus ShardIndexGenerator::BindParameterExecuteSQL( const auto &place_holder = std::get<0>(field); const auto &field_type = std::get<1>(field); const auto &field_value = std::get<2>(field); + int index = sqlite3_bind_parameter_index(stmt, common::SafeCStr(place_holder)); if (field_type == "INTEGER") { if (sqlite3_bind_int(stmt, index, std::stoi(field_value)) != SQLITE_OK) { @@ -463,17 +478,24 @@ INDEX_FIELDS ShardIndexGenerator::GenerateIndexFields(const std::vector &s if (field.first >= schema_detail.size()) { return {FAILED, {}}; } - auto field_value = GetField(field.second, schema_detail[field.first]); + auto field_value = GetValueByField(field.second, schema_detail[field.first]); + if (field_value.first != SUCCESS) { + MS_LOG(ERROR) << "Get value from json by field name failed"; + return {FAILED, {}}; + } + auto result = shard_header_.GetSchemaByID(field.first); if (result.second != SUCCESS) { return {FAILED, {}}; } + std::string field_type = ConvertJsonToSQL(TakeFieldType(field.second, result.first->GetSchema()["schema"])); auto ret = GenerateFieldName(field); if (ret.first != SUCCESS) { return {FAILED, {}}; } - fields.emplace_back(ret.second, field_type, field_value[0]); + + fields.emplace_back(ret.second, field_type, field_value.second); } return {SUCCESS, std::move(fields)}; } @@ -490,6 +512,10 @@ MSRStatus ShardIndexGenerator::ExecuteTransaction(const int &shard_no, const std std::fstream in; in.open(common::SafeCStr(shard_address), std::ios::in | std::ios::binary); + if (!in.good()) { + MS_LOG(ERROR) << "File could not opened"; + return FAILED; + } (void)sqlite3_exec(db.second, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); for (int raw_page_id : raw_page_ids) { auto sql = GenerateRawSQL(fields_); diff --git a/mindspore/ccsrc/mindrecord/io/shard_reader.cc b/mindspore/ccsrc/mindrecord/io/shard_reader.cc index f91d28544e..fd3fede5a2 100644 --- a/mindspore/ccsrc/mindrecord/io/shard_reader.cc +++ b/mindspore/ccsrc/mindrecord/io/shard_reader.cc @@ -25,6 +25,15 @@ using mindspore::MsLogLevel::INFO; namespace mindspore { namespace mindrecord { +template +// convert the string to exactly number type (int32_t/int64_t/float/double) +Type StringToNum(const std::string &str) { + std::istringstream iss(str); + Type num; + iss >> num; + return num; +} + ShardReader::ShardReader() { task_id_ = 0; deliver_id_ = 0; @@ -116,13 +125,10 @@ MSRStatus ShardReader::Open() { for (const auto &file : file_paths_) { std::shared_ptr fs = std::make_shared(); - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::binary); - if (fs->fail()) { - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); - if (fs->fail()) { - MS_LOG(ERROR) << "File could not opened"; - return FAILED; - } + fs->open(common::SafeCStr(file), std::ios::in | std::ios::binary); + if (!fs->good()) { + MS_LOG(ERROR) << "File could not opened"; + return FAILED; } MS_LOG(INFO) << "Open shard file successfully."; file_streams_.push_back(fs); @@ -137,13 +143,10 @@ MSRStatus ShardReader::Open(int n_consumer) { for (const auto &file : file_paths_) { for (int j = 0; j < n_consumer; ++j) { std::shared_ptr fs = std::make_shared(); - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::binary); - if (fs->fail()) { - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); - if (fs->fail()) { - MS_LOG(ERROR) << "File could not opened"; - return FAILED; - } + fs->open(common::SafeCStr(file), std::ios::in | std::ios::binary); + if (!fs->good()) { + MS_LOG(ERROR) << "File could not opened"; + return FAILED; } file_streams_random_[j].push_back(fs); } @@ -259,16 +262,25 @@ MSRStatus ShardReader::ConvertLabelToJson(const std::vectorget_schemas()[0]->GetSchema()["schema"]; + + // convert the string to base type by schema + if (schema[columns[j]]["type"] == "int32") { + construct_json[columns[j]] = StringToNum(labels[i][j + 3]); + } else if (schema[columns[j]]["type"] == "int64") { + construct_json[columns[j]] = StringToNum(labels[i][j + 3]); + } else if (schema[columns[j]]["type"] == "float32") { + construct_json[columns[j]] = StringToNum(labels[i][j + 3]); + } else if (schema[columns[j]]["type"] == "float64") { + construct_json[columns[j]] = StringToNum(labels[i][j + 3]); + } else { + construct_json[columns[j]] = std::string(labels[i][j + 3]); } } - json_str += "}"; - column_values[shard_id].emplace_back(json::parse(json_str)); + column_values[shard_id].emplace_back(construct_json); } } @@ -293,12 +305,10 @@ MSRStatus ShardReader::ReadAllRowsInShard(int shard_id, const std::string &sql, std::string file_name = file_paths_[shard_id]; std::shared_ptr fs = std::make_shared(); if (!all_in_index_) { - fs->open(common::SafeCStr(file_name), std::ios::in | std::ios::out | std::ios::binary); - if (fs->fail()) { - fs->open(common::SafeCStr(file_name), std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); - if (fs->fail()) { - MS_LOG(ERROR) << "File could not opened"; - } + fs->open(common::SafeCStr(file_name), std::ios::in | std::ios::binary); + if (!fs->good()) { + MS_LOG(ERROR) << "File could not opened"; + return FAILED; } } sqlite3_free(errmsg); @@ -402,7 +412,16 @@ std::vector> ShardReader::GetImageOffset(int page_id, int // whether use index search if (!criteria.first.empty()) { - sql += " AND " + criteria.first + "_" + std::to_string(column_schema_id_[criteria.first]) + " = " + criteria.second; + auto schema = shard_header_->get_schemas()[0]->GetSchema(); + + // not number field should add '' in sql + if (kNumberFieldTypeSet.find(schema["schema"][criteria.first]["type"]) != kNumberFieldTypeSet.end()) { + sql += + " AND " + criteria.first + "_" + std::to_string(column_schema_id_[criteria.first]) + " = " + criteria.second; + } else { + sql += " AND " + criteria.first + "_" + std::to_string(column_schema_id_[criteria.first]) + " = '" + + criteria.second + "'"; + } } sql += ";"; std::vector> image_offsets; @@ -493,8 +512,8 @@ std::pair> ShardReader::GetLabelsFromBinaryFile( std::string file_name = file_paths_[shard_id]; std::vector res; std::shared_ptr fs = std::make_shared(); - fs->open(common::SafeCStr(file_name), std::ios::in | std::ios::out | std::ios::binary); - if (fs->fail()) { + fs->open(common::SafeCStr(file_name), std::ios::in | std::ios::binary); + if (!fs->good()) { MS_LOG(ERROR) << "File could not opened"; return {FAILED, {}}; } @@ -603,16 +622,25 @@ std::pair> ShardReader::GetLabels(int page_id, int std::vector ret; for (unsigned int i = 0; i < labels.size(); ++i) ret.emplace_back(json{}); for (unsigned int i = 0; i < labels.size(); ++i) { - string json_str = "{"; + json construct_json; for (unsigned int j = 0; j < columns.size(); ++j) { - // construct string json "f1": value - json_str = json_str + "\"" + columns[j] + "\":" + labels[i][j]; - if (j < columns.size() - 1) { - json_str += ","; + // construct json "f1": value + auto schema = shard_header_->get_schemas()[0]->GetSchema()["schema"]; + + // convert the string to base type by schema + if (schema[columns[j]]["type"] == "int32") { + construct_json[columns[j]] = StringToNum(labels[i][j]); + } else if (schema[columns[j]]["type"] == "int64") { + construct_json[columns[j]] = StringToNum(labels[i][j]); + } else if (schema[columns[j]]["type"] == "float32") { + construct_json[columns[j]] = StringToNum(labels[i][j]); + } else if (schema[columns[j]]["type"] == "float64") { + construct_json[columns[j]] = StringToNum(labels[i][j]); + } else { + construct_json[columns[j]] = std::string(labels[i][j]); } } - json_str += "}"; - ret[i] = json::parse(json_str); + ret[i] = construct_json; } return {SUCCESS, ret}; } @@ -743,8 +771,12 @@ MSRStatus ShardReader::Launch(bool isSimpleReader) { // Sort row group by (group_id, shard_id), prepare for parallel reading std::sort(row_group_summary.begin(), row_group_summary.end(), ResortRowGroups); - CreateTasks(row_group_summary, operators_); - MS_LOG(INFO) << "Launching read threads"; + if (CreateTasks(row_group_summary, operators_) != SUCCESS) { + MS_LOG(ERROR) << "Failed to launch read threads."; + interrupt_ = true; + return FAILED; + } + MS_LOG(INFO) << "Launching read threads."; if (isSimpleReader) return SUCCESS; @@ -955,8 +987,10 @@ TASK_RETURN_CONTENT ShardReader::ConsumerOneTask(int task_id, uint32_t consumer_ MSRStatus ShardReader::ConsumerByRow(int consumer_id) { // Set thread name +#if !defined(_WIN32) && !defined(_WIN64) auto thread_id = kThreadName + std::to_string(consumer_id); prctl(PR_SET_NAME, common::SafeCStr(thread_id), 0, 0, 0); +#endif // Loop forever for (;;) { @@ -1008,8 +1042,10 @@ MSRStatus ShardReader::ReadBlob(const int &shard_id, const uint64_t &page_offset MSRStatus ShardReader::ConsumerByBlock(int consumer_id) { // Set thread name +#if !defined(_WIN32) && !defined(_WIN64) auto thread_id = kThreadName + std::to_string(consumer_id); prctl(PR_SET_NAME, common::SafeCStr(thread_id), 0, 0, 0); +#endif // Loop forever for (;;) { @@ -1116,6 +1152,9 @@ std::vector, json>> ShardReader::GetBlockNext() } std::vector, json>> ShardReader::GetNext() { + if (interrupt_) { + return std::vector, json>>(); + } if (block_reader_) return GetBlockNext(); if (deliver_id_ >= static_cast(tasks_.Size())) { return std::vector, json>>(); diff --git a/mindspore/ccsrc/mindrecord/io/shard_segment.cc b/mindspore/ccsrc/mindrecord/io/shard_segment.cc index 94ef0d8167..e015831d6b 100644 --- a/mindspore/ccsrc/mindrecord/io/shard_segment.cc +++ b/mindspore/ccsrc/mindrecord/io/shard_segment.cc @@ -311,14 +311,23 @@ std::pair, json>>> ShardS MS_LOG(ERROR) << "Get category info"; return {FAILED, std::vector, json>>{}}; } + + // category_name to category_id + int64_t category_id = -1; for (const auto &categories : ret.second) { - if (std::get<1>(categories) == category_name) { - auto result = ReadAllAtPageById(std::get<0>(categories), page_no, n_rows_of_page); - return {SUCCESS, result.second}; + std::string categories_name = std::get<1>(categories); + + if (categories_name == category_name) { + category_id = std::get<0>(categories); + break; } } - return {SUCCESS, std::vector, json>>{}}; + if (category_id == -1) { + return {FAILED, std::vector, json>>{}}; + } + + return ReadAllAtPageById(category_id, page_no, n_rows_of_page); } std::pair, pybind11::object>>> ShardSegment::ReadAtPageByIdPy( diff --git a/mindspore/ccsrc/mindrecord/io/shard_writer.cc b/mindspore/ccsrc/mindrecord/io/shard_writer.cc index 54cf0e156b..864e6697d0 100644 --- a/mindspore/ccsrc/mindrecord/io/shard_writer.cc +++ b/mindspore/ccsrc/mindrecord/io/shard_writer.cc @@ -63,6 +63,15 @@ MSRStatus ShardWriter::Open(const std::vector &paths, bool append) MS_LOG(ERROR) << "Securec func failed"; return FAILED; } +#if defined(_WIN32) || defined(_WIN64) + if (_fullpath(resolved_path, dirname(&(buf[0])), PATH_MAX) == nullptr) { + MS_LOG(ERROR) << "Invalid file path"; + return FAILED; + } + if (_fullpath(resolved_path, common::SafeCStr(path), PATH_MAX) == nullptr) { + MS_LOG(DEBUG) << "Path " << resolved_path; + } +#else if (realpath(dirname(&(buf[0])), resolved_path) == nullptr) { MS_LOG(ERROR) << "Invalid file path"; return FAILED; @@ -70,22 +79,34 @@ MSRStatus ShardWriter::Open(const std::vector &paths, bool append) if (realpath(common::SafeCStr(path), resolved_path) == nullptr) { MS_LOG(DEBUG) << "Path " << resolved_path; } +#endif file_paths_.emplace_back(string(resolved_path)); } // Open files for (const auto &file : file_paths_) { std::shared_ptr fs = std::make_shared(); - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::binary); - if (fs->fail()) { - fs->open(common::SafeCStr(file), std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); - if (fs->fail()) { - MS_LOG(ERROR) << "File could not opened"; + if (!append) { + // if not append and mindrecord file exist, return FAILED + fs->open(common::SafeCStr(file), std::ios::in | std::ios::binary); + if (fs->good()) { + MS_LOG(ERROR) << "MindRecord file already existed."; + fs->close(); + return FAILED; + } + fs->close(); + + // open the mindrecord file to write + fs->open(common::SafeCStr(file), std::ios::out | std::ios::binary); + if (!fs->good()) { + MS_LOG(ERROR) << "MindRecord file could not opened."; return FAILED; } } else { - if (!append) { - MS_LOG(ERROR) << "MindRecord file already existed"; + // open the mindrecord file to append + fs->open(common::SafeCStr(file), std::ios::out | std::ios::in | std::ios::binary); + if (!fs->good()) { + MS_LOG(ERROR) << "MindRecord file could not opened for append."; return FAILED; } } diff --git a/mindspore/ccsrc/mindrecord/meta/shard_category.cc b/mindspore/ccsrc/mindrecord/meta/shard_category.cc index c64a7bfc70..859a3b343f 100644 --- a/mindspore/ccsrc/mindrecord/meta/shard_category.cc +++ b/mindspore/ccsrc/mindrecord/meta/shard_category.cc @@ -23,6 +23,6 @@ ShardCategory::ShardCategory(const std::vector> &ShardCategory::get_categories() const { return categories_; } -MSRStatus ShardCategory::operator()(ShardTask &tasks) { return SUCCESS; } +MSRStatus ShardCategory::execute(ShardTask &tasks) { return SUCCESS; } } // namespace mindrecord } // namespace mindspore diff --git a/mindspore/ccsrc/mindrecord/meta/shard_sample.cc b/mindspore/ccsrc/mindrecord/meta/shard_sample.cc index ea365a0e2a..ef627b0c09 100644 --- a/mindspore/ccsrc/mindrecord/meta/shard_sample.cc +++ b/mindspore/ccsrc/mindrecord/meta/shard_sample.cc @@ -22,32 +22,38 @@ using mindspore::MsLogLevel::ERROR; namespace mindspore { namespace mindrecord { -ShardSample::ShardSample(int n) { - numerator_ = 0; - denominator_ = 0; - no_of_samples_ = n; - partition_id_ = 0; -} +ShardSample::ShardSample(int n) + : numerator_(0), + denominator_(0), + no_of_samples_(n), + partition_id_(0), + indices_({}), + sampler_type_(kCustomTopNSampler) {} -ShardSample::ShardSample(int num, int den) { - if (num < 0 || den <= 0 || num > den) { - no_of_samples_ = 5; - numerator_ = 0; - denominator_ = 0; - partition_id_ = 0; - return; - } - numerator_ = num; - denominator_ = den; - no_of_samples_ = 0; - partition_id_ = 0; -} +ShardSample::ShardSample(int num, int den) + : numerator_(num), + denominator_(den), + no_of_samples_(0), + partition_id_(0), + indices_({}), + sampler_type_(kCustomTopPercentSampler) {} + +ShardSample::ShardSample(int num, int den, int par) + : numerator_(num), + denominator_(den), + no_of_samples_(0), + partition_id_(par), + indices_({}), + sampler_type_(kCustomTopPercentSampler) {} -ShardSample::ShardSample(int num, int den, int par) { - numerator_ = num; - denominator_ = den; - no_of_samples_ = 0; - partition_id_ = par; +ShardSample::ShardSample(const std::vector &indices, uint32_t seed) + : numerator_(0), + denominator_(0), + no_of_samples_(0), + partition_id_(0), + indices_(indices), + sampler_type_(kSubsetRandomSampler) { + shuffle_op_ = std::make_shared(seed); } const std::pair ShardSample::get_partitions() const { @@ -57,15 +63,20 @@ const std::pair ShardSample::get_partitions() const { return std::pair(-1, -1); } -MSRStatus ShardSample::operator()(ShardTask &tasks) { +MSRStatus ShardSample::execute(ShardTask &tasks) { int no_of_categories = static_cast(tasks.categories); int total_no = static_cast(tasks.Size()); int taking = 0; - if (no_of_samples_ > 0) { // non sharding case constructor #1 + if (sampler_type_ == kCustomTopNSampler) { // non sharding case constructor #1 no_of_samples_ = std::min(no_of_samples_, total_no); taking = no_of_samples_ - no_of_samples_ % no_of_categories; - } else { // constructor #2 & #3 + } else if (sampler_type_ == kSubsetRandomSampler) { + if (indices_.size() > total_no) { + MS_LOG(ERROR) << "parameter indices's size is greater than dataset size."; + return FAILED; + } + } else { // constructor TopPercent if (numerator_ > 0 && denominator_ > 0 && numerator_ <= denominator_) { if (numerator_ == 1 && denominator_ > 1) { // sharding taking = (total_no / denominator_) + (total_no % denominator_ == 0 ? 0 : 1); @@ -82,8 +93,15 @@ MSRStatus ShardSample::operator()(ShardTask &tasks) { if (tasks.permutation_.empty()) { ShardTask new_tasks; total_no = static_cast(tasks.Size()); - for (int i = partition_id_ * taking; i < (partition_id_ + 1) * taking; i++) { - new_tasks.InsertTask(tasks.get_task_by_id(i % total_no)); // rounding up. if overflow, go back to start + if (sampler_type_ == kSubsetRandomSampler) { + for (int i = 0; i < indices_.size(); ++i) { + int index = ((indices_[i] % total_no) + total_no) % total_no; + new_tasks.InsertTask(tasks.get_task_by_id(index)); // different mod result between c and python + } + } else { + for (int i = partition_id_ * taking; i < (partition_id_ + 1) * taking; i++) { + new_tasks.InsertTask(tasks.get_task_by_id(i % total_no)); // rounding up. if overflow, go back to start + } } std::swap(tasks, new_tasks); } else { @@ -99,5 +117,14 @@ MSRStatus ShardSample::operator()(ShardTask &tasks) { } return SUCCESS; } + +MSRStatus ShardSample::suf_execute(ShardTask &tasks) { + if (sampler_type_ == kSubsetRandomSampler) { + if (SUCCESS != (*shuffle_op_)(tasks)) { + return FAILED; + } + } + return SUCCESS; +} } // namespace mindrecord } // namespace mindspore diff --git a/mindspore/ccsrc/mindrecord/meta/shard_shuffle.cc b/mindspore/ccsrc/mindrecord/meta/shard_shuffle.cc index 14816e9e9f..f8ad2c341d 100644 --- a/mindspore/ccsrc/mindrecord/meta/shard_shuffle.cc +++ b/mindspore/ccsrc/mindrecord/meta/shard_shuffle.cc @@ -22,7 +22,7 @@ namespace mindspore { namespace mindrecord { ShardShuffle::ShardShuffle(uint32_t seed) : shuffle_seed_(seed) {} -MSRStatus ShardShuffle::operator()(ShardTask &tasks) { +MSRStatus ShardShuffle::execute(ShardTask &tasks) { if (tasks.categories < 1) { return FAILED; } diff --git a/mindspore/ccsrc/onnx/onnx_exporter.cc b/mindspore/ccsrc/onnx/onnx_exporter.cc index 3bd4a38881..80661a4539 100644 --- a/mindspore/ccsrc/onnx/onnx_exporter.cc +++ b/mindspore/ccsrc/onnx/onnx_exporter.cc @@ -174,14 +174,14 @@ OPERATOR_ONNX_CONVERT_DEFINE(Sigmoid, Sigmoid, OpNameInfo()) OPERATOR_ONNX_CONVERT_DEFINE(Flatten, Flatten, OpNameInfo()) OPERATOR_ONNX_CONVERT_DEFINE(Squeeze, Squeeze, OpNameInfo().Attr("axis", "axes", onnx::AttributeProto_AttributeType_INTS, - SetAttrTupleValueToProto)) + SetAttrTupleValueToProto<0>)) OPERATOR_ONNX_CONVERT_DEFINE( Conv2D, Conv, OpNameInfo() - .Attr("dilation", "dilations", onnx::AttributeProto_AttributeType_INTS, SetAttrValueToProto) + .Attr("dilation", "dilations", onnx::AttributeProto_AttributeType_INTS, SetAttrTupleValueToProto<2>) .Attr("group", "group", onnx::AttributeProto_AttributeType_INT, SetAttrValueToProto) - .Attr("kernel_size", "kernel_shape", onnx::AttributeProto_AttributeType_INTS, SetAttrTupleValueToProto) + .Attr("kernel_size", "kernel_shape", onnx::AttributeProto_AttributeType_INTS, SetAttrTupleValueToProto<0>) .Attr("pad_mode", "auto_pad", onnx::AttributeProto_AttributeType_STRING, [](ValuePtr value, onnx::AttributeProto_AttributeType, onnx::AttributeProto* const attr_proto, const PrimitivePtr& prim) { @@ -197,8 +197,7 @@ OPERATOR_ONNX_CONVERT_DEFINE( prim); } }) - .Attr("stride", "strides", onnx::AttributeProto_AttributeType_INTS, SetAttrValueToProto)) - + .Attr("stride", "strides", onnx::AttributeProto_AttributeType_INTS, SetAttrTupleValueToProto<2>)) OPERATOR_ONNX_CONVERT_DEFINE(BiasAdd, Add, OpNameInfo()) OPERATOR_ONNX_CONVERT_DEFINE(MatMul, Gemm, OpNameInfo() diff --git a/mindspore/ccsrc/operator/cc_implementations.cc b/mindspore/ccsrc/operator/cc_implementations.cc index 5ff49758b4..49dc3ab791 100644 --- a/mindspore/ccsrc/operator/cc_implementations.cc +++ b/mindspore/ccsrc/operator/cc_implementations.cc @@ -103,7 +103,7 @@ T InnerScalarMul(T x, T y) { } template -T InnerScalarDiv(T x, T y) { +float InnerScalarDiv(T x, T y) { if (y == 0) { MS_LOG(EXCEPTION) << "Divisor could not be zero"; } @@ -111,23 +111,41 @@ T InnerScalarDiv(T x, T y) { MS_LOG(EXCEPTION) << "Overflow of the div of two signed number x: " << std::to_string(x) << ", y: " << std::to_string(y) << "."; } - return x / y; + return static_cast(x) / static_cast(y); } -int32_t InnerScalarMod(int32_t x, int32_t y) { +template +T InnerScalarFloordiv(T x, T y) { + auto ret = std::floor(InnerScalarDiv(x, y)); + if (std::is_integral::value) { + return static_cast(ret); + } + return ret; +} + +template +T InnerScalarMod(T x, T y) { if (y == 0) { MS_LOG(EXCEPTION) << "Could not mod to zero."; } - if (IsSignedIntOverflow(x, y, OpType::MOD)) { + if (std::is_integral::value && std::is_signed::value && IsSignedIntOverflow(x, y, OpType::MOD)) { MS_LOG(EXCEPTION) << "Overflow of the mod of two signed number x: " << std::to_string(x) << ", y: " << std::to_string(y) << "."; } - return x % y; + if (std::is_integral::value) { + return static_cast(x) % static_cast(y); + } + float x_int = std::floor(x); + float y_int = std::ceil(y); + float max = x_int / y_int; + float ret = x - y * max; + return ret; } -float InnerScalarMod(float, float) { MS_LOG(EXCEPTION) << "Float does not support mod operator."; } - -double InnerScalarMod(double, double) { MS_LOG(EXCEPTION) << "Double does not support mod operator."; } +template +T InnerScalarPow(T x, U y) { + return std::pow(x, y); +} template bool InnerScalarEq(T x, U y) { @@ -183,6 +201,14 @@ bool InnerScalarGe(T x, U y) { int sum = InnerScalar##op_t(GetValue(x), GetValue(y)); \ return MakeValue(sum); \ } \ + if (x->isa() && y->isa()) { \ + float sum = InnerScalar##op_t(IntToFloat(GetValue(x)), GetValue(y)); \ + return MakeValue(sum); \ + } \ + if (x->isa() && y->isa()) { \ + float sum = InnerScalar##op_t(GetValue(x), IntToFloat(GetValue(y))); \ + return MakeValue(sum); \ + } \ MS_LOG(EXCEPTION) << "Unsupported Value for Scalar" << #op_t << ", x: " << x->ToString() \ << ", y: " << y->ToString(); \ } while (0); \ @@ -193,6 +219,8 @@ SCALAR_OP(Sub) SCALAR_OP(Mul) SCALAR_OP(Div) SCALAR_OP(Mod) +SCALAR_OP(Pow) +SCALAR_OP(Floordiv) #define LOGIC_OP(op_t) \ ValuePtr Scalar##op_t(const ValuePtrList& list) { \ @@ -227,6 +255,10 @@ SCALAR_OP(Mod) bool sum = InnerScalar##op_t(GetValue(x), GetValue(y)); \ return MakeValue(sum); \ } \ + if (x->isa() && y->isa()) { \ + bool sum = InnerScalar##op_t(GetValue(x), GetValue(y)); \ + return MakeValue(sum); \ + } \ if (x->isa() && y->isa()) { \ bool sum = InnerScalar##op_t(GetValue(x), GetValue(y)); \ return MakeValue(sum); \ diff --git a/mindspore/ccsrc/operator/cc_implementations.h b/mindspore/ccsrc/operator/cc_implementations.h index 2c2936fc92..69981cea7d 100644 --- a/mindspore/ccsrc/operator/cc_implementations.h +++ b/mindspore/ccsrc/operator/cc_implementations.h @@ -37,9 +37,10 @@ ValuePtr ScalarSub(const ValuePtrList& list); ValuePtr ScalarMul(const ValuePtrList& list); ValuePtr ScalarDiv(const ValuePtrList& list); ValuePtr ScalarMod(const ValuePtrList& list); +ValuePtr ScalarPow(const ValuePtrList& list); +ValuePtr ScalarFloordiv(const ValuePtrList& list); ValuePtr ScalarUAdd(const ValuePtrList& list); ValuePtr ScalarUSub(const ValuePtrList& list); -ValuePtr ScalarUSub(const ValuePtrList& list); ValuePtr ScalarLog(const ValuePtrList& list); ValuePtr ScalarEq(const ValuePtrList& list); ValuePtr ScalarLt(const ValuePtrList& list); diff --git a/mindspore/ccsrc/operator/composite/composite.cc b/mindspore/ccsrc/operator/composite/composite.cc index 347641829d..9a665e8a30 100644 --- a/mindspore/ccsrc/operator/composite/composite.cc +++ b/mindspore/ccsrc/operator/composite/composite.cc @@ -743,7 +743,7 @@ FuncGraphPtr MultitypeFuncGraph::GenerateFromTypes(const TypePtrList& types) { } oss << ++idx << ". " << item.first << "\n " << trace::GetDebugInfo(func_graph->debug_info()) << "\n"; } - MS_LOG(EXCEPTION) << "Fail to find overload function for `" << name_ << "` with type " << buffer.str() << "\n" + MS_LOG(EXCEPTION) << "The '" << name_ << "' operation does not support the type " << buffer.str() << "\n" << oss.str(); } diff --git a/mindspore/ccsrc/operator/composite/do_signature.cc b/mindspore/ccsrc/operator/composite/do_signature.cc index 62de1c71f2..a4a26377f5 100644 --- a/mindspore/ccsrc/operator/composite/do_signature.cc +++ b/mindspore/ccsrc/operator/composite/do_signature.cc @@ -88,14 +88,17 @@ std::map GetMaxDtypeIndex(const std::vectorisa()) { - m_index = indexs[i]; + + for (const auto& index : indexs) { + AbstractBasePtr arg_value = args_spec_list[index]; + if (arg_value->isa()) { + arg_value = arg_value->cast()->ref(); + } + + if (arg_value->isa()) { + (void)dst_type.insert(std::make_pair(type, index)); + break; } - } - if (args_spec_list[m_index]->isa()) { - (void)dst_type.insert(std::make_pair(type, m_index)); } } return dst_type; @@ -119,15 +122,19 @@ void DoAutoCast(const std::vector& signature, const abstract::Abstrac (void)std::transform(signature.begin(), signature.end(), std::back_inserter(dtypes), [](const Signature& sig) { return sig.dtype; }); int empty_dtype_count = std::count(dtypes.begin(), dtypes.end(), SignatureEnumDType::kDTypeEmptyDefaultValue); - if (dtypes.size() == 0 || static_cast(dtypes.size()) == empty_dtype_count) { + if (dtypes.empty() || static_cast(dtypes.size()) == empty_dtype_count) { return; } // Stat the index of the arguments with the largest type in the same SignatureEnumDType. std::map dst_type = GetMaxDtypeIndex(dtypes, args_spec_list); // Identify which arg requires auto cast for (size_t i = 0; i < args_spec_list.size(); ++i) { + AbstractBasePtr arg_value = args_spec_list[i]; + if (arg_value->isa()) { + arg_value = arg_value->cast()->ref(); + } auto it = dst_type.find(dtypes[i]); - if (it == dst_type.end() || it->second == i || !args_spec_list[i]->isa()) { + if (it == dst_type.end() || it->second == i || !arg_value->isa()) { continue; } // get source node for cast diff --git a/mindspore/ccsrc/operator/ops.cc b/mindspore/ccsrc/operator/ops.cc old mode 100644 new mode 100755 index 12e6b70a6f..b1a8a9b782 --- a/mindspore/ccsrc/operator/ops.cc +++ b/mindspore/ccsrc/operator/ops.cc @@ -28,6 +28,7 @@ const PrimitivePtr kPrimScalarAdd = std::make_shared("scalar_add"); const PrimitivePtr kPrimScalarSub = std::make_shared("scalar_sub"); const PrimitivePtr kPrimScalarMul = std::make_shared("scalar_mul"); const PrimitivePtr kPrimScalarDiv = std::make_shared("scalar_div"); +const PrimitivePtr kPrimScalarFloordiv = std::make_shared("scalar_floordiv"); const PrimitivePtr kPrimScalarMod = std::make_shared("scalar_mod"); const PrimitivePtr kPrimScalarPow = std::make_shared("scalar_pow"); const PrimitivePtr kPrimScalarTrunc = std::make_shared("scalar_trunc"); @@ -78,6 +79,7 @@ const PrimitivePtr kPrimCreateInstance = std::make_shared("create_ins // Structure const PrimitivePtr kPrimStringEqual = std::make_shared("string_equal"); +const PrimitivePtr kPrimStringConcat = std::make_shared("string_concat"); const PrimitivePtr kPrimMakeTuple = std::make_shared("make_tuple"); const PrimitivePtr kPrimMakeList = std::make_shared("make_list"); const PrimitivePtr kPrimMakeDict = std::make_shared("make_dict"); @@ -154,6 +156,9 @@ const PrimitivePtr kPrimMul = std::make_shared("Mul"); const PrimitivePtr kPrimMinimum = std::make_shared("Minimum"); const PrimitivePtr kPrimMaximum = std::make_shared("Maximum"); const PrimitivePtr kPrimSquare = std::make_shared("Square"); +const PrimitivePtr kPrimEqual = std::make_shared("Equal"); +const PrimitivePtr kPrimLess = std::make_shared("Less"); +const PrimitivePtr kPrimLessEqual = std::make_shared("LessEqual"); // NN const PrimitivePtr kPrimFlatten = std::make_shared("Flatten"); @@ -218,6 +223,8 @@ const PrimitivePtr kPrimBroadcastGradientArgs = std::make_shared("Bro const PrimitivePtr kPrimControlDepend = std::make_shared("ControlDepend"); const PrimitivePtr kPrimIs_ = std::make_shared("is_"); const PrimitivePtr kPrimIsNot = std::make_shared("is_not"); +const PrimitivePtr kPrimInDict = std::make_shared("in_dict"); +const PrimitivePtr kPrimNotInDict = std::make_shared("not_in_dict"); // Comm ops const PrimitivePtr kPrimMirror = std::make_shared("_MirrorOperator"); @@ -228,6 +235,7 @@ const PrimitivePtr kPrimVirtualDataset = std::make_shared("_VirtualDa const PrimitivePtr kPrimScalarSummary = std::make_shared("ScalarSummary"); const PrimitivePtr kPrimImageSummary = std::make_shared("ImageSummary"); const PrimitivePtr kPrimTensorSummary = std::make_shared("TensorSummary"); +const PrimitivePtr kPrimHistogramSummary = std::make_shared("HistogramSummary"); ValuePtr GetPythonOps(const std::string& op_name, const std::string& module_name) { py::object obj = parse::python_adapter::GetPyFn(module_name, op_name); diff --git a/mindspore/ccsrc/operator/ops.h b/mindspore/ccsrc/operator/ops.h old mode 100644 new mode 100755 index 5fbf2b7067..26c13993e0 --- a/mindspore/ccsrc/operator/ops.h +++ b/mindspore/ccsrc/operator/ops.h @@ -34,6 +34,7 @@ extern const PrimitivePtr kPrimScalarAdd; extern const PrimitivePtr kPrimScalarSub; extern const PrimitivePtr kPrimScalarMul; extern const PrimitivePtr kPrimScalarDiv; +extern const PrimitivePtr kPrimScalarFloordiv; extern const PrimitivePtr kPrimScalarMod; extern const PrimitivePtr kPrimScalarPow; extern const PrimitivePtr kPrimScalarTrunc; @@ -84,6 +85,7 @@ extern const PrimitivePtr kPrimCreateInstance; // Structure extern const PrimitivePtr kPrimStringEqual; +extern const PrimitivePtr kPrimStringConcat; extern const PrimitivePtr kPrimMakeTuple; extern const PrimitivePtr kPrimMakeList; extern const PrimitivePtr kPrimMakeDict; @@ -160,6 +162,9 @@ extern const PrimitivePtr kPrimMul; extern const PrimitivePtr kPrimMinimum; extern const PrimitivePtr kPrimMaximum; extern const PrimitivePtr kPrimSquare; +extern const PrimitivePtr kPrimEqual; +extern const PrimitivePtr kPrimLess; +extern const PrimitivePtr kPrimLessEqual; // NN extern const PrimitivePtr kPrimFlatten; @@ -220,12 +225,13 @@ extern const PrimitivePtr kPrimStateSetItem; extern const PrimitivePtr kPrimScalarSummary; extern const PrimitivePtr kPrimImageSummary; extern const PrimitivePtr kPrimTensorSummary; +extern const PrimitivePtr kPrimHistogramSummary; extern const PrimitivePtr kPrimBroadcastGradientArgs; extern const PrimitivePtr kPrimControlDepend; extern const PrimitivePtr kPrimIs_; extern const PrimitivePtr kPrimIsNot; -extern const PrimitivePtr kPrimMinimumGrad; -extern const PrimitivePtr kPrimMaximumGrad; +extern const PrimitivePtr kPrimInDict; +extern const PrimitivePtr kPrimNotInDict; // Comm ops extern const PrimitivePtr kPrimMirror; diff --git a/mindspore/ccsrc/operator/prim_debug.cc b/mindspore/ccsrc/operator/prim_debug.cc index 28f7e92303..c8db775320 100644 --- a/mindspore/ccsrc/operator/prim_debug.cc +++ b/mindspore/ccsrc/operator/prim_debug.cc @@ -69,7 +69,7 @@ AbstractBasePtr InferImplTensorSummary(const AnalysisEnginePtr &, const Primitiv int tensor_rank = SizeToInt(tensor_value->shape()->shape().size()); if (tensor_rank == 0) { - MS_LOG(EXCEPTION) << "Tensor/Image Summary evaluator second arg should be an tensor, but got a scalar"; + MS_LOG(EXCEPTION) << op_name << " summary evaluator second arg should be an tensor, but got a scalar, rank is 0"; } // Reomve the force check to support batch set summary use 'for' loop diff --git a/mindspore/ccsrc/operator/prim_nn.cc b/mindspore/ccsrc/operator/prim_nn.cc index 892bf2921e..3591168187 100644 --- a/mindspore/ccsrc/operator/prim_nn.cc +++ b/mindspore/ccsrc/operator/prim_nn.cc @@ -114,12 +114,12 @@ void FusedBatchNormCheckDim(const PrimitivePtr &primitive, const AbstractBasePtr AbstractTensorPtr arg = CheckArg(op_name, args_spec_list, i); ShapePtr arg_shape = dyn_cast(arg->GetShapeTrack()); if (arg_shape == nullptr) { - MS_LOG(EXCEPTION) << "" << op_name << " type of args[" << i << "] should be Shape, but " << arg->ToString(); + MS_LOG(EXCEPTION) << op_name << " type of args[" << i << "] should be Shape, but " << arg->ToString(); } if (i == 0) { if (arg_shape->shape().size() < 2) { - MS_LOG(EXCEPTION) << "" << op_name << " shape of args[" << i + MS_LOG(EXCEPTION) << op_name << " shape of args[" << i << "] should be TensorShape with dimension greater than 1, but shape: " << arg_shape->ToString(); } @@ -127,7 +127,7 @@ void FusedBatchNormCheckDim(const PrimitivePtr &primitive, const AbstractBasePtr } if (arg_shape->shape().size() != 1) { - MS_LOG(EXCEPTION) << "" << op_name << " shape of args[" << i + MS_LOG(EXCEPTION) << op_name << " shape of args[" << i << "] should be TensorShape with dimension: 1, but shape: " << arg_shape->ToString(); } } @@ -159,7 +159,7 @@ AbstractBasePtr InferImplFusedBatchNorm(const AnalysisEnginePtr &, const Primiti MS_LOG(EXCEPTION) << "Arg shape size should >= 1."; } if (arg_shape_list[0] != input_shape_list[1]) { - MS_LOG(EXCEPTION) << "" << op_name << " size of tensor param[" << i << "](which is " << arg_shape_list[0] + MS_LOG(EXCEPTION) << op_name << " size of tensor param[" << i << "](which is " << arg_shape_list[0] << ") should match the second dimension of tensor" " param[0](which is " << input_shape_list[1] << ")."; @@ -378,7 +378,7 @@ AbstractBasePtr InferImplDropoutGenMask(const AnalysisEnginePtr &, const Primiti TypePtr prob_type = keep_prob->element()->BuildType(); if ((prob_type->type_id() != kNumberTypeFloat16) && (prob_type->type_id() != kNumberTypeFloat32)) { - MS_LOG(EXCEPTION) << "" << op_name << " keep_prob type should be float16 or float32, but " << prob_type->ToString() + MS_LOG(EXCEPTION) << op_name << " keep_prob type should be float16 or float32, but " << prob_type->ToString() << "."; } diff --git a/mindspore/ccsrc/operator/prim_statement.cc b/mindspore/ccsrc/operator/prim_statement.cc index 7d5038d4e1..239aed5bde 100644 --- a/mindspore/ccsrc/operator/prim_statement.cc +++ b/mindspore/ccsrc/operator/prim_statement.cc @@ -169,5 +169,36 @@ AbstractBasePtr InferImplIsNot(const AnalysisEnginePtr &, const PrimitivePtr &pr return std::make_shared(!(*t == *x)); } + +bool IsInDict(const PrimitivePtr &primitive, const AbstractBasePtrList &args_spec_list) { + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + auto key = CheckArg(op_name, args_spec_list, 0); + auto dict = CheckArg(op_name, args_spec_list, 1); + + ValuePtr key_value = key->BuildValue(); + if (!key_value->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); + } + auto key_str = GetValue(key_value); + std::vector dict_elems = dict->elements(); + auto it = std::find_if(dict_elems.begin(), dict_elems.end(), + [key_str](const AbstractAttribute &item) { return item.first == key_str; }); + return it != dict_elems.end(); +} + +AbstractBasePtr InferImplInDict(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // statement: x in t + // Inputs: x, t + return std::make_shared(IsInDict(primitive, args_spec_list)); +} + +AbstractBasePtr InferImplNotInDict(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // statement: x not in t + // Inputs: x, t + return std::make_shared(!IsInDict(primitive, args_spec_list)); +} } // namespace abstract } // namespace mindspore diff --git a/mindspore/ccsrc/operator/prim_structures.cc b/mindspore/ccsrc/operator/prim_structures.cc index 88699c4d38..31d2bff43d 100644 --- a/mindspore/ccsrc/operator/prim_structures.cc +++ b/mindspore/ccsrc/operator/prim_structures.cc @@ -36,7 +36,7 @@ AbstractBasePtr InferImplStringEqual(const AnalysisEnginePtr &, const PrimitiveP ValuePtr value_x = scalar_x->BuildValue(); ValuePtr value_y = scalar_y->BuildValue(); if (!value_x->isa() || !value_y->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " requires 2 parameters are string, but got param0: " << value_x->ToString() + MS_LOG(EXCEPTION) << op_name << " requires 2 parameters are string, but got param0: " << value_x->ToString() << ", param1: " << value_y->ToString(); } @@ -44,6 +44,25 @@ AbstractBasePtr InferImplStringEqual(const AnalysisEnginePtr &, const PrimitiveP return std::make_shared(ret); } +AbstractBasePtr InferImplStringConcat(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: two scalars whose value is a string. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractScalarPtr scalar_x = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr scalar_y = CheckArg(op_name, args_spec_list, 1); + + ValuePtr value_x = scalar_x->BuildValue(); + ValuePtr value_y = scalar_y->BuildValue(); + if (!value_x->isa() || !value_y->isa()) { + MS_LOG(EXCEPTION) << op_name << " requires 2 parameters are string, but got param0: " << value_x->ToString() + << ", param1: " << value_y->ToString(); + } + + std::string ret = (value_x->cast()->value() + value_y->cast()->value()); + return std::make_shared(ret); +} + AbstractBasePtr InferImplMakeTuple(const AnalysisEnginePtr &, const PrimitivePtr &, const AbstractBasePtrList &args_spec_list) { return std::make_shared(args_spec_list); @@ -64,7 +83,7 @@ AbstractBasePtr InferImplMakeDict(const AnalysisEnginePtr &, const PrimitivePtr size_t keys_size = keys->size(); if (values->size() != keys_size) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator keys' size is not equal with values' size"; + MS_LOG(EXCEPTION) << op_name << " evaluator keys' size is not equal with values' size"; } std::vector key_value; @@ -76,7 +95,7 @@ AbstractBasePtr InferImplMakeDict(const AnalysisEnginePtr &, const PrimitivePtr ValuePtr keyPtr = key->BuildValue(); MS_EXCEPTION_IF_NULL(keyPtr); if (!keyPtr->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator keys should be string, but got " << keyPtr->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator keys should be string, but got " << keyPtr->ToString(); } std::string key_string = GetValue(keyPtr); key_value.emplace_back(key_string, value_list[index]); @@ -93,7 +112,7 @@ AbstractBasePtr InferImplMakeKwarg(const AnalysisEnginePtr &, const PrimitivePtr ValuePtr keyPtr = key->BuildValue(); if (!keyPtr->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator key should be string, but got " << keyPtr->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << keyPtr->ToString(); } std::string key_string = GetValue(keyPtr); return std::make_shared(key_string, args_spec_list[1]); @@ -109,14 +128,13 @@ AbstractBasePtr InferImplExtractKwarg(const AnalysisEnginePtr &, const Primitive ValuePtr key_value = key->BuildValue(); if (!key_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator key should be string, but got " << key_value->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); } std::string key_input = GetValue(key_value); std::string key_actual = kwarg->get_key(); if (key_actual != key_input) { - MS_LOG(EXCEPTION) << "" << op_name - << " evaluator input key should be same as AbstractKeywordArg' key, but input is " << key_input - << ", AbstractKeywordArg' key is " << key_actual; + MS_LOG(EXCEPTION) << op_name << " evaluator input key should be same as AbstractKeywordArg' key, but input is " + << key_input << ", AbstractKeywordArg' key is " << key_actual; } return kwarg->get_arg(); } @@ -187,13 +205,12 @@ AbstractBasePtr InferTupleOrListGetItem(const std::string &op_name, const Abstra ValuePtr index_value = index->BuildValue(); if (!index_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator index should be an int32 number, but got " - << index_value->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator index should be an int32 number, but got " << index_value->ToString(); } int idx_v = GetValue(index_value); std::size_t nelems = queue->elements().size(); if (idx_v >= SizeToInt(nelems) || idx_v < -SizeToInt(nelems)) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator index should be in range[-" << SizeToInt(nelems) << ", " + MS_LOG(EXCEPTION) << op_name << " evaluator index should be in range[-" << SizeToInt(nelems) << ", " << SizeToInt(nelems) << "), but got " << idx_v << "."; } @@ -215,8 +232,7 @@ AbstractBasePtr InferTupleOrListSetItem(const std::string &op_name, const Abstra ValuePtr index_value = index->BuildValue(); if (!index_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator index should be an int32 number, but got " - << index_value->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator index should be an int32 number, but got " << index_value->ToString(); } int idx_v = GetValue(index_value); if (idx_v < 0) { @@ -227,8 +243,7 @@ AbstractBasePtr InferTupleOrListSetItem(const std::string &op_name, const Abstra AbstractBasePtrList elements = queue->elements(); std::size_t nelems = elements.size(); if (uidx_v >= nelems) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator the index: " << uidx_v << " to set out of range: " << nelems - 1 - << "."; + MS_LOG(EXCEPTION) << op_name << " evaluator the index: " << uidx_v << " to set out of range: " << nelems - 1 << "."; } elements[uidx_v] = args_spec_list[2]; return std::make_shared(elements); @@ -264,12 +279,12 @@ AbstractBasePtr InferImplDictGetItem(const AnalysisEnginePtr &, const PrimitiveP ValuePtr key_value = key->BuildValue(); if (!key_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator key should be string, but got " << key_value->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); } - std::string key_str = GetValue(key_value); + auto key_str = GetValue(key_value); std::vector dict_elems = dict->elements(); auto it = std::find_if(dict_elems.begin(), dict_elems.end(), - [key_str](AbstractAttribute &item) { return item.first == key_str; }); + [key_str](const AbstractAttribute &item) { return item.first == key_str; }); if (it == dict_elems.end()) { MS_LOG(EXCEPTION) << "The key " << key_str << " does not exist in the dict:" << args_spec_list[0]->ToString(); @@ -287,7 +302,7 @@ AbstractBasePtr InferImplDictSetItem(const AnalysisEnginePtr &, const PrimitiveP ValuePtr key_value = key->BuildValue(); if (!key_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator key should be string, but got " << key_value->ToString(); + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); } std::string key_str = GetValue(key_value); std::vector dict_elems = dict->elements(); @@ -446,27 +461,27 @@ AbstractBasePtr InferImplReduceShape(const AnalysisEnginePtr &, const PrimitiveP auto x_shp_value = shape_x->BuildValue(); if (x_shp_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name + MS_LOG(EXCEPTION) << op_name << " evaluator shape's data field can't be anything: " << args_spec_list[1]->ToString(); } // Axis can be scalar, tuple or None AbstractTuplePtr axis = nullptr; if (args_spec_list[1]->isa()) { - MS_LOG(DEBUG) << "" << op_name << " evaluator second parameter is scalar"; + MS_LOG(DEBUG) << op_name << " evaluator second parameter is scalar"; AbstractBasePtrList axis_list = {dyn_cast(args_spec_list[1])}; axis = std::make_shared(axis_list); } else if (args_spec_list[1]->isa()) { - MS_LOG(DEBUG) << "" << op_name << " evaluator second parameter is tuple"; + MS_LOG(DEBUG) << op_name << " evaluator second parameter is tuple"; axis = args_spec_list[1]->cast(); } else { - MS_LOG(EXCEPTION) << "" << op_name << " evaluator second parameter should be a scalar or tuple, but got " + MS_LOG(EXCEPTION) << op_name << " evaluator second parameter should be a scalar or tuple, but got " << args_spec_list[1]->ToString(); } auto axis_value = axis->BuildValue(); if (axis_value->isa()) { - MS_LOG(EXCEPTION) << "" << op_name + MS_LOG(EXCEPTION) << op_name << " evaluator shape's data field can't be anything: " << args_spec_list[1]->ToString(); } auto axis_value_ptr = axis_value->cast(); diff --git a/mindspore/ccsrc/operator/prim_to_function.cc b/mindspore/ccsrc/operator/prim_to_function.cc index 234c829d44..bdfe48157c 100644 --- a/mindspore/ccsrc/operator/prim_to_function.cc +++ b/mindspore/ccsrc/operator/prim_to_function.cc @@ -24,36 +24,35 @@ namespace mindspore { namespace prim { PrimToFunction::PrimToFunction() - : prim_func_type_map_({ - // ONE_ARG prim - {"bool_not", kPrimTypeOneArg}, - {"scalar_cos", kPrimTypeOneArg}, - {"scalar_exp", kPrimTypeOneArg}, - {"scalar_floor", kPrimTypeOneArg}, - {"scalar_log", kPrimTypeOneArg}, - {"scalar_sin", kPrimTypeOneArg}, - {"scalar_tan", kPrimTypeOneArg}, - {"scalar_trunc", kPrimTypeOneArg}, - {"typeof", kPrimTypeOneArg}, - {"scalar_uadd", kPrimTypeOneArg}, - {"scalar_usub", kPrimTypeOneArg}, - // TWO_ARGS prim - {"scalar_add", kPrimTypeTwoArgs}, - {"bool_and", kPrimTypeTwoArgs}, - {"bool_eq", kPrimTypeTwoArgs}, - {"bool_or", kPrimTypeTwoArgs}, - {"scalar_div", kPrimTypeTwoArgs}, - {"scalar_eq", kPrimTypeTwoArgs}, - {"scalar_ge", kPrimTypeTwoArgs}, - {"scalar_gt", kPrimTypeTwoArgs}, - {"scalar_le", kPrimTypeTwoArgs}, - {"scalar_lt", kPrimTypeTwoArgs}, - {"scalar_ne", kPrimTypeTwoArgs}, - {"scalar_mod", kPrimTypeTwoArgs}, - {"scalar_mul", kPrimTypeTwoArgs}, - {"scalar_pow", kPrimTypeTwoArgs}, - {"scalar_sub", kPrimTypeTwoArgs}, - }) {} + : prim_func_type_map_({// ONE_ARG prim + {"bool_not", kPrimTypeOneArg}, + {"scalar_cos", kPrimTypeOneArg}, + {"scalar_exp", kPrimTypeOneArg}, + {"scalar_floor", kPrimTypeOneArg}, + {"scalar_log", kPrimTypeOneArg}, + {"scalar_sin", kPrimTypeOneArg}, + {"scalar_tan", kPrimTypeOneArg}, + {"scalar_trunc", kPrimTypeOneArg}, + {"typeof", kPrimTypeOneArg}, + {"scalar_uadd", kPrimTypeOneArg}, + {"scalar_usub", kPrimTypeOneArg}, + // TWO_ARGS prim + {"scalar_add", kPrimTypeTwoArgs}, + {"bool_and", kPrimTypeTwoArgs}, + {"bool_eq", kPrimTypeTwoArgs}, + {"bool_or", kPrimTypeTwoArgs}, + {"scalar_div", kPrimTypeTwoArgs}, + {"scalar_eq", kPrimTypeTwoArgs}, + {"scalar_ge", kPrimTypeTwoArgs}, + {"scalar_gt", kPrimTypeTwoArgs}, + {"scalar_le", kPrimTypeTwoArgs}, + {"scalar_lt", kPrimTypeTwoArgs}, + {"scalar_ne", kPrimTypeTwoArgs}, + {"scalar_mod", kPrimTypeTwoArgs}, + {"scalar_mul", kPrimTypeTwoArgs}, + {"scalar_pow", kPrimTypeTwoArgs}, + {"scalar_sub", kPrimTypeTwoArgs}, + {"scalar_floordiv", kPrimTypeTwoArgs}}) {} bool PrimToFunction::GetFunction(const PrimitivePtr& prim, FunctionPtr* const func) const { bool result = false; diff --git a/mindspore/ccsrc/optimizer/ad/kprim.cc b/mindspore/ccsrc/optimizer/ad/kprim.cc index 4576cc1ea9..2c8ddbfa82 100644 --- a/mindspore/ccsrc/optimizer/ad/kprim.cc +++ b/mindspore/ccsrc/optimizer/ad/kprim.cc @@ -92,9 +92,11 @@ FuncGraphPtr KPrim::KPrimitive(const ValueNodePtr &value_node, const pipeline::R return nullptr; } + bool is_faked_bprop = false; auto bprop_fg = GetBprop(prim); if (bprop_fg == nullptr) { bprop_fg = FakeBprop(value_node, resources); + is_faked_bprop = true; } auto expanded_fg = BpropToK(prim, bprop_fg); @@ -104,8 +106,11 @@ FuncGraphPtr KPrim::KPrimitive(const ValueNodePtr &value_node, const pipeline::R << trace::GetDebugInfo(bprop_fg->debug_info()); } - // Set bprop_g graph cache - bprop_registry_[prim] = expanded_fg; + // To support primitives with variable params, do not cache faked bprop + if (!is_faked_bprop) { + // Set bprop_g graph cache + bprop_registry_[prim] = expanded_fg; + } return expanded_fg; } diff --git a/mindspore/ccsrc/optimizer/irpass.cc b/mindspore/ccsrc/optimizer/irpass.cc index 0991c31b00..be9c8f787a 100644 --- a/mindspore/ccsrc/optimizer/irpass.cc +++ b/mindspore/ccsrc/optimizer/irpass.cc @@ -40,6 +40,7 @@ #include "optimizer/irpass/incorporate_getitem.h" #include "optimizer/irpass/incorporate_call.h" #include "optimizer/irpass/grad_var_prepare.h" +#include "optimizer/irpass/param_replace.h" namespace mindspore { namespace opt { @@ -51,7 +52,8 @@ OptimizeIRPassLib::OptimizeIRPassLib() { special_op_eliminate_ = MakeSubstitution(SpecialOpEliminater(), "special_op_eliminate", {prim::kPrimInsertGradientOf, prim::kPrimPrintShapeType, prim::kPrimGetRefKey, prim::kPrimMirror, prim::kPrimVirtualDiv}); - zero_like_fill_zero_ = MakeSubstitution(ZeroLikeFillZero(), "zero_like_fill_zero", prim::kPrimZerosLikeTensor); + zero_like_fill_zero_ = + MakeSubstitution(ZeroLikeFillZero(), "zero_like_fill_zero", prim::kPrimZerosLikeTensor, opt::FORCE_RENORM); // ops eliminate item_tuple_eliminate_ = @@ -80,7 +82,10 @@ OptimizeIRPassLib::OptimizeIRPassLib() { make_ref_eliminate_ = MakeSubstitution(MakeRefEliminater(), "make_ref_eliminate", prim::kPrimMakeRef); get_make_ref_eliminate_ = MakeSubstitution(GetMakeRefEliminater(), "get_make_ref_eliminate", {prim::kPrimGetRefKey, prim::kPrimGetRefValue}); - replace_refkey_by_param_ = MakeSubstitution(ReplaceRefkeyByParam(), "replace_refkey_by_param", IsValueNode); + + replace_refkey_by_param_ = + MakeSubstitution(ReplaceRefkeyByParam(), "replace_refkey_by_param", IsValueNode, opt::FORCE_RENORM); + replace_old_param_ = MakeSubstitution(ReplaceOldParam(), "replace_old_param", IsParam); // Gradient transforms expand_jprim_ = MakeSubstitution(ExpandJPrim(), "expand_jprim", prim::kPrimJ); diff --git a/mindspore/ccsrc/optimizer/irpass.h b/mindspore/ccsrc/optimizer/irpass.h index bdaf42b3ed..00274bdcc8 100644 --- a/mindspore/ccsrc/optimizer/irpass.h +++ b/mindspore/ccsrc/optimizer/irpass.h @@ -58,6 +58,7 @@ class OptimizeIRPassLib { SubstitutionPtr make_ref_eliminate_; SubstitutionPtr get_make_ref_eliminate_; SubstitutionPtr replace_refkey_by_param_; + SubstitutionPtr replace_old_param_; // Branch culling SubstitutionPtr switch_simplify_; diff --git a/mindspore/ccsrc/optimizer/irpass/branch_culling.cc b/mindspore/ccsrc/optimizer/irpass/branch_culling.cc index 7c4ada8b3b..d90b2bd44c 100644 --- a/mindspore/ccsrc/optimizer/irpass/branch_culling.cc +++ b/mindspore/ccsrc/optimizer/irpass/branch_culling.cc @@ -51,25 +51,14 @@ bool InConvertWhiteList(const AnfNodePtr &node, size_t index) { // node because it is attribute or ge specific reason. // Example : when convert CNode(kPrimReduceSum, x, axis), node of index 2 in CNode->inputs is axis which should not be // converted to switch guarded. - std::vector>> white_list({{prim::kPrimApplyMomentum, {1, 2}}, - {prim::kPrimMomentum, {2, 3}}, - {prim::kPrimStateSetItem, {1}}, - {prim::kPrimEnvGetItem, {1}}, - {prim::kPrimEnvSetItem, {1}}, - {prim::kPrimReduceSum, {2}}, - {prim::kPrimReduceMean, {2}}, - {prim::kPrimReduceAll, {2}}, - {prim::kPrimCast, {2}}, - {prim::kPrimTranspose, {2}}, - {prim::kPrimOneHot, {2}}, - {prim::kPrimGatherV2, {3}}, - {prim::kPrimReshape, {2}}, - {prim::kPrimAssign, {1}}, - {prim::kPrimAssignAdd, {1}}, - {prim::kPrimAssignSub, {1}}, - {prim::kPrimTensorSummary, {1}}, - {prim::kPrimImageSummary, {1}}, - {prim::kPrimScalarSummary, {1}}}); + std::vector>> white_list( + {{prim::kPrimApplyMomentum, {1, 2}}, {prim::kPrimMomentum, {2, 3}}, {prim::kPrimStateSetItem, {1}}, + {prim::kPrimEnvGetItem, {1}}, {prim::kPrimEnvSetItem, {1}}, {prim::kPrimReduceSum, {2}}, + {prim::kPrimReduceMean, {2}}, {prim::kPrimReduceAll, {2}}, {prim::kPrimCast, {2}}, + {prim::kPrimTranspose, {2}}, {prim::kPrimOneHot, {2}}, {prim::kPrimGatherV2, {3}}, + {prim::kPrimReshape, {2}}, {prim::kPrimAssign, {1}}, {prim::kPrimAssignAdd, {1}}, + {prim::kPrimAssignSub, {1}}, {prim::kPrimTensorSummary, {1}}, {prim::kPrimImageSummary, {1}}, + {prim::kPrimScalarSummary, {1}}, {prim::kPrimHistogramSummary, {1}}}); for (auto &item : white_list) { auto matched = std::any_of(item.second.begin(), item.second.end(), [&item, &node, &index](size_t idx) { return IsPrimitiveCNode(node, item.first) && idx == index; diff --git a/mindspore/ccsrc/optimizer/irpass/incorporate_getitem.h b/mindspore/ccsrc/optimizer/irpass/incorporate_getitem.h index 9dc8e7255b..77f3fa7b36 100644 --- a/mindspore/ccsrc/optimizer/irpass/incorporate_getitem.h +++ b/mindspore/ccsrc/optimizer/irpass/incorporate_getitem.h @@ -15,7 +15,7 @@ */ #ifndef MINDSPORE_CCSRC_OPTIMIZER_IRPASS_INCORPORATE_GETITEM_H_ -#define MINDSPORE_CCSRC_OPTIMIZER_IRPASS_INCORPORATE_GETITEM_H__ +#define MINDSPORE_CCSRC_OPTIMIZER_IRPASS_INCORPORATE_GETITEM_H_ #include #include diff --git a/mindspore/ccsrc/optimizer/irpass/param_replace.h b/mindspore/ccsrc/optimizer/irpass/param_replace.h new file mode 100644 index 0000000000..c0c4c832d7 --- /dev/null +++ b/mindspore/ccsrc/optimizer/irpass/param_replace.h @@ -0,0 +1,60 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_OPTIMIZER_IRPASS_PARAM_REPLACE_H_ +#define MINDSPORE_CCSRC_OPTIMIZER_IRPASS_PARAM_REPLACE_H_ + +#include + +#include "optimizer/optimizer.h" +#include "optimizer/irpass.h" +#include "ir/visitor.h" +#include "operator/ops.h" +#include "pipeline/parse/parse.h" + +namespace mindspore { +namespace opt { +namespace irpass { +class ReplaceOldParam : public AnfVisitor { + public: + AnfNodePtr operator()(const OptimizerPtr &optimizer, const AnfNodePtr &node) override { + if (!IsParam(node)) { + return nullptr; + } + auto resource = std::dynamic_pointer_cast(optimizer->resource()); + MS_EXCEPTION_IF_NULL(resource); + + auto top_graph = resource->func_graph(); // parse::Parser::GetTopFuncGraph(); + MS_EXCEPTION_IF_NULL(top_graph); + + auto param_node = node->cast(); + if (!param_node->has_default() || node->func_graph() == top_graph) { + return nullptr; + } + auto para_name = param_node->name(); + for (const auto &tnode : top_graph->parameters()) { + auto para = tnode->cast(); + if (para != nullptr && para->name() == para_name) { + return para; + } + } + return nullptr; + } +}; +} // namespace irpass +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_OPTIMIZER_IRPASS_PARAM_REPLACE_H_ diff --git a/mindspore/ccsrc/optimizer/opt.cc b/mindspore/ccsrc/optimizer/opt.cc index a0faa2bf46..24339ddb84 100644 --- a/mindspore/ccsrc/optimizer/opt.cc +++ b/mindspore/ccsrc/optimizer/opt.cc @@ -31,14 +31,14 @@ namespace mindspore { /* namespace to support opt */ namespace opt { -SubstitutionPtr MakeSubstitution(const TransformFuncType& transform, const std::string& name, - const PrimitivePtr& prim) { +SubstitutionPtr MakeSubstitution(const TransformFuncType& transform, const std::string& name, const PrimitivePtr& prim, + const RenormAction& renorm_action) { auto fn = [prim](const AnfNodePtr& node) -> bool { return IsPrimitiveCNode(node, prim); }; - return std::make_shared(transform, name, fn); + return std::make_shared(transform, name, fn, renorm_action); } SubstitutionPtr MakeSubstitution(const TransformFuncType& transform, const std::string& name, - const std::vector& prims) { + const std::vector& prims, const RenormAction& renorm_action) { auto fn = [prims](const AnfNodePtr& node) -> bool { if (!node->isa()) { return false; @@ -52,12 +52,12 @@ SubstitutionPtr MakeSubstitution(const TransformFuncType& transform, const std:: return false; }; - return std::make_shared(transform, name, fn); + return std::make_shared(transform, name, fn, renorm_action); } SubstitutionPtr MakeSubstitution(const TransformFuncType& transform, const std::string& name, - const PredicateFuncType& predicate) { - return std::make_shared(transform, name, predicate); + const PredicateFuncType& predicate, const RenormAction& renorm_action) { + return std::make_shared(transform, name, predicate, renorm_action); } AnfNodePtr Substitution::operator()(const OptimizerPtr& optimizer, const AnfNodePtr& node) const { @@ -74,6 +74,16 @@ AnfNodePtr Substitution::operator()(const OptimizerPtr& optimizer, const AnfNode } } #endif + if (optimizer != nullptr && optimizer->is_watch_renormalize() && result != nullptr) { + if (renorm_action_ == FORCE_RENORM) { + optimizer->add_node_to_renormalize(result); + } else { + // renorm_action_ is CHECK_RENORM + if (result->abstract() == nullptr) { + optimizer->add_node_to_renormalize(result); + } + } + } return result; } diff --git a/mindspore/ccsrc/optimizer/opt.h b/mindspore/ccsrc/optimizer/opt.h index bd548645f4..24191998e8 100644 --- a/mindspore/ccsrc/optimizer/opt.h +++ b/mindspore/ccsrc/optimizer/opt.h @@ -36,24 +36,34 @@ using OptimizerWeakPtr = std::weak_ptr; using PredicateFuncType = std::function; using TransformFuncType = std::function; +// Define the interaction mode between an Optimize pass and Renormalize pass +// FORCE_RENORM: if the pass modified the graph then the next Renormalize will be executed +// CHECK_RENORM: check if the new node is un-typed to decide if the next Renormalize will be executted +enum RenormAction : int { FORCE_RENORM = 0, CHECK_RENORM }; + class Substitution { public: TransformFuncType transform_{nullptr}; std::string name_; PredicateFuncType predicate_{nullptr}; - explicit Substitution(const TransformFuncType &transform, const std::string &name, const PredicateFuncType &predicate) - : transform_(transform), name_(name), predicate_(predicate) {} + // an enum to mark this Substitution relation to renormalize pass + RenormAction renorm_action_; + explicit Substitution(const TransformFuncType &transform, const std::string &name, const PredicateFuncType &predicate, + const RenormAction &renorm_action) + : transform_(transform), name_(name), predicate_(predicate), renorm_action_(renorm_action) {} ~Substitution() = default; AnfNodePtr operator()(const OptimizerPtr &optimizer, const AnfNodePtr &node) const; }; using SubstitutionPtr = std::shared_ptr; -SubstitutionPtr MakeSubstitution(const TransformFuncType &transform, const std::string &name, const PrimitivePtr &prim); +SubstitutionPtr MakeSubstitution(const TransformFuncType &transform, const std::string &name, const PrimitivePtr &prim, + const RenormAction &action_renorm = CHECK_RENORM); SubstitutionPtr MakeSubstitution(const TransformFuncType &transform, const std::string &name, - const std::vector &prims); + const std::vector &prims, + const RenormAction &action_renorm = CHECK_RENORM); SubstitutionPtr MakeSubstitution(const TransformFuncType &transform, const std::string &name, - const PredicateFuncType &predicate); + const PredicateFuncType &predicate, const RenormAction &action_renorm = CHECK_RENORM); class SubstitutionList { public: diff --git a/mindspore/ccsrc/optimizer/optimizer.h b/mindspore/ccsrc/optimizer/optimizer.h index d821e826cf..f67466efba 100644 --- a/mindspore/ccsrc/optimizer/optimizer.h +++ b/mindspore/ccsrc/optimizer/optimizer.h @@ -87,11 +87,12 @@ using OptPassGroupMap = std::vector>; class Optimizer : public std::enable_shared_from_this { public: Optimizer(const std::string &name, const pipeline::ResourceBasePtr &resource_ptr) - : name_(name), resource_(resource_ptr), run_only_once_(false) {} + : name_(name), resource_(resource_ptr), run_only_once_(false), is_watch_renormalize_(false) {} virtual ~Optimizer() = default; void Init(const OptPassGroupMap &passes, bool run_only_once) { run_only_once_ = run_only_once; + is_watch_renormalize_ = false; for (auto &iter : passes) { const std::string &name = iter.first; @@ -118,9 +119,13 @@ class Optimizer : public std::enable_shared_from_this { } static std::shared_ptr MakeOptimizer(const std::string &name, const pipeline::ResourceBasePtr resource_ptr, - const OptPassGroupMap &passes, bool run_only_once = false) { + const OptPassGroupMap &passes, bool run_only_once = false, + bool watch_renormalize = false) { OptimizerPtr optimizer = std::make_shared(name, resource_ptr); optimizer->Init(passes, run_only_once); + if (watch_renormalize) { + optimizer->enable_watch_renormalize(); + } return optimizer; } @@ -138,7 +143,16 @@ class Optimizer : public std::enable_shared_from_this { if (opt.is_renormalize()) { auto resource_ptr = std::dynamic_pointer_cast(resource_); if (resource_ptr != nullptr) { - func_graph = pipeline::Renormalize(resource_ptr, func_graph, args_spec); + if (is_watch_renormalize_) { + if (untyped_nodes_.size() > 0) { + func_graph = pipeline::Renormalize(resource_ptr, func_graph, args_spec); + clear_untyped_nodes(); + } else { + MS_LOG(INFO) << "Optimizer::step: Skipping Renormalize because untyped_nodes_ is empty."; + } + } else { + func_graph = pipeline::Renormalize(resource_ptr, func_graph, args_spec); + } } } else if (opt(func_graph, shared_from_this())) { changes = true; @@ -180,12 +194,26 @@ class Optimizer : public std::enable_shared_from_this { const std::string name() const { return name_; } + void add_node_to_renormalize(AnfNodePtr anode) { + if (std::find(untyped_nodes_.begin(), untyped_nodes_.end(), anode) == untyped_nodes_.end()) { + untyped_nodes_.push_back(anode); + } + } + + void clear_untyped_nodes() { untyped_nodes_.clear(); } + + void enable_watch_renormalize() { is_watch_renormalize_ = true; } + void disable_watch_renormalize() { is_watch_renormalize_ = false; } + bool is_watch_renormalize() { return is_watch_renormalize_; } + private: const std::string name_; pipeline::ResourceBasePtr resource_; std::vector passes_; std::vector pass_names_; bool run_only_once_; + std::vector untyped_nodes_; + bool is_watch_renormalize_; }; } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/allreduce_fusion/step_allreduce_fusion.cc b/mindspore/ccsrc/parallel/allreduce_fusion/step_allreduce_fusion.cc index 9dbd3a0246..8ab0895216 100644 --- a/mindspore/ccsrc/parallel/allreduce_fusion/step_allreduce_fusion.cc +++ b/mindspore/ccsrc/parallel/allreduce_fusion/step_allreduce_fusion.cc @@ -38,10 +38,12 @@ bool StepAllreduceFusion(const FuncGraphPtr &root, const opt::OptimizerPtr &opti (root->has_flag(ALLREDUCE_FUSION_RUN_ONCE_ONLY))) { return changes; } - +#if defined(_WIN32) || defined(_WIN64) + auto start_time = std::chrono::steady_clock::now(); +#else struct timeval start_time, end_time; (void)gettimeofday(&start_time, nullptr); - +#endif MS_LOG(INFO) << "Now entering allreduce fusion"; DumpGraph(root, std::string(ALLREDUCE_FUSION_BEGIN)); @@ -63,11 +65,16 @@ bool StepAllreduceFusion(const FuncGraphPtr &root, const opt::OptimizerPtr &opti // allreduce fusion only run once root->flags()[ALLREDUCE_FUSION_RUN_ONCE_ONLY] = true; res->results()[pipeline::kStepParallelGraph] = root; - +#if defined(_WIN32) || defined(_WIN64) + auto end_time = std::chrono::steady_clock::now(); + std::chrono::duration> cost = end_time - start_time; + MS_LOG(INFO) << "Now leaving allreduce fusion, used time: " << cost.count() << " us"; +#else (void)gettimeofday(&end_time, nullptr); uint64_t time = 1000000 * static_cast(end_time.tv_sec - start_time.tv_sec); time += static_cast(end_time.tv_usec - start_time.tv_usec); MS_LOG(INFO) << "Now leaving allreduce fusion, used time: " << time << " us"; +#endif return changes; } } // namespace parallel diff --git a/mindspore/ccsrc/parallel/auto_parallel/costmodel.h b/mindspore/ccsrc/parallel/auto_parallel/costmodel.h index 229f0fbf5e..9e9003848b 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/costmodel.h +++ b/mindspore/ccsrc/parallel/auto_parallel/costmodel.h @@ -207,15 +207,13 @@ struct ContractEliminationDecision : public Decision { */ struct TriangleEliminationDecision : public Decision { TriangleEliminationDecision(StrategyPtr elimi_stra, CostPtr elimi_op_cost, CostPtr l_edge_cost, CostPtr r_edge_cost, - StrategyPtr left_stra, CostPtr l_node_cost, StrategyPtr right_stra, CostPtr r_node_cost) + StrategyPtr left_stra, CostPtr l_node_cost) : eliminated_op_strategy_(std::move(elimi_stra)), eliminated_op_cost_(std::move(elimi_op_cost)), left_edge_cost_(std::move(l_edge_cost)), right_edge_cost_(std::move(r_edge_cost)), left_node_strategy_(std::move(left_stra)), - left_node_cost_(std::move(l_node_cost)), - right_node_strategy_(std::move(right_stra)), - right_node_cost_(std::move(r_node_cost)) { + left_node_cost_(std::move(l_node_cost)) { type_ = DecisionType::TRIANGLE_ELIMINATION; } @@ -225,8 +223,6 @@ struct TriangleEliminationDecision : public Decision { CostPtr right_edge_cost_; StrategyPtr left_node_strategy_; CostPtr left_node_cost_; - StrategyPtr right_node_strategy_; - CostPtr right_node_cost_; MS_DECLARE_PARENT(TriangleEliminationDecision, Decision); }; diff --git a/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.cc b/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.cc index 060caa4cca..dd21096fcc 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.cc +++ b/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.cc @@ -76,7 +76,6 @@ Status GetStrategy(const CostGraphPtr& graph) { auto l_r_edge = triangle_pair.second; auto left_node = l_r_edge->prev_operator(); - auto right_node = l_r_edge->next_operator(); auto left_edge = eliminated_node->GetAliveSuccEdges()[0]; auto right_edge = eliminated_node->GetAliveSuccEdges()[1]; MS_EXCEPTION_IF_NULL(left_edge); @@ -86,8 +85,7 @@ Status GetStrategy(const CostGraphPtr& graph) { right_edge = tmp; } auto left_node_cpy = graph->EliminationTriangle(eliminated_node, l_r_edge); - auto elimi = - std::make_shared(eliminated_node, left_edge, left_node_cpy, right_edge, right_node); + auto elimi = std::make_shared(eliminated_node, left_edge, left_node_cpy, right_edge); eliminations.emplace_back(std::move(elimi)); } auto star_center = graph->CheckStarElimination(); @@ -183,14 +181,13 @@ Status RecoverStrategy(std::vector eliminations) { auto left_edge = elimination->left_edge_; auto eliminated_node = elimination->eliminated_node_; auto right_edge = elimination->right_edge_; - auto right_node = elimination->right_node_; auto decision = left_node->selected_cost()->decision_ptr_->cast(); eliminated_node->SetSelectedStrategyAndCost(decision->eliminated_op_strategy_, decision->eliminated_op_cost_); left_edge->set_selected_cost(decision->left_edge_cost_); right_edge->set_selected_cost(decision->right_edge_cost_); + // Since Triangle is eliminated into 'left_node', only 'left_node' is needed to recover the strategy. left_node->SetSelectedStrategyAndCost(decision->left_node_strategy_, decision->left_node_cost_); - right_node->SetSelectedStrategyAndCost(decision->right_node_strategy_, decision->right_node_cost_); MS_LOG(INFO) << "Recover triangleElimination succeeded."; } else if ((*rit)->isa()) { auto elimination = (*rit)->cast(); @@ -204,9 +201,11 @@ Status RecoverStrategy(std::vector eliminations) { for (size_t i = 0; i < succ_edges.size(); ++i) { succ_edges[i]->set_selected_cost(decision->succ_edges_cost_list_[i]); } - for (size_t j = 0; j < succ_nodes.size(); ++j) { - succ_nodes[j]->SetSelectedStrategyAndCost(decision->succ_ops_stra_list_[j], decision->succ_ops_cost_list_[j]); - } + MS_EXCEPTION_IF_NULL(succ_nodes[0]); + MS_EXCEPTION_IF_NULL(decision->succ_ops_stra_list_[0]); + MS_EXCEPTION_IF_NULL(decision->succ_ops_cost_list_[0]); + // Since Star is eliminated into 'succ_nodes[0]', only 'succ_nodes[0]' is needed to recover the strategy. + succ_nodes[0]->SetSelectedStrategyAndCost(decision->succ_ops_stra_list_[0], decision->succ_ops_cost_list_[0]); MS_LOG(INFO) << "Recover starElimination succeeded."; } else { MS_LOG(ERROR) << "Unknown Elimination type."; diff --git a/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.h b/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.h index 0cb58c49da..6d43218e19 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.h +++ b/mindspore/ccsrc/parallel/auto_parallel/dp_algo_costmodel.h @@ -102,20 +102,17 @@ struct ContractElimination : public Elimination { // Triangle Elimination struct TriangleElimination : public Elimination { - TriangleElimination(OperatorInfoPtr elim_node, EdgePtr l_edge, OperatorInfoPtr l_node, EdgePtr r_edge, - OperatorInfoPtr r_node) + TriangleElimination(OperatorInfoPtr elim_node, EdgePtr l_edge, OperatorInfoPtr l_node, EdgePtr r_edge) : Elimination(nullptr, Elimination::EliminationType::TRIANGLE), eliminated_node_(std::move(elim_node)), left_edge_(std::move(l_edge)), left_node_(std::move(l_node)), - right_edge_(std::move(r_edge)), - right_node_(std::move(r_node)) {} + right_edge_(std::move(r_edge)) {} OperatorInfoPtr eliminated_node_; EdgePtr left_edge_; OperatorInfoPtr left_node_; EdgePtr right_edge_; - OperatorInfoPtr right_node_; MS_DECLARE_PARENT(TriangleElimination, Elimination); }; diff --git a/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.cc b/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.cc index 653f6c903d..21e67f9f7b 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.cc +++ b/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.cc @@ -61,11 +61,12 @@ Status Edge::InitEdgeCost() { auto target_output_lyt = target_output.second[prev_op_output_index_].tensor_layout(); auto target_output_str = target_output.first; auto type_length = prev_op_->GetOutputTypeLengths()[prev_op_output_index_]; + auto type = prev_op_->outputs_type()[prev_op_output_index_]; for (auto& target_input : next_op_input_) { auto target_input_lyt = target_input.second[next_op_input_index_].tensor_layout(); auto target_input_str = target_input.first; CostPtr cost; - if (GetRedistributionCost(target_output_lyt, target_input_lyt, type_length, &cost) != SUCCESS) { + if (GetRedistributionCost(target_output_lyt, target_input_lyt, type_length, type, &cost) != SUCCESS) { MS_LOG(EXCEPTION) << "Failure: redistribution cost calculation failed"; } MS_EXCEPTION_IF_NULL(cost); @@ -84,10 +85,10 @@ Status Edge::InitEdgeCost() { } } if (!has_available_cost) { - if (!NOT_FULLY_USE_DEVICES) { + if (FULLY_USE_DEVICES) { MS_LOG(EXCEPTION) << "Generating cost for edge: " << edge_name_ - << " failed, it may be caused by setting 'not_fully_use_devices' false. Try to set " - "'not_fully_use_devices' true."; + << " failed, it may be caused by setting 'fully_use_devices' true. Try to set " + "'fully_use_devices' false."; } else if (ELEMENTWISE_OP_STRA_FOLLOW) { MS_LOG(EXCEPTION) << "Generating cost for edge: " << edge_name_ << " failed, it may be caused by setting 'elementwise_op_strategy_follow' true. " @@ -99,7 +100,7 @@ Status Edge::InitEdgeCost() { } Status Edge::GetRedistributionCost(const TensorLayout& prev_op_output_layout, const TensorLayout& next_op_input_layout, - size_t type_length, CostPtr* cost) { + size_t type_length, TypePtr type, CostPtr* cost) { MS_EXCEPTION_IF_NULL(prev_op_); MS_EXCEPTION_IF_NULL(cost); RankList dev_list = prev_op_->global_device_list(); @@ -118,7 +119,15 @@ Status Edge::GetRedistributionCost(const TensorLayout& prev_op_output_layout, co double forward_comm_cost = tensor_redistribution.forward_comm_cost(); double backward_comm_cost = tensor_redistribution.backward_comm_cost(); double computation_cost = tensor_redistribution.computation_cost(); + double mem_cost = tensor_redistribution.memory_cost(); + // Now AllGather, ReduceScatter, AlltoAll don't support bool type + MS_EXCEPTION_IF_NULL(type); + if ((type->type_id() == kNumberTypeBool) && (comm_cost > 0)) { + computation_cost = INF; + comm_cost = INF; + MS_LOG(WARNING) << "Communication Operators don't support bool dtype!"; + } *cost = std::make_shared(type_length * computation_cost, type_length * comm_cost); (*cost)->communication_without_parameter_ = type_length * comm_cost; (*cost)->communication_with_partial_para_ = @@ -126,6 +135,7 @@ Status Edge::GetRedistributionCost(const TensorLayout& prev_op_output_layout, co COST_MODEL_GAMMA * ((*cost)->communication_cost_ - (*cost)->communication_without_parameter_); (*cost)->communication_redis_forward_ = type_length * forward_comm_cost; (*cost)->communication_redis_backward_ = type_length * backward_comm_cost; + (*cost)->memory_with_reuse_ = mem_cost; return Status::SUCCESS; } @@ -150,8 +160,8 @@ CostPtrList Edge::CreateEdgeEliminationCostList(const StrategyPtr& output_st_ptr (void)std::transform(edges.begin(), edges.end(), all_cost_list.begin(), LocalGetCostList); CostPtrList selected_cost_list(all_cost_list.size(), nullptr); - std::function recursive = - [&](size_t k, double computation, double communication, double communication_without_para) { + std::function recursive = + [&](size_t k, double computation, double memory, double communication, double communication_without_para) { if (k == edges.size()) { auto decision = std::make_shared(selected_cost_list); CostPtr new_cost = std::make_shared(computation, communication); @@ -159,6 +169,7 @@ CostPtrList Edge::CreateEdgeEliminationCostList(const StrategyPtr& output_st_ptr new_cost->communication_without_parameter_ = communication_without_para; new_cost->communication_with_partial_para_ = communication_without_para + COST_MODEL_GAMMA * (communication - communication_without_para); + new_cost->memory_with_reuse_ = memory; new_cost->decision_ptr_ = decision; result.push_back(new_cost); return; @@ -166,11 +177,12 @@ CostPtrList Edge::CreateEdgeEliminationCostList(const StrategyPtr& output_st_ptr for (auto& c : all_cost_list[k]) { MS_EXCEPTION_IF_NULL(c); selected_cost_list[k] = c; - recursive(k + 1, computation + c->computation_cost_, communication + c->communication_cost_, + recursive(k + 1, computation + c->computation_cost_, memory + c->memory_with_reuse_, + communication + c->communication_cost_, communication_without_para + c->communication_without_parameter_); } }; - recursive(0, 0, 0, 0); + recursive(0, 0.0, 0.0, 0.0, 0.0); SimplifyForDreasingCommunicationWithPartialPara(&result); return result; } @@ -210,6 +222,8 @@ void Edge::CreateOpEliminationSubCostList(StrategyPtr op_strategy, const CostPtr double communication_without_para = left_cost->communication_without_parameter_ + middle_cost->communication_without_parameter_ + right_cost->communication_without_parameter_; + double memory_cost = + left_cost->memory_with_reuse_ + middle_cost->memory_with_reuse_ + right_cost->memory_with_reuse_; auto decision = std::make_shared(op_strategy, left_cost, middle_cost, right_cost); auto cost = std::make_shared(computation, communication, decision); @@ -217,6 +231,7 @@ void Edge::CreateOpEliminationSubCostList(StrategyPtr op_strategy, const CostPtr cost->communication_without_parameter_ = communication_without_para; cost->communication_with_partial_para_ = communication_without_para + COST_MODEL_GAMMA * (communication - communication_without_para); + cost->memory_with_reuse_ = memory_cost; ret_cost_list->emplace_back(std::move(cost)); } } @@ -259,5 +274,24 @@ void Edge::OpEliminationSetNewCost(const EdgePtr& e1, const OperatorInfoPtr& op, MS_LOG(EXCEPTION) << "Creating edge: " << edge_name_ << " failed."; } } + +Status Edge::CalculateMemoryCost() { + if (is_output_parameter_involve_ == -1) { + MS_LOG(ERROR) << "is_output_parameter_involve_ is unset."; + return FAILED; + } + if (is_output_parameter_involve_ == 0) { + // In this case, it is sure that the tensor redistribution along this edge is NOT parameter-involved, thus it is + // unnecessary to keep them in memory. + for (auto& cost_kv : cost_map_) { + auto& cost_v = cost_kv.second; + if (!cost_v.empty()) { + cost_v[0]->memory_with_reuse_ = 0; + } + } + } + + return SUCCESS; +} } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.h b/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.h index eb89466d7c..f974125749 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.h +++ b/mindspore/ccsrc/parallel/auto_parallel/edge_costmodel.h @@ -84,7 +84,7 @@ class Edge { // and the input tensor layout of v, return the redistribution cost, // and the op_list to carry out the redistribution. Status GetRedistributionCost(const TensorLayout& prev_op_output_layout, const TensorLayout& next_op_input_layout, - size_t, CostPtr* cost); + size_t, TypePtr type, CostPtr* cost); void set_pre_op_output(const std::vector, std::vector>>& output_set) { pre_op_output_ = output_set; @@ -133,7 +133,7 @@ class Edge { void set_parameter_involve(int para_invol) { is_output_parameter_involve_ = para_invol; } // When the input of a operator contains WEIGHT or a output from other operators involving WEIGHT, then these input // should stay in memory until it is used in the backward phase, which is kept in memory at the end of forward phase. - Status CalculateMemoryCost() const { return SUCCESS; } + Status CalculateMemoryCost(); private: std::string edge_name_; diff --git a/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.cc b/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.cc index 88a54662d3..c56d3a6fbd 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.cc +++ b/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.cc @@ -36,7 +36,7 @@ double COST_MODEL_COMMUNI_CONST = DEFAULT_COST_MODEL_COMMUNI_CONST; double COST_MODEL_COMMUNI_BIAS = DEFAULT_COST_MODEL_COMMUNI_BIAS; bool TENSOR_SLICE_ALIGNMENT_ENABLE = DEFAULT_TENSOR_SLICE_ALIGNMENT_ENABLE; size_t TENSOR_SLICE_ALIGNMENT_SIZE = DEFAULT_TENSOR_SLICE_ALIGNMENT_SIZE; -bool NOT_FULLY_USE_DEVICES = DEFAULT_NOT_FULLY_USE_DEVICES; +bool FULLY_USE_DEVICES = DEFAULT_FULLY_USE_DEVICES; bool ELEMENTWISE_OP_STRA_FOLLOW = DEFAULT_ELEMENTWISE_OP_STRA_FOLLOW; void CostGraph::SetDeviceMemoryAndCostParameter() { @@ -125,13 +125,13 @@ void CostGraph::SetDeviceMemoryAndCostParameter() { TENSOR_SLICE_ALIGNMENT_SIZE = align_size; MS_LOG(INFO) << "tensor_slice_align_size: " << TENSOR_SLICE_ALIGNMENT_SIZE << "."; - // NOT_FULLY_USE_DEVICES - auto not_fully_devices = CostModelContext::GetInstance()->not_fully_use_device(); - NOT_FULLY_USE_DEVICES = not_fully_devices; - if (NOT_FULLY_USE_DEVICES) { - MS_LOG(INFO) << "not_fully_use_devices: true."; + // FULLY_USE_DEVICES + auto fully_devices = CostModelContext::GetInstance()->fully_use_device(); + FULLY_USE_DEVICES = fully_devices; + if (FULLY_USE_DEVICES) { + MS_LOG(INFO) << "fully_use_devices: true."; } else { - MS_LOG(INFO) << "not_fully_use_devices: false."; + MS_LOG(INFO) << "fully_use_devices: false."; } // ELEMENTWISE_OP_STRA_FOLLOW @@ -248,6 +248,7 @@ CostPtrList CostGraph::CreateFinalCostList(const OperatorInfoPtr& u, const std:: MS_EXCEPTION_IF_NULL(cost2); MS_EXCEPTION_IF_NULL(cost3); double computation = cost1->computation_cost_ + cost2->computation_cost_ + cost3->computation_cost_; + double memory = cost1->memory_with_reuse_ + cost2->memory_with_reuse_ + cost3->memory_with_reuse_; double commmunication = cost1->communication_cost_ + cost2->communication_cost_ + cost3->communication_cost_; double communication_without_para = cost1->communication_without_parameter_ + @@ -260,6 +261,7 @@ CostPtrList CostGraph::CreateFinalCostList(const OperatorInfoPtr& u, const std:: cost->communication_without_parameter_ = communication_without_para; cost->communication_with_partial_para_ = communication_without_para + COST_MODEL_GAMMA * (commmunication - communication_without_para); + cost->memory_with_reuse_ = memory; ret.push_back(cost); } } @@ -288,6 +290,7 @@ CostPtrList CostGraph::CreateFinalSingleCostList(const OperatorInfoPtr& u) { new_cost->communication_with_partial_para_ = cost1->communication_without_parameter_ + COST_MODEL_GAMMA * (cost1->communication_cost_ - cost1->communication_without_parameter_); + new_cost->memory_with_reuse_ = cost1->memory_with_reuse_; ret.push_back(new_cost); } } @@ -297,9 +300,14 @@ CostPtrList CostGraph::CreateFinalSingleCostList(const OperatorInfoPtr& u) { } CostPtr CostGraph::SelectCostWithMemoryConstraint(const CostPtrList& cost_list, double memory) { - if (cost_list.empty() || cost_list[0]->computation_cost_ >= memory) { - return nullptr; + CostPtrList after_mem_filter; + // Filter out the valid costs + for (auto& a_cost : cost_list) { + if (a_cost->memory_with_reuse_ <= memory) { + after_mem_filter.emplace_back(std::move(a_cost)); + } } + std::function LocalCompare = [&](CostPtr init, const CostPtr& cost_x) { MS_EXCEPTION_IF_NULL(cost_x); if (init == nullptr || cost_x->computation_cost_ < memory) { @@ -308,7 +316,7 @@ CostPtr CostGraph::SelectCostWithMemoryConstraint(const CostPtrList& cost_list, return init; }; CostPtr ret = nullptr; - return std::accumulate(cost_list.begin(), cost_list.end(), ret, LocalCompare); + return std::accumulate(after_mem_filter.begin(), after_mem_filter.end(), ret, LocalCompare); } CostPtr CostGraph::SelectCostWithMinTrainingTime(const CostPtrList& cost_list, double memory) { @@ -318,36 +326,46 @@ CostPtr CostGraph::SelectCostWithMinTrainingTime(const CostPtrList& cost_list, d MS_LOG(ERROR) << "Final cost list is null."; return nullptr; } - CostPtr ret = cost_list[0]; - MS_EXCEPTION_IF_NULL(ret); - if (ret->computation_cost_ >= memory) { - MS_LOG(ERROR) << "No available cost; the minimum cost is " << ret->computation_cost_ + CostPtrList after_mem_filter; + double minimum_memory = DBL_MAX; + // Filter out the valid costs. + for (auto& a_cost : cost_list) { + if (a_cost->memory_with_reuse_ <= memory) { + after_mem_filter.emplace_back(std::move(a_cost)); + } else if (a_cost->memory_with_reuse_ < minimum_memory) { + minimum_memory = a_cost->memory_with_reuse_; + } + } + if (after_mem_filter.empty()) { + MS_LOG(ERROR) << "No available cost. The minimum memory cost is: " << minimum_memory << ", the memory capacity is: " << memory << "."; return nullptr; } + // Init the returned value with first cost. + CostPtr ret = after_mem_filter[0]; + double minimum = costmodel_alpha_ * ret->computation_cost_ + costmodel_beta_ * ret->communication_with_partial_para_; - MS_LOG(INFO) << "minimum: " << minimum << ", computation_cost_: " << ret->computation_cost_ + MS_LOG(INFO) << "Cost 0: " + << "memory_cost: " << ret->memory_with_reuse_ << ", computation_cost_: " << ret->computation_cost_ << ", communication_with_partial_para_: " << ret->communication_with_partial_para_ << ", communication_cost_: " << ret->communication_cost_ << ", communication_without_parameter_: " << ret->communication_without_parameter_ << "."; - for (size_t i = 1; i < cost_list.size(); ++i) { - MS_EXCEPTION_IF_NULL(cost_list[i]); - if (cost_list[i]->computation_cost_ >= memory) { - MS_LOG(INFO) << "cost_list " << i << " computation_cost_: " << cost_list[i]->computation_cost_ - << ", is larger than the memory capacity: " << memory << "."; - break; - } - MS_LOG(INFO) << "cost_list " << i << " computation_cost_: " << cost_list[i]->computation_cost_ - << ", communication_with_partial_para_: " << cost_list[i]->communication_with_partial_para_ - << ", communication_cost_: " << cost_list[i]->communication_cost_ - << ", communication_without_parameter_: " << cost_list[i]->communication_without_parameter_ << "."; - auto tmp = costmodel_alpha_ * cost_list[i]->computation_cost_ + - costmodel_beta_ * cost_list[i]->communication_with_partial_para_; - MS_LOG(INFO) << "tmp: " << tmp; + MS_LOG(INFO) << "Cost 0: totoal_cost: " << minimum; + for (size_t i = 1; i < after_mem_filter.size(); ++i) { + MS_EXCEPTION_IF_NULL(after_mem_filter[i]); + MS_LOG(INFO) << "Cost " << i << ": memory_cost: " << after_mem_filter[i]->memory_with_reuse_ + << ", computation_cost_: " << after_mem_filter[i]->computation_cost_ + << ", communication_with_partial_para_: " << after_mem_filter[i]->communication_with_partial_para_ + << ", communication_cost_: " << after_mem_filter[i]->communication_cost_ + << ", communication_without_parameter_: " << after_mem_filter[i]->communication_without_parameter_ + << "."; + auto tmp = costmodel_alpha_ * after_mem_filter[i]->computation_cost_ + + costmodel_beta_ * after_mem_filter[i]->communication_with_partial_para_; + MS_LOG(INFO) << "Cost " << i << ": total_cost: " << tmp; if (minimum > tmp) { minimum = tmp; - ret = cost_list[i]; - MS_LOG(INFO) << "selected: " << i; + ret = after_mem_filter[i]; + MS_LOG(INFO) << "Selected: " << i; } } return ret; @@ -356,17 +374,21 @@ CostPtr CostGraph::SelectCostWithMinTrainingTime(const CostPtrList& cost_list, d CostPtrList CostGraph::SelectCostListWithMinTrainingTimeMultiple(const std::vector& all_cost_list, double available_memory) { CostPtrList selected_cost_list(all_cost_list.size(), nullptr); - double minimum = 0.0, total_memory = 0.0; + double minimum = DBL_MAX, total_memory = 0.0; CostPtrList ret(all_cost_list.size(), nullptr); + // Check whether valid costs exist. for (size_t i = 0; i < all_cost_list.size(); ++i) { if (all_cost_list[i][0] == nullptr) { MS_LOG(ERROR) << "The cost list " << i << " is empty."; return ret; } else { - total_memory += all_cost_list[i][0]->computation_cost_; - minimum += costmodel_alpha_ * all_cost_list[i][0]->computation_cost_ + - costmodel_beta_ * all_cost_list[i][0]->communication_with_partial_para_; - ret[i] = all_cost_list[i][0]; + double memory_i_cost = DBL_MAX; + for (size_t j = 0; j < all_cost_list[i].size(); ++j) { + if (all_cost_list[i][j]->memory_with_reuse_ < memory_i_cost) { + memory_i_cost = all_cost_list[i][j]->memory_with_reuse_; + } + } + total_memory += memory_i_cost; } } if (total_memory >= available_memory) { @@ -381,7 +403,7 @@ CostPtrList CostGraph::SelectCostListWithMinTrainingTimeMultiple(const std::vect double tmp_memory = 0.0, tmp_minimum = 0.0; for (size_t i = 0; i < selected_cost_list.size(); ++i) { MS_EXCEPTION_IF_NULL(selected_cost_list[i]); - tmp_memory += selected_cost_list[i]->computation_cost_; + tmp_memory += selected_cost_list[i]->memory_with_reuse_; tmp_minimum += costmodel_alpha_ * selected_cost_list[i]->computation_cost_ + costmodel_beta_ * selected_cost_list[i]->communication_with_partial_para_; } @@ -816,6 +838,7 @@ void CostGraph::CreateMergeEliminationSubCostList(StrategyPtr op_strategy, const auto& tar_cost = tar_cost_list[k]; MS_EXCEPTION_IF_NULL(tar_cost); double computation = op_cost->computation_cost_ + edge_cost->computation_cost_ + tar_cost->computation_cost_; + double memory = op_cost->memory_with_reuse_ + edge_cost->memory_with_reuse_ + tar_cost->memory_with_reuse_; double communication = op_cost->communication_cost_ + edge_cost->communication_cost_ + tar_cost->communication_cost_; double communication_without_para = op_cost->communication_without_parameter_ + @@ -829,6 +852,7 @@ void CostGraph::CreateMergeEliminationSubCostList(StrategyPtr op_strategy, const new_cost->communication_without_parameter_ = communication_without_para; new_cost->communication_with_partial_para_ = communication_without_para + COST_MODEL_GAMMA * (communication - communication_without_para); + new_cost->memory_with_reuse_ = memory; MS_EXCEPTION_IF_NULL(tar_cost_list_new); tar_cost_list_new->emplace_back(std::move(new_cost)); } @@ -894,6 +918,8 @@ void CostGraph::CreateContractEliminationSubCostList(StrategyPtr contract_op_str MS_EXCEPTION_IF_NULL(tar_cost); double computation = contract_op_cost->computation_cost_ + edge_cost->computation_cost_ + tar_cost->computation_cost_; + double memory = + contract_op_cost->memory_with_reuse_ + edge_cost->memory_with_reuse_ + tar_cost->memory_with_reuse_; double communication = contract_op_cost->communication_cost_ + edge_cost->communication_cost_ + tar_cost->communication_cost_; double communication_without_para = contract_op_cost->communication_without_parameter_ + @@ -906,6 +932,7 @@ void CostGraph::CreateContractEliminationSubCostList(StrategyPtr contract_op_str new_cost->communication_without_parameter_ = communication_without_para; new_cost->communication_with_partial_para_ = communication_without_para + COST_MODEL_GAMMA * (communication - communication_without_para); + new_cost->memory_with_reuse_ = memory; tar_cost_list_new->emplace_back(std::move(new_cost)); } } @@ -966,23 +993,22 @@ void CostGraph::CreateTriangleEliminationSubCostList(StrategyPtr elimi_op_stra, for (auto& left_node_cost : left_node_clist_origin) { MS_EXCEPTION_IF_NULL(left_node_cost); double new_computation = elimi_op_cost->computation_cost_ + left_edge_cost->computation_cost_ + - left_node_cost->computation_cost_ + right_edge_cost->computation_cost_ + - right_op_cost->computation_cost_; + left_node_cost->computation_cost_ + right_edge_cost->computation_cost_; + double new_memory = elimi_op_cost->memory_with_reuse_ + left_edge_cost->memory_with_reuse_ + + left_node_cost->memory_with_reuse_ + right_edge_cost->memory_with_reuse_; double new_commu_cost = elimi_op_cost->communication_cost_ + left_edge_cost->communication_cost_ + - left_node_cost->communication_cost_ + right_edge_cost->communication_cost_ + - right_op_cost->communication_cost_; + left_node_cost->communication_cost_ + right_edge_cost->communication_cost_; double new_commu_without = elimi_op_cost->communication_without_parameter_ + left_edge_cost->communication_without_parameter_ + - left_node_cost->communication_without_parameter_ + right_edge_cost->communication_without_parameter_ + - right_op_cost->communication_without_parameter_; + left_node_cost->communication_without_parameter_ + right_edge_cost->communication_without_parameter_; - auto decision = - std::make_shared(elimi_op_stra, elimi_op_cost, left_edge_cost, right_edge_cost, - left_op_stra, left_node_cost, right_op_stra, right_op_cost); + auto decision = std::make_shared(elimi_op_stra, elimi_op_cost, left_edge_cost, + right_edge_cost, left_op_stra, left_node_cost); auto new_cost = std::make_shared(new_computation, new_commu_cost, decision); new_cost->communication_without_parameter_ = new_commu_without; new_cost->communication_with_partial_para_ = new_commu_without + COST_MODEL_GAMMA * (new_commu_cost - new_commu_without); + new_cost->memory_with_reuse_ = new_memory; left_node_clist_new->emplace_back(std::move(new_cost)); } } @@ -1085,14 +1111,22 @@ void CostGraph::CreateStarEliminationSubCostList(const StrategyPtr& first_succ_n succ_nodes_costs[0] = first_succ_node_cost; double computation_cost = merged_node_cost->computation_cost_, - commu_cost = merged_node_cost->communication_cost_, + memory_cost = merged_node_cost->memory_with_reuse_, commu_cost = merged_node_cost->communication_cost_, commu_without = merged_node_cost->communication_without_parameter_; for (size_t i = 0; i < succ_nodes_stras.size(); ++i) { MS_EXCEPTION_IF_NULL(succ_edges_costs[i]); - computation_cost += succ_edges_costs[i]->computation_cost_ + succ_nodes_costs[i]->computation_cost_; - commu_cost += succ_edges_costs[i]->communication_cost_ + succ_nodes_costs[i]->communication_cost_; - commu_without += succ_edges_costs[i]->communication_without_parameter_ + - succ_nodes_costs[i]->communication_without_parameter_; + if (i == 0) { + computation_cost += succ_edges_costs[i]->computation_cost_ + succ_nodes_costs[i]->computation_cost_; + memory_cost += succ_edges_costs[i]->memory_with_reuse_ + succ_nodes_costs[i]->memory_with_reuse_; + commu_cost += succ_edges_costs[i]->communication_cost_ + succ_nodes_costs[i]->communication_cost_; + commu_without += succ_edges_costs[i]->communication_without_parameter_ + + succ_nodes_costs[i]->communication_without_parameter_; + } else { + computation_cost += succ_edges_costs[i]->computation_cost_; + memory_cost += succ_edges_costs[i]->memory_with_reuse_; + commu_cost += succ_edges_costs[i]->communication_cost_; + commu_without += succ_edges_costs[i]->communication_without_parameter_; + } } auto decision = std::make_shared(merged_op_stra, merged_node_cost, succ_edges_costs, @@ -1100,6 +1134,7 @@ void CostGraph::CreateStarEliminationSubCostList(const StrategyPtr& first_succ_n auto new_cost = std::make_shared(computation_cost, commu_cost, decision); new_cost->communication_without_parameter_ = commu_without; new_cost->communication_with_partial_para_ = commu_without + COST_MODEL_GAMMA * (commu_cost - commu_without); + new_cost->memory_with_reuse_ = memory_cost; first_succ_node_clist_new->emplace_back(std::move(new_cost)); } } @@ -1259,5 +1294,35 @@ OperatorInfoPtr CostGraph::FindTmpIdentityByParameterName(std::string& p_name) c } return nullptr; } +Status CostGraph::CorrectOpsMemoryCost() { + for (auto& one_op : ops_) { + if ((one_op->name().find(IDENTITY_INFO) != std::string::npos) && (one_op->is_output_parameter_involve() == 1)) { + if (one_op->GetAliveSuccEdges().size() > 1) { + // Filter out the case when the TmpIdentity being used by multiple operators + std::map output_count; + for (size_t i = 0; i < one_op->GetAliveSuccEdges().size(); ++i) { + auto output_index = one_op->GetAliveSuccEdges()[i]->prev_op_output_index(); + output_count[output_index]++; + } + for (size_t i = 0; i < one_op->GetAliveSuccEdges().size(); ++i) { + auto output_index = one_op->GetAliveSuccEdges()[i]->prev_op_output_index(); + if (output_count[output_index] <= 1) { + continue; + } + auto next_op = one_op->GetAliveSuccEdges()[i]->next_operator(); + MS_EXCEPTION_IF_NULL(next_op); + auto input_index = one_op->GetAliveSuccEdges()[i]->next_op_input_index(); + if (next_op->CorrectMemoryCost(input_index) != SUCCESS) { + MS_LOG(ERROR) << "The operator name: " << one_op->name() << ", the next operator name: " << next_op->name() + << ", the output_index: " << output_index << ", the input_index: " << input_index << "."; + return FAILED; + } + output_count[output_index]--; + } + } + } + } + return SUCCESS; +} } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.h b/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.h index c149534826..b6591c0741 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.h +++ b/mindspore/ccsrc/parallel/auto_parallel/graph_costmodel.h @@ -42,7 +42,7 @@ namespace parallel { #define DEFAULT_COST_MODEL_COMMUNI_BIAS 1024.0 #define DEFAULT_TENSOR_SLICE_ALIGNMENT_ENABLE false #define DEFAULT_TENSOR_SLICE_ALIGNMENT_SIZE 16 -#define DEFAULT_NOT_FULLY_USE_DEVICES false +#define DEFAULT_FULLY_USE_DEVICES true #define DEFAULT_ELEMENTWISE_OP_STRA_FOLLOW false class CostGraph; @@ -57,7 +57,7 @@ extern double COST_MODEL_COMMUNI_CONST; extern double COST_MODEL_COMMUNI_BIAS; extern bool TENSOR_SLICE_ALIGNMENT_ENABLE; extern size_t TENSOR_SLICE_ALIGNMENT_SIZE; -extern bool NOT_FULLY_USE_DEVICES; +extern bool FULLY_USE_DEVICES; extern bool ELEMENTWISE_OP_STRA_FOLLOW; class CostGraph { @@ -187,6 +187,9 @@ class CostGraph { size_t GetNumPairs() const { return edges_.size(); } Status InitSelectedStrategy(); OperatorInfoPtr FindTmpIdentityByParameterName(std::string&) const; + // When TmpIdentity is used by mulitple operators, the corresponding parameter's memory cost should be calculated only + // once (instead of multiple times), this method is used to correct this. + Status CorrectOpsMemoryCost(); // Needed by rec_parser void add_inputs_tensor_name(const std::vector& inputs_tensor_name) { inputs_tensor_name_list_.push_back(inputs_tensor_name); diff --git a/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.cc b/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.cc index 93d7dc56c5..0192dce8b8 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.cc +++ b/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.cc @@ -17,6 +17,7 @@ #include "parallel/auto_parallel/operator_costmodel.h" #include +#include #include "parallel/device_matrix.h" #include "parallel/tensor_layout/tensor_redistribution.h" @@ -24,15 +25,47 @@ namespace mindspore { namespace parallel { void OperatorCost::set_is_parameter(const std::vector& is_parameter) { is_parameter_ = is_parameter; } +void OperatorCost::set_is_parameter_involve(const std::vector& is_parameter_inv) { + is_parameter_involve_ = is_parameter_inv; +} + +void OperatorCost::set_output_parameter_involve(int output_para) { output_parameter_involve_ = output_para; } + void OperatorCost::SetInputAndOutputTypeLength(const std::vector& input_lengths, const std::vector& output_lengths) { inputs_type_lengths_ = input_lengths; outputs_type_lengths_ = output_lengths; } +double OperatorCost::GetMemoryCost(const std::vector& inputs, + const std::vector& outputs) const { + double result = 0.0; + if (output_parameter_involve_ == 1) { + // When this operator has multiple outputs, they all contributes to the memory. + for (size_t i = 0; i < outputs.size(); ++i) { + result += ListProduct(outputs[i].slice_shape()) * static_cast(outputs_type_lengths_[i]); + } + bool is_any_para_inv = + std::any_of(is_parameter_involve_.begin(), is_parameter_involve_.end(), [](bool value) { return value; }); + if (is_any_para_inv) { + for (size_t i = 0; i < inputs.size(); ++i) { + if (is_parameter_[i]) { + result += ListProduct(inputs[i].slice_shape()) * static_cast(inputs_type_lengths_[i]); + } else if (inputs_related_ && (!is_parameter_involve_[i])) { + // When the inputs of this operator are related, and they are not parameter-involved, then they are included + // in the memory cost. + result += ListProduct(inputs[i].slice_shape()) * static_cast(inputs_type_lengths_[i]); + } + } + } + } + + return result; +} + // return the per device communication cost in the forward phase. double MatMulCost::GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t&) const { + int32_t) const { TensorInfo input0 = inputs[0]; TensorInfo output0 = outputs[0]; Shape input0_shape = input0.shape(); @@ -48,7 +81,7 @@ double MatMulCost::GetForwardCommCost(const std::vector& inputs, con // return the per device communication cost in the forward phase. double MatMulCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { // In backward phase, the communication cost is incurred only when tensor B is a Parameter and tensor B does not // fully utilize all devices double result = 0.0; @@ -72,11 +105,11 @@ double MatMulCost::GetBackwardCommCost(const std::vector& inputs, co return result; } -// Return the per device memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double MatMulCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector& outputs, const int32_t&) const { - // In forward phase, the memory cost = slice(A) + slice(B) + (0 or 1) allreduce(slice(C)) + const std::vector& outputs, int32_t) const { + // In forward phase, the compuatation cost = slice(A) + slice(B) + (0 or 1) allreduce(slice(C)) double result = 0.0; TensorInfo output0 = outputs[0]; Shape input0_slice_shape = inputs[0].slice_shape(); @@ -91,11 +124,11 @@ double MatMulCost::GetForwardComputationCost(const std::vector& inpu return result; } -// Return the per device memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double MatMulCost::GetBackwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { - // In backward phase, the memory cost = (0 or 1) allreduce(slice(B)) + int32_t stage_id) const { + // In backward phase, the computation cost = (0 or 1) allreduce(slice(B)) double result = 0.0; if (is_parameter_[1]) { TensorInfo input1 = inputs[1]; // tensor B @@ -119,14 +152,14 @@ double MatMulCost::GetBackwardComputationCost(const std::vector& inp // Return the per device communication cost in the forward phase. double ActivationCost::GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const { + int32_t) const { // ReLU is the element-wise operator, thus it does not need communication in the forward phase return 0.0; } // Return the per device communication cost in the backward phase. double ActivationCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; if (is_parameter_[0]) { TensorInfo input1 = inputs[0]; @@ -145,32 +178,31 @@ double ActivationCost::GetBackwardCommCost(const std::vector& inputs return result; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double ActivationCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { + int32_t) const { TensorInfo input0_info = inputs[0]; Shape input0_slice_shape = input0_info.slice_shape(); return ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]); } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double ActivationCost::GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const { + int32_t) const { return 0.0; } // Return the per device communication cost in the forward phase. -double SoftmaxCost::GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const { +double SoftmaxCost::GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const { // In the forward phase, the communication cost = 0 return 0.0; } // Return the per device communication cost in the backward phase. double SoftmaxCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; if (is_parameter_[0]) { TensorInfo input1 = inputs[0]; @@ -189,59 +221,59 @@ double SoftmaxCost::GetBackwardCommCost(const std::vector& inputs, c return result; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double SoftmaxCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { - // In the forward phase, the memory cost = slice(A) + int32_t) const { + // In the forward phase, the computation cost = slice(A) TensorInfo input0 = inputs[0]; Shape input0_slice_shape = input0.slice_shape(); return ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]); } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double SoftmaxCost::GetBackwardComputationCost(const std::vector&, - const std::vector&, - const int32_t&) const { + const std::vector&, int32_t) const { return 0.0; } // return the per device communication cost in the forward phase. double TmpIdentityCost::GetForwardCommCost(const std::vector&, - const std::vector&, const int32_t&) const { + const std::vector&, int32_t) const { // Identity is the element-wise operator, thus it does not need communication in the forward phase return 0.0; } // return the per device communication cost in the backward phase. double TmpIdentityCost::GetBackwardCommCost(const std::vector&, - const std::vector&, const int32_t&) const { + const std::vector&, int32_t) const { // Identity is the element-wise operator, thus it does not need communication in the backward phase return 0.0; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses -double TmpIdentityCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector&, - const int32_t&) const { - TensorInfo input0_info = inputs[0]; - Shape input0_slice_shape = input0_info.slice_shape(); - return ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]); +double TmpIdentityCost::GetForwardComputationCost(const std::vector&, + const std::vector&, int32_t) const { + return 0.0; } -// Return the per memory cost in the backward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the backward phase. The cost is calculated according to the bytes // this operator uses double TmpIdentityCost::GetBackwardComputationCost(const std::vector&, - const std::vector&, - const int32_t&) const { + const std::vector&, int32_t) const { + return 0.0; +} + +// Return the per device PEAK memory cost contributed by this operator in a training iteration. +double TmpIdentityCost::GetMemoryCost(const std::vector&, const std::vector&) const { return 0.0; } double BatchParallelCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { + int32_t) const { double cost = 0.0; for (size_t i = 0; i < inputs.size(); ++i) { cost += ListProduct(inputs[i].slice_shape()) * static_cast(inputs_type_lengths_[i]); @@ -251,20 +283,44 @@ double BatchParallelCost::GetForwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const { + int32_t) const { return 0.0; } +double BatchParallelCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, + int32_t stage_id) const { + double result = 0.0; + CheckGlobalDeviceManager(); + MS_EXCEPTION_IF_NULL(g_device_manager); + auto total_device_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); + + for (size_t j = 0; j < inputs.size(); ++j) { + if (!is_parameter_[j]) { + continue; + } + TensorInfo input_a_tensor_info = inputs[j]; + Shape input_a_shape = input_a_tensor_info.shape(); + Shape input_a_slice_shape = input_a_tensor_info.slice_shape(); + int32_t used_device_num = 1; + for (size_t i = 0; i < input_a_shape.size(); ++i) { + used_device_num *= input_a_shape[i] / input_a_slice_shape[i]; + } + if (total_device_num != IntToSize(used_device_num)) { + result += ListProduct(input_a_slice_shape) * static_cast(inputs_type_lengths_[0]); + } + } + + return result; +} // return the per device communication cost in the forward phase. -double PReLUCost::GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const { +double PReLUCost::GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const { // prelu does not need communication in the forward phase return 0.0; } // return the per device communication cost in the backward phase. double PReLUCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; if (is_parameter_[1]) { TensorInfo input1 = inputs[1]; @@ -284,11 +340,11 @@ double PReLUCost::GetBackwardCommCost(const std::vector& inputs, con return result; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double PReLUCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { - // In forward phase, the memory cost = slice(A) + slice(B) + int32_t) const { + // In forward phase, the computation cost = slice(A) + slice(B) Shape input0_slice_shape = inputs[0].slice_shape(); Shape input1_slice_shape = inputs[1].slice_shape(); double result = ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]) + @@ -296,12 +352,12 @@ double PReLUCost::GetForwardComputationCost(const std::vector& input return result; } -// Return the per memory cost in the backward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the backward phase. The cost is calculated according to the bytes // this operator uses double PReLUCost::GetBackwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { - // In backward phase, the memory cost = (0 or 1) allreduce(slice(B)) + int32_t stage_id) const { + // In backward phase, the computation cost = (0 or 1) allreduce(slice(B)) double result = 0.0; if (is_parameter_[1]) { TensorInfo input1 = inputs[1]; // tensor B @@ -324,55 +380,52 @@ double PReLUCost::GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const { +double OneHotCost::GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const { // onehot does not need communication in the forward phase return 0.0; } // return the per device communication cost in the backward phase. -double OneHotCost::GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const { +double OneHotCost::GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const { // onehot does not need communication in the backward phase return 0.0; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double OneHotCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { - // In onehot's forward phase, the memory cost = slice(A) + int32_t) const { + // In onehot's forward phase, the computation cost = slice(A) Shape input0_slice_shape = inputs[0].slice_shape(); return ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]); } -// Return the per memory cost in the backward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the backward phase. The cost is calculated according to the bytes // this operator uses double OneHotCost::GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const { + int32_t) const { return 0.0; } // return the per device communication cost in the forward phase. double SoftmaxCrossEntropyWithLogitsCost::GetForwardCommCost(const std::vector&, - const std::vector&, const int32_t&) const { + const std::vector&, int32_t) const { // SoftmaxCrossEntropyWithLogitsCost does not need communication in the forward phase return 0.0; } // return the per device communication cost in the backward phase. double SoftmaxCrossEntropyWithLogitsCost::GetBackwardCommCost(const std::vector&, - const std::vector&, const int32_t&) const { + const std::vector&, int32_t) const { // SoftmaxCrossEntropyWithLogitsCost does not need communication in the backward phase return 0.0; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double SoftmaxCrossEntropyWithLogitsCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector&, - const int32_t&) const { - // In forward phase, the memory cost = slice(A) + slice(B) + const std::vector&, int32_t) const { + // In forward phase, the computation cost = slice(A) + slice(B) Shape input0_slice_shape = inputs[0].slice_shape(); Shape input1_slice_shape = inputs[1].slice_shape(); double result = ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]) + @@ -380,17 +433,16 @@ double SoftmaxCrossEntropyWithLogitsCost::GetForwardComputationCost(const std::v return result; } -// Return the per memory cost in the backward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the backward phase. The cost is calculated according to the bytes // this operator uses double SoftmaxCrossEntropyWithLogitsCost::GetBackwardComputationCost(const std::vector&, - const std::vector&, - const int32_t&) const { + const std::vector&, int32_t) const { return 0.0; } // return the per device communication cost in the forward phase. double ReshapeCost::GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const { + int32_t stage_id) const { CheckGlobalDeviceManager(); MS_EXCEPTION_IF_NULL(g_device_manager); RankList dev_list = g_device_manager->GetDeviceListByStageId(stage_id); @@ -405,15 +457,30 @@ double ReshapeCost::GetForwardCommCost(const std::vector& inputs, co } // return the per device communication cost in the backward phase. -double ReshapeCost::GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const { - return 0.0; +double ReshapeCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, + int32_t stage_id) const { + double result = 0.0; + if (is_parameter_[0]) { + TensorInfo input1 = inputs[0]; + MS_EXCEPTION_IF_NULL(g_device_manager); + auto total_device_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); + Shape input1_shape = input1.shape(); + Shape input1_slice_shape = input1.slice_shape(); + int32_t used_device_num = 1; + for (size_t i = 0; i < input1_shape.size(); ++i) { + used_device_num *= input1_shape[i] / input1_slice_shape[i]; + } + if (total_device_num != IntToSize(used_device_num)) { + result = ListProduct(input1_slice_shape) * static_cast(inputs_type_lengths_[1]); + } + } + return result; } -// Return the per memory cost in the forward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the forward phase. The cost is calculated according to the bytes // this operator uses double ReshapeCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector& outputs, const int32_t& stage_id) const { + const std::vector& outputs, int32_t stage_id) const { CheckGlobalDeviceManager(); MS_EXCEPTION_IF_NULL(g_device_manager); RankList dev_list = g_device_manager->GetDeviceListByStageId(stage_id); @@ -427,16 +494,15 @@ double ReshapeCost::GetForwardComputationCost(const std::vector& inp return (inputs_type_lengths_[0] * tensor_redistribution.computation_cost()); } -// Return the per memory cost in the backward phase. The cost is calculated according to the bytes +// Return the per device computation cost in the backward phase. The cost is calculated according to the bytes // this operator uses double ReshapeCost::GetBackwardComputationCost(const std::vector&, - const std::vector&, - const int32_t&) const { + const std::vector&, int32_t) const { return 0.0; } double ArithmeticCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t&) const { + int32_t) const { double result; result = ListProduct(inputs[0].slice_shape()) * static_cast(inputs_type_lengths_[0]) + ListProduct(inputs[1].slice_shape()) * static_cast(inputs_type_lengths_[1]); @@ -444,7 +510,7 @@ double ArithmeticCost::GetForwardComputationCost(const std::vector& } double ArithmeticCost::GetBackwardComputationCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; CheckGlobalDeviceManager(); MS_EXCEPTION_IF_NULL(g_device_manager); @@ -479,7 +545,7 @@ double ArithmeticCost::GetBackwardComputationCost(const std::vector& } double ArithmeticCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; CheckGlobalDeviceManager(); MS_EXCEPTION_IF_NULL(g_device_manager); @@ -514,7 +580,7 @@ double ArithmeticCost::GetBackwardCommCost(const std::vector& inputs return result; } -bool IsDataParallel(const Shape& shape, const Shape& slice_shape, const int32_t& stage_id) { +bool IsDataParallel(const Shape& shape, const Shape& slice_shape, int32_t stage_id) { CheckGlobalDeviceManager(); MS_EXCEPTION_IF_NULL(g_device_manager); auto total_device_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); @@ -524,7 +590,7 @@ bool IsDataParallel(const Shape& shape, const Shape& slice_shape, const int32_t& } double ReduceMethodCost::GetForwardCommCost(const std::vector& inputs, - const std::vector& outputs, const int32_t& stage_id) const { + const std::vector& outputs, int32_t stage_id) const { double result = 0.0; TensorInfo input0 = inputs[0]; TensorInfo output0 = outputs[0]; @@ -535,7 +601,7 @@ double ReduceMethodCost::GetForwardCommCost(const std::vector& input } std::vector dim_list = input0.reduce_dim(); std::vector::iterator pos; - pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](const int32_t& index) { + pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](int32_t index) { return input0_shape[IntToSize(index)] != input0_slice_shape[IntToSize(index)]; }); if (pos != dim_list.end()) { @@ -546,7 +612,7 @@ double ReduceMethodCost::GetForwardCommCost(const std::vector& input } double ReduceMethodCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, - const int32_t& stage_id) const { + int32_t stage_id) const { double result = 0.0; if (is_parameter_[0]) { TensorInfo input_tensor_info = inputs[0]; @@ -569,8 +635,7 @@ double ReduceMethodCost::GetBackwardCommCost(const std::vector& inpu } double ReduceMethodCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector& outputs, - const int32_t& stage_id) const { + const std::vector& outputs, int32_t stage_id) const { double result = 0.0; TensorInfo input0 = inputs[0]; TensorInfo output0 = outputs[0]; @@ -579,7 +644,7 @@ double ReduceMethodCost::GetForwardComputationCost(const std::vector Shape input0_shape = input0.shape(); if (!cross_batch_ || !IsDataParallel(input0_shape, input0_slice_shape, stage_id)) { std::vector::iterator pos; - pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](const int32_t& index) { + pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](int32_t index) { return input0_shape[IntToSize(index)] != input0_slice_shape[IntToSize(index)]; }); if (pos != dim_list.end()) { @@ -592,8 +657,7 @@ double ReduceMethodCost::GetForwardComputationCost(const std::vector } double ReduceMeanCost::GetForwardComputationCost(const std::vector& inputs, - const std::vector& outputs, - const int32_t& stage_id) const { + const std::vector& outputs, int32_t stage_id) const { double result = 0.0; TensorInfo input0 = inputs[0]; TensorInfo output0 = outputs[0]; @@ -602,7 +666,7 @@ double ReduceMeanCost::GetForwardComputationCost(const std::vector& Shape input0_shape = input0.shape(); if (!cross_batch_ || !IsDataParallel(input0_shape, input0_slice_shape, stage_id)) { std::vector::iterator pos; - pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](const int32_t& index) { + pos = std::find_if(dim_list.begin(), dim_list.end(), [input0_shape, input0_slice_shape](int32_t index) { return input0_shape[IntToSize(index)] != input0_slice_shape[IntToSize(index)]; }); if (pos != dim_list.end()) { @@ -613,5 +677,111 @@ double ReduceMeanCost::GetForwardComputationCost(const std::vector& return result; } + +double DropOutCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, + int32_t) const { + if (inputs.empty()) { + return 0.0; + } + TensorInfo input0 = inputs[0]; + Shape input0_slice_shape = input0.slice_shape(); + return ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]) * DROPOUT_COST_RATE; +} + +// return the per device communication cost in the forward phase. +double GatherV2Cost::GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const { + // GatherV2Cost does not need communication in the forward phase + return 0.0; +} + +// return the per device communication cost in the backward phase. +double GatherV2Cost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, + int32_t stage_id) const { + double result = 0.0; + CheckGlobalDeviceManager(); + MS_EXCEPTION_IF_NULL(g_device_manager); + auto total_device_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); + + for (size_t j = 0; j < inputs.size(); ++j) { + if (!is_parameter_[j]) { + continue; + } + TensorInfo input_a_tensor_info = inputs[j]; + Shape input_a_shape = input_a_tensor_info.shape(); + Shape input_a_slice_shape = input_a_tensor_info.slice_shape(); + int32_t used_device_num = 1; + for (size_t i = 0; i < input_a_shape.size(); ++i) { + used_device_num *= input_a_shape[i] / input_a_slice_shape[i]; + } + if (total_device_num != IntToSize(used_device_num)) { + result += ListProduct(input_a_slice_shape) * static_cast(inputs_type_lengths_[0]); + } + } + + return result; +} + +double GatherV2Cost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, + int32_t) const { + // In forward phase, the computation cost = slice(A) + slice(B) + Shape input0_slice_shape = inputs[0].slice_shape(); + Shape input1_slice_shape = inputs[1].slice_shape(); + double result = ListProduct(input0_slice_shape) * static_cast(inputs_type_lengths_[0]) + + ListProduct(input1_slice_shape) * static_cast(inputs_type_lengths_[1]); + return result; +} + +double GatherV2Cost::GetBackwardComputationCost(const std::vector&, const std::vector&, + int32_t) const { + return 0.0; +} + +double LayerNormCost::GetBackwardCommCost(const std::vector& inputs, const std::vector&, + int32_t stage_id) const { + double result = 0.0; + if (is_parameter_.size() != inputs.size()) { + MS_LOG(EXCEPTION) << "Invalid parameter size " << is_parameter_.size() << " for layer norm cost"; + } + if (inputs_type_lengths_.size() != inputs.size()) { + MS_LOG(EXCEPTION) << "Invalid inputs type size " << inputs_type_lengths_.size() << " for layer norm cost"; + } + + MS_EXCEPTION_IF_NULL(g_device_manager); + auto total_device_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); + + for (size_t index = 0; index < inputs.size(); ++index) { + if (is_parameter_[index]) { + TensorInfo tensor_info = inputs[index]; + Shape shape = tensor_info.shape(); + Shape slice_shape = tensor_info.slice_shape(); + int32_t used_device_num = 1; + for (size_t i = 0; i < shape.size(); ++i) { + if (slice_shape[i] == 0) { + MS_LOG(EXCEPTION) << "Invalid slice shape " << ShapeToString(slice_shape); + } + used_device_num *= shape[i] / slice_shape[i]; + } + if (total_device_num != IntToSize(used_device_num)) { + result += ListProduct(slice_shape) * static_cast(inputs_type_lengths_[index]); + } + } + } + return result; +} + +double LayerNormCost::GetForwardComputationCost(const std::vector& inputs, const std::vector&, + int32_t) const { + double result = 0.0; + if (inputs_type_lengths_.size() != inputs.size()) { + MS_LOG(EXCEPTION) << "Invalid inputs type size " << inputs_type_lengths_.size() << " for layer norm cost"; + } + + for (size_t index = 0; index < inputs.size(); ++index) { + TensorInfo tensor_info = inputs[index]; + Shape slice_shape = tensor_info.slice_shape(); + result += ListProduct(slice_shape) * static_cast(inputs_type_lengths_[index]); + } + return result; +} } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.h b/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.h index 73f3ff139f..37b054aa98 100644 --- a/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.h +++ b/mindspore/ccsrc/parallel/auto_parallel/operator_costmodel.h @@ -26,6 +26,7 @@ namespace mindspore { namespace parallel { #define MAXIMUM_INPUT_NUMBER 100 #define DEFAULT_DATA_TYPE_LENGTH 4 +#define DROPOUT_COST_RATE 1.125 // the DropoutGenMask need 12.5% memory class OperatorCost; using OperatorCostPtr = std::shared_ptr; @@ -42,10 +43,20 @@ double ListProduct(std::vector vec) { // entries timing the length of each entry's data type class OperatorCost { public: - OperatorCost() { + explicit OperatorCost(bool is_inputs_related) : inputs_related_(is_inputs_related) { // this is only for the case when set_is_parameter() and SetInputAndOutputTypeLength() are not invoked for (size_t i = 0; i < MAXIMUM_INPUT_NUMBER; ++i) { is_parameter_.push_back(false); + is_parameter_involve_.push_back(false); + inputs_type_lengths_.push_back(DEFAULT_DATA_TYPE_LENGTH); + outputs_type_lengths_.push_back(DEFAULT_DATA_TYPE_LENGTH); + } + } + OperatorCost() : inputs_related_(false) { + // this is only for the case when set_is_parameter() and SetInputAndOutputTypeLength() are not invoked + for (size_t i = 0; i < MAXIMUM_INPUT_NUMBER; ++i) { + is_parameter_.push_back(false); + is_parameter_involve_.push_back(false); inputs_type_lengths_.push_back(DEFAULT_DATA_TYPE_LENGTH); outputs_type_lengths_.push_back(DEFAULT_DATA_TYPE_LENGTH); } @@ -53,26 +64,39 @@ class OperatorCost { virtual ~OperatorCost() = default; void set_is_parameter(const std::vector& is_parameter); + void set_is_parameter_involve(const std::vector&); + void set_output_parameter_involve(int); void SetInputAndOutputTypeLength(const std::vector& input_lengths, const std::vector& output_lengths); std::vector inputs_type_lengths() const { return inputs_type_lengths_; } std::vector outputs_type_lengths() const { return outputs_type_lengths_; } // per device communication cost virtual double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const = 0; + int32_t stage_id) const = 0; virtual double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const = 0; + int32_t stage_id) const = 0; virtual double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const = 0; + int32_t stage_id) const = 0; // per device computation cost virtual double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const = 0; + int32_t stage_id) const = 0; virtual double GetForwardComputationCost(const std::vector& inputs, - const std::vector& outputs, const int32_t& stage_id) const = 0; + const std::vector& outputs, int32_t stage_id) const = 0; virtual double GetBackwardComputationCost(const std::vector& inputs, - const std::vector& outputs, const int32_t& stage_id) const = 0; + const std::vector& outputs, int32_t stage_id) const = 0; + // per device PEAK memory cost in a training iteration + // Typically, the PEAK memory cost contributed by an operator is its output (if the output is parameter-invovled), + // plus necessary inputs. + virtual double GetMemoryCost(const std::vector& inputs, const std::vector& outputs) const; protected: + // For each input in 'inputs_', a bool variable is true if the corresponding one is a parameter or a output of + // pre-operator that has parameters as input. + std::vector is_parameter_involve_; + int output_parameter_involve_ = -1; // -1: unset; 0: not parameter_involved; 1: parameter_involved + // Whether the inputs are related or not? For example, TensorAdd's two inputs are independent (not related), while + // Mul's two inputs are dependent (related). + bool inputs_related_; // for each input in 'inputs_', there is a bool variable indicating whether that the corresponding input is parameter std::vector is_parameter_; // for each input and output, the followings record the number of bytes of each element @@ -80,165 +104,170 @@ class OperatorCost { std::vector outputs_type_lengths_; }; +using OperatorCostPtr = std::shared_ptr; + class MatMulCost : public OperatorCost { public: - MatMulCost() = default; + explicit MatMulCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + MatMulCost() : OperatorCost(true) {} ~MatMulCost() override = default; // per device communication cost double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; // per device computation cost double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; - using MatMulCostPtr = std::shared_ptr; class ActivationCost : public OperatorCost { public: - ActivationCost() = default; + explicit ActivationCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + ActivationCost() : OperatorCost(false) {} ~ActivationCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; - using ActivationCostPtr = std::shared_ptr; using TransposeCost = ActivationCost; using TransposeCostPtr = std::shared_ptr; class SoftmaxCost : public OperatorCost { public: - SoftmaxCost() = default; + explicit SoftmaxCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + SoftmaxCost() : OperatorCost(false) {} ~SoftmaxCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t&) const override; + int32_t) const override; }; - using SoftmaxCostPtr = std::shared_ptr; class TmpIdentityCost : public OperatorCost { public: - TmpIdentityCost() = default; + explicit TmpIdentityCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + TmpIdentityCost() : OperatorCost(false) {} ~TmpIdentityCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; + // per device PEAK memory cost in a training iteration + double GetMemoryCost(const std::vector& inputs, const std::vector& outputs) const override; }; using TmpIdentityCostPtr = std::shared_ptr; class BatchParallelCost : public OperatorCost { public: - BatchParallelCost() = default; + explicit BatchParallelCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + BatchParallelCost() : OperatorCost(false) {} ~BatchParallelCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } - double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { - return 0.0; - } - double GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using BatchParallelCostPtr = std::shared_ptr; class VirtualDatasetCost : public OperatorCost { public: - VirtualDatasetCost() = default; + explicit VirtualDatasetCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + VirtualDatasetCost() : OperatorCost(false) {} ~VirtualDatasetCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } - double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } - double GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } double GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { + return 0.0; + } + // per device PEAK memory cost in a training iteration + double GetMemoryCost(const std::vector& inputs, const std::vector& outputs) const override { return 0.0; } }; @@ -246,33 +275,32 @@ using VirtualDatasetCostPtr = std::shared_ptr; class GeneratorBaseCost : public OperatorCost { public: - GeneratorBaseCost() = default; + explicit GeneratorBaseCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + GeneratorBaseCost() : OperatorCost(false) {} ~GeneratorBaseCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } - double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } - double GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } // Inputs vector is empty for generator ops. double GetForwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } // Generator ops don't have backward steps. double GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } }; @@ -280,141 +308,144 @@ using GeneratorBaseCostPtr = std::shared_ptr; class PReLUCost : public OperatorCost { public: - PReLUCost() = default; + explicit PReLUCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + PReLUCost() : OperatorCost(true) {} ~PReLUCost() override = default; // per device communication cost double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; // per device computation cost double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using PReLUCostPtr = std::shared_ptr; class OneHotCost : public OperatorCost { public: - OneHotCost() = default; + explicit OneHotCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + OneHotCost() : OperatorCost(true) {} ~OneHotCost() override = default; // per device communication cost double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; // per device computation cost double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using OneHotCostPtr = std::shared_ptr; class SoftmaxCrossEntropyWithLogitsCost : public OperatorCost { public: - SoftmaxCrossEntropyWithLogitsCost() = default; + explicit SoftmaxCrossEntropyWithLogitsCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + SoftmaxCrossEntropyWithLogitsCost() : OperatorCost(false) {} ~SoftmaxCrossEntropyWithLogitsCost() override = default; // per device communication cost double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; // per device computation cost double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using SoftmaxCrossEntropyWithLogitsCostPtr = std::shared_ptr; class ReshapeCost : public OperatorCost { public: - ReshapeCost() = default; + explicit ReshapeCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + ReshapeCost() : OperatorCost(true) {} ~ReshapeCost() override = default; // per device communication cost double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; // per device computation cost double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using ReshapeCostPtr = std::shared_ptr; class ArithmeticCost : public OperatorCost { public: - ArithmeticCost() = default; + explicit ArithmeticCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + ArithmeticCost() : OperatorCost(false) {} ~ArithmeticCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } - double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } - double GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override; + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using ArithmeticCostPtr = std::shared_ptr; using BiasAddCost = ArithmeticCost; @@ -422,25 +453,26 @@ using BiasAddCostPtr = std::shared_ptr; class ReduceMethodCost : public OperatorCost { public: - ReduceMethodCost() = default; + explicit ReduceMethodCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + ReduceMethodCost() : OperatorCost(true) {} ~ReduceMethodCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; double GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } void set_cross_batch(bool cb) { cross_batch_ = cb; } @@ -452,47 +484,131 @@ using ReduceMethodCostPtr = std::shared_ptr; class ReduceMeanCost : public ReduceMethodCost { public: - ReduceMeanCost() = default; + explicit ReduceMeanCost(bool is_inputs_related) : ReduceMethodCost(is_inputs_related) {} + ReduceMeanCost() : ReduceMethodCost(true) {} ~ReduceMeanCost() override = default; double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override; + int32_t stage_id) const override; }; using ReduceMeanCostPtr = std::shared_ptr; class GetNextCost : public OperatorCost { public: - GetNextCost() = default; + explicit GetNextCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + GetNextCost() : OperatorCost(false) {} ~GetNextCost() override = default; double GetCommCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); } - double GetForwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } - double GetBackwardCommCost(const std::vector&, const std::vector&, - const int32_t&) const override { + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override { return 0.0; } double GetComputationCost(const std::vector& inputs, const std::vector& outputs, - const int32_t& stage_id) const override { + int32_t stage_id) const override { return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); } // Inputs vector is empty for generator ops. double GetForwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } // Generator ops don't have backward steps. double GetBackwardComputationCost(const std::vector&, const std::vector&, - const int32_t&) const override { + int32_t) const override { return 0.0; } }; using GetNextCostPtr = std::shared_ptr; + +class DropOutCost : public OperatorCost { + public: + explicit DropOutCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + DropOutCost() : OperatorCost(true) {} + ~DropOutCost() override = default; + + double GetCommCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); + } + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { + return 0.0; + } + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override { + return 0.0; + } + double GetComputationCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); + } + double GetForwardComputationCost(const std::vector&, const std::vector&, + int32_t) const override; + double GetBackwardComputationCost(const std::vector&, const std::vector&, + int32_t) const override { + return 0.0; + } +}; + +using DropOutCostPtr = std::shared_ptr; + +class LayerNormCost : public OperatorCost { + public: + explicit LayerNormCost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + LayerNormCost() : OperatorCost(true) {} + ~LayerNormCost() override = default; + + double GetCommCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); + } + double GetForwardCommCost(const std::vector&, const std::vector&, int32_t) const override { + return 0.0; + } + double GetBackwardCommCost(const std::vector&, const std::vector&, int32_t) const override; + double GetComputationCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); + } + double GetForwardComputationCost(const std::vector&, const std::vector&, + int32_t) const override; + double GetBackwardComputationCost(const std::vector&, const std::vector&, + int32_t) const override { + return 0.0; + } +}; + +using DropOutCostPtr = std::shared_ptr; + +class GatherV2Cost : public OperatorCost { + public: + explicit GatherV2Cost(bool is_inputs_related) : OperatorCost(is_inputs_related) {} + GatherV2Cost() : OperatorCost(true) {} + ~GatherV2Cost() override = default; + + double GetCommCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardCommCost(inputs, outputs, stage_id) + GetBackwardCommCost(inputs, outputs, stage_id); + } + double GetForwardCommCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override; + double GetBackwardCommCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override; + double GetComputationCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override { + return GetForwardComputationCost(inputs, outputs, stage_id) + GetBackwardComputationCost(inputs, outputs, stage_id); + } + double GetForwardComputationCost(const std::vector& inputs, const std::vector& outputs, + int32_t stage_id) const override; + double GetBackwardComputationCost(const std::vector& inputs, const std::vector& outputs, + int32_t) const override; +}; + +using GatherV2CostPtr = std::shared_ptr; } // namespace parallel } // namespace mindspore #endif // PARALLEL_AUTO_PARALLEL_OPERATOR_COSTMODEL_H_ diff --git a/mindspore/ccsrc/parallel/costmodel_context.cc b/mindspore/ccsrc/parallel/costmodel_context.cc index 0ebbd2c626..82b260f967 100644 --- a/mindspore/ccsrc/parallel/costmodel_context.cc +++ b/mindspore/ccsrc/parallel/costmodel_context.cc @@ -60,7 +60,7 @@ void CostModelContext::ResetAlgoParameters() { costmodel_simplify_cal_ = DEFAULT_COST_MODEL_SIMPLIFY_CALCULATION; tensor_slice_alignment_enable_ = DEFAULT_TENSOR_SLICE_ALIGNMENT_ENABLE; tensor_slice_alignment_size_ = DEFAULT_TENSOR_SLICE_ALIGNMENT_SIZE; - not_fully_use_device_ = DEFAULT_NOT_FULLY_USE_DEVICES; + fully_use_device_ = DEFAULT_FULLY_USE_DEVICES; elementwise_stra_follow_ = DEFAULT_ELEMENTWISE_OP_STRA_FOLLOW; } @@ -118,7 +118,7 @@ void CostModelContext::set_tensor_slice_alignment_size(size_t ts_align_size) { tensor_slice_alignment_size_ = ts_align_size; } -void CostModelContext::set_not_fully_use_device(bool not_fully_use) { not_fully_use_device_ = not_fully_use; } +void CostModelContext::set_fully_use_device(bool fully_use) { fully_use_device_ = fully_use; } void CostModelContext::set_elementwise_stra_follow(bool elementwise_follow) { elementwise_stra_follow_ = elementwise_follow; diff --git a/mindspore/ccsrc/parallel/costmodel_context.h b/mindspore/ccsrc/parallel/costmodel_context.h index 04782fa366..23c9f7cc8d 100644 --- a/mindspore/ccsrc/parallel/costmodel_context.h +++ b/mindspore/ccsrc/parallel/costmodel_context.h @@ -102,9 +102,9 @@ class CostModelContext { void set_tensor_slice_alignment_size(size_t); size_t tensor_slice_alignment_size() const { return tensor_slice_alignment_size_; } - // NOT_FULLY_USE_DEVICES - void set_not_fully_use_device(bool); - bool not_fully_use_device() const { return not_fully_use_device_; } + // FULLY_USE_DEVICES + void set_fully_use_device(bool); + bool fully_use_device() const { return fully_use_device_; } // ELEMENTWISE_OP_STRA_FOLLOW void set_elementwise_stra_follow(bool); @@ -158,8 +158,8 @@ class CostModelContext { // TENSOR_SLICE_ALIGNMENT_SIZE size_t tensor_slice_alignment_size_; - // NOT_FULLY_USE_DEVICES - bool not_fully_use_device_; + // FULLY_USE_DEVICES + bool fully_use_device_; // ELEMENTWISE_OP_STRA_FOLLOW bool elementwise_stra_follow_; diff --git a/mindspore/ccsrc/parallel/device_manager.cc b/mindspore/ccsrc/parallel/device_manager.cc index 3a553e08ec..0b34cedc00 100644 --- a/mindspore/ccsrc/parallel/device_manager.cc +++ b/mindspore/ccsrc/parallel/device_manager.cc @@ -370,6 +370,5 @@ void DeviceManager::Clear() { stage_devices_.clear(); gm_.Clear(); } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/device_matrix.cc b/mindspore/ccsrc/parallel/device_matrix.cc index a581dbf275..3fdc3dd15a 100644 --- a/mindspore/ccsrc/parallel/device_matrix.cc +++ b/mindspore/ccsrc/parallel/device_matrix.cc @@ -29,7 +29,6 @@ namespace mindspore { namespace parallel { - DeviceMatrix::DeviceMatrix(int32_t rank, RankList dev_list, Shape dev_shape) : rank_(rank), dev_list_(std::move(dev_list)), dev_shape_(std::move(dev_shape)) { if (!std::any_of(dev_list_.begin(), dev_list_.end(), [rank](int32_t a) { return a == rank; })) { diff --git a/mindspore/ccsrc/parallel/dynamic_creator.h b/mindspore/ccsrc/parallel/dynamic_creator.h index 1270116f50..bad947687d 100644 --- a/mindspore/ccsrc/parallel/dynamic_creator.h +++ b/mindspore/ccsrc/parallel/dynamic_creator.h @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - #define REGISTER(className) \ OperatorInfoPtr objectCreator##className(std::string name, Shapes in, Shapes out, PrimitiveAttrs& attrs) { \ return std::make_shared(name, in, out, attrs); \ @@ -102,6 +101,7 @@ REGISTER(CosInfo); REGISTER(ACosInfo); REGISTER(LogicalNotInfo); REGISTER(L2NormalizeInfo); +REGISTER(LayerNormInfo); REGISTER(ReduceMaxInfo); REGISTER(ArgMaxWithValueInfo); REGISTER(ArgMinWithValueInfo); @@ -111,10 +111,10 @@ REGISTER(ReduceMinInfo); REGISTER(TransposeInfo); REGISTER(PReLUInfo); REGISTER(DropoutDoMaskInfo); -REGISTER(DropoutGenMaskInfo) REGISTER(ReshapeInfo); REGISTER(FloorDivInfo); REGISTER(MaximumInfo); +REGISTER(MinimumInfo); REGISTER(CastInfo); REGISTER(GreaterInfo); REGISTER(SparseSoftmaxCrossEntropyWithLogitsInfo); @@ -126,6 +126,9 @@ REGISTER(GetNextInfo); REGISTER(NegInfo); REGISTER(BatchMatMulInfo); REGISTER(ExpandDimsInfo); +REGISTER(SqueezeInfo); +REGISTER(SigmoidCrossEntropyWithLogitsInfo); +REGISTER(SquareInfo); } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/node_check.cc b/mindspore/ccsrc/parallel/node_check.cc index fc6115c3c5..e43d03c29c 100644 --- a/mindspore/ccsrc/parallel/node_check.cc +++ b/mindspore/ccsrc/parallel/node_check.cc @@ -66,11 +66,13 @@ const std::set BLACK_LIST = {TUPLE_GETITEM, SCALARSUMMARY, IMAGESUMMARY, TENSORSUMMARY, + HISTOGRAMSUMMARY, COL2IMV1, RESOLVE, BROADCASTGRADIENTARGS, INVERTPERMUTATION, CONTROLDEPEND, + DROPOUT_GEN_MASK, EMBED, CREATINSTANCE, ZEROSLIKETENSOR, diff --git a/mindspore/ccsrc/parallel/ops_info/activation_info.cc b/mindspore/ccsrc/parallel/ops_info/activation_info.cc index 9ba3624b01..e659759de2 100644 --- a/mindspore/ccsrc/parallel/ops_info/activation_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/activation_info.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include "ir/value.h" #include "parallel/auto_parallel/costmodel.h" @@ -194,8 +195,8 @@ Status Softmax::GetAttrs() { // for example: tensor dimension is 4, then axis range [-4, 3] int32_t dim = SizeToInt(inputs_shape_.at(0).size()); - auto it = std::find_if(axis_.begin(), axis_.end(), - [dim](const int32_t& element) { return ((element >= dim) || (element < -dim)); }); + auto it = + std::find_if(axis_.begin(), axis_.end(), [dim](int32_t element) { return ((element >= dim) || (element < -dim)); }); if (it != axis_.end()) { MS_LOG(ERROR) << name_ << " : The axis(" << *it << ") is out of range[" << -dim << ", " << dim - 1 << "]."; return FAILED; @@ -228,7 +229,8 @@ Status Softmax::GenerateStrategies(int32_t stage_id) { } is_auto_parallel_ = true; - Shape input0_split(inputs_shape_[0].size(), 1); + Shape input0_split; + (void)input0_split.insert(input0_split.begin(), inputs_shape_[0].size(), 1); for (auto& element : axis_) { int32_t axis_index = element; if (element < 0) { @@ -544,5 +546,160 @@ Status ExpandDimsInfo::InferMirrorOps() { MS_LOG(INFO) << name_ << ": Create mirror ops success, the group name is " << group[0].name(); return SUCCESS; } + +Status SqueezeInfo::InferAxis(const ValueTuplePtr& value_tuple) { + std::vector axis; + auto axis_list = value_tuple->value(); + if (inputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs shape is empty"; + return FAILED; + } + Shape input_shape = inputs_shape_.at(0); + size_t input_size = input_shape.size(); + // if axis tuple is empty, we should exclude the axis that the corresponding slice shape is 1. + if (axis_list.empty()) { + for (size_t i = 0; i < input_size; ++i) { + if (input_shape[i] == 1) { + axis.push_back(i); + } + } + axis_ = MakeValue(axis)->cast(); + return SUCCESS; + } + + // convert negative axis to positive. + for (auto& dim : axis_list) { + if (!dim->isa()) { + MS_LOG(ERROR) << name_ << ": The type of axis is not int"; + return FAILED; + } + int32_t dim_value = GetValue(dim); + int32_t positive_value = (dim_value < 0) ? (dim_value + SizeToInt(input_size)) : dim_value; + axis.push_back(positive_value); + } + axis_ = MakeValue(axis)->cast(); + return SUCCESS; +} + +Status SqueezeInfo::GetAttrs() { + auto iter = attrs_.find(AXIS); + if (iter == attrs_.end()) { + MS_LOG(ERROR) << name_ << ": Can't find axis attribute."; + return FAILED; + } + MS_EXCEPTION_IF_NULL(iter->second); + auto value_tuple = iter->second->cast(); + MS_EXCEPTION_IF_NULL(value_tuple); + InferAxis(value_tuple); + attrs_[AXIS] = axis_; + return SUCCESS; +} + +Status SqueezeInfo::InferReplaceOps(const StrategyPtr& strategy) { + Attr attr = std::make_pair(AXIS, axis_); + OperatorAttrs attrs = {attr}; + OperatorParams params; + OperatorArgs args = std::make_pair(attrs, params); + replace_op_ = {std::make_pair(SQUEEZE, args)}; + return SUCCESS; +} + +Status SqueezeInfo::InferTensorMap() { + // for example: if the shape of input is [32, 32, 1], and the axis is (2, ), + // then the input_tensor_map is [2, 1, 0], the output_tensor_map is [2, 1] + std::vector input_tensor_map, output_tensor_map; + if (inputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs shape is empty"; + return FAILED; + } + size_t size = inputs_shape_[0].size(); + std::vector axis = GetValue>(axis_); + for (size_t i = 0; i < size; ++i) { + size_t index = size - i - 1; + auto iter = std::find(axis.begin(), axis.end(), SizeToInt(i)); + if (iter == axis.end()) { + output_tensor_map.push_back(SizeToInt(index)); + } + input_tensor_map.push_back(SizeToInt(index)); + } + inputs_tensor_map_.push_back(input_tensor_map); + outputs_tensor_map_.push_back(output_tensor_map); + MS_LOG(INFO) << name_ << ": The tensor map of input is " << ShapeToString(input_tensor_map) + << ", and the tensor map of output is " << ShapeToString(output_tensor_map); + + return SUCCESS; +} + +Status SqueezeInfo::InferTensorInfo() { + if (inputs_shape_.empty() || outputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The shape of inputs or outputs is empty"; + return FAILED; + } + + if (inputs_tensor_map_.empty() || outputs_tensor_map_.empty()) { + MS_LOG(ERROR) << name_ << ": The tensor map of inputs or outputs is empty"; + return FAILED; + } + + Shape input_shape = inputs_shape_[0]; + Shape output_shape = outputs_shape_[0]; + + // infer slice shape + Shapes inputs_slice_shape, outputs_slice_shape; + Strategys inputs_strategy = strategy_->GetInputDim(); + Dimensions output_strategy; + std::vector axis = GetValue>(axis_); + for (size_t i = 0; i < inputs_shape_[0].size(); ++i) { + auto iter = std::find(axis.begin(), axis.end(), SizeToInt(i)); + if (iter == axis.end()) { + output_strategy.push_back(inputs_strategy[0].at(i)); + } + } + Strategys outputs_strategy = {output_strategy}; + if (InferSliceShape(inputs_strategy, outputs_strategy, &inputs_slice_shape, &outputs_slice_shape) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Infer slice shape failed"; + return FAILED; + } + + if (inputs_slice_shape.empty() || outputs_slice_shape.empty()) { + MS_LOG(ERROR) << name_ << ": The slice shape of inputs or outputs is empty"; + return FAILED; + } + + Shape input_slice_shape = inputs_slice_shape[0]; + Shape output_slice_shape = outputs_slice_shape[0]; + + // infer tensor layout + TensorLayout input_tensor_layout, output_tensor_layout; + if (input_tensor_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_[0], input_shape) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init tensor layout for input failed"; + return FAILED; + } + + if (output_tensor_layout.InitFromVector(dev_matrix_shape_, outputs_tensor_map_[0], output_shape) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init tensor layout for output failed"; + return FAILED; + } + + TensorInfo input_tensor_info(input_tensor_layout, input_shape, input_slice_shape); + TensorInfo output_tensor_info(output_tensor_layout, output_shape, output_slice_shape); + + inputs_tensor_info_.push_back(input_tensor_info); + outputs_tensor_info_.push_back(output_tensor_info); + return SUCCESS; +} + +Status SqueezeInfo::Init(const StrategyPtr& strategy) { + if (InitWithAutoRepeatCalc(strategy) != SUCCESS) { + MS_LOG(ERROR) << name_ << " : Init failed."; + } + + if (InferReplaceOps(strategy) != SUCCESS) { + MS_LOG(ERROR) << name_ << " : Infer replace ops failed"; + } + + MS_LOG(INFO) << name_ << " : Init success."; + return SUCCESS; +} } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/activation_info.h b/mindspore/ccsrc/parallel/ops_info/activation_info.h index 21774c43ee..887be5ea33 100644 --- a/mindspore/ccsrc/parallel/ops_info/activation_info.h +++ b/mindspore/ccsrc/parallel/ops_info/activation_info.h @@ -51,7 +51,7 @@ class Activation : public ActivationBase { public: Activation(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ActivationBase(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : ActivationBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~Activation() override = default; Status GenerateStrategies(int32_t stage_id) override; Status SetCostUnderStrategy(const StrategyPtr& strategy) override; @@ -102,7 +102,7 @@ class Softmax : public ActivationBase { public: explicit Softmax(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ActivationBase(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : ActivationBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~Softmax() override = default; Status GenerateStrategies(int32_t stage_id) override; Status SetCostUnderStrategy(const StrategyPtr& strategy) override; @@ -184,6 +184,33 @@ class ExpandDimsInfo : public ActivationOther { Strategys inputs_strategy_; Strategys outputs_strategy_; }; + +class SqueezeInfo : public ActivationOther { + public: + SqueezeInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : ActivationOther(name, inputs_shape, outputs_shape, attrs) {} + ~SqueezeInfo() override = default; + + protected: + Status InferAxis(const ValueTuplePtr& value_tuple); + Status GetAttrs() override; + Status InferReplaceOps(const StrategyPtr& strategy); + Status InferTensorMap() override; + Status InferTensorInfo() override; + Status Init(const StrategyPtr& strategy) override; + + private: + ValueTuplePtr axis_; +}; + +class SquareInfo : public ActivationOther { + public: + SquareInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : ActivationOther(name, inputs_shape, outputs_shape, attrs) {} + ~SquareInfo() override = default; +}; } // namespace parallel } // namespace mindspore -#endif // MINDSPORE_CCSRC_OPTIMIZER_OPS_INFO_PARALLEL_ACTIVATION_INFO_H_ +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_ACTIVATION_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/arithmetic_info.h b/mindspore/ccsrc/parallel/ops_info/arithmetic_info.h index daa2ad595c..78dfc23803 100644 --- a/mindspore/ccsrc/parallel/ops_info/arithmetic_info.h +++ b/mindspore/ccsrc/parallel/ops_info/arithmetic_info.h @@ -32,8 +32,8 @@ namespace parallel { class ArithmeticBase : public OperatorInfo { public: ArithmeticBase(const std::string& operator_name, const Shapes& inputs_shape, const Shapes& outputs_shape, - const PrimitiveAttrs& attrs) - : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + const PrimitiveAttrs& attrs, OperatorCostPtr cost) + : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, cost) {} ~ArithmeticBase() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; @@ -56,7 +56,7 @@ class ArithmeticBase : public OperatorInfo { class SubInfo : public ArithmeticBase { public: SubInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~SubInfo() override = default; }; @@ -64,21 +64,21 @@ class TensorAddInfo : public ArithmeticBase { public: TensorAddInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~TensorAddInfo() override = default; }; class MulInfo : public ArithmeticBase { public: MulInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~MulInfo() override = default; }; class DivInfo : public ArithmeticBase { public: DivInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~DivInfo() override = default; }; @@ -86,7 +86,7 @@ class RealDivInfo : public ArithmeticBase { public: RealDivInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~RealDivInfo() override = default; }; @@ -94,15 +94,22 @@ class FloorDivInfo : public ArithmeticBase { public: FloorDivInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~FloorDivInfo() override = default; }; +class PowInfo : public ArithmeticBase { + public: + PowInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} + ~PowInfo() override = default; +}; + class GreaterInfo : public ArithmeticBase { public: GreaterInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~GreaterInfo() override = default; }; @@ -110,10 +117,19 @@ class AssignSubInfo : public ArithmeticBase { public: AssignSubInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~AssignSubInfo() override = default; }; + +// All dimensions can be split arbitrarily, but the split method of Logits should be the same as that of label. +class SigmoidCrossEntropyWithLogitsInfo : public ArithmeticBase { + public: + SigmoidCrossEntropyWithLogitsInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} + ~SigmoidCrossEntropyWithLogitsInfo() override = default; +}; } // namespace parallel } // namespace mindspore -#endif // MINDSPORE_CCSRC_OPTIMIZER_OPS_INFO_PARALLEL_ARITHMETIC_INFO_H_ +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_ARITHMETIC_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.cc b/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.cc index 793452b8ad..9d356cd573 100644 --- a/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.cc @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - Status BatchParallelInfo::CheckStrategy(const StrategyPtr& strategy) { if (CheckStrategyValue(strategy, inputs_shape_, is_auto_parallel_) != SUCCESS) { if (is_auto_parallel_) { @@ -228,26 +227,6 @@ void SparseSoftmaxCrossEntropyWithLogitsInfo::ReComputeBatchSplitFlagList() { } } -void GatherV2Info::ReComputeBatchSplitFlagList() { - MS_ASSERT(inputs_shape_.size() == 2); - MS_ASSERT(input_value_.size() == 3); - MS_ASSERT(input_value_[0] == nullptr); - // the second input is the index tensor - MS_ASSERT(input_value_[1] != nullptr); - // the third input is the axis - MS_ASSERT(input_value_[2] != nullptr); - int axis = GetValue(input_value_[2]); - MS_ASSERT(axis < inputs_shape_[0].size() && axis >= 0 - inputs_shape_[0].size()); - if (axis < 0) { - axis += SizeToInt(inputs_shape_[0].size()); - } - split_flag_list_[0] = true; - // if gather axis is 0, the index's strategy is equal to device number - if (axis == 0) { - split_flag_list_[1] = true; - } -} - Status BatchParallelInfo::InferAsLossDivisor() { as_loss_divisor_ = 1; return SUCCESS; diff --git a/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.h b/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.h index fae96dcab5..4cedb9b7b8 100644 --- a/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.h +++ b/mindspore/ccsrc/parallel/ops_info/batch_parallel_info.h @@ -29,9 +29,13 @@ namespace mindspore { namespace parallel { class BatchParallelInfo : public OperatorInfo { public: + BatchParallelInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs, OperatorCostPtr cost) + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, cost), dev_num_(1) {} BatchParallelInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()), dev_num_(1) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)), + dev_num_(1) {} ~BatchParallelInfo() override = default; Status Init(const StrategyPtr& strategy) override; @@ -58,19 +62,10 @@ class SparseSoftmaxCrossEntropyWithLogitsInfo : public BatchParallelInfo { public: SparseSoftmaxCrossEntropyWithLogitsInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : BatchParallelInfo(name, inputs_shape, outputs_shape, attrs) {} + : BatchParallelInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~SparseSoftmaxCrossEntropyWithLogitsInfo() override = default; void ReComputeBatchSplitFlagList() override; }; - -class GatherV2Info : public BatchParallelInfo { - public: - GatherV2Info(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, - const PrimitiveAttrs& attrs) - : BatchParallelInfo(name, inputs_shape, outputs_shape, attrs) {} - ~GatherV2Info() override = default; - void ReComputeBatchSplitFlagList() override; -}; } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/bias_add_info.h b/mindspore/ccsrc/parallel/ops_info/bias_add_info.h index dea5c90c88..e792858338 100644 --- a/mindspore/ccsrc/parallel/ops_info/bias_add_info.h +++ b/mindspore/ccsrc/parallel/ops_info/bias_add_info.h @@ -34,7 +34,7 @@ class BiasAddInfo : public OperatorInfo { public: BiasAddInfo(const std::string& operator_name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~BiasAddInfo() override = default; Status Init(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/comparison_function_info.h b/mindspore/ccsrc/parallel/ops_info/comparison_function_info.h index 110a9a6c38..9ea496e0b0 100644 --- a/mindspore/ccsrc/parallel/ops_info/comparison_function_info.h +++ b/mindspore/ccsrc/parallel/ops_info/comparison_function_info.h @@ -18,6 +18,7 @@ #define MINDSPORE_CCSRC_PARALLEL_OPS_INFO_COMPARISON_FUNCTION_INFO_H_ #include +#include #include #include #include "ir/value.h" @@ -31,7 +32,7 @@ class EqualInfo : public ArithmeticBase { public: EqualInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~EqualInfo() override = default; }; @@ -39,7 +40,7 @@ class NotEqualInfo : public ArithmeticBase { public: NotEqualInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~NotEqualInfo() override = default; }; @@ -47,10 +48,18 @@ class MaximumInfo : public ArithmeticBase { public: MaximumInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ArithmeticBase(name, inputs_shape, outputs_shape, attrs) {} + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~MaximumInfo() override = default; }; + +class MinimumInfo : public ArithmeticBase { + public: + MinimumInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : ArithmeticBase(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} + ~MinimumInfo() override = default; +}; } // namespace parallel } // namespace mindspore -#endif // MINDSPORE_CCSRC_OPTIMIZER_OPS_INFO_PARALLEL_COMPARISON_FUNCTION_INFO_H_ +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_COMPARISON_FUNCTION_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.cc b/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.cc index c6cd94b7be..c755cc785d 100644 --- a/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include #include "ir/value.h" +#include "pipeline/resource.h" #include "parallel/auto_parallel/costmodel.h" #include "parallel/device_matrix.h" #include "parallel/strategy.h" @@ -29,13 +30,32 @@ namespace mindspore { namespace parallel { +static int32_t SEED_NUM = 1; + Status DropoutDoMaskInfo::CheckStrategy(const StrategyPtr& strategy) { - Shapes input_shape = {inputs_shape_.at(0)}; + if (strategy == nullptr) { + MS_LOG(ERROR) << name_ << ": The strategy is null"; + return FAILED; + } + + std::vector stra = strategy->GetInputDim(); + if (stra.size() != 1) { + MS_LOG(ERROR) << name_ << ": Invalid strategy size " << stra.size() << ", it must be 1"; + return FAILED; + } + + if (inputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs shape is empty"; + return FAILED; + } + + // only check the input[0] + Shapes input_shape = {inputs_shape_[0]}; if (CheckStrategyValue(strategy, input_shape, is_auto_parallel_) != SUCCESS) { if (is_auto_parallel_) { - MS_LOG(DEBUG) << name_ << " : Invalid strategy."; + MS_LOG(DEBUG) << name_ << ": Invalid strategy"; } else { - MS_LOG(ERROR) << name_ << " : Invalid strategy."; + MS_LOG(ERROR) << name_ << ": Invalid strategy"; } return FAILED; } @@ -43,68 +63,69 @@ Status DropoutDoMaskInfo::CheckStrategy(const StrategyPtr& strategy) { } Status DropoutDoMaskInfo::InferDevMatrixShape() { - std::vector stra = strategy_->GetInputDim(); - Dimensions input_strategy = stra.at(0); + if (strategy_ == nullptr) { + MS_LOG(ERROR) << name_ << ": The strategy is null"; + return FAILED; + } - dev_matrix_shape_ = input_strategy; + std::vector strategy = strategy_->GetInputDim(); + if (strategy.empty()) { + MS_LOG(ERROR) << name_ << ": The strategy is empty"; + return FAILED; + } + dev_matrix_shape_ = strategy[0]; return SUCCESS; } Status DropoutDoMaskInfo::InferTensorMap() { + if (inputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs shape is empty"; + return FAILED; + } + std::vector tensor_map_index; - size_t size = inputs_shape_.at(0).size(); - // such as 4: tensor_map_index [3,2,1,0] + size_t size = inputs_shape_[0].size(); + // if the dimension of input is 4, and tensor_map_index is [3, 2, 1, 0] for (size_t i = 0; i < size; ++i) { - tensor_map_index.push_back((int32_t)(LAST_INDEX(size) - i)); + tensor_map_index.push_back(SizeToInt(size - i - 1)); } - TensorMap input_b_tensor_map = {MAP_NONE}; - inputs_tensor_map_.push_back(tensor_map_index); - inputs_tensor_map_.push_back(input_b_tensor_map); - outputs_tensor_map_.push_back(tensor_map_index); + // the input[1] do not need tensor map + inputs_tensor_map_.push_back(tensor_map_index); // input_0 + outputs_tensor_map_.push_back(tensor_map_index); // output return SUCCESS; } Status DropoutDoMaskInfo::InferTensorInfo() { - // infer tensor shape - Shape input_a_shape = inputs_shape_.at(0); - Shape input_b_shape = inputs_shape_.at(1); - Shape output_shape = outputs_shape_.at(0); - - // infer slice shape - Shapes inputs_slice_shape, outputs_slice_shape; - Strategys inputs_strategy = strategy_->GetInputDim(); - Dimensions input_b_strategy = {1}, input_x_strategy = {}; - inputs_strategy.emplace_back(input_b_strategy); - inputs_strategy.emplace_back(input_x_strategy); - Strategys outputs_strategy = {inputs_strategy.at(0)}; - if (InferSliceShape(inputs_strategy, outputs_strategy, &inputs_slice_shape, &outputs_slice_shape) != SUCCESS) { + if (inputs_shape_.size() != 3) { + MS_LOG(ERROR) << name_ << ": Invalid inputs shape size " << inputs_shape_.size(); return FAILED; } - Shape input_a_slice_shape = inputs_slice_shape.at(0); - Shape input_b_slice_shape = inputs_slice_shape.at(1); - Shape output_slice_shape = outputs_slice_shape.at(0); - TensorLayout input_a_tensor_layout, input_b_tensor_layout; - TensorLayout output_tensor_layout; - if (input_a_tensor_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_[0], input_a_shape) != SUCCESS) { + if (strategy_ == nullptr) { + MS_LOG(ERROR) << name_ << ": The strategy is null"; return FAILED; } - if (input_b_tensor_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_[1], input_b_shape) != SUCCESS) { + + Shape input_0_shape = inputs_shape_[0]; + + if (inputs_tensor_map_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs tensor map is empty"; return FAILED; } - if (output_tensor_layout.InitFromVector(dev_matrix_shape_, outputs_tensor_map_[0], output_shape) != SUCCESS) { + + TensorLayout input_0_tensor_layout; + if (input_0_tensor_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_[0], input_0_shape) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init tensor layout failed"; return FAILED; } - TensorInfo input_a_tensor_info(input_a_tensor_layout, input_a_shape, input_a_slice_shape); - TensorInfo input_b_tensor_info(input_b_tensor_layout, input_b_shape, input_b_slice_shape); - TensorInfo output_tensor_info(output_tensor_layout, output_shape, output_slice_shape); - inputs_tensor_info_.push_back(input_a_tensor_info); - inputs_tensor_info_.push_back(input_b_tensor_info); - outputs_tensor_info_.push_back(output_tensor_info); + TensorInfo input_0_tensor_info(input_0_tensor_layout); + // input_1 do not need tensor info + inputs_tensor_info_.push_back(input_0_tensor_info); // input_0 + outputs_tensor_info_.push_back(input_0_tensor_info); // output return SUCCESS; } @@ -122,20 +143,29 @@ Status DropoutDoMaskInfo::SetCostUnderStrategy(const StrategyPtr& strategy) { } Status DropoutDoMaskInfo::GenerateStrategies(int32_t stage_id) { - CheckGlobalDeviceManager(); + if (inputs_shape_.empty()) { + MS_LOG(ERROR) << name_ << ": The inputs shape is empty"; + return FAILED; + } + is_auto_parallel_ = true; - size_t dev_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); - Dimensions strategy(inputs_shape_[0].size() - 1, 1); - (void)strategy.insert(strategy.begin(), SizeToInt(dev_num)); - std::vector stra = {strategy}; - StrategyPtr sp = std::make_shared(stage_id, stra); - if (SetCostUnderStrategy(sp) == SUCCESS) { - MS_LOG(INFO) << name_ << " : Successfully generated batch-parallel-strategy."; - PrintStrategy(sp); - } else { - MS_LOG(ERROR) << name_ << " : Generating batch-parallel-strategy failed."; + Shape input0_split(inputs_shape_[0].size(), 1); + Shapes splittable_inputs = {input0_split}; + Shapes used_inputs_shape = {inputs_shape_[0]}; + + std::vector sp_vector; + if (GenerateStrategiesForIndependentInputs(stage_id, used_inputs_shape, splittable_inputs, &sp_vector) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Generate strategies failed"; return FAILED; } + size_t success = 0; + for (auto& sp : sp_vector) { + if (SetCostUnderStrategy(sp) == SUCCESS) { + success++; + MS_LOG(INFO) << name_ << ": Successfully generated " << success << " strategy"; + PrintStrategy(sp); + } + } return SUCCESS; } @@ -150,26 +180,105 @@ std::shared_ptr>> DropoutDoMaskInfo::GenerateBa Status DropoutDoMaskInfo::Init(const StrategyPtr& strategy) { if (InitWithAutoRepeatCalc(strategy) != SUCCESS) { - MS_LOG(ERROR) << name_ << " : Init failed."; + MS_LOG(ERROR) << name_ << ": Init failed."; return FAILED; } - MS_LOG(INFO) << name_ << " : Init success."; + MS_LOG(INFO) << name_ << ": Init success."; return SUCCESS; } Status DropoutDoMaskInfo::InitForCostModel(const StrategyPtr& strategy) { if (InitForCostModelWithAutoRepeatCalc(strategy) != SUCCESS) { if (is_auto_parallel_) { - MS_LOG(DEBUG) << name_ << " : Init for cost model failed."; + MS_LOG(DEBUG) << name_ << ": Init for cost model failed."; } else { - MS_LOG(ERROR) << name_ << " : Init for cost model failed."; + MS_LOG(ERROR) << name_ << ": Init for cost model failed."; } return FAILED; } - MS_LOG(INFO) << name_ << " : Init for cost model success."; + MS_LOG(INFO) << name_ << ": Init for cost model success."; return SUCCESS; } + +PrimitivePtr GetDropoutGenMaskPrim(const CNodePtr& cnode) { + MS_EXCEPTION_IF_NULL(cnode); + if (cnode->inputs().size() != DROPOUT_DO_MASK_CNODE_INPUT_SIZE) { + MS_LOG(EXCEPTION) << "The size of dropout do mask cnode's inputs must be " << DROPOUT_DO_MASK_CNODE_INPUT_SIZE; + } + + AnfNodePtr dropout_gen_mask = cnode->input(DROPOUT_GEN_MASK_INDEX); + MS_EXCEPTION_IF_NULL(dropout_gen_mask); + if (!dropout_gen_mask->isa()) { + MS_LOG(EXCEPTION) << "The dropout do mask cnode's input[" << DROPOUT_GEN_MASK_INDEX << "] must be a cnode"; + } + + auto dropout_gen_mask_cnode = dropout_gen_mask->cast(); + MS_EXCEPTION_IF_NULL(dropout_gen_mask_cnode); + if (dropout_gen_mask_cnode->inputs().size() != DROPOUT_GEN_MASK_CNODE_INPUT_SIZE) { + MS_LOG(EXCEPTION) << "The size of dropout gen mask cnode's inputs must be " << DROPOUT_GEN_MASK_CNODE_INPUT_SIZE; + } + if (!IsValueNode(dropout_gen_mask_cnode->input(0))) { + MS_LOG(EXCEPTION) << "The input[0] of dropout gen mask cnode is not primitive"; + } + + ValueNodePtr value_node = dropout_gen_mask_cnode->input(0)->cast(); + MS_EXCEPTION_IF_NULL(value_node); + PrimitivePtr prim = value_node->value()->cast(); + MS_EXCEPTION_IF_NULL(prim); + if (prim->name() != DROPOUT_GEN_MASK) { + MS_LOG(EXCEPTION) << "The primitive name is not DropoutGenMask"; + } + return prim; +} + +// DropoutDoMask needs to be used together with DropoutGenMask. Only the first input tensor of DropoutGenMask is +// split. Find the DropoutGenMask node in the anf graph according to DropoutDoMask node, and modify the input shape +// of DropoutGenMask according to the strategy of DropoutDoMask. When the DropoutDoMask performs repeated calculation +// and both seeds of DropoutGenMask are 0, two new seeds are automatically generated for DropoutGenMask. +Operator DropoutDoMaskInfo::GetDropoutGenMaskReplaceOp(const CNodePtr& cnode) { + MS_EXCEPTION_IF_NULL(cnode); + PrimitivePtr prim = GetDropoutGenMaskPrim(cnode); + MS_EXCEPTION_IF_NULL(prim); + + if (inputs_tensor_info_.empty()) { + MS_LOG(EXCEPTION) << "The tensor info of dropout do mask is empty"; + } + + if (cnode->inputs().size() != DROPOUT_DO_MASK_CNODE_INPUT_SIZE) { + MS_LOG(EXCEPTION) << "The size of dropout do mask cnode's inputs must be " << DROPOUT_DO_MASK_CNODE_INPUT_SIZE; + } + + if (!cnode->input(DROPOUT_DO_MASK_KEEP_PROB_INDEX)->isa()) { + MS_LOG(EXCEPTION) << "The keep prob of dropout do mask is not value node"; + } + + ValuePtr keep_prob = GetValueNode(cnode->input(DROPOUT_DO_MASK_KEEP_PROB_INDEX)); + MS_EXCEPTION_IF_NULL(keep_prob); + auto attr = prim->attrs(); + if ((attr.find(SEED0) == attr.end()) || (attr.find(SEED1) == attr.end())) { + MS_LOG(EXCEPTION) << "The attrs of dropout gen mask must be have seed0 and seed1"; + } + int32_t seed_0 = GetValue(attr[SEED0]); + int32_t seed_1 = GetValue(attr[SEED1]); + if ((seed_0 == 0) && (seed_1 == 0) && (repeated_calc_num_ > 1)) { + seed_0 = SEED_NUM; + seed_1 = SEED_NUM; + SEED_NUM++; + } + + Shape input_slice_shape = inputs_tensor_info_[0].slice_shape(); + ValuePtr new_shape = MakeValue(input_slice_shape); + Attr attr_0 = std::make_pair(SEED0, MakeValue(seed_0)); + Attr attr_1 = std::make_pair(SEED1, MakeValue(seed_1)); + OperatorAttrs attrs = {attr_0, attr_1}; + Attr param_0 = std::make_pair(SHAPE, new_shape); + Attr param_1 = std::make_pair(KEEP_PROB, keep_prob); + OperatorParams params = {std::make_pair(param_0, 1), std::make_pair(param_1, 2)}; + OperatorArgs args = std::make_pair(attrs, params); + Operator replace_op = {std::make_pair(DROPOUT_GEN_MASK, args)}; + return replace_op; +} } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.h b/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.h index 859b3e06a4..3b154bd6db 100644 --- a/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.h +++ b/mindspore/ccsrc/parallel/ops_info/dropout_do_mask_info.h @@ -33,7 +33,7 @@ class DropoutDoMaskInfo : public OperatorInfo { public: DropoutDoMaskInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~DropoutDoMaskInfo() override = default; Status Init(const StrategyPtr& strategy) override; @@ -41,6 +41,7 @@ class DropoutDoMaskInfo : public OperatorInfo { Status SetCostUnderStrategy(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; std::shared_ptr>> GenerateBatchStrategies() override; + Operator GetDropoutGenMaskReplaceOp(const CNodePtr& cnode); protected: Status CheckStrategy(const StrategyPtr& strategy) override; @@ -51,6 +52,8 @@ class DropoutDoMaskInfo : public OperatorInfo { Status InferTensorInfo() override; Status InferDevMatrixShape() override; }; + +using DropoutDoMaskInfoPtr = std::shared_ptr; } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/elementary_function_info.cc b/mindspore/ccsrc/parallel/ops_info/elementary_function_info.cc deleted file mode 100644 index d4f79aca65..0000000000 --- a/mindspore/ccsrc/parallel/ops_info/elementary_function_info.cc +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2019 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "parallel/ops_info/elementary_function_info.h" - -namespace mindspore { -namespace parallel { -Status PowInfo::InferMirrorOps() { - mirror_ops_.clear(); - - Shape tensor_map = inputs_tensor_map_[0]; - std::vector group; - if (CreateGroupByTensorMap(tensor_map, &group) != SUCCESS) { - MS_LOG(ERROR) << name_ << " : Create group failed."; - return FAILED; - } - - OperatorVector mirror_op; - OperatorVector op_for_value; - if (group.empty()) { - MS_LOG(INFO) << name_ << " : The mirror ops is empty."; - return SUCCESS; - } else { - mirror_op = CreateMirrorOps(group[0].name(), group[0].GetDevNum()); - mirror_ops_.push_back(mirror_op); - mirror_ops_.push_back(op_for_value); - std::string group_name = group[0].name(); - MS_LOG(INFO) << name_ << " : Create the mirror ops success, the group name is " << group_name; - } - - return SUCCESS; -} -} // namespace parallel -} // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/elementary_function_info.h b/mindspore/ccsrc/parallel/ops_info/elementary_function_info.h index 57b4650f26..84b8030f37 100644 --- a/mindspore/ccsrc/parallel/ops_info/elementary_function_info.h +++ b/mindspore/ccsrc/parallel/ops_info/elementary_function_info.h @@ -27,16 +27,6 @@ namespace mindspore { namespace parallel { -class PowInfo : public ActivationOther { - public: - PowInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : ActivationOther(name, inputs_shape, outputs_shape, attrs) {} - ~PowInfo() override = default; - - protected: - Status InferMirrorOps() override; -}; - class ExpInfo : public ActivationOther { public: ExpInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) diff --git a/mindspore/ccsrc/parallel/ops_info/gather_v2_info.cc b/mindspore/ccsrc/parallel/ops_info/gather_v2_info.cc new file mode 100644 index 0000000000..c315991849 --- /dev/null +++ b/mindspore/ccsrc/parallel/ops_info/gather_v2_info.cc @@ -0,0 +1,350 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "parallel/ops_info/gather_v2_info.h" + +#include +#include +#include + +#include "ir/meta_tensor.h" +#include "ir/value.h" +#include "parallel/auto_parallel/costmodel.h" +#include "parallel/device_matrix.h" +#include "parallel/graph_util/generate_graph.h" +#include "parallel/strategy.h" +#include "utils/log_adapter.h" + +namespace mindspore { +namespace parallel { +Status GatherV2Info::GetAttrs() { + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs shape size must be 2, but is " << inputs_shape_.size(); + return FAILED; + } + if (outputs_shape_.size() != GATHER_V2_OUTPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": outputs shape size must be 1, but is " << outputs_shape_.size(); + return FAILED; + } + if (input_value_.size() != GATHER_V2_INPUTS_VALUE_SIZE) { + MS_LOG(ERROR) << name_ << ": input value size must be 3, but is " << input_value_.size(); + return FAILED; + } + // the second input is the index tensor + + // the third input is the axis, is a ValueNode + if (input_value_.at(2) == nullptr) { + MS_LOG(ERROR) << name_ << ": the third input value is nullptr, is not a ValueNode!"; + return FAILED; + } + + if (inputs_shape_.at(0).size() == 0) { + MS_LOG(ERROR) << name_ << ": input can not be a scalar!"; + return FAILED; + } + int axis = GetValue(input_value_.at(2)); + if (axis >= SizeToInt(inputs_shape_.at(0).size()) || axis < 0 - SizeToInt(inputs_shape_.at(0).size())) { + MS_LOG(ERROR) << "Axis is " << axis << ", not in [-" << inputs_shape_.at(0).size() << ", " + << inputs_shape_.at(0).size() << ")."; + } + if (axis < 0) { + axis += SizeToInt(inputs_shape_[0].size()); + } + axis_ = axis; + + index_size_ = inputs_shape_.at(1).size(); + + return SUCCESS; +} + +Status GatherV2Info::CheckStrategy(const StrategyPtr& strategy) { + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs shape size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_shape_.size(); + return FAILED; + } + if (outputs_shape_.size() != GATHER_V2_OUTPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": outputs shape size must be " << GATHER_V2_OUTPUTS_SIZE << ", but is " + << outputs_shape_.size(); + return FAILED; + } + // Only strategy of the first input should be set. + if (CheckStrategyValue(strategy, {inputs_shape_.at(0)}, is_auto_parallel_) != SUCCESS) { + if (is_auto_parallel_) { + MS_LOG(DEBUG) << name_ << ": Invalid strategy."; + } else { + MS_LOG(ERROR) << name_ << ": Invalid strategy."; + } + return FAILED; + } + axis_strategy_ = strategy->GetInputDim().at(0).at(axis_); + if (index_size_ != 1 && axis_strategy_ != 1) { + MS_LOG(ERROR) << name_ + << ": Invalid strategy. If the index is a scalar or a more than 1 dimension vector, the strategy " + "corresponding to axis must be 1, but is " + << axis_strategy_; + return FAILED; + } + if (index_size_ == 1 && axis_strategy_ != 1 && inputs_shape_.at(1).at(0) % axis_strategy_ != 0) { + MS_LOG(ERROR) << name_ + << ": Invalid strategy. The first dimension of index can not be divided by strategy corresponding to " + "axis. The first dimension of index is " + << inputs_shape_.at(1).at(0) << " strategy corresponding to axis is " << axis_strategy_; + return FAILED; + } + return SUCCESS; +} + +Status GatherV2Info::InferDevMatrixShape() { + std::vector stra = strategy_->GetInputDim(); + dev_matrix_shape_ = stra.at(0); + return SUCCESS; +} + +// If index is a scalar, output dimension is input dimension minus 1; +// If index is a n dimension tensor, output dimension is input dimension plus (n - 1). +// Tensor map dimension is equal to the corresponding input and output dimension. +// If index's dimension is more than 1, we insert -1 for the output tensor map. +Status GatherV2Info::InferTensorMap() { + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs shape size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_shape_.size(); + return FAILED; + } + if (outputs_shape_.size() != GATHER_V2_OUTPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": outputs shape size must be " << GATHER_V2_OUTPUTS_SIZE << ", but is " + << outputs_shape_.size(); + return FAILED; + } + std::vector tensor_map_in; + std::vector tensor_map_out; + size_t size = inputs_shape_.at(0).size(); + // such as 4: tensor_map_index [3,2,1,0] + for (size_t i = 0; i < size; ++i) { + tensor_map_in.push_back(SizeToInt(size - i - 1)); + tensor_map_out.push_back(SizeToInt(size - i - 1)); + } + + if (index_size_ == 0) { + (void)tensor_map_out.erase(tensor_map_out.begin() + axis_); + } else if (index_size_ > 1) { + (void)tensor_map_out.insert(tensor_map_out.begin() + axis_, index_size_ - 1, -1); + } + if (tensor_map_out.size() != outputs_shape_.at(0).size()) { + MS_LOG(ERROR) << "Out tensor map size is not equal to output size! Out tensor map size is " << tensor_map_out.size() + << " output size is " << outputs_shape_.at(0).size(); + return FAILED; + } + + std::vector tensor_map_in_index; + if (index_size_ >= 1) { + tensor_map_in_index.push_back(SizeToInt(size - axis_ - 1)); + } + for (size_t i = 1; i < index_size_; ++i) { + tensor_map_in_index.push_back(-1); + } + inputs_tensor_map_.emplace_back(std::move(tensor_map_in)); + inputs_tensor_map_.emplace_back(std::move(tensor_map_in_index)); + outputs_tensor_map_.emplace_back(std::move(tensor_map_out)); + return SUCCESS; +} + +Status GatherV2Info::InferTensorInfo() { + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs shape size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_shape_.size(); + return FAILED; + } + if (outputs_shape_.size() != GATHER_V2_OUTPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": outputs shape size must be " << GATHER_V2_OUTPUTS_SIZE << ", but is " + << outputs_shape_.size(); + return FAILED; + } + if (inputs_tensor_map_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs tensor map size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_tensor_map_.size(); + return FAILED; + } + if (outputs_tensor_map_.size() != GATHER_V2_OUTPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": outputs tensor map size must be " << GATHER_V2_OUTPUTS_SIZE << ", but is " + << outputs_tensor_map_.size(); + return FAILED; + } + // infer tensor shape + Shape input_shape = inputs_shape_.at(0); + Shape input_index_shape = inputs_shape_.at(1); + Shape output_shape = outputs_shape_.at(0); + + TensorLayout input_tensor_layout, input_index_layout, output_tensor_layout; + if ((input_tensor_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_.at(0), input_shape) != SUCCESS) || + (input_index_layout.InitFromVector(dev_matrix_shape_, inputs_tensor_map_.at(1), input_index_shape) != SUCCESS) || + (output_tensor_layout.InitFromVector(dev_matrix_shape_, outputs_tensor_map_.at(0), output_shape) != SUCCESS)) { + return FAILED; + } + + TensorInfo input_tensor_info(input_tensor_layout); + TensorInfo input_index_info(input_index_layout); + TensorInfo output_tensor_info(output_tensor_layout); + + inputs_tensor_info_.push_back(input_tensor_info); + inputs_tensor_info_.push_back(input_index_info); + outputs_tensor_info_.push_back(output_tensor_info); + return SUCCESS; +} + +OperatorVector CreateSubOp(int32_t sub_value) { + OperatorVector ops; + OperatorName operator_name = SUB; + OperatorAttrs operator_attrs; + + py::tuple tuple = py::make_tuple(sub_value); + mindspore::tensor::TensorPtr tensor_ptr = std::make_shared(tuple, kInt32); + ValuePtr op_param_value = MakeValue(tensor_ptr); + + Attr op1_param = std::make_pair("", op_param_value); + OperatorParams operator_param = {std::make_pair(op1_param, 2)}; + + OperatorArgs operator_args = std::make_pair(operator_attrs, operator_param); + Operator op = std::make_pair(operator_name, operator_args); + ops.push_back(op); + return ops; +} + +Status GatherV2Info::InferTensorSubOps() { + sub_ops_.clear(); + if ((index_size_ == 0) || (axis_strategy_ == 1)) { + return SUCCESS; + } + int32_t mod_n = 1; + for (size_t i = IntToSize(axis_) + 1; i < dev_matrix_shape_.size(); i++) { + mod_n *= dev_matrix_shape_.at(i); + } + if ((axis_ >= SizeToInt(dev_matrix_shape_.size())) || axis_ < 0) { + MS_LOG(ERROR) << "Axis is " << axis_ << ", not in [0, " << dev_matrix_shape_.size() << ")."; + } + int32_t mod_p = mod_n * dev_matrix_shape_.at(axis_); + int32_t rank = g_device_manager->global_rank(); + int32_t mod_rank = rank % mod_p; + mod_rank = static_cast(mod_rank / mod_n); + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(ERROR) << name_ << ": inputs shape size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_shape_.size(); + return FAILED; + } + if ((axis_ >= SizeToInt(inputs_shape_.at(0).size())) || axis_ < 0) { + MS_LOG(ERROR) << "Axis is " << axis_ << ", not in [0, " << inputs_shape_.at(0).size() << ")."; + } + int32_t sub_value = static_cast(inputs_shape_.at(0).at(axis_) / dev_matrix_shape_.at(axis_)) * mod_rank; + + OperatorVector sub_op; + sub_ops_.emplace_back(std::move(sub_op)); + sub_op = CreateSubOp(sub_value); + sub_ops_.emplace_back(std::move(sub_op)); + return SUCCESS; +} + +Status GatherV2Info::Init(const StrategyPtr& strategy) { + if (InitWithAutoRepeatCalc(strategy) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init failed."; + return FAILED; + } + Status status = InferTensorSubOps(); + if (status != SUCCESS) { + MS_LOG(ERROR) << name_ << ": InferTensorSubOps failed."; + return status; + } + MS_LOG(INFO) << name_ << ": Init success."; + return SUCCESS; +} + +Status GatherV2Info::InitForCostModel(const StrategyPtr& strategy) { + if (InitForCostModelWithAutoRepeatCalc(strategy) != SUCCESS) { + if (is_auto_parallel_) { + MS_LOG(DEBUG) << name_ << ": Init for cost model failed."; + } else { + MS_LOG(ERROR) << name_ << ": Init for cost model failed."; + } + return FAILED; + } + MS_LOG(INFO) << name_ << ": Init for cost model success."; + return SUCCESS; +} + +Status GatherV2Info::GenerateStrategies(int32_t stage_id) { + if ((inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) || (outputs_shape_.size() != GATHER_V2_OUTPUTS_SIZE)) { + MS_LOG(ERROR) << name_ << " : Inputs shape size(" << inputs_shape_.size() << ") or outputs shape size(" + << outputs_shape_.size() << "is wrong."; + return FAILED; + } + + is_auto_parallel_ = true; + Shape input0_split(inputs_shape_[0].size(), 1); + Shapes splittable_inputs = {input0_split}; + + std::vector sp_vector; + if (GenerateStrategiesForIndependentInputs(stage_id, {inputs_shape_.at(0)}, splittable_inputs, &sp_vector) != + SUCCESS) { + MS_LOG(ERROR) << name_ << " : Generate strategies for independent inputs() failed."; + return FAILED; + } + size_t success = 0; + for (auto& sp : sp_vector) { + if (SetCostUnderStrategy(sp) == SUCCESS) { + success++; + MS_LOG(INFO) << name_ << " : Successfully generated " << success << " strategy"; + PrintStrategy(sp); + } + } + return SUCCESS; +} + +Status GatherV2Info::SetCostUnderStrategy(const StrategyPtr& strategy) { + if (SetCostUnderStrategyBase(strategy) != SUCCESS) { + if (is_auto_parallel_) { + MS_LOG(DEBUG) << name_ << ": Set cost under strategy failed."; + } else { + MS_LOG(ERROR) << name_ << ": Set cost under strategy failed."; + } + return FAILED; + } + return SUCCESS; +} + +std::shared_ptr>> GatherV2Info::GenerateBatchStrategies() { + if (inputs_shape_.size() != GATHER_V2_INPUTS_SIZE) { + MS_LOG(EXCEPTION) << name_ << ": inputs shape size must be " << GATHER_V2_INPUTS_SIZE << ", but is " + << inputs_shape_.size(); + } + CheckGlobalDeviceManager(); + size_t dev_num = g_device_manager->GetDeviceListByStageId(0).size(); + if (GetAttrs() != SUCCESS) { + MS_LOG(EXCEPTION) << "GetAttrs failed!"; + } + + Dimensions strategy; + if (index_size_ != 1) { + strategy.push_back(1); + } else { + strategy.push_back(SizeToInt(dev_num)); + } + for (size_t i = 1; i < inputs_shape_[0].size(); i++) { + strategy.push_back(1); + } + std::vector strategy_v = {strategy}; + return std::make_shared>>(strategy_v); +} +} // namespace parallel +} // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/gather_v2_info.h b/mindspore/ccsrc/parallel/ops_info/gather_v2_info.h new file mode 100644 index 0000000000..773d46f429 --- /dev/null +++ b/mindspore/ccsrc/parallel/ops_info/gather_v2_info.h @@ -0,0 +1,73 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GATHER_V2_INFO_H_ +#define MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GATHER_V2_INFO_H_ + +#include +#include +#include +#include + +#include "ir/value.h" +#include "parallel/auto_parallel/operator_costmodel.h" +#include "parallel/ops_info/operator_info.h" +#include "parallel/strategy.h" + +namespace mindspore { +namespace parallel { +constexpr size_t GATHER_V2_INPUTS_SIZE = 2; +constexpr size_t GATHER_V2_OUTPUTS_SIZE = 1; +constexpr size_t GATHER_V2_INPUTS_VALUE_SIZE = 3; +// We now supported limited parallel strategies. +// If the strategy corresponding to axis is more than 1, index must be evenly distributed across the axis-dimension of +// the input. +// If Index is a scalar or n-dimension vector(n > 1), the strategy corresponding to axis must be 1. +class GatherV2Info : public OperatorInfo { + public: + GatherV2Info(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()), + axis_(-1), + index_size_(0), + axis_strategy_(1) {} + ~GatherV2Info() override = default; + Status Init(const StrategyPtr& strategy) override; + Status InitForCostModel(const StrategyPtr& strategy) override; + + Status GenerateStrategies(int32_t stage_id) override; + Status SetCostUnderStrategy(const StrategyPtr& strategy) override; + std::shared_ptr>> GenerateBatchStrategies() override; + + protected: + Status CheckStrategy(const StrategyPtr& strategy) override; + Status InferMirrorOps() override { return SUCCESS; } + Status InferForwardCommunication() override { return SUCCESS; } + Status InferTensorInfo() override; + Status InferDevMatrixShape() override; + Status InferTensorMap() override; + Status GetAttrs() override; + + private: + Status InferTensorSubOps(); + + int32_t axis_; + size_t index_size_; + int32_t axis_strategy_; +}; +} // namespace parallel +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GATHER_V2_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/generator_info.cc b/mindspore/ccsrc/parallel/ops_info/generator_info.cc deleted file mode 100644 index a39f9faab9..0000000000 --- a/mindspore/ccsrc/parallel/ops_info/generator_info.cc +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Copyright 2019 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "parallel/ops_info/generator_info.h" - -#include -#include -#include -#include - -#include "ir/value.h" -#include "parallel/device_matrix.h" -#include "parallel/strategy.h" -#include "parallel/tensor_layout/tensor_redistribution.h" - -namespace mindspore { -namespace parallel { -Status GeneratorBase::InferTensorMap() { - TensorMap output_tensor_map = {MAP_NONE}; - outputs_tensor_map_.push_back(output_tensor_map); - return SUCCESS; -} - -Status GeneratorBase::InferTensorInfo() { - Shape output_shape = outputs_shape_.at(0); - Shape output_slice_shape = outputs_shape_.at(0); - - TensorLayout output_tensor_layout; - if (output_tensor_layout.InitFromVector(dev_matrix_shape_, outputs_tensor_map_[0], output_shape) != SUCCESS) { - MS_LOG(ERROR) << name_ << " : Creat output tensor layout failed."; - return FAILED; - } - TensorInfo output_tensor_info(output_tensor_layout, output_shape, output_slice_shape); - outputs_tensor_info_.push_back(output_tensor_info); - - return SUCCESS; -} - -Status GeneratorBase::InferDevMatrixShape() { - std::vector stra = strategy_->GetInputDim(); - Dimensions input_strategy = stra.at(0); - - dev_matrix_shape_ = input_strategy; - - return SUCCESS; -} - -Status GeneratorBase::SetCostUnderStrategy(const StrategyPtr &strategy) { - if (SetCostUnderStrategyBase(strategy) != SUCCESS) { - if (is_auto_parallel_) { - MS_LOG(DEBUG) << name_ << " : Set cost under strategy failed."; - } else { - MS_LOG(ERROR) << name_ << " : Set cost under strategy failed."; - } - return FAILED; - } - - return SUCCESS; -} - -Status DropoutGenMaskInfo::GenerateStrategies(int32_t stage_id) { - if (input_value_.empty()) { - MS_LOG(ERROR) << name_ << " : Input value is empty."; - return FAILED; - } - Shape param = GetValue>(input_value_[0]); - if (param.empty()) { - MS_LOG(ERROR) << name_ << " : Input value [0] is empty."; - return FAILED; - } - // Now,only support batch parallel. - CheckGlobalDeviceManager(); - is_auto_parallel_ = true; - size_t dev_num = g_device_manager->GetDeviceListByStageId(stage_id).size(); - Dimensions strategy(param.size() - 1, 1); - (void)strategy.insert(strategy.begin(), SizeToInt(dev_num)); - std::vector stra = {strategy}; - StrategyPtr sp = std::make_shared(stage_id, stra); - if (SetCostUnderStrategy(sp) == SUCCESS) { - MS_LOG(INFO) << name_ << " : Successfully generated batch-parallel-strategy."; - PrintStrategy(sp); - } else { - MS_LOG(ERROR) << name_ << " : Generating batch-parallel-strategy failed."; - return FAILED; - } - return SUCCESS; -} - -Status DropoutGenMaskInfo::CheckStrategy(const StrategyPtr &strategy) { - if (strategy->GetInputNumber() != 1) { - if (is_auto_parallel_) { - MS_LOG(DEBUG) << name_ << " : The strategy is wrong."; - } else { - MS_LOG(ERROR) << name_ << " : The strategy is wrong."; - } - return FAILED; - } - - return SUCCESS; -} - -Status DropoutGenMaskInfo::InferReplaceOps(const StrategyPtr &strategy) { - Shape shape = GetValue>(input_value_[0]); - Strategys stra = strategy->GetInputDim(); - Dimensions input_strategy = stra.at(0); - int32_t dev_num = *(input_strategy.begin()); - if (dev_num <= 0) { - MS_LOG(ERROR) << name_ << " : The number of devices should not be less than 0."; - return FAILED; - } - // Batch parallel - if (shape[0] % dev_num != 0) { - MS_LOG(ERROR) << name_ << " : The shape " << shape[0] << " can't be exact divided by device number " << dev_num; - return FAILED; - } - shape[0] = shape[0] / dev_num; - ValuePtr shape_ptr = MakeValue(shape); - Attr attr_0 = std::make_pair(SEED0, attrs_[SEED0]); - Attr attr_1 = std::make_pair(SEED1, attrs_[SEED1]); - OperatorAttrs attrs = {attr_0, attr_1}; - Attr param_0 = std::make_pair(SHAPE, shape_ptr); - Attr param_1 = std::make_pair(KEEP_PROB, input_value_[1]); - OperatorParams params = {std::make_pair(param_0, 1), std::make_pair(param_1, 2)}; - OperatorArgs args = std::make_pair(attrs, params); - replace_op_ = {std::make_pair(DROPOUT_GEN_MASK, args)}; - return SUCCESS; -} - -std::shared_ptr>> DropoutGenMaskInfo::GenerateBatchStrategies() { - if (input_value_.empty()) { - MS_LOG(EXCEPTION) << name_ << " : Input value is empty."; - } - Shape param = GetValue>(input_value_[0]); - if (param.empty()) { - MS_LOG(EXCEPTION) << name_ << " : Input value [0] is empty."; - } - // Now,only support batch parallel. - CheckGlobalDeviceManager(); - size_t dev_num = g_device_manager->GetDeviceListByStageId(0).size(); - Dimensions strategy(param.size() - 1, 1); - (void)strategy.insert(strategy.begin(), SizeToInt(dev_num)); - std::vector strategy_v = {strategy}; - return std::make_shared>>(strategy_v); -} - -Status GeneratorBase::Init(const StrategyPtr &strategy) { - if (InitWithAutoRepeatCalc(strategy) != SUCCESS) { - MS_LOG(ERROR) << name_ << " : Init failed."; - return FAILED; - } - - if (InferReplaceOps(strategy) != SUCCESS) { - MS_LOG(ERROR) << name_ << " : Infer replace ops failed."; - return FAILED; - } - - MS_LOG(INFO) << name_ << " : Init success."; - return SUCCESS; -} - -Status GeneratorBase::InitForCostModel(const StrategyPtr &strategy) { - if (InitForCostModelWithAutoRepeatCalc(strategy) != SUCCESS) { - if (is_auto_parallel_) { - MS_LOG(DEBUG) << name_ << " : Init for cost model failed."; - } else { - MS_LOG(ERROR) << name_ << " : Init for cost model failed."; - } - return FAILED; - } - - MS_LOG(INFO) << name_ << " : Init for cost model success."; - return SUCCESS; -} -} // namespace parallel -} // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/generator_info.h b/mindspore/ccsrc/parallel/ops_info/generator_info.h deleted file mode 100644 index 68024593f3..0000000000 --- a/mindspore/ccsrc/parallel/ops_info/generator_info.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright 2019 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GENERATOR_INFO_H_ -#define MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GENERATOR_INFO_H_ - -#include -#include -#include -#include - -#include "parallel/auto_parallel/operator_costmodel.h" -#include "parallel/ops_info/operator_info.h" -#include "parallel/strategy.h" - -namespace mindspore { -namespace parallel { -class GeneratorBase : public OperatorInfo { - public: - GeneratorBase(const std::string &operator_name, const Shapes &inputs_shape, const Shapes &outputs_shape, - const PrimitiveAttrs &attrs) - : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} - - ~GeneratorBase() override = default; - - Status Init(const StrategyPtr &strategy) override; - Status SetCostUnderStrategy(const StrategyPtr &strategy) override; - Status InitForCostModel(const StrategyPtr &strategy) override; - - protected: - // For now, generator ops don't have attributes - Status GetAttrs() override { return Status::SUCCESS; } - Status InferTensorMap() override; - Status InferTensorInfo() override; - Status InferDevMatrixShape() override; - Status InferMirrorOps() override { return SUCCESS; } - Status InferForwardCommunication() override { return SUCCESS; } - virtual Status InferReplaceOps(const StrategyPtr &strategy) = 0; -}; - -class DropoutGenMaskInfo : public GeneratorBase { - public: - DropoutGenMaskInfo(const std::string &name, const Shapes &inputs_shape, const Shapes &outputs_shape, - const PrimitiveAttrs &attrs) - : GeneratorBase(name, inputs_shape, outputs_shape, attrs) {} - ~DropoutGenMaskInfo() override = default; - Status GenerateStrategies(int32_t stage_id) override; - std::shared_ptr>> GenerateBatchStrategies() override; - - protected: - Status CheckStrategy(const StrategyPtr &strategy) override; - Status InferReplaceOps(const StrategyPtr &strategy) override; -}; -} // namespace parallel -} // namespace mindspore - -#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_GENERATOR_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/get_next_info.h b/mindspore/ccsrc/parallel/ops_info/get_next_info.h index 9a65eff035..ba209910b7 100644 --- a/mindspore/ccsrc/parallel/ops_info/get_next_info.h +++ b/mindspore/ccsrc/parallel/ops_info/get_next_info.h @@ -32,7 +32,7 @@ class GetNextInfo : public OperatorInfo { public: GetNextInfo(const std::string &operator_name, const Shapes &inputs_shape, const Shapes &outputs_shape, const PrimitiveAttrs &attrs) - : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~GetNextInfo() override = default; Status Init(const StrategyPtr &strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/layer_norm_info.cc b/mindspore/ccsrc/parallel/ops_info/layer_norm_info.cc new file mode 100644 index 0000000000..3abfc3d2ed --- /dev/null +++ b/mindspore/ccsrc/parallel/ops_info/layer_norm_info.cc @@ -0,0 +1,324 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "parallel/ops_info/layer_norm_info.h" +#include +#include +#include "parallel/device_matrix.h" +#include "parallel/strategy.h" + +namespace mindspore { +namespace parallel { +Status LayerNormInfo::GetAttrs() { + auto iter = attrs_.find(BEGIN_NORM_AXIS); + if (iter == attrs_.end()) { + MS_LOG(ERROR) << name_ << ": Can not find the attr of begin norm axis"; + return FAILED; + } + if ((iter->second == nullptr) || !iter->second->isa()) { + MS_LOG(ERROR) << name_ << ": The axis type is not int"; + return FAILED; + } + + int32_t dim = SizeToInt(input_shape_.size()); + auto axis = GetValue(iter->second); + if ((axis >= dim) || (axis < -dim)) { + MS_LOG(ERROR) << name_ << ": The axis(" << axis << ") is out of range[" << -dim << ", " << dim - 1 << "]"; + return FAILED; + } + + if (axis < 0) { + axis = axis + dim; + } + begin_norm_axis_ = IntToSize(axis); + return SUCCESS; +} + +Status LayerNormInfo::CheckStrategy(const StrategyPtr &strategy) { + MS_EXCEPTION_IF_NULL(strategy); + std::vector stra = strategy->GetInputDim(); + if (stra.size() != LAYER_NORM_INPUT_SIZE) { + MS_LOG(ERROR) << name_ << ": Invalid strategy size " << stra.size(); + return FAILED; + } + + if (CheckStrategyValue(strategy, inputs_shape_, is_auto_parallel_) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Invalid strategy value"; + return FAILED; + } + + Dimensions input_strategy = stra[LAYER_NORM_INPUT_INDEX]; + Dimensions gamma_strategy = stra[LAYER_NORM_GAMMA_INDEX]; + Dimensions beta_strategy = stra[LAYER_NORM_BETA_INDEX]; + if (begin_norm_axis_ >= input_strategy.size()) { + MS_LOG(ERROR) << name_ << ": Invalid begin norm axis " << begin_norm_axis_; + return FAILED; + } + // check input strategy + for (size_t i = begin_norm_axis_; i < input_strategy.size(); ++i) { + if (input_strategy[begin_norm_axis_] != NO_SPLIT_STRATEGY) { + MS_LOG(ERROR) << name_ << ": Invalid input strategy " << ShapeToString(input_strategy); + return FAILED; + } + } + + // check gamma and beta strategy + if ((gamma_strategy.size() > input_strategy.size()) || (beta_strategy.size() > input_strategy.size())) { + MS_LOG(ERROR) << name_ << " : The strategy size of gamma or beta is lager than input strategy"; + return FAILED; + } + + size_t gamma_diff = input_strategy.size() - gamma_strategy.size(); + for (size_t j = 0; j < gamma_strategy.size(); ++j) { + if (gamma_strategy[j] != input_strategy[gamma_diff + j]) { + MS_LOG(ERROR) << name_ << ": Invalid gamma strategy " << ShapeToString(gamma_strategy); + return FAILED; + } + } + + size_t beta_diff = input_strategy.size() - beta_strategy.size(); + for (size_t k = 0; k < beta_strategy.size(); ++k) { + if (beta_strategy[k] != input_strategy[beta_diff + k]) { + MS_LOG(ERROR) << name_ << ": Invalid beta strategy " << ShapeToString(beta_strategy); + return FAILED; + } + } + return SUCCESS; +} + +Status LayerNormInfo::InferDevMatrixShape() { + if (strategy_ == nullptr) { + MS_LOG(ERROR) << name_ << ": The strategy is null"; + return FAILED; + } + std::vector stra = strategy_->GetInputDim(); + if (stra.empty()) { + MS_LOG(ERROR) << name_ << ": The strategy is empty"; + return FAILED; + } + dev_matrix_shape_ = stra[0]; + return SUCCESS; +} + +Status LayerNormInfo::CreateTensorMap(size_t input_index) { + if (inputs_shape_.size() <= input_index) { + MS_LOG(ERROR) << name_ << ": Invalid index" << input_index; + return FAILED; + } + Shape shape = inputs_shape_[input_index]; + Shape tensor_map; + for (size_t i = 0; i < shape.size(); ++i) { + tensor_map.push_back(SizeToInt(shape.size() - i - 1)); + } + inputs_tensor_map_.push_back(tensor_map); + outputs_tensor_map_.push_back(tensor_map); + return SUCCESS; +} + +Status LayerNormInfo::InferTensorMap() { + if ((CreateTensorMap(LAYER_NORM_INPUT_INDEX) != SUCCESS) || (CreateTensorMap(LAYER_NORM_GAMMA_INDEX) != SUCCESS) || + (CreateTensorMap(LAYER_NORM_BETA_INDEX) != SUCCESS)) { + MS_LOG(ERROR) << name_ << ": Create tensor map failed"; + return FAILED; + } + return SUCCESS; +} + +Status LayerNormInfo::CreateMirrorOp(size_t input_index) { + if (inputs_tensor_map_.size() <= input_index) { + MS_LOG(ERROR) << name_ << ": Invalid index " << input_index; + return FAILED; + } + Shape tensor_map = inputs_tensor_map_[input_index]; + std::vector group; + if (CreateGroupByTensorMap(tensor_map, &group) != SUCCESS) { + MS_LOG(ERROR) << name_ << " : Create group for input " << input_index << " failed"; + return FAILED; + } + OperatorVector mirror_op; + if (!group.empty()) { + mirror_op = CreateMirrorOps(group[0].name(), group[0].GetDevNum()); + MS_LOG(INFO) << name_ << " : Create the mirror ops for input " << input_index << " success, group is " + << group[0].name(); + } + mirror_ops_.push_back(mirror_op); + return SUCCESS; +} + +Status LayerNormInfo::InferMirrorOps() { + if ((CreateMirrorOp(LAYER_NORM_INPUT_INDEX) != SUCCESS) || (CreateMirrorOp(LAYER_NORM_GAMMA_INDEX) != SUCCESS) || + (CreateMirrorOp(LAYER_NORM_BETA_INDEX) != SUCCESS)) { + MS_LOG(ERROR) << name_ << ": Create mirror op failed"; + return FAILED; + } + return SUCCESS; +} + +Status LayerNormInfo::CreateTensorInfo(size_t input_index) { + if ((inputs_shape_.size() <= input_index) || (inputs_tensor_map_.size() <= input_index)) { + MS_LOG(ERROR) << name_ << ": Invalid input index" << input_index; + return FAILED; + } + Shape tensor_map = inputs_tensor_map_[input_index]; + Shape shape = inputs_shape_[input_index]; + TensorLayout tensor_layout; + if (tensor_layout.InitFromVector(dev_matrix_shape_, tensor_map, shape) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init tensor layout for input " << input_index << " failed"; + return FAILED; + } + + TensorInfo tensor_info(tensor_layout); + inputs_tensor_info_.push_back(tensor_info); + outputs_tensor_info_.push_back(tensor_info); + return SUCCESS; +} + +Status LayerNormInfo::InferTensorInfo() { + if ((CreateTensorInfo(LAYER_NORM_INPUT_INDEX) != SUCCESS) || (CreateTensorInfo(LAYER_NORM_GAMMA_INDEX) != SUCCESS) || + (CreateTensorInfo(LAYER_NORM_BETA_INDEX) != SUCCESS)) { + MS_LOG(ERROR) << name_ << ": Create tensor info failed"; + return FAILED; + } + return SUCCESS; +} + +Status LayerNormInfo::InferAsLossDivisor() { + if (outputs_tensor_map_.size() != LAYER_NORM_INPUT_SIZE) { + MS_LOG(ERROR) << name_ << ": The size of outputs tensor map " << outputs_tensor_map_.size() << " is error"; + return FAILED; + } + as_loss_divisor_ = ComputeRepeatDeviceNumByTensorMap(dev_matrix_shape_, outputs_tensor_map_[0]); + MS_LOG(INFO) << name_ << " : The dev matrix shape is " << ShapeToString(dev_matrix_shape_) + << ", the output[0]'s tensor map is " << ShapeToString(outputs_tensor_map_[0]) + << ", as_loss_divisor_ is " << as_loss_divisor_; + return SUCCESS; +} + +Status LayerNormInfo::SetCostUnderStrategy(const StrategyPtr &strategy) { + if (SetCostUnderStrategyBase(strategy) != SUCCESS) { + MS_LOG(ERROR) << name_ << " : Set cost failed"; + return FAILED; + } + return SUCCESS; +} + +Status LayerNormInfo::GenerateGammaAndBetaStrategies(const std::vector &sp_vector) { + if ((gamma_shape_.size() > input_shape_.size()) || (beta_shape_.size() > input_shape_.size())) { + MS_LOG(ERROR) << name_ << ": The dimension of gamma or beta is lager than input"; + return FAILED; + } + + size_t gamma_diff = input_shape_.size() - gamma_shape_.size(); + size_t beta_diff = input_shape_.size() - beta_shape_.size(); + for (auto &sp : sp_vector) { + if ((sp == nullptr) || sp->GetInputDim().empty()) { + MS_LOG(ERROR) << name_ << ": Invalid strategy"; + return FAILED; + } + std::vector tmp_strategy; + Dimensions input_strategy = sp->GetInputDim()[0]; + Dimensions gamma_strategy = input_strategy; + (void)gamma_strategy.erase(gamma_strategy.begin(), + gamma_strategy.begin() + static_cast(gamma_diff)); + Dimensions beta_strategy = input_strategy; + (void)beta_strategy.erase(beta_strategy.begin(), beta_strategy.begin() + static_cast(beta_diff)); + + // reset the strategy + tmp_strategy.push_back(input_strategy); + tmp_strategy.push_back(gamma_strategy); + tmp_strategy.push_back(beta_strategy); + sp->ResetInputs(tmp_strategy); + } + return SUCCESS; +} + +Status LayerNormInfo::GenerateStrategies(int32_t stage_id) { + if (InitShapes() != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init shapes failed"; + return FAILED; + } + if (GetAttrs() != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Get attrs failed"; + return FAILED; + } + Shape input_split(input_shape_.size(), SPLIT_FLAG); + if (begin_norm_axis_ >= input_split.size()) { + MS_LOG(ERROR) << name_ << ": Invalid begin norm axis " << begin_norm_axis_; + return FAILED; + } + + // Can not split the dimensions from begin norm axis + for (size_t i = begin_norm_axis_; i < input_split.size(); ++i) { + input_split[i] = NO_SPLIT_FLAG; + } + + // Generate strategy for input + Shapes splittable_inputs = {input_split}; + Shapes tmp_inputs_shape = {input_shape_}; + std::vector sp_vector; + is_auto_parallel_ = true; + if (GenerateStrategiesForIndependentInputs(stage_id, tmp_inputs_shape, splittable_inputs, &sp_vector) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Generate input strategy failed"; + return FAILED; + } + + // Generate the strategies for gamma and beta + if (GenerateGammaAndBetaStrategies(sp_vector) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Generate gamma and beta strategies failed"; + return FAILED; + } + + size_t success = 0; + for (auto &sp : sp_vector) { + if (SetCostUnderStrategy(sp) == SUCCESS) { + success++; + MS_LOG(DEBUG) << name_ << ": Successfully generated " << success << " strategy"; + } + } + return SUCCESS; +} + +Status LayerNormInfo::InitShapes() { + if (inputs_shape_.size() != LAYER_NORM_INPUT_SIZE) { + MS_LOG(ERROR) << name_ << ": Invalid inputs size"; + return FAILED; + } + input_shape_ = inputs_shape_[LAYER_NORM_INPUT_INDEX]; + gamma_shape_ = inputs_shape_[LAYER_NORM_GAMMA_INDEX]; + beta_shape_ = inputs_shape_[LAYER_NORM_BETA_INDEX]; + return SUCCESS; +} + +Status LayerNormInfo::Init(const StrategyPtr &strategy) { + if ((InitShapes() != SUCCESS) || (InitWithAutoRepeatCalc(strategy)) != SUCCESS) { + MS_LOG(ERROR) << name_ << ": Init failed"; + return FAILED; + } + MS_LOG(INFO) << name_ << ": Init success"; + return SUCCESS; +} + +Status LayerNormInfo::InitForCostModel(const StrategyPtr &strategy) { + if ((InitShapes() != SUCCESS) || (InitForCostModelWithAutoRepeatCalc(strategy) != SUCCESS)) { + MS_LOG(ERROR) << name_ << ": Init for cost model failed"; + return FAILED; + } + + MS_LOG(INFO) << name_ << ": Init for cost model success"; + return SUCCESS; +} +} // namespace parallel +} // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/layer_norm_info.h b/mindspore/ccsrc/parallel/ops_info/layer_norm_info.h new file mode 100644 index 0000000000..c52645ade2 --- /dev/null +++ b/mindspore/ccsrc/parallel/ops_info/layer_norm_info.h @@ -0,0 +1,76 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_PARALLEL_OPS_INFO_LAYER_NORM_INFO_H_ +#define MINDSPORE_CCSRC_PARALLEL_OPS_INFO_LAYER_NORM_INFO_H_ + +#include +#include +#include +#include +#include "ir/value.h" +#include "parallel/auto_parallel/operator_costmodel.h" +#include "parallel/ops_info/operator_info.h" +#include "parallel/strategy.h" + +namespace mindspore { +namespace parallel { +constexpr size_t LAYER_NORM_INPUT_SIZE = 3; +constexpr size_t LAYER_NORM_INPUT_INDEX = 0; +constexpr size_t LAYER_NORM_GAMMA_INDEX = 1; +constexpr size_t LAYER_NORM_BETA_INDEX = 2; +constexpr char BEGIN_NORM_AXIS[] = "begin_norm_axis"; + +// The dimensions of input tensor starting from begin norm axis cannot be split. Other dimensions can be split +// arbitrarily. Gamma and beta should match input to meet the broadcast requirements of mul and add. +class LayerNormInfo : public OperatorInfo { + public: + LayerNormInfo(const std::string& operator_name, const Shapes& inputs_shape, const Shapes& outputs_shape, + const PrimitiveAttrs& attrs) + : OperatorInfo(operator_name, inputs_shape, outputs_shape, attrs, std::make_shared(true)), + begin_norm_axis_(0) {} + ~LayerNormInfo() override = default; + + Status Init(const StrategyPtr& strategy) override; + Status InitForCostModel(const StrategyPtr& strategy) override; + Status GenerateStrategies(int32_t) override; + Status SetCostUnderStrategy(const StrategyPtr&) override; + + protected: + Status GetAttrs() override; + Status CheckStrategy(const StrategyPtr& strategy) override; + Status InferMirrorOps() override; + Status InferForwardCommunication() override { return SUCCESS; } + Status InferTensorInfo() override; + Status InferDevMatrixShape() override; + Status InferTensorMap() override; + Status InferAsLossDivisor() override; + Status CreateTensorMap(size_t input_index); + Status CreateTensorInfo(size_t input_index); + Status CreateMirrorOp(size_t input_index); + Status GenerateGammaAndBetaStrategies(const std::vector& sp_vector); + Status InitShapes(); + + private: + size_t begin_norm_axis_; + Shape input_shape_; + Shape gamma_shape_; + Shape beta_shape_; +}; +} // namespace parallel +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_LAYER_NORM_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/loss_info.cc b/mindspore/ccsrc/parallel/ops_info/loss_info.cc index 31f80e338b..28ea19f120 100644 --- a/mindspore/ccsrc/parallel/ops_info/loss_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/loss_info.cc @@ -194,7 +194,8 @@ Status SoftmaxCrossEntropyWithLogitsInfo::GenerateStrategies(int32_t stage_id) { } is_auto_parallel_ = true; - Shape input0_split(inputs_shape_[0].size(), 1); + Shape input0_split; + (void)input0_split.insert(input0_split.begin(), inputs_shape_[0].size(), 1); input0_split[IntToSize(axis_index)] = 0; Shapes splittable_inputs = {input0_split, input0_split}; std::vector sp_vector; diff --git a/mindspore/ccsrc/parallel/ops_info/loss_info.h b/mindspore/ccsrc/parallel/ops_info/loss_info.h index f1c2537a39..44fe22ce90 100644 --- a/mindspore/ccsrc/parallel/ops_info/loss_info.h +++ b/mindspore/ccsrc/parallel/ops_info/loss_info.h @@ -36,7 +36,8 @@ class SoftmaxCrossEntropyWithLogitsInfo : public OperatorInfo { public: SoftmaxCrossEntropyWithLogitsInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, + std::make_shared(false)) {} ~SoftmaxCrossEntropyWithLogitsInfo() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/matmul_info.cc b/mindspore/ccsrc/parallel/ops_info/matmul_info.cc index 848116d68a..8d1264482b 100644 --- a/mindspore/ccsrc/parallel/ops_info/matmul_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/matmul_info.cc @@ -465,7 +465,7 @@ Status MatMulBase::PrepareStrategy(int32_t stage_id, size_t dev_num, mindspore::parallel::Dimensions combined_partitions, size_t input0_shape_size, size_t input1_shape_size, mindspore::parallel::StrategyPtr* const sp) { int32_t product = std::accumulate(combined_partitions.begin(), combined_partitions.end(), 1, std::multiplies()); - if (NOT_FULLY_USE_DEVICES) { + if (!FULLY_USE_DEVICES) { if (IntToSize(product) > dev_num) { return FAILED; } @@ -593,11 +593,11 @@ Status MatMulBase::SetCostUnderStrategy(const mindspore::parallel::StrategyPtr& // Here, we use the origin outputs_, because we only use the slice size of the output tensor. // It does not matter whether the output tensor is transposed or not. double computation_cost = - cost()->GetForwardComputationCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); - double communication_cost = cost()->GetCommCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); + operator_cost()->GetForwardComputationCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); + double communication_cost = operator_cost()->GetCommCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); std::shared_ptr result = std::make_shared(computation_cost, communication_cost); result->communication_without_parameter_ = - cost()->GetForwardCommCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); + operator_cost()->GetForwardCommCost(relica_inputs_tensor_vector, outputs_tensor_info_, stage_id); result->communication_with_partial_para_ = result->communication_without_parameter_ + COST_MODEL_GAMMA * (communication_cost - result->communication_without_parameter_); diff --git a/mindspore/ccsrc/parallel/ops_info/matmul_info.h b/mindspore/ccsrc/parallel/ops_info/matmul_info.h index 2d3312774d..8a64fb7206 100644 --- a/mindspore/ccsrc/parallel/ops_info/matmul_info.h +++ b/mindspore/ccsrc/parallel/ops_info/matmul_info.h @@ -34,7 +34,7 @@ class MatMulBase : public OperatorInfo { public: MatMulBase(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~MatMulBase() override = default; Status Init(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/onehot_info.h b/mindspore/ccsrc/parallel/ops_info/onehot_info.h index a54d8479b3..a4f00ea093 100644 --- a/mindspore/ccsrc/parallel/ops_info/onehot_info.h +++ b/mindspore/ccsrc/parallel/ops_info/onehot_info.h @@ -33,7 +33,7 @@ class OneHotInfo : public OperatorInfo { public: OneHotInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~OneHotInfo() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; @@ -65,4 +65,4 @@ class OneHotInfo : public OperatorInfo { }; } // namespace parallel } // namespace mindspore -#endif // MINDSPORE_CCSRC_OPTIMIZER_OPS_INFO_PARALLEL_ONEHOT_INFO_H_ +#endif // MINDSPORE_CCSRC_PARALLEL_OPS_INFO_ONEHOT_INFO_H_ diff --git a/mindspore/ccsrc/parallel/ops_info/operator_info.cc b/mindspore/ccsrc/parallel/ops_info/operator_info.cc index a24f3e616b..c6115a9fa6 100644 --- a/mindspore/ccsrc/parallel/ops_info/operator_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/operator_info.cc @@ -112,6 +112,7 @@ void OperatorInfo::ResetQueueMember() { dev_matrix_shape_.clear(); forward_op_.clear(); mirror_ops_.clear(); + sub_ops_.clear(); replace_op_.clear(); replace_op_info_.clear(); virtual_div_op_.clear(); @@ -236,7 +237,7 @@ OperatorVector CreateMirrorOps(const std::string& group_name, size_t dev_num) { OperatorName operator_name = MIRROR_OPERATOR; ValuePtr attr0_value = MakeValue(group_name); - ValuePtr attr1_value = MakeValue(dev_num); + ValuePtr attr1_value = MakeValue(SizeToInt(dev_num)); ValuePtr attr2_value = MakeValue(mean_flag); Attr attr0 = std::make_pair(GROUP, attr0_value); @@ -674,7 +675,7 @@ Status PrepareStrategyBase(int32_t stage_id, size_t dev_num, const Shapes& input for (auto& input_partition : inputs_partitions) { product *= std::accumulate(input_partition.begin(), input_partition.end(), 1, std::multiplies()); } - if (NOT_FULLY_USE_DEVICES) { + if (!FULLY_USE_DEVICES) { if (IntToSize(product) > dev_num) { return FAILED; } @@ -1034,11 +1035,12 @@ Status OperatorInfo::SetCostUnderStrategyBase(const StrategyPtr& strategy) { return FAILED; } int32_t stage_id = strategy->GetInputStage(); - double computation_cost = cost()->GetForwardComputationCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); - double communication_cost = cost()->GetCommCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); + double computation_cost = + operator_cost()->GetForwardComputationCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); + double communication_cost = operator_cost()->GetCommCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); std::shared_ptr result = std::make_shared(computation_cost, communication_cost); result->communication_without_parameter_ = - cost()->GetForwardCommCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); + operator_cost()->GetForwardCommCost(inputs_tensor_info_, outputs_tensor_info_, stage_id); result->communication_with_partial_para_ = result->communication_without_parameter_ + COST_MODEL_GAMMA * (communication_cost - result->communication_without_parameter_); @@ -1095,7 +1097,38 @@ Status OperatorInfo::set_is_parameter(const std::vector& is_parameter) { return FAILED; } is_parameter_ = is_parameter; - cost()->set_is_parameter(is_parameter); + operator_cost()->set_is_parameter(is_parameter); + return SUCCESS; +} + +Status OperatorInfo::CalculateMemoryCost() { + // First, set the 'is_parameter_involve_' and 'is_output_parameter_involve_' into OperatorCost, which are necessary to + // calculate memory cost. + if (is_parameter_involve_.size() != is_parameter_.size()) { + MS_LOG(ERROR) << "'is_parameter_' does not have the same number of input size of 'is_parameter_involve_'."; + return FAILED; + } + operator_cost()->set_is_parameter_involve(is_parameter_involve_); + operator_cost()->set_output_parameter_involve(is_output_parameter_involve_); + // Set the memory cost in the 'strategy_cost_' + for (auto& swc : strategy_cost_) { + auto mem_cost = operator_cost()->GetMemoryCost(swc->inputs_ptr, swc->outputs_ptr); + swc->cost_list[0]->memory_with_reuse_ = mem_cost; + } + return SUCCESS; +} + +Status OperatorInfo::CorrectMemoryCost(size_t input_index) { + for (auto& swc : strategy_cost_) { + double parameter_mem_cost = ListProduct(swc->inputs_ptr[input_index].slice_shape()) * + static_cast(operator_cost()->inputs_type_lengths()[input_index]); + swc->cost_list[0]->memory_with_reuse_ -= parameter_mem_cost; + if (swc->cost_list[0]->memory_with_reuse_ < 0) { + MS_LOG(ERROR) << "The memory cost after correction is: " << swc->cost_list[0]->memory_with_reuse_ + << ", the parameter memory cost is: " << parameter_mem_cost; + return FAILED; + } + } return SUCCESS; } @@ -1192,7 +1225,17 @@ Status OperatorInfo::SetInputAndOutputTypeLength(const std::vector& inpu } inputs_type_lengths_ = input_lengths; outputs_type_lengths_ = output_lengths; - cost()->SetInputAndOutputTypeLength(input_lengths, output_lengths); + operator_cost()->SetInputAndOutputTypeLength(input_lengths, output_lengths); + return SUCCESS; +} + +Status OperatorInfo::set_outputs_type(const std::vector& outputs_type) { + if (outputs_type.size() != outputs_shape_.size()) { + MS_LOG(ERROR) << "Outputs type: " << outputs_type.size() + << " do not have the same number of outputs shape: " << outputs_shape_.size(); + return FAILED; + } + outputs_type_ = outputs_type; return SUCCESS; } @@ -1210,8 +1253,7 @@ void OperatorInfo::BreakingTiesForPerferringDataParallel(const StrategyPtr& stra } double OperatorInfo::GetForwardMemoryCostFromCNode() { - return cost()->GetForwardComputationCost(inputs_tensor_info_, outputs_tensor_info_, 0); + return operator_cost()->GetForwardComputationCost(inputs_tensor_info_, outputs_tensor_info_, 0); } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/ops_info/operator_info.h b/mindspore/ccsrc/parallel/ops_info/operator_info.h index 8fcae8ad33..19e0eeeda1 100644 --- a/mindspore/ccsrc/parallel/ops_info/operator_info.h +++ b/mindspore/ccsrc/parallel/ops_info/operator_info.h @@ -41,6 +41,7 @@ namespace mindspore { namespace parallel { using ForwardOp = OperatorVector; using MirrorOps = std::vector; +using Ops = std::vector; using VirtualDivOp = OperatorVector; using TensorMaps = std::vector>; using TensorLayouts = std::vector; @@ -59,7 +60,8 @@ class OperatorInfo { outputs_shape_(std::move(outputs_shape)), attrs_(std::move(attrs)), is_alive_(true), - cost_(cost) { + operator_cost_(cost), + outputs_type_() { std::vector not_parameteter(inputs_shape_.size(), false); is_parameter_ = not_parameteter; refkey_parameter_name_ = ""; @@ -70,14 +72,19 @@ class OperatorInfo { Status set_is_parameter(const std::vector& is_parameter); Status SetInputAndOutputTypeLength(const std::vector& input_lengths, const std::vector& output_lengths); + // Set outputs dtype. + // If only one output, outputs_type.size() is 1. + // If output is tuple, outputs_type.size() is greater than 1. + Status set_outputs_type(const std::vector& outputs_type); + const std::vector& outputs_type() const { return outputs_type_; } virtual Status Init(const StrategyPtr& strategy) = 0; virtual Status InitForCostModel(const StrategyPtr& strategy) = 0; // only init the necessary parts // Given the stage_id (which indicates the number of devices), // generate all strategies for this operator virtual Status GenerateStrategies(int32_t stage_id) = 0; - const OperatorCostPtr& cost() const { return cost_; } - void set_cost(const OperatorCostPtr& cost) { cost_ = cost; } + const OperatorCostPtr& operator_cost() const { return operator_cost_; } + void set_cost(const OperatorCostPtr& cost) { operator_cost_ = cost; } virtual Status SetCostUnderStrategy(const StrategyPtr& strategy) = 0; virtual std::shared_ptr>> GenerateBatchStrategies(); @@ -91,7 +98,7 @@ class OperatorInfo { std::vector> GetStrategyCost() { return strategy_cost_; } // When the input of a operator contains WEIGHT or a output from other operators involving WEIGHT, then these input // should stay in memory until it is used in the backward phase, which is kept in memory at the end of forward phase. - Status CalculateMemoryCost() const { return SUCCESS; } + Status CalculateMemoryCost(); int ComputeOpAndPrevEdgeParameterInvolved(); ForwardOp forward_op() const { return forward_op_; } @@ -99,6 +106,7 @@ class OperatorInfo { OutPutInfoVector replace_op_info() const { return replace_op_info_; } virtual ReplaceGraphPtr replace_graph(const CNodePtr&) { return replace_graph_; } MirrorOps mirror_ops() const { return mirror_ops_; } + Ops sub_ops() const { return sub_ops_; } VirtualDivOp virtual_div_op() const { return virtual_div_op_; } Shape dev_matrix_shape() const { return dev_matrix_shape_; } std::vector inputs_tensor_info() const { return inputs_tensor_info_; } @@ -117,7 +125,7 @@ class OperatorInfo { void ReplaceSuccEdge(const std::shared_ptr& op, const std::shared_ptr& new_edge); void ReplacePreEdges(const std::shared_ptr& op, const std::shared_ptr& new_edge); void ReplaceSuccEdges(const std::shared_ptr& op, const std::shared_ptr& new_edge); - std::vector GetOutputTypeLengths() const { return cost()->outputs_type_lengths(); } + std::vector GetOutputTypeLengths() const { return operator_cost()->outputs_type_lengths(); } void SetSelectedStrategyAndCost(const StrategyPtr& s_strategy, const CostPtr& cost) { selected_strategy_ = s_strategy; selected_cost_ = cost; @@ -134,6 +142,10 @@ class OperatorInfo { void set_strategy(const StrategyPtr& strategy) { strategy_ = strategy; } void set_refkey_parameter_name(std::string p_name) { refkey_parameter_name_ = std::move(p_name); } const std::string& refkey_parameter_name() const { return refkey_parameter_name_; } + // When the output of a Parameter (require_grad) being used by multiple operators, the Parameter's cost is calculated + // multiple times. This method is to correct this, and makes the cost is calulated only once. + Status CorrectMemoryCost(size_t input_index); + int is_output_parameter_involve() const { return is_output_parameter_involve_; } int used_devices() const { return used_devices_; } // needed by rec_parser void set_type(const std::string& type) { type_ = type; } @@ -190,6 +202,7 @@ class OperatorInfo { TensorMaps inputs_tensor_map_; TensorMaps outputs_tensor_map_; ForwardOp forward_op_; + Ops sub_ops_; ForwardOp replace_op_; OutPutInfoVector replace_op_info_; ReplaceGraphPtr replace_graph_; @@ -225,7 +238,8 @@ class OperatorInfo { int32_t used_devices_ = -1; private: - OperatorCostPtr cost_; + OperatorCostPtr operator_cost_; + std::vector outputs_type_; }; Shape GetSliceShape(const Shape& tensor_shape, const Dimensions& strategy); diff --git a/mindspore/ccsrc/parallel/ops_info/ops_info_head_files.h b/mindspore/ccsrc/parallel/ops_info/ops_info_head_files.h index cc13512b54..aec25f7f41 100644 --- a/mindspore/ccsrc/parallel/ops_info/ops_info_head_files.h +++ b/mindspore/ccsrc/parallel/ops_info/ops_info_head_files.h @@ -24,9 +24,10 @@ #include "parallel/ops_info/comparison_function_info.h" #include "parallel/ops_info/dropout_do_mask_info.h" #include "parallel/ops_info/elementary_function_info.h" -#include "parallel/ops_info/generator_info.h" +#include "parallel/ops_info/gather_v2_info.h" #include "parallel/ops_info/get_next_info.h" #include "parallel/ops_info/l2_normalize_info.h" +#include "parallel/ops_info/layer_norm_info.h" #include "parallel/ops_info/loss_info.h" #include "parallel/ops_info/matmul_info.h" #include "parallel/ops_info/onehot_info.h" diff --git a/mindspore/ccsrc/parallel/ops_info/ops_utils.h b/mindspore/ccsrc/parallel/ops_info/ops_utils.h index fe2a5d2c86..bdae87858d 100644 --- a/mindspore/ccsrc/parallel/ops_info/ops_utils.h +++ b/mindspore/ccsrc/parallel/ops_info/ops_utils.h @@ -26,6 +26,8 @@ constexpr int32_t PRELU_CHANNEL_INDEX = 1; constexpr int32_t PRELU_CHANNEL_STRATEGY = 1; constexpr int32_t NO_SPLIT_MAP = -1; constexpr int32_t NO_SPLIT_STRATEGY = 1; +constexpr int32_t SPLIT_FLAG = 1; +constexpr int32_t NO_SPLIT_FLAG = 0; constexpr size_t MATMUL_ATTRS_SIZE = 2; constexpr size_t MATMUL_INPUTS_SIZE = 2; constexpr size_t MATMUL_OUTPUTS_SIZE = 1; @@ -34,10 +36,15 @@ constexpr size_t SOFTMAX_ATTR_SIZE = 1; constexpr size_t ACTIVATION_INPUTS_SIZE = 1; constexpr size_t ACTIVATION_OUTPUTS_SIZE = 1; constexpr size_t EXPANDDIMS_INPUT_SIZE = 2; +constexpr size_t DROPOUT_DO_MASK_CNODE_INPUT_SIZE = 4; +constexpr size_t DROPOUT_GEN_MASK_CNODE_INPUT_SIZE = 3; +constexpr size_t DROPOUT_GEN_MASK_INDEX = 2; +constexpr size_t DROPOUT_DO_MASK_KEEP_PROB_INDEX = 3; constexpr size_t SoftmaxCrossEntropyWithLogitsAttrSize = 1; constexpr size_t SoftmaxCrossEntropyWithLogitsInputsSize = 2; constexpr size_t SoftmaxCrossEntropyWithLogitsOutputsSize = 2; constexpr double EPS = 1e-6; +constexpr double INF = 1e20; constexpr char AUTO_PARALLEL_RUN_ONCE_ONLY[] = "auto_parallel_run_once_only"; constexpr char SEMI_AUTO_PARALLEL_RUN_ONCE_ONLY[] = "semi_auto_parallel_run_once_only"; @@ -131,6 +138,7 @@ constexpr char ALL_GATHER[] = "AllGather"; constexpr char REDUCE_SCATTER[] = "ReduceScatter"; constexpr char CONCAT[] = "Concat"; constexpr char SOFTMAX_CROSS_ENTROPY_WITH_LOGITS[] = "SoftmaxCrossEntropyWithLogits"; +constexpr char SIGMOID_CROSS_ENTROPY_WITH_LOGITS[] = "SigmoidCrossEntropyWithLogits"; constexpr char MATMUL[] = "MatMul"; constexpr char GELU[] = "Gelu"; constexpr char TANH[] = "Tanh"; @@ -168,6 +176,7 @@ constexpr char ARGMINWITHVALUE[] = "ArgMinWithValue"; constexpr char CONV2D[] = "Conv2D"; constexpr char FUSE_BATCH_NORM[] = "FusedBatchNorm"; constexpr char BATCH_NORM[] = "BatchNorm"; +constexpr char LAYER_NORM[] = "LayerNorm"; constexpr char POOLING[] = "Pooling"; constexpr char CAST[] = "Cast"; constexpr char MAX_POOL_WITH_ARGMAX[] = "MaxPoolWithArgmax"; @@ -182,6 +191,7 @@ constexpr char LOG[] = "Log"; constexpr char SIGMOID[] = "Sigmoid"; constexpr char POW[] = "Pow"; constexpr char MAXIMUM[] = "Maximum"; +constexpr char MINIMUM[] = "Minimum"; constexpr char EQUAL[] = "Equal"; constexpr char NOT_EQUAL[] = "NotEqual"; constexpr char LOGICALNOT[] = "LogicalNot"; @@ -192,9 +202,10 @@ constexpr char SQRT[] = "Sqrt"; constexpr char ASSIGN[] = "Assign"; constexpr char GET_NEXT[] = "GetNext"; constexpr char SQUEEZE[] = "Squeeze"; -constexpr char Neg[] = "Neg"; +constexpr char NEG[] = "Neg"; constexpr char BATCH_MATMUL[] = "BatchMatMul"; constexpr char EXPAND_DIMS[] = "ExpandDims"; +constexpr char SQUARE[] = "Square"; // Parallel don't care constexpr char TUPLE_GETITEM[] = "tuple_getitem"; @@ -235,6 +246,7 @@ constexpr char STATESETITEM[] = "state_setitem"; constexpr char SCALARSUMMARY[] = "ScalarSummary"; constexpr char IMAGESUMMARY[] = "ImageSummary"; constexpr char TENSORSUMMARY[] = "TensorSummary"; +constexpr char HISTOGRAMSUMMARY[] = "HistogramSummary"; constexpr char BROADCASTGRADIENTARGS[] = "BroadcastGradientArgs"; constexpr char INVERTPERMUTATION[] = "InvertPermutation"; constexpr char CONTROLDEPEND[] = "ControlDepend"; diff --git a/mindspore/ccsrc/parallel/ops_info/prelu_info.cc b/mindspore/ccsrc/parallel/ops_info/prelu_info.cc index 1a44501f42..a4d601dbe9 100644 --- a/mindspore/ccsrc/parallel/ops_info/prelu_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/prelu_info.cc @@ -212,8 +212,10 @@ Status PReLUInfo::GenerateStrategies(int32_t stage_id) { return FAILED; } is_auto_parallel_ = true; - Shape input0_split(inputs_shape_[0].size(), 1); - input0_split[1] = 0; + Shape input0_split; + input0_split.emplace_back(1); + input0_split.emplace_back(0); + (void)input0_split.insert(input0_split.end(), inputs_shape_[0].size() - 2, 1); Shape input1_split(inputs_shape_[1].size(), 0); Shapes splittable_inputs = {input0_split, input1_split}; std::vector sp_vector; diff --git a/mindspore/ccsrc/parallel/ops_info/prelu_info.h b/mindspore/ccsrc/parallel/ops_info/prelu_info.h index bdfb11550b..396407c1ee 100644 --- a/mindspore/ccsrc/parallel/ops_info/prelu_info.h +++ b/mindspore/ccsrc/parallel/ops_info/prelu_info.h @@ -35,7 +35,7 @@ class PReLUInfo : public OperatorInfo { public: PReLUInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~PReLUInfo() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/reduce_method_info.cc b/mindspore/ccsrc/parallel/ops_info/reduce_method_info.cc index aa64e72d05..44eab20588 100644 --- a/mindspore/ccsrc/parallel/ops_info/reduce_method_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/reduce_method_info.cc @@ -109,7 +109,7 @@ Status ReduceMethod::GetAttrs() { } cross_batch_ = cross_batch_iter->second->cast()->value(); } - auto reducemethodcost = std::dynamic_pointer_cast(cost()); + auto reducemethodcost = std::dynamic_pointer_cast(operator_cost()); if (reducemethodcost == nullptr) { MS_LOG(ERROR) << "Cost cast to ReduceMethodCostPtr failed!"; return FAILED; diff --git a/mindspore/ccsrc/parallel/ops_info/reduce_method_info.h b/mindspore/ccsrc/parallel/ops_info/reduce_method_info.h index c2ddbc87ce..2911bdfe10 100644 --- a/mindspore/ccsrc/parallel/ops_info/reduce_method_info.h +++ b/mindspore/ccsrc/parallel/ops_info/reduce_method_info.h @@ -34,7 +34,7 @@ class ReduceMethod : public OperatorInfo { public: ReduceMethod(const std::string &name, const Shapes &inputs_shape, const Shapes &outputs_shape, const PrimitiveAttrs &attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(true)) {} ~ReduceMethod() override = default; Status Init(const StrategyPtr &strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/reshape_info.cc b/mindspore/ccsrc/parallel/ops_info/reshape_info.cc index 0c95ee9c05..4cb81ee769 100644 --- a/mindspore/ccsrc/parallel/ops_info/reshape_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/reshape_info.cc @@ -413,8 +413,9 @@ Status ReshapeInfo::GenerateStrategies(int32_t stage_id) { return FAILED; } is_auto_parallel_ = true; - Shape input0_split(inputs_shape_[0].size(), 0); - input0_split[0] = 1; + Shape input0_split; + input0_split.emplace_back(1); + (void)input0_split.insert(input0_split.end(), inputs_shape_[0].size() - 1, 0); Shapes splittable_inputs = {input0_split}; std::vector sp_vector; if (GenerateStrategiesForIndependentInputs(stage_id, inputs_shape_, splittable_inputs, &sp_vector) != SUCCESS) { diff --git a/mindspore/ccsrc/parallel/ops_info/reshape_info.h b/mindspore/ccsrc/parallel/ops_info/reshape_info.h index 38192a5d01..3864d2b93d 100644 --- a/mindspore/ccsrc/parallel/ops_info/reshape_info.h +++ b/mindspore/ccsrc/parallel/ops_info/reshape_info.h @@ -36,7 +36,7 @@ class ReshapeInfo : public OperatorInfo { public: ReshapeInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()), + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)), dev_num_(0), input_layout_set_flag_(false), output_layout_set_flag_(false) {} diff --git a/mindspore/ccsrc/parallel/ops_info/tmp_identity_info.h b/mindspore/ccsrc/parallel/ops_info/tmp_identity_info.h index cf850683a6..3682fe334f 100644 --- a/mindspore/ccsrc/parallel/ops_info/tmp_identity_info.h +++ b/mindspore/ccsrc/parallel/ops_info/tmp_identity_info.h @@ -34,7 +34,7 @@ class TmpIdentityInfo : public OperatorInfo { public: TmpIdentityInfo(const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs, const std::string& name = IDENTITY_INFO) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~TmpIdentityInfo() override = default; Status Init(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/transpose_info.h b/mindspore/ccsrc/parallel/ops_info/transpose_info.h index 2714b352b6..e4e2b90b7b 100644 --- a/mindspore/ccsrc/parallel/ops_info/transpose_info.h +++ b/mindspore/ccsrc/parallel/ops_info/transpose_info.h @@ -35,7 +35,7 @@ class TransposeInfo : public OperatorInfo { public: TransposeInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~TransposeInfo() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; diff --git a/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.cc b/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.cc index acb39247d4..cd3b40315c 100644 --- a/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.cc +++ b/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.cc @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - Status VirtualDatasetInfo::CheckStrategy(const StrategyPtr& strategy) { if (CheckStrategyValue(strategy, inputs_shape_, is_auto_parallel_) != SUCCESS) { if (is_auto_parallel_) { @@ -225,8 +224,9 @@ Status VirtualDatasetInfo::GenerateStrategies(int32_t stage_id) { StrategyPtr sp; std::vector strategy; for (auto& shape : inputs_shape_) { - Shape temp(shape.size(), 1); - temp[0] = SizeToInt(total_dev_num); + Shape temp; + temp.emplace_back(SizeToInt(total_dev_num)); + (void)temp.insert(temp.end(), shape.size() - 1, 1); strategy.push_back(temp); } sp = std::make_shared(stage_id, strategy); diff --git a/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.h b/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.h index b958adeabe..398bae3585 100644 --- a/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.h +++ b/mindspore/ccsrc/parallel/ops_info/virtual_dataset_info.h @@ -32,7 +32,7 @@ class VirtualDatasetInfo : public OperatorInfo { public: VirtualDatasetInfo(const std::string& name, const Shapes& inputs_shape, const Shapes& outputs_shape, const PrimitiveAttrs& attrs) - : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared()) {} + : OperatorInfo(name, inputs_shape, outputs_shape, attrs, std::make_shared(false)) {} ~VirtualDatasetInfo() override = default; Status Init(const StrategyPtr& strategy) override; Status InitForCostModel(const StrategyPtr& strategy) override; @@ -51,7 +51,6 @@ class VirtualDatasetInfo : public OperatorInfo { Status GetAttrs() override; Status InferAsLossDivisor() override; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/status.h b/mindspore/ccsrc/parallel/status.h index 9d773f0d9b..6bfe9f0e72 100644 --- a/mindspore/ccsrc/parallel/status.h +++ b/mindspore/ccsrc/parallel/status.h @@ -21,7 +21,6 @@ namespace mindspore { namespace parallel { - enum Status { SUCCESS = 0, FAILED, diff --git a/mindspore/ccsrc/parallel/step_auto_parallel.cc b/mindspore/ccsrc/parallel/step_auto_parallel.cc index d7d48c35bb..81aae04c73 100644 --- a/mindspore/ccsrc/parallel/step_auto_parallel.cc +++ b/mindspore/ccsrc/parallel/step_auto_parallel.cc @@ -69,7 +69,6 @@ std::vector splittable_op_ = {MATMUL, RELU, ONEHOT, DROPOUT_DO_MASK, - DROPOUT_GEN_MASK, REDUCE_MAX, REDUCE_MIN, ARGMAXWITHVALUE, @@ -79,10 +78,12 @@ std::vector splittable_op_ = {MATMUL, FUSE_BATCH_NORM, POOLING, SOFTMAX_CROSS_ENTROPY_WITH_LOGITS, + SIGMOID_CROSS_ENTROPY_WITH_LOGITS, MAX_POOL_WITH_ARGMAX, SIMPLE_MEAN, FLATTEN, BATCH_NORM, + LAYER_NORM, BIAS_ADD, ASSIGN_SUB, COS, @@ -94,6 +95,7 @@ std::vector splittable_op_ = {MATMUL, SIGMOID, POW, MAXIMUM, + MINIMUM, EQUAL, NOT_EQUAL, LOGICALNOT, @@ -102,15 +104,14 @@ std::vector splittable_op_ = {MATMUL, SQRT, GET_NEXT, CAST, - Neg, + NEG, + SQUARE, BATCH_MATMUL, EXPAND_DIMS, SQUEEZE}; -std::vector elementwise_op_ = {ACTIVATION, GELU, TANH, SOFTMAX, LOG_SOFTMAX, RELU, SQRT, - CAST, POW, EXP, LOG, COS, ACOS, LOGICALNOT}; - -std::vector ignore_manual_strategy_op_ = {BATCH_NORM}; +std::vector elementwise_op_ = {ACTIVATION, GELU, TANH, SOFTMAX, LOG_SOFTMAX, RELU, SQRT, CAST, + POW, EXP, LOG, COS, ACOS, LOGICALNOT, NEG, SQUARE}; bool StepAutoParallel(const FuncGraphPtr &root, const opt::OptimizerPtr &) { MS_EXCEPTION_IF_NULL(root); @@ -229,7 +230,7 @@ size_t GetLengthOfDataType(const TypePtr &type) { case kNumberTypeInt: return sizeof(int); case kNumberTypeUInt: - return sizeof(uint); + return sizeof(unsigned int); case kNumberTypeFloat: return sizeof(float); default: @@ -255,12 +256,9 @@ size_t GetInputsTypeLen(const AnfNodePtr &input) { return input_type_len; } -// Given the node, return the element length of input and output -std::vector> ExtractInputAndOutputTypeLengthByNode(const CNodePtr &node) { +std::vector ExtractInputTypeLengthByNode(const CNodePtr &node) { MS_EXCEPTION_IF_NULL(node); std::vector inputs_type_len; - std::vector outputs_type_len; - std::vector> all_types; std::vector node_inputs{node->inputs()}; // extract input element length @@ -278,9 +276,13 @@ std::vector> ExtractInputAndOutputTypeLengthByNode(const CNo inputs_type_len.push_back(GetInputsTypeLen(input)); } } - all_types.push_back(inputs_type_len); + return inputs_type_len; +} - // extract output element length +std::vector ExtractOutputTypeByNode(const CNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + std::vector outputs_type; + // extract output element type auto primary_output_type = node->Type(); MS_EXCEPTION_IF_NULL(primary_output_type); if (primary_output_type->isa()) { @@ -290,7 +292,7 @@ std::vector> ExtractInputAndOutputTypeLengthByNode(const CNo for (auto &ele : elements) { if (ele->isa()) { auto ele_element_type = ele->cast()->element(); - outputs_type_len.push_back(GetLengthOfDataType(ele_element_type)); + outputs_type.push_back(ele_element_type); } else { MS_LOG(EXCEPTION) << "Unknown type: " << primary_output_type->type_name(); } @@ -299,24 +301,12 @@ std::vector> ExtractInputAndOutputTypeLengthByNode(const CNo // in this case, the output is a single tensor if (primary_output_type->isa()) { auto element_type = primary_output_type->cast()->element(); - outputs_type_len.push_back(GetLengthOfDataType(element_type)); + outputs_type.push_back(element_type); } else { MS_LOG(EXCEPTION) << "Unknown type: " << primary_output_type->type_name(); } } - all_types.push_back(outputs_type_len); - - return all_types; -} - -// Be careful the argument is cnode_full_name, not the op_name -bool IsIgnoreStrategyOperator(const std::string &cnode_full_name) { - for (auto &ignore_op : ignore_manual_strategy_op_) { - if (cnode_full_name.find(ignore_op) != std::string::npos) { - return true; - } - } - return false; + return outputs_type; } bool IsElementWiseOperator(const std::string &op_name) { @@ -367,11 +357,20 @@ OperatorInfoPtr CreateTheOperatorInfo(const PrimitivePtr &prim, const CNodePtr & return nullptr; } // Set the data type for inputs and outputs of this OperatorInfo - std::vector> type_lengths = ExtractInputAndOutputTypeLengthByNode(cnode); - if (operator_info->SetInputAndOutputTypeLength(type_lengths[0], type_lengths[1]) != SUCCESS) { + auto inputs_type_length = ExtractInputTypeLengthByNode(cnode); + auto outputs_type = ExtractOutputTypeByNode(cnode); + std::vector outputs_type_length; + outputs_type_length.reserve(outputs_type.size()); + std::transform(outputs_type.begin(), outputs_type.end(), std::back_inserter(outputs_type_length), + GetLengthOfDataType); + if (operator_info->SetInputAndOutputTypeLength(inputs_type_length, outputs_type_length) != SUCCESS) { MS_LOG(ERROR) << "Setting the lengths of inputs and outputs failed for operator: " << operator_info->name(); return nullptr; } + if (operator_info->set_outputs_type(outputs_type) != SUCCESS) { + MS_LOG(ERROR) << "Setting the types of outputs failed for operator: " << operator_info->name(); + return nullptr; + } // When the 'inputs' contains numerical values for some operators, these values should be extracted from // ANF graph auto &inputs = cnode->inputs(); @@ -406,18 +405,20 @@ OperatorInfoPtr CreateTheOperatorInfo(const PrimitivePtr &prim, const CNodePtr & // Set cost for this configured strategy if (operator_info->SetCostUnderStrategy(strategyPtr) != SUCCESS) { MS_LOG(EXCEPTION) << "Failure: operator " << prim->name() << " SetCostUnderStrategy failed"; - } else if (!NOT_FULLY_USE_DEVICES) { - if (!IsIgnoreStrategyOperator(cnode->fullname_with_scope())) { - // If configured to fully use devices, then checking for the user-specified strategy - int32_t used_devices = operator_info->used_devices(); - MS_EXCEPTION_IF_NULL(g_device_manager); - auto total_device_num = g_device_manager->GetDeviceListByStageId(0).size(); - // 'used_devices == -1' means that 'used_devices_' is not set - if ((used_devices == -1) || IntToSize(used_devices) != total_device_num) { - MS_LOG(EXCEPTION) << "In configuration 'NOT_FULLY_USE_DEVICES' = False, " - << "but the specified strategy uses device: " << used_devices - << ", total devices: " << total_device_num; - } + } else if (FULLY_USE_DEVICES) { + // If configured to fully use devices, then checking for the user-specified strategy + int32_t used_devices = operator_info->used_devices(); + MS_EXCEPTION_IF_NULL(g_device_manager); + auto total_device_num = g_device_manager->GetDeviceListByStageId(0).size(); + // 'used_devices == 1' means that ALL-1 strategy, which is valid in auto-parallel + if (used_devices == 1) { + return operator_info; + } + // 'used_devices == -1' means that 'used_devices_' is not set + if ((used_devices == -1) || IntToSize(used_devices) != total_device_num) { + MS_LOG(EXCEPTION) << "In configuration 'FULLY_USE_DEVICES' = True, " + << "but the specified strategy uses device: " << used_devices + << ", total devices: " << total_device_num; } } } @@ -479,7 +480,6 @@ Status ConstructCostGraphNodes(const std::vector &all_nodes, const F bool is_find_wrong = (current_op_ptr->name().find(VIRTUAL_DATA_SET_INFO) == std::string::npos) && (current_op_ptr->name().find(BATCH_PARALLEL) == std::string::npos) && (current_op_ptr->name().find(prim->name()) == std::string::npos); - if (is_find_wrong) { MS_LOG(EXCEPTION) << "The OperatorInfo: " << current_op_ptr->name() << " does not match the Prim: " << prim->name(); @@ -637,6 +637,15 @@ void AugmentCostGraph(const std::vector &all_nodes) { // Dealing with the RefKey case auto refkeys = cnode_with_refkeys.second; auto cnode = cnode_with_refkeys.first; + + auto cnode_ptr = cnode->cast(); + if (cnode_ptr == nullptr || !IsValueNode(cnode_ptr->input(0))) { + continue; + } + if (!IsAutoParallelCareNode(cnode_ptr)) { + continue; + } + if (refkeys.size() > 1) { MS_LOG(EXCEPTION) << "CNode: " << cnode->fullname_with_scope() << " 's inputs have more than 1 RefKeys."; } @@ -857,11 +866,15 @@ Status ParallelStrategySearch(const std::vector &all_nodes, const Fu if (entire_costgraph->ComputeOpsAndEdgesParameterInvolved() == SUCCESS) { // Calculate operators' memory usage if (entire_costgraph->CalculateOpsMemoryCost() != SUCCESS) { - MS_LOG(EXCEPTION) << "Correcting operators' cost for memory reuse failed."; + MS_LOG(EXCEPTION) << "Calculating operators' cost for memory cost failed."; } // Calculate edges' memory usage if (entire_costgraph->CalculateEdgesMemoryCost() != SUCCESS) { - MS_LOG(EXCEPTION) << "Correcting edges' cost for memory reuse failed."; + MS_LOG(EXCEPTION) << "Calculating edges' cost for memory cost failed."; + } + // Correct memory usage caused by TmpIdentity + if (entire_costgraph->CorrectOpsMemoryCost() != SUCCESS) { + MS_LOG(EXCEPTION) << "Correcting operators' cost for memory cost failed."; } } else { MS_LOG(EXCEPTION) << "Computing operators' parameter_involved failed."; @@ -926,7 +939,6 @@ Status ParallelStrategyRecSearch(const std::vector &all_nodes, const graph = EliminateGraph(graph, eli_list, index_list); size_t num_device = g_device_manager->DeviceNum(); - if (PartitionForAllDevices(num_device, graph) == SUCCESS) { MS_LOG(INFO) << "Partition Success With " << num_device << " devices."; } else { diff --git a/mindspore/ccsrc/parallel/step_auto_parallel.h b/mindspore/ccsrc/parallel/step_auto_parallel.h index 5ee75ca162..f120edcc61 100644 --- a/mindspore/ccsrc/parallel/step_auto_parallel.h +++ b/mindspore/ccsrc/parallel/step_auto_parallel.h @@ -39,7 +39,9 @@ size_t GetLengthOfDataType(const TypePtr &type); std::vector ExtractInputParameterByNode(const CNodePtr &node); -std::vector> ExtractInputAndOutputTypeLengthByNode(const CNodePtr &node); +std::vector ExtractInputTypeLengthByNode(const CNodePtr &node); + +std::vector ExtractOutputTypeByNode(const CNodePtr &node); Status ConstructCostGraphNodes(const std::vector &all_nodes, const FuncGraphPtr &root); @@ -53,7 +55,6 @@ Status ParallelStrategyRecSearch(const std::vector &all_nodes, const std::vector> RecInputTensorNames(const std::map::iterator &it, std::vector> input_tensor_names); - } // namespace parallel } // namespace mindspore #endif // PARALLEL_STEP_AUTO_PARALLEL_H_ diff --git a/mindspore/ccsrc/parallel/step_parallel.cc b/mindspore/ccsrc/parallel/step_parallel.cc index 9a08ead584..bcd4dc3763 100644 --- a/mindspore/ccsrc/parallel/step_parallel.cc +++ b/mindspore/ccsrc/parallel/step_parallel.cc @@ -47,8 +47,8 @@ using mindspore::tensor::Tensor; namespace mindspore { namespace parallel { -const std::set COMMUNICATION_OPS = {ALL_REDUCE, ALL_GATHER, ALL_TO_ALL, REDUCE_SCATTER}; -const std::set INVALID_LOSS_OPS = {GET_NEXT, VIRTUALLOSS}; +static const std::set COMMUNICATION_OPS = {ALL_REDUCE, ALL_GATHER, ALL_TO_ALL, REDUCE_SCATTER}; +static const std::set INVALID_LOSS_OPS = {GET_NEXT, VIRTUALLOSS}; // g_RefMap, for CNode B input i is a RefKey[Parameter C], // it will be one item in map with key: C, and value: (B, i) static std::map> g_RefMap; @@ -464,6 +464,14 @@ void SplitTensor(const AnfNodePtr& node, const CNodePtr& next_node, int index) { MS_EXCEPTION_IF_NULL(func_graph); Operator op = CreateGetTensorSliceOp(tensor_layout); InsertGetTensorSliceOp(op, next_node, func_graph, index, SPLIT_TENSOR); + if (!op_info->sub_ops().empty()) { + auto sub_ops = op_info->sub_ops(); + for (size_t i = 0; i < sub_ops.size(); i++) { + if (!sub_ops.at(i).empty()) { + InsertGetTensorSliceOp(sub_ops.at(i).at(0), next_node, func_graph, index, SUB); + } + } + } } void StepSplitTensor(const AnfNodePtr& node, const FuncGraphManagerPtr& manager) { @@ -484,8 +492,6 @@ void StepSplitTensor(const AnfNodePtr& node, const FuncGraphManagerPtr& manager) } if (IsParallelCareNode(use_cnode)) { SplitTensor(node, use_cnode, node_pair.second); - } else { - StepSplitTensor(use_cnode, manager); } } } @@ -525,6 +531,26 @@ std::vector ReplaceOpInput(const Operator& replace_op, const std::st return replace_input; } +void ReplaceOneOp(const Operator& replace_op, const CNodePtr& node) { + FuncGraphPtr func_graph = node->func_graph(); + MS_EXCEPTION_IF_NULL(func_graph); + FuncGraphManagerPtr manager = func_graph->manager(); + if (manager == nullptr) { + MS_LOG(EXCEPTION) << "Failure:AddNode error since manager is nullptr"; + } + std::string instance_name = CreateInstanceName(node, 0); + std::vector replace_input; + replace_input = ReplaceOpInput(replace_op, instance_name, node); + CNodePtr replace_node = func_graph->NewCNode(replace_input); + MS_EXCEPTION_IF_NULL(replace_node); + ScopePtr scope = node->scope(); + MS_EXCEPTION_IF_NULL(scope); + replace_node->set_scope(scope); + replace_node->set_in_forward_flag(true); + replace_input[0]->set_scope(scope); + (void)manager->Replace(node, replace_node); +} + void StepReplaceOp(OperatorVector replace_op, const CNodePtr& node) { // step1:get graph manager distribute_operator OperatorInfoPtr distribute_operator = node->operator_info(); @@ -1757,6 +1783,28 @@ void StepReplace(const OperatorInfoPtr& distribute_operator, const CNodePtr& cno } } +void HandleDropoutNode(const OperatorInfoPtr& distribute_operator, const CNodePtr& cnode) { + MS_EXCEPTION_IF_NULL(distribute_operator); + MS_EXCEPTION_IF_NULL(cnode); + + std::string op_name = distribute_operator->name(); + if (op_name.find(DROPOUT_DO_MASK) == std::string::npos) { + return; + } + + DropoutDoMaskInfoPtr dropout_do_mask = std::dynamic_pointer_cast(distribute_operator); + MS_EXCEPTION_IF_NULL(dropout_do_mask); + Operator replace_op = dropout_do_mask->GetDropoutGenMaskReplaceOp(cnode); + if (cnode->inputs().size() != DROPOUT_DO_MASK_CNODE_INPUT_SIZE) { + MS_LOG(EXCEPTION) << "The size of drop out do mask cnode's input is not " << DROPOUT_DO_MASK_CNODE_INPUT_SIZE; + } + ReplaceOneOp(replace_op, cnode->input(DROPOUT_GEN_MASK_INDEX)->cast()); +} + +void HandleSpecialNode(const OperatorInfoPtr& distribute_operator, const CNodePtr& cnode) { + HandleDropoutNode(distribute_operator, cnode); +} + void ParallelCommunication(const FuncGraphPtr& root, const std::vector& all_nodes, const FuncGraphManagerPtr& manager) { MS_EXCEPTION_IF_NULL(root); @@ -1792,7 +1840,6 @@ void ParallelCommunication(const FuncGraphPtr& root, const std::vector(node)) { StepSplitTensor(node, manager); } @@ -1978,7 +2027,6 @@ CNodePtr FindLossCNode(const FuncGraphPtr& func_graph) { current_prim = GetValueNode(pre_cnode->input(0)); } - // notice: the GetNext op has not input if (INVALID_LOSS_OPS.find(current_prim->name()) != INVALID_LOSS_OPS.end()) { MS_LOG(INFO) << "The loss is: " << current_prim->name(); @@ -2046,7 +2094,6 @@ CNodePtr FindLossCNodeFromRoot(const FuncGraphPtr& root) { MS_EXCEPTION_IF_NULL(root_return_node); const auto& all_nodes = root->nodes(); FuncGraphPtr func_graph = FindForwardGraphByRootNodes(all_nodes); - if (func_graph == nullptr) { return FindLossCNode(root); } else { @@ -2061,7 +2108,6 @@ FuncGraphPtr ForwardGraph(const FuncGraphPtr& root) { MS_EXCEPTION_IF_NULL(root_return_node); const auto& all_nodes = root->nodes(); FuncGraphPtr func_graph = FindForwardGraphByRootNodes(all_nodes); - if (func_graph != nullptr) { forward_graph = func_graph; } diff --git a/mindspore/ccsrc/parallel/strategy.h b/mindspore/ccsrc/parallel/strategy.h index acc6ca928f..93d4d4dff1 100644 --- a/mindspore/ccsrc/parallel/strategy.h +++ b/mindspore/ccsrc/parallel/strategy.h @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - #define MIN_SLICE_NUM 1 using Dimensions = std::vector; diff --git a/mindspore/ccsrc/parallel/tensor_layout/arrangement.cc b/mindspore/ccsrc/parallel/tensor_layout/arrangement.cc index 68acae87f3..b42ba30242 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/arrangement.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/arrangement.cc @@ -26,7 +26,6 @@ namespace mindspore { namespace parallel { - Status Arrangement::Init(const std::vector& array) { Status status = Array::Init(array); if (status != Status::SUCCESS) { diff --git a/mindspore/ccsrc/parallel/tensor_layout/arrangement.h b/mindspore/ccsrc/parallel/tensor_layout/arrangement.h index 6d64e07f03..2dc13038c1 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/arrangement.h +++ b/mindspore/ccsrc/parallel/tensor_layout/arrangement.h @@ -28,7 +28,6 @@ namespace mindspore { namespace parallel { - class Arrangement : public Array { public: Arrangement() : size_(1) {} @@ -53,7 +52,6 @@ class Arrangement : public Array { void ComputeSize(); int32_t size_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/array.cc b/mindspore/ccsrc/parallel/tensor_layout/array.cc index ce1b9b8ecf..ba3858ae00 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/array.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/array.cc @@ -21,7 +21,6 @@ namespace mindspore { namespace parallel { - std::string Array::ToString() const { std::ostringstream buffer; buffer << "[ "; diff --git a/mindspore/ccsrc/parallel/tensor_layout/array.h b/mindspore/ccsrc/parallel/tensor_layout/array.h index 3a47f0d818..f7d9c3c673 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/array.h +++ b/mindspore/ccsrc/parallel/tensor_layout/array.h @@ -26,7 +26,6 @@ namespace mindspore { namespace parallel { - class Array { public: Array() = default; @@ -43,7 +42,6 @@ class Array { protected: std::vector array_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/construct_operator.h b/mindspore/ccsrc/parallel/tensor_layout/construct_operator.h index 91f5236037..cf6cff456a 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/construct_operator.h +++ b/mindspore/ccsrc/parallel/tensor_layout/construct_operator.h @@ -52,7 +52,6 @@ class ConstructOperator { Shape dev_matrix_shape_; Status CreateGroupByDim(size_t axis, std::vector* group); }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.cc b/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.cc index b2ee51b40b..190a5846ba 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.cc @@ -20,7 +20,6 @@ namespace mindspore { namespace parallel { - std::string LayoutTransfer::ToString() const { std::ostringstream buffer; buffer << std::endl << std::string("from_in_ tensor layout:" + from_in_.ToString()); @@ -37,6 +36,5 @@ Status LayoutTransfer::Init(const TensorLayout& from_in, const TensorLayout& to_ Status status = CheckValidTransfer(); return status; } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.h b/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.h index b892a87d30..b05128f5b8 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.h +++ b/mindspore/ccsrc/parallel/tensor_layout/layout_transfer.h @@ -23,7 +23,6 @@ namespace mindspore { namespace parallel { - class LayoutTransfer { public: LayoutTransfer() = default; @@ -43,7 +42,6 @@ class LayoutTransfer { private: virtual Status CheckValidTransfer() = 0; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/map.cc b/mindspore/ccsrc/parallel/tensor_layout/map.cc index 4f3f2369c7..320dbe6ebd 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/map.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/map.cc @@ -26,7 +26,6 @@ namespace mindspore { namespace parallel { - Status Map::Init(const std::vector& array) { Status status = Array::Init(array); if (status != Status::SUCCESS) { diff --git a/mindspore/ccsrc/parallel/tensor_layout/map.h b/mindspore/ccsrc/parallel/tensor_layout/map.h index f7bc061aa1..3f839ef198 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/map.h +++ b/mindspore/ccsrc/parallel/tensor_layout/map.h @@ -46,7 +46,6 @@ class Map : public Array { private: bool IsValidMap(); }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.cc b/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.cc index 2ee682fad8..7ed07ac02e 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.cc @@ -21,7 +21,6 @@ namespace mindspore { namespace parallel { - Status RedistributionLayoutTransfer::CheckValidTransfer() { return Status::SUCCESS; } /* @@ -66,6 +65,5 @@ std::shared_ptr RedistributionLayoutTransfer::UnifyDevice } return unified_device_arrangement_ptr->UnifyDeviceArrangementAndTensorShape(); } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.h b/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.h index 6522b7f8c2..7b57f46dd6 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.h +++ b/mindspore/ccsrc/parallel/tensor_layout/redistribution_layout_transfer.h @@ -24,7 +24,6 @@ namespace mindspore { namespace parallel { - class RedistributionLayoutTransfer : public LayoutTransfer { public: RedistributionLayoutTransfer() = default; @@ -35,7 +34,6 @@ class RedistributionLayoutTransfer : public LayoutTransfer { Status CheckValidTransfer() override; std::shared_ptr UnifyDeviceArrangement() const; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.cc b/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.cc index 028fb5874a..b4ec6a016f 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.cc @@ -22,7 +22,6 @@ namespace mindspore { namespace parallel { - Status RedistributionOperatorInfer::Init(const TensorLayout& tensor_layout, const Map& out_tensor_map, RankList dev_list) { in_tensor_map_ = tensor_layout.tensor_map(); @@ -273,6 +272,5 @@ Status RedistributionOperatorInfer::TransferConcatByAxis(Args args) { } return Status::SUCCESS; } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.h b/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.h index 13f9e7af24..b4ec0c4633 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.h +++ b/mindspore/ccsrc/parallel/tensor_layout/redistribution_operator_infer.h @@ -28,7 +28,6 @@ #include "utils/convert_utils.h" namespace mindspore { namespace parallel { - using DeviceArrangement = std::vector; using TensorMap = std::vector; using TensorShape = std::vector; @@ -69,7 +68,6 @@ class RedistributionOperatorInfer { RankList dev_list_; bool construct_op_flag_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.cc b/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.cc index 1d56aa2220..39a6bef92d 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.cc @@ -20,7 +20,6 @@ namespace mindspore { namespace parallel { - Status ReshapeLayoutTransfer::CheckValidTransfer() { if (!IsSameDeviceArrangement()) { return Status::FAILED; diff --git a/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.h b/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.h index 9ad8e67635..8aae71631d 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.h +++ b/mindspore/ccsrc/parallel/tensor_layout/reshape_layout_transfer.h @@ -23,7 +23,6 @@ namespace mindspore { namespace parallel { - class ReshapeLayoutTransfer : public LayoutTransfer { public: ReshapeLayoutTransfer() = default; @@ -43,7 +42,6 @@ class ReshapeLayoutTransfer : public LayoutTransfer { bool FromTensorShapeCanBeExpandByTo() const; bool ToTensorShapeCanBeExpandByFrom() const; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/shape_util.cc b/mindspore/ccsrc/parallel/tensor_layout/shape_util.cc index 54bb976032..a26627fb3c 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/shape_util.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/shape_util.cc @@ -21,7 +21,6 @@ namespace mindspore { namespace parallel { - /* * example: * shape = [2, 8, 32] @@ -260,6 +259,5 @@ Status ExpandShape(const std::vector& in, const std::vector& e } return status; } - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/shape_util.h b/mindspore/ccsrc/parallel/tensor_layout/shape_util.h index 85ca70969b..e83156500c 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/shape_util.h +++ b/mindspore/ccsrc/parallel/tensor_layout/shape_util.h @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - /* * compute the accumulating product of all the values in shape from left to right, * the accumulating results are saved in shape_accum from left to right @@ -167,7 +166,6 @@ Status ExpandAccumulateProduct(const std::vector& in_accum_reverse, * out = [2, 4, 2, 4, 8] */ Status ExpandShape(const std::vector& in, const std::vector& expand, std::vector* out); - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/tensor_info.h b/mindspore/ccsrc/parallel/tensor_layout/tensor_info.h index 9fc6a229e2..4a64ab472c 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/tensor_info.h +++ b/mindspore/ccsrc/parallel/tensor_layout/tensor_info.h @@ -28,7 +28,6 @@ namespace mindspore { namespace parallel { - using Shapes = std::vector; class TensorInfo { @@ -55,7 +54,6 @@ class TensorInfo { // reduce method's reduce dim std::vector reduce_dim_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.cc b/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.cc index f49b967abc..5fbd04431c 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.cc @@ -27,7 +27,6 @@ namespace mindspore { namespace parallel { - std::string TensorLayout::ToString() const { return StandardToString() + OriginToString(); } std::string TensorLayout::StandardToString() const { @@ -337,7 +336,7 @@ Status TensorLayout::UpdateTensorMap(uint32_t index, int32_t value) { MS_LOG(ERROR) << "Index is out of the size of the tensor map!"; return Status::FAILED; } - Shape shape = tensor_map_.array(); + auto shape = tensor_map_.array(); shape[index] = value; if (tensor_map_.Init(shape) == Status::FAILED) { MS_LOG(ERROR) << "Update tensor map failed!"; diff --git a/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.h b/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.h index 238c9373d9..e6ddc2a708 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.h +++ b/mindspore/ccsrc/parallel/tensor_layout/tensor_layout.h @@ -30,7 +30,6 @@ namespace mindspore { namespace parallel { - class TensorLayout { public: TensorLayout() = default; @@ -94,7 +93,6 @@ class TensorLayout { Map tensor_map_; Arrangement tensor_shape_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.cc b/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.cc index 55e6a300e0..d8eef7e7a5 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.cc +++ b/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.cc @@ -24,7 +24,6 @@ namespace mindspore { namespace parallel { - Status TensorRedistribution::Init(const TensorLayout& from, const TensorLayout& to, const RankList& dev_list) { from_origin_ = from; to_origin_ = to; @@ -159,6 +158,7 @@ Status TensorRedistribution::ComputeCost() { backward_comm_cost_ += prod; comm_cost_ += 2.0 * prod; computation_cost_ += prod; + memory_cost_ += prod; } else if (str == CONCAT_BY_AXIS) { // communication cost = all_gather + reduce_scatter = before_slice_shape + after_slice_shape // computation cost = before_slice_shape @@ -175,20 +175,25 @@ Status TensorRedistribution::ComputeCost() { if (concat_dim == 0) { // computation cost = all_gather computation_cost_ += prod; + memory_cost_ += prod * dev_num; } else { // computation cost = all_gather + split + concat computation_cost_ += (prod + prod * dev_num + prod * dev_num); + memory_cost_ += (prod * dev_num + prod * dev_num + prod); } } else { // There is only computation cost in SplitByAxis. // computation cost = before_slice_shape computation_cost_ += prod; + // This addtion may be erroneous + memory_cost_ += prod; } } if (reshape_flag()) { Shape prev_slice_shape = from_.slice_shape().array(); double prev_prod = std::accumulate(prev_slice_shape.begin(), prev_slice_shape.end(), 1, std::multiplies()); computation_cost_ += 2.0 * prev_prod; + memory_cost_ += 2.0 * prev_prod; } return Status::SUCCESS; } diff --git a/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.h b/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.h index e933b9b8eb..ebaccadf53 100644 --- a/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.h +++ b/mindspore/ccsrc/parallel/tensor_layout/tensor_redistribution.h @@ -33,7 +33,6 @@ namespace mindspore { namespace parallel { - class TensorRedistribution { public: explicit TensorRedistribution(bool construct_op_flag = true, bool keep_reshape = false) @@ -42,6 +41,7 @@ class TensorRedistribution { forward_comm_cost_(0.0), backward_comm_cost_(0.0), computation_cost_(0.0), + memory_cost_(0.0), construct_op_flag_(construct_op_flag), keep_reshape_(keep_reshape) {} Status Init(const TensorLayout& from, const TensorLayout& to, const RankList& dev_list); @@ -54,6 +54,7 @@ class TensorRedistribution { double computation_cost() const { return computation_cost_; } double forward_comm_cost() const { return forward_comm_cost_; } double backward_comm_cost() const { return backward_comm_cost_; } + double memory_cost() const { return memory_cost_; } private: Status InferReshape(const TensorLayout& from_layout, const TensorLayout& to_layout, @@ -72,11 +73,15 @@ class TensorRedistribution { double forward_comm_cost_; // backward communication cost double backward_comm_cost_; + // computation_cost models the time spending on computing in this tensor redistribution, which is calculated by the + // inputs. double computation_cost_; + // memory_cost models the PEAK memory cost in a traning iteration contributed by this tensor redistribution, which is + // calculated by the outputs. + double memory_cost_; bool construct_op_flag_; bool keep_reshape_; }; - } // namespace parallel } // namespace mindspore diff --git a/mindspore/ccsrc/pipeline/action.cc b/mindspore/ccsrc/pipeline/action.cc index baf4bea7ec..3e0f8804e7 100644 --- a/mindspore/ccsrc/pipeline/action.cc +++ b/mindspore/ccsrc/pipeline/action.cc @@ -88,6 +88,7 @@ FuncGraphPtr Renormalize(const ResourcePtr& res, const FuncGraphPtr& func_graph, double t2 = GetTime(); #endif auto ret = ProgramSpecialize(res, func_graph, result.context); + res->set_func_graph(ret); #ifdef ENABLE_PROFILE double t3 = GetTime(); MsProfile::StatTime("renormalize.infer", t2 - t1); @@ -263,7 +264,7 @@ bool TaskEmitAction(const ResourcePtr& res) { auto bc_ptr = res->results()[kBackend].cast(); std::vector cut_list = compile::nonlinear_ops; if (bc_ptr->name() == kMsConvert) { - cut_list = compile::ms_nonlinear_ops; + cut_list = compile::GetMsNonlinearOps(); } std::shared_ptr compile = std::make_shared(bc_ptr, cut_list); res->results()[kOutput] = compile->CompileAndLink(func_graph); diff --git a/mindspore/ccsrc/pipeline/init.cc b/mindspore/ccsrc/pipeline/init.cc index 24ead047d3..b709199c87 100644 --- a/mindspore/ccsrc/pipeline/init.cc +++ b/mindspore/ccsrc/pipeline/init.cc @@ -29,8 +29,11 @@ #include "parallel/context.h" #include "parallel/device_manager.h" #include "parallel/costmodel_context.h" +#ifdef ENABLE_GPU_COLLECTIVE #include "device/gpu/distribution/collective_init.h" - +#else +#include "device/gpu/distribution/collective_fake_init.h" +#endif namespace py = pybind11; using FuncGraph = mindspore::FuncGraph; @@ -261,10 +264,10 @@ PYBIND11_MODULE(_c_expression, m) { "Set the parameter tensor_slice_size in strategy generation.") .def("get_tensor_slice_align_size", &CostModelContext::tensor_slice_alignment_size, "Get the parameter tensor_slice_size in strategy generation.") - .def("set_not_fully_use_devices", &CostModelContext::set_not_fully_use_device, - "Set the parameter not_fully_use_devices in the DP algorithm.") - .def("get_not_fully_use_devices", &CostModelContext::not_fully_use_device, - "Get the parameter not_fully_use_devices in the DP algorithm.") + .def("set_fully_use_devices", &CostModelContext::set_fully_use_device, + "Set the parameter fully_use_devices in the DP algorithm.") + .def("get_fully_use_devices", &CostModelContext::fully_use_device, + "Get the parameter fully_use_devices in the DP algorithm.") .def("set_elementwise_op_strategy_follow", &CostModelContext::set_elementwise_stra_follow, "Set the parameter elementwise_op_strategy_follow in the DP algorithm.") .def("get_elementwise_op_strategy_follow", &CostModelContext::elementwise_stra_follow, @@ -297,9 +300,16 @@ PYBIND11_MODULE(_c_expression, m) { (void)py::class_>(m, "Oplib") .def(py::init()) .def("reg_op", &OpLib::RegOp, "Register op info."); - +#ifdef ENABLE_GPU_COLLECTIVE (void)m.def("init_gpu_collective", &mindspore::device::gpu::CollectiveInitializer::InitCollective, "Init gpu collective communication mode."); (void)m.def("finalize_gpu_collective", &mindspore::device::gpu::CollectiveInitializer::FinalizeCollective, "Finalize gpu collective communication mode."); +#else + (void)m.def("init_gpu_collective", &mindspore::device::gpu::CollectiveFakeInitializer::InitCollective, + "Init gpu collective communication mode."); + (void)m.def("finalize_gpu_collective", &mindspore::device::gpu::CollectiveFakeInitializer::FinalizeCollective, + "Finalize gpu collective communication mode."); + +#endif } diff --git a/mindspore/ccsrc/pipeline/parse/parse.cc b/mindspore/ccsrc/pipeline/parse/parse.cc index 231b98ab00..51c4fc17ec 100644 --- a/mindspore/ccsrc/pipeline/parse/parse.cc +++ b/mindspore/ccsrc/pipeline/parse/parse.cc @@ -68,9 +68,7 @@ AnfNodePtr GetMixedPrecisionCastHelp(const FuncGraphPtr &func_graph, const AnfNo return param; } auto cast_helper = prim::GetPythonOps("_mp_cast_helper", "mindspore.ops.composite.base"); - auto partial = - func_graph->NewCNode({NewValueNode(prim::kPrimPartial), NewValueNode(cast_helper), NewValueNode(dst_type)}); - auto cast = func_graph->NewCNode({NewValueNode(prim::kCompositeHyperMap), partial, param}); + auto cast = func_graph->NewCNode({NewValueNode(cast_helper), NewValueNode(dst_type), param}); return cast; } diff --git a/mindspore/ccsrc/pipeline/pass.cc b/mindspore/ccsrc/pipeline/pass.cc index a58ecf41b6..b3eda4c37b 100644 --- a/mindspore/ccsrc/pipeline/pass.cc +++ b/mindspore/ccsrc/pipeline/pass.cc @@ -114,11 +114,9 @@ OptPassGroupMap GetOptPassesA(const opt::irpass::OptimizeIRPassLib& irpass) { opt::OptPassConfig grad = opt::OptPassConfig({irpass.expand_jprim_}, true); opt::irpass::ResolveIRPassLib resolve_irpass; - opt::OptPassConfig resolve_pass = opt::OptPassConfig({ - resolve_irpass.resolver_resolve_, - resolve_irpass.resolver_getattr_, - irpass.get_make_ref_eliminate_, - }); + opt::OptPassConfig resolve_pass = + opt::OptPassConfig({resolve_irpass.resolver_resolve_, resolve_irpass.resolver_getattr_, + irpass.get_make_ref_eliminate_, irpass.replace_old_param_}); OptPassGroupMap map_a({{"a_1", a_1}, {"a_2", a_2}, @@ -187,8 +185,8 @@ void InitOpt(const ResourcePtr& res) { if (g_pass_opts.size() == 0) { opt::irpass::OptimizeIRPassLib irpass; g_pass_opts["opt_a"] = Optimizer::MakeOptimizer("opt_a", res, GetOptPassesA(irpass)); - g_pass_opts["opt_b"] = Optimizer::MakeOptimizer("opt_b", res, GetOptPassesB(irpass)); - g_pass_opts["opt_control"] = Optimizer::MakeOptimizer("opt_control", res, GetControlPhases(irpass)); + g_pass_opts["opt_b"] = Optimizer::MakeOptimizer("opt_b", res, GetOptPassesB(irpass), false, true); + g_pass_opts["opt_control"] = Optimizer::MakeOptimizer("opt_control", res, GetControlPhases(irpass), false, true); g_pass_opts["opt_prepare"] = Optimizer::MakeOptimizer("opt_prepare", res, GetPreparePhases(irpass)); } } diff --git a/mindspore/ccsrc/pipeline/pipeline.cc b/mindspore/ccsrc/pipeline/pipeline.cc index 003d4c15e9..cd4fe28db9 100644 --- a/mindspore/ccsrc/pipeline/pipeline.cc +++ b/mindspore/ccsrc/pipeline/pipeline.cc @@ -616,17 +616,19 @@ py::object ExecutorPy::Run(const py::tuple& args, const py::object& phase) { return ExecDFGraph(info_, args, phase_s); } #else - if (backend == "ge") { - std::shared_ptr ret_val = std::make_shared(); + if (backend == "ms" || backend == "ge") { + auto ret_val = std::make_shared(); if (info_.count(phase_s) != 0 && info_[phase_s]->func_graph != nullptr) { if (IsGraphOutputValueNodeOrParameter(info_[phase_s]->func_graph->output(), args, ret_val)) { return *ret_val; } } - if (args.size() > 0) { - return args[0]; + if (backend == "ge") { + if (args.size() > 0) { + return args[0]; + } + return args; } - return args; } #endif std::size_t full_arg_size = ArgListSize(phase_s); diff --git a/mindspore/ccsrc/pipeline/static_analysis/evaluator.cc b/mindspore/ccsrc/pipeline/static_analysis/evaluator.cc index 9b120f731c..5bad1634d5 100644 --- a/mindspore/ccsrc/pipeline/static_analysis/evaluator.cc +++ b/mindspore/ccsrc/pipeline/static_analysis/evaluator.cc @@ -17,6 +17,7 @@ #include "pipeline/static_analysis/evaluator.h" #include +#include #include "ir/func_graph_cloner.h" #include "pipeline/static_analysis/utils.h" @@ -61,6 +62,33 @@ AnalysisContextPtr BaseFuncGraphEvaluator::MakeContext(const AnalysisEnginePtr & return context; } +static std::vector FastShadowSort(const AnfNodePtr &ret_node) { + auto ori_func_graph = ret_node->func_graph(); + MS_EXCEPTION_IF_NULL(ori_func_graph); + + std::vector sorted_nodes; + std::unordered_set checked_cnodes; + std::size_t index = 0; + sorted_nodes.emplace_back(ret_node); + while (index < sorted_nodes.size()) { + auto current = sorted_nodes[index]; + index++; + MS_EXCEPTION_IF_NULL(current); + if (current->isa()) { + auto &inputs = current->cast()->inputs(); + for (auto it = inputs.begin(); it != inputs.end(); it++) { + AnfNodePtr input = *it; + if (input != nullptr && input->isa() && checked_cnodes.find(input) == checked_cnodes.end() && + input->func_graph() == ori_func_graph) { + sorted_nodes.emplace_back(input); + (void)checked_cnodes.insert(input); + } + } + } + } + return sorted_nodes; +} + AbstractBasePtr BaseFuncGraphEvaluator::Infer(AnalysisEnginePtr engine, const AbstractBasePtrList &args_spec_list) { FuncGraphPtr fg = GetFuncGraph(engine, args_spec_list); MS_EXCEPTION_IF_NULL(fg); @@ -86,20 +114,20 @@ AbstractBasePtr BaseFuncGraphEvaluator::Infer(AnalysisEnginePtr engine, const Ab MS_LOG(DEBUG) << "Analysis FuncGraph begin, func graph: " << fg->ToString() << ", context: " << graph_context_->ToString() << ", return node: " << func_node->DebugString(); - const std::vector &all_nodes = TopoSort(func_node); - for (const auto &node : all_nodes) { + AbstractBasePtr ret_base = nullptr; + std::vector nodes = FastShadowSort(func_node); + for (auto it = nodes.crbegin(); it != nodes.crend(); it++) { + const auto &node = *it; AnfNodeConfigPtr node_conf = engine->MakeConfig(node, graph_context_); MS_LOG(DEBUG) << "Analysis node begin, func graph: " << fg->ToString() << ", node_conf: " << node_conf->ToString(); - AbstractBasePtr base = engine->GetEvaluatedValue(node_conf); + ret_base = engine->GetEvaluatedValue(node_conf); MS_LOG(DEBUG) << "Analysis node end, func graph: " << fg->ToString() << ", node_conf: " << node_conf->ToString() - << ", abstract: " << base->ToString(); + << ", abstract: " << ret_base->ToString(); } - AnfNodeConfigPtr ret_conf = engine->MakeConfig(func_node, graph_context_); - AbstractBasePtr base = engine->GetEvaluatedValue(ret_conf); - MS_EXCEPTION_IF_NULL(base); - MS_LOG(DEBUG) << "BaseFuncGraph " << fg->ToString() << " infer end, inferred abstract: " << base->ToString(); - return base; + MS_EXCEPTION_IF_NULL(ret_base); + MS_LOG(DEBUG) << "BaseFuncGraph " << fg->ToString() << " infer end, inferred abstract: " << ret_base->ToString(); + return ret_base; } AbstractBasePtrList FuncGraphEvaluator::NormalizeArgs(const AbstractBasePtrList &args_spec_list) const { diff --git a/mindspore/ccsrc/pipeline/static_analysis/prim.cc b/mindspore/ccsrc/pipeline/static_analysis/prim.cc index 403bbdf433..233d5df305 100644 --- a/mindspore/ccsrc/pipeline/static_analysis/prim.cc +++ b/mindspore/ccsrc/pipeline/static_analysis/prim.cc @@ -52,6 +52,8 @@ PrimitiveEvalImplMap &GetPrimitiveToEvalImplMap() { {prim::kPrimSwitch, {InferImplSwitch, true}}, {prim::kPrimIs_, {InferImplIs_, true}}, {prim::kPrimIsNot, {InferImplIsNot, true}}, + {prim::kPrimInDict, {InferImplInDict, true}}, + {prim::kPrimNotInDict, {InferImplNotInDict, true}}, // Maths {prim::kPrimMaximumGrad, {InferImplMinOrMaxGrad, true}}, {prim::kPrimMinimumGrad, {InferImplMinOrMaxGrad, true}}, @@ -91,6 +93,7 @@ PrimitiveEvalImplMap &GetPrimitiveToEvalImplMap() { {prim::kPrimMakeRange, {InferImplMakeRange, false}}, {prim::kPrimStopGradient, {InferImplStopGradient, false}}, {prim::kPrimStringEqual, {InferImplStringEqual, false}}, + {prim::kPrimStringConcat, {InferImplStringConcat, false}}, {prim::kPrimDictLen, {InferImplDictLen, false}}, // NN {prim::kPrimPooling, {InferImplPooling, true}}, @@ -128,6 +131,7 @@ PrimitiveEvalImplMap &GetPrimitiveToEvalImplMap() { {prim::kPrimScalarSummary, {InferImplScalarSummary, true}}, {prim::kPrimImageSummary, {InferImplTensorSummary, true}}, {prim::kPrimTensorSummary, {InferImplTensorSummary, true}}, + {prim::kPrimHistogramSummary, {InferImplTensorSummary, true}}, }; return prim_eval_implement_map; } @@ -442,6 +446,9 @@ AbstractBasePtr UniformPrimEvaluator::EvalPrim(const AnalysisEnginePtr &, const } ValuePtr inferred_value = RunImpl(value_list); + if (!(*inferred_value == *kAnyValue)) { + ret_value_type = inferred_value->type(); + } // for comparison primitives , return type shall have be specified to be bool. if (specify_out_type_ != nullptr) { ret_value_type = specify_out_type_; @@ -988,6 +995,8 @@ PrimitiveToImplMap &GetUniformPrimitiveToImplMap() { {prim::kPrimScalarMul, {prim::ScalarMul, true, nullptr, true}}, {prim::kPrimScalarDiv, {prim::ScalarDiv, true, nullptr, true}}, {prim::kPrimScalarMod, {prim::ScalarMod, true, nullptr, true}}, + {prim::kPrimScalarPow, {prim::ScalarPow, true, nullptr, true}}, + {prim::kPrimScalarFloordiv, {prim::ScalarFloordiv, true, nullptr, true}}, {prim::kPrimScalarUadd, {prim::ScalarUAdd, true, nullptr, true}}, {prim::kPrimScalarUsub, {prim::ScalarUSub, true, nullptr, true}}, {prim::kPrimScalarLog, {prim::ScalarLog, true, nullptr, true}}, diff --git a/mindspore/ccsrc/pipeline/static_analysis/prim.h b/mindspore/ccsrc/pipeline/static_analysis/prim.h index e154473dbb..be71f3200a 100644 --- a/mindspore/ccsrc/pipeline/static_analysis/prim.h +++ b/mindspore/ccsrc/pipeline/static_analysis/prim.h @@ -178,6 +178,10 @@ AbstractBasePtr InferImplIs_(const AnalysisEnginePtr &, const PrimitivePtr &, const AbstractBasePtrList &args_spec_list); AbstractBasePtr InferImplIsNot(const AnalysisEnginePtr &, const PrimitivePtr &, const AbstractBasePtrList &args_spec_list); +AbstractBasePtr InferImplInDict(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list); +AbstractBasePtr InferImplNotInDict(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list); AbstractBasePtr InferImplPooling(const AnalysisEnginePtr &, const PrimitivePtr &primitive, const AbstractBasePtrList &args_spec_list); AbstractBasePtr InferImplPoolingGrad(const AnalysisEnginePtr &, const PrimitivePtr &primitive, @@ -287,6 +291,8 @@ AbstractBasePtr InferImplStopGradient(const AnalysisEnginePtr &, const Primitive const AbstractBasePtrList &args_spec_list); AbstractBasePtr InferImplStringEqual(const AnalysisEnginePtr &, const PrimitivePtr &primitive, const AbstractBasePtrList &args_spec_list); +AbstractBasePtr InferImplStringConcat(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list); AbstractBasePtr InferImplDictLen(const AnalysisEnginePtr &, const PrimitivePtr &primitive, const AbstractBasePtrList &args_spec_list); diff --git a/mindspore/ccsrc/pre_activate/ascend/ascend_backend_optimization.cc b/mindspore/ccsrc/pre_activate/ascend/ascend_backend_optimization.cc index 432d88e7a4..7a35627e25 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ascend_backend_optimization.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ascend_backend_optimization.cc @@ -21,7 +21,7 @@ #include "pre_activate/ascend/ir_fission/bn_grad_split.h" #include "pre_activate/ascend/ir_fusion/fused_batch_norm_fusion.h" #include "pre_activate/ascend/ir_fission/layer_norm_grad_split.h" -#include "pre_activate/common/ir_fusion/allreduce_fusion.h" +#include "pre_activate/pass/allreduce_fusion.h" #include "pre_activate/ascend/ir_fusion/square_sum_fusion.h" #include "pre_activate/ascend/ir_fusion/clip_by_norm_no_div_square_sum_fusion.h" #include "pre_activate/ascend/ir_fusion/lamb_update_with_lr_rule_fusion.h" @@ -37,6 +37,7 @@ #include "pre_activate/ascend/ir_fusion/transpose_reshape_fusion.h" #include "pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h" #include "pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.h" +#include "pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.h" #include "pre_activate/ascend/ir_fusion/transpose_transdata_fusion.h" #include "pre_activate/ascend/ir_fusion/transdata_split.h" #include "pre_activate/ascend/ir_fission/topk_split.h" @@ -58,7 +59,10 @@ #include "pre_activate/ascend/ir_fission/add_memcpy_async.h" #include "pre_activate/ascend/format_type/insert_cast_for_runop.h" #include "pre_activate/ascend/format_type/insert_transdata_for_runop.h" +#include "pre_activate/ascend/enhancer/getnext_memcpy_elimination.h" +#include "pre_activate/ascend/ir_fission/addn_fission.h" #include "utils/context/ms_context.h" +#include "utils/config_manager.h" #include "debug/anf_ir_dump.h" #include "debug/anf_ir_utils.h" @@ -90,6 +94,7 @@ void RunOpAscendMixPrecision(const std::shared_ptr &kernel mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); + mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); @@ -110,8 +115,8 @@ void AscendDataLayout(const std::shared_ptr &kernel_graph) data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); - data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); + data_layout_pm->AddPass(std::make_shared()); optimizer->AddPassManager(data_layout_pm); (void)optimizer->Optimize(kernel_graph); kernel_graph->SetExecOrderByDefault(); @@ -126,6 +131,7 @@ void AscendMixPrecision(const std::shared_ptr &kernel_grap mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); + mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); mixed_precision_pm->AddPass(std::make_shared()); @@ -175,6 +181,7 @@ void AscendBackendIRFusionOptimization(const std::shared_ptrAddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); + ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); } @@ -237,9 +244,13 @@ void AscendBackendOptimization(const std::shared_ptr &kern auto optimizer = std::make_shared(); auto other_pm = std::make_shared("other_pm"); other_pm->AddPass(std::make_shared()); + other_pm->AddPass(std::make_shared()); other_pm->AddPass(std::make_shared()); other_pm->AddPass(std::make_shared()); other_pm->AddPass(std::make_shared()); + if (context_ptr->enable_task_sink() && context_ptr->loop_sink_flag() && ConfigManager::GetInstance().iter_num() > 1) { + other_pm->AddPass(std::make_shared()); + } other_pm->AddPass(std::make_shared()); optimizer->AddPassManager(other_pm); (void)optimizer->Optimize(kernel_graph); diff --git a/mindspore/ccsrc/pre_activate/ascend/ascend_helper.cc b/mindspore/ccsrc/pre_activate/ascend/ascend_helper.cc index 7f11c8f2c7..fbb3e345df 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ascend_helper.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ascend_helper.cc @@ -18,20 +18,22 @@ #include #include "common/trans.h" #include "common/utils.h" +#include "pre_activate/common/helper.h" +#include "utils/utils.h" #include "device/kernel_info.h" #include "kernel/oplib/oplib.h" #include "operator/ops.h" #include "session/anf_runtime_algorithm.h" #include "session/kernel_graph.h" #include "utils/context/ms_context.h" -#include "utils/utils.h" namespace mindspore { namespace opt { using KernelBuildInfoBuilder = kernel::KernelBuildInfo::KernelBuildInfoBuilder; namespace { -kernel::KernelBuildInfoPtr CreateKernelBuildInfo(const std::string &input_format, const std::string &output_format, - const AnfNodePtr &node, const kernel::KernelBuildInfo ori_build_info) { +kernel::KernelBuildInfoPtr RefreshKernelBuildInfo(const std::string &input_format, const std::string &output_format, + const AnfNodePtr &node, + const kernel::KernelBuildInfo ori_build_info) { KernelBuildInfoBuilder builder; builder.SetInputsFormat({input_format}); builder.SetOutputsFormat({output_format}); @@ -54,9 +56,11 @@ CNodePtr NewTransOpNode(const FuncGraphPtr &func_graph, const AnfNodePtr &input, CNodePtr trans_node = func_graph->NewCNode(trans_inputs); MS_EXCEPTION_IF_NULL(trans_node); if (need_padding) { - AnfAlgo::SetOutputInferTypeAndShape({AnfAlgo::GetOutputInferDataType(input, 0)}, - {trans::TransShapeTo4d(AnfAlgo::GetOutputInferShape(input, 0))}, - trans_node.get()); + // if need padding we should set the transdata node's shape to the padding shape + AnfAlgo::SetOutputInferTypeAndShape( + {AnfAlgo::GetOutputInferDataType(input, 0)}, + {trans::PaddingShapeTo4d(AnfAlgo::GetOutputInferShape(input, 0), AnfAlgo::GetOutputReshapeType(input, 0))}, + trans_node.get()); } else { AnfAlgo::SetOutputInferTypeAndShape({AnfAlgo::GetOutputInferDataType(input, 0)}, {AnfAlgo::GetOutputInferShape(input, 0)}, trans_node.get()); @@ -92,9 +96,11 @@ AnfNodePtr CreateReshapeNode(const FuncGraphPtr &func_graph, const AnfNodePtr &i AnfNodePtr GetTransInputNodePtr(const FuncGraphPtr &func_graph, const CNodePtr &node, size_t index, const KernelSelectPtr &kernel_select) { MS_EXCEPTION_IF_NULL(node); - bool padding_flag = false; auto input_node = AnfAlgo::GetInputNode(node, index); - if (!AnfAlgo::IsFeatureMapInput(node, index)) { + auto node_with_index = AnfAlgo::VisitKernel(input_node, 0); + MS_EXCEPTION_IF_NULL(node_with_index.first); + auto real_input = node_with_index.first; + if (real_input->isa() || real_input->isa()) { input_node = InsertTransOpForOutput(func_graph, input_node, kernel_select); MS_EXCEPTION_IF_NULL(input_node); AnfAlgo::SetNodeInput(node, input_node, index); @@ -106,33 +112,11 @@ AnfNodePtr GetTransInputNodePtr(const FuncGraphPtr &func_graph, const CNodePtr & std::vector origin_shape = AnfAlgo::GetPrevNodeOutputInferShape(node, index); std::string origin_format = kOpFormat_DEFAULT; std::string dest_format = AnfAlgo::GetInputFormat(node, index); - if (dest_format == kOpFormat_C1HWNCoC0) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, node, kernel_select, index, padding_flag, - origin_format, dest_format, kTransDataOpName, true); - MS_EXCEPTION_IF_NULL(replace_input); - return replace_input; - } - if (dest_format == kOpFormat_NC1HWC0 && origin_shape.size() > 1) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, node, kernel_select, index, padding_flag, - origin_format, dest_format, kTransDataOpName, true); - MS_EXCEPTION_IF_NULL(replace_input); - MS_LOG(DEBUG) << "Inserted Translate45, index: " << index; - return replace_input; - } else if (dest_format == kOpFormat_FRAC_NZ) { - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, node, kernel_select, index, padding_flag, - origin_format, dest_format, kTransDataOpName, true); - MS_EXCEPTION_IF_NULL(replace_input); - MS_LOG(DEBUG) << "inserted translate " << AnfAlgo::GetInputFormat(node, index) << " To default, index: " << index; - return replace_input; - } else if (dest_format == kOpFormat_FRAC_Z && !origin_shape.empty()) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, node, kernel_select, index, padding_flag, - origin_format, dest_format, kTransDataOpName, true); - MS_EXCEPTION_IF_NULL(replace_input); - MS_LOG(DEBUG) << "Inserted Translate45, index: " << index; - return replace_input; + if (kNeedTransFormatSet.find(dest_format) != kNeedTransFormatSet.end() && origin_shape.size() > 1) { + MS_LOG(DEBUG) << node->DebugString() << "Insert transdata " << AnfAlgo::GetInputFormat(node, index) + << " To DefaultFormat , index: " << index; + return AddTransOpNodeToGraph(func_graph, node, kernel_select, index, origin_format, dest_format, kTransDataOpName, + true); } return input_node; } @@ -140,7 +124,6 @@ AnfNodePtr GetTransInputNodePtr(const FuncGraphPtr &func_graph, const CNodePtr & AnfNodePtr InsertTransOpForSingleOutput(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const KernelSelectPtr &kernel_select) { MS_EXCEPTION_IF_NULL(node); - bool padding_flag = false; std::string output_format; std::vector origin_shape; if (!AnfAlgo::IsRealKernel(node)) { @@ -156,46 +139,14 @@ AnfNodePtr InsertTransOpForSingleOutput(const FuncGraphPtr &func_graph, const An } std::string origin_format = output_format; std::string dest_format = kOpFormat_DEFAULT; - if (output_format == kOpFormat_C1HWNCoC0) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, node, kernel_select, 0, padding_flag, origin_format, - dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_input); - return replace_input; - } - if (output_format == kOpFormat_NC1HWC0 && origin_shape.size() > 1) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, node, kernel_select, 0, padding_flag, origin_format, - dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Trans54"; - return replace_output; - } else if (output_format == kOpFormat_FRAC_NZ) { - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, node, kernel_select, 0, padding_flag, origin_format, - dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Translate " << output_format << " To default, index: 0"; - return replace_output; - } else if (output_format == kOpFormat_FRAC_Z && !origin_shape.empty()) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, node, kernel_select, 0, padding_flag, origin_format, - dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Trans54"; - return replace_output; + if (kNeedTransFormatSet.find(output_format) != kNeedTransFormatSet.end() && origin_shape.size() > 1) { + MS_LOG(DEBUG) << "Inserted Transdata " << output_format << " To default , index :0"; + return AddTransOpNodeToGraph(func_graph, node, kernel_select, 0, origin_format, dest_format, kTransDataOpName, + false); } return node; } -void GetTransDataInputFormat(const AnfNodePtr &node, size_t idx, std::string *input_format) { - MS_EXCEPTION_IF_NULL(input_format); - if (AnfAlgo::IsRealKernel(node)) { - *input_format = AnfAlgo::GetOutputFormat(node, idx); - } else { - *input_format = AnfAlgo::GetPrevNodeOutputFormat(node, 0); - } -} - AnfNodePtr InsertTransOpForMultipleOutput(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const KernelSelectPtr &kernel_select) { MS_EXCEPTION_IF_NULL(func_graph); @@ -203,46 +154,17 @@ AnfNodePtr InsertTransOpForMultipleOutput(const FuncGraphPtr &func_graph, const std::vector make_tuple_inputs; make_tuple_inputs.push_back(NewValueNode(prim::kPrimMakeTuple)); for (size_t output_idx = 0; output_idx < AnfAlgo::GetOutputTensorNum(node); ++output_idx) { - bool padding_flag = false; - - std::string output_format; - GetTransDataInputFormat(node, output_idx, &output_format); + std::string output_format = AnfAlgo::GetOutputFormat(node, output_idx); if (output_format == kOpFormat_NC1KHKWHWC0) { - MS_LOG(EXCEPTION) << "got the hw format" << output_format << " when insert the transdata node " + MS_LOG(EXCEPTION) << "Got the special format" << output_format << " when insert the transdata node " << node->DebugString(); } auto tuple_getitem = CreatTupleGetItemNode(func_graph, node, output_idx); std::vector origin_shape = AnfAlgo::GetOutputInferShape(node, output_idx); - std::string origin_format = output_format; std::string dest_format = kOpFormat_DEFAULT; - if (output_format == kOpFormat_C1HWNCoC0) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_input = AddTransOpNodeToGraph(func_graph, tuple_getitem, kernel_select, 0, padding_flag, - origin_format, dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_input); - return replace_input; - } - if (output_format == kOpFormat_NC1HWC0 && origin_shape.size() > 1) { - padding_flag = (origin_shape.size() != kShape4dDims); - // Insert a 5to4 trans op. - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, tuple_getitem, kernel_select, 0, padding_flag, - origin_format, dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Translate54"; - make_tuple_inputs.push_back(replace_output); - } else if (output_format == kOpFormat_FRAC_NZ) { - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, tuple_getitem, kernel_select, 0, padding_flag, - origin_format, dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Translate " << output_format << " To default, index: " << output_idx; - make_tuple_inputs.push_back(replace_output); - } else if (output_format == kOpFormat_FRAC_Z && !origin_shape.empty()) { - padding_flag = (origin_shape.size() != kShape4dDims); - AnfNodePtr replace_output = AddTransOpNodeToGraph(func_graph, tuple_getitem, kernel_select, 0, padding_flag, - origin_format, dest_format, kTransDataOpName, false); - MS_EXCEPTION_IF_NULL(replace_output); - MS_LOG(DEBUG) << "Inserted Translate54"; - make_tuple_inputs.push_back(replace_output); + if (kNeedTransFormatSet.find(output_format) != kNeedTransFormatSet.end() && origin_shape.size() > 1) { + make_tuple_inputs.emplace_back(AddTransOpNodeToGraph(func_graph, tuple_getitem, kernel_select, 0, output_format, + dest_format, kTransDataOpName, false)); } else { // No need insert trans op. make_tuple_inputs.push_back(tuple_getitem); @@ -253,16 +175,17 @@ AnfNodePtr InsertTransOpForMultipleOutput(const FuncGraphPtr &func_graph, const } } // namespace AnfNodePtr AddTransOpNodeToGraph(const FuncGraphPtr &func_graph, const AnfNodePtr &node, - const KernelSelectPtr &kernel_select, size_t insert_index, const bool padding_flag, + const KernelSelectPtr &kernel_select, size_t insert_index, const std::string &origin_format, const std::string &dest_format, const std::string &op_name, bool is_insert_input) { AnfNodePtr trans_node = nullptr; - AnfNodePtr input_node = nullptr; + AnfNodePtr input_node = node; AnfNodePtr trans_data = nullptr; MS_EXCEPTION_IF_NULL(node); if (origin_format.empty() || dest_format.empty()) { MS_LOG(EXCEPTION) << "trans op format is error, origin = " << origin_format << ", dest " << origin_format; } + // if insert transdata for input we need to change the input if (is_insert_input) { if (!node->isa()) { MS_LOG(EXCEPTION) << "cannot insert a transdata node to a node's input which the node is not a cnode"; @@ -270,29 +193,34 @@ AnfNodePtr AddTransOpNodeToGraph(const FuncGraphPtr &func_graph, const AnfNodePt auto cnode = node->cast(); MS_EXCEPTION_IF_NULL(cnode); input_node = AnfAlgo::GetInputNode(cnode, insert_index); - if (padding_flag) { - auto padd_shape = trans::TransShapeTo4d(AnfAlgo::GetOutputInferShape(input_node, 0)); - auto reshape_node = CreateReshapeNode(func_graph, input_node, kernel_select, padd_shape); - trans_data = NewTransOpNode(func_graph, reshape_node, kernel_select, padding_flag, op_name); - } else { - trans_data = NewTransOpNode(func_graph, input_node, kernel_select, padding_flag, op_name); - } + } + bool need_padding = (trans::IsNeedPadding(dest_format, AnfAlgo::GetOutputInferShape(input_node, 0).size()) && + op_name == kTransDataOpName); + if (!need_padding) { + // don't need padding insert transdata only + trans_data = NewTransOpNode(func_graph, input_node, kernel_select, need_padding, op_name); + trans_node = trans_data; + } else if (is_insert_input) { + // if need padding & is input need insert a transdata + // reshape[padding shape] -> transdata[padding shape] -> node + auto padding_shape = + trans::PaddingShapeTo4d(AnfAlgo::GetOutputInferShape(input_node, 0), AnfAlgo::GetInputReshapeType(node, 0)); + auto reshape_node = CreateReshapeNode(func_graph, input_node, kernel_select, padding_shape); + trans_data = NewTransOpNode(func_graph, reshape_node, kernel_select, need_padding, op_name); trans_node = trans_data; } else { - input_node = node; - trans_data = NewTransOpNode(func_graph, input_node, kernel_select, padding_flag, op_name); - if (padding_flag) { - auto reshape_node = - CreateReshapeNode(func_graph, trans_data, kernel_select, AnfAlgo::GetOutputInferShape(input_node, 0)); - trans_node = reshape_node; - } else { - trans_node = trans_data; - } + // if need padding & is output need insert a transdata + // node -> transdata[padding shape] -> reshape[ori_shape] + trans_data = NewTransOpNode(func_graph, input_node, kernel_select, need_padding, op_name); + auto reshape_node = + CreateReshapeNode(func_graph, trans_data, kernel_select, AnfAlgo::GetOutputInferShape(input_node, 0)); + trans_node = reshape_node; } + // refresh the transdata's format to ori format & dst format MS_EXCEPTION_IF_NULL(trans_data); MS_EXCEPTION_IF_NULL(trans_data->kernel_info()); auto trans_ori_build_info = trans_data->kernel_info()->select_kernel_build_info(); - auto kernel_build_info = CreateKernelBuildInfo(origin_format, dest_format, input_node, *trans_ori_build_info); + auto kernel_build_info = RefreshKernelBuildInfo(origin_format, dest_format, input_node, *trans_ori_build_info); AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info, trans_data.get()); return trans_node; } @@ -376,7 +304,17 @@ CNodePtr InsertCastForInput(const FuncGraphPtr &func_graph, const CNodePtr &cnod for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(cnode); ++input_index) { TypeId origin_type; auto cur_input = AnfAlgo::GetInputNode(cnode, input_index); - if (!AnfAlgo::IsFeatureMapInput(cnode, input_index)) { + auto kernel_with_index = AnfAlgo::VisitKernel(cur_input, 0); + auto is_weight_boundary = [](const AnfNodePtr &node) -> bool { + if (node->isa()) { + return true; + } else if (node->isa() && AnfAlgo::IsParameterWeight(node->cast())) { + return true; + } + return false; + }; + auto real_input_node = kernel_with_index.first; + if (is_weight_boundary(real_input_node)) { // weight origin_type = AnfAlgo::GetPrevNodeOutputDeviceDataType(cnode, input_index); } else { @@ -409,19 +347,16 @@ CNodePtr InsertCastForInput(const FuncGraphPtr &func_graph, const CNodePtr &cnod return new_node; } -AnfNodePtr CreatTupleGetItemNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, size_t output_idx) { - auto idx = NewValueNode(SizeToInt(output_idx)); - MS_EXCEPTION_IF_NULL(idx); - auto imm = std::make_shared(SizeToInt(output_idx)); - auto abstract_scalar = std::make_shared(imm); - idx->set_abstract(abstract_scalar); - AnfNodePtr tuple_getitem = func_graph->NewCNode({NewValueNode(prim::kPrimTupleGetItem), node, idx}); - MS_EXCEPTION_IF_NULL(tuple_getitem); - tuple_getitem->set_scope(node->scope()); - std::vector origin_shape = AnfAlgo::GetOutputInferShape(node, output_idx); - TypeId origin_type = AnfAlgo::GetOutputInferDataType(node, output_idx); - AnfAlgo::SetOutputInferTypeAndShape({origin_type}, {origin_shape}, tuple_getitem.get()); - return tuple_getitem; +AnfNodePtr CreateMemcpyAsyncOp(const FuncGraphPtr &graph, const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(node); + auto prim = std::make_shared(kMemCpyAsyncOpName); + std::vector new_node_inputs = {NewValueNode(prim), node}; + auto new_node = graph->NewCNode(new_node_inputs); + MS_EXCEPTION_IF_NULL(new_node); + new_node->set_abstract(node->abstract()); + new_node->set_scope(node->scope()); + return new_node; } } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ascend_helper.h b/mindspore/ccsrc/pre_activate/ascend/ascend_helper.h index b605d700c3..a8fd7dc514 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ascend_helper.h +++ b/mindspore/ccsrc/pre_activate/ascend/ascend_helper.h @@ -48,7 +48,7 @@ class KernelQuery { using KernelQueryPtr = std::shared_ptr; AnfNodePtr AddTransOpNodeToGraph(const FuncGraphPtr &func_graph, const AnfNodePtr &node, - const KernelSelectPtr &kernel_select, size_t insert_index, bool padding_flag, + const KernelSelectPtr &kernel_select, size_t insert_index, const std::string &origin_format, const std::string &dest_format, const std::string &op_name, bool is_insert_input); @@ -64,7 +64,7 @@ AnfNodePtr InsertTransOpForOutput(const FuncGraphPtr &func_graph, const AnfNodeP CNodePtr InsertCastForInput(const FuncGraphPtr &func_graph, const CNodePtr &cnode); -AnfNodePtr CreatTupleGetItemNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, size_t output_idx); +AnfNodePtr CreateMemcpyAsyncOp(const FuncGraphPtr &graph, const AnfNodePtr &node); } // namespace opt } // namespace mindspore #endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ASCEND_HELPER_H_ diff --git a/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc b/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc new file mode 100644 index 0000000000..a39918ecee --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc @@ -0,0 +1,72 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pre_activate/ascend/enhancer/getnext_memcpy_elimination.h" +#include +#include "session/anf_runtime_algorithm.h" +#include "optimizer/opt.h" + +namespace mindspore::opt { + +const BaseRef GetnextMemcpyElimination::DefinePattern() const { + auto prim_memcpy = std::make_shared(kMemCpyAsyncOpName); + VarPtr x = std::make_shared(); + VectorRef memcpy_async({prim_memcpy, x}); + return memcpy_async; +} + +const AnfNodePtr GetnextMemcpyElimination::Process(const FuncGraphPtr &graph, const AnfNodePtr &node, + const EquivPtr &equiv) const { + if (graph == nullptr || node == nullptr || equiv == nullptr) { + return nullptr; + } + auto memcpy_cnode = node->cast(); + if (memcpy_cnode == nullptr) { + return nullptr; + } + + // 1. memcpy has attr kAttrLabelForInsertStreamActive + if (!AnfAlgo::HasNodeAttr(kAttrLabelForInsertStreamActive, node)) { + MS_LOG(DEBUG) << "node has no label_for_insert_stream_active attr"; + return nullptr; + } + + // 2. memcpy's output has only one user next_node + auto manager = graph->manager(); + MS_EXCEPTION_IF_NULL(manager); + if (manager->node_users().find(memcpy_cnode) == manager->node_users().end()) { + MS_LOG(EXCEPTION) << "memcpy has no output in manager"; + } + auto next_nodes = manager->node_users()[memcpy_cnode]; + if (next_nodes.size() > 1) { + MS_LOG(DEBUG) << "node's output has more than one users"; + return nullptr; + } + + // 3. next_node has only one input which is memcpy's output + for (auto &item : next_nodes) { + auto next_node = item.first->cast(); + if (next_node->inputs().size() != 2) { + MS_LOG(DEBUG) << "next node has more than one input"; + return nullptr; + } + // add attr label_for_insert_stream_active for next_node + AnfAlgo::SetNodeAttr(kAttrLabelForInsertStreamActive, MakeValue(true), next_node); + } + + return memcpy_cnode->input(1); +} +} // namespace mindspore::opt diff --git a/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.h b/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.h new file mode 100644 index 0000000000..523fc87a38 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.h @@ -0,0 +1,33 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_GETNEXT_MEMCPY_ELIMINATION_H +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_GETNEXT_MEMCPY_ELIMINATION_H + +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +class GetnextMemcpyElimination : public PatternProcessPass { + public: + explicit GetnextMemcpyElimination(bool multigraph = true) + : PatternProcessPass("getnext_memcpy_elimination", multigraph) {} + ~GetnextMemcpyElimination() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_GETNEXT_MEMCPY_ELIMINATION_H diff --git a/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc b/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc new file mode 100644 index 0000000000..fb8b19047c --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc @@ -0,0 +1,75 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.h" +#include +#include +#include "pre_activate/ascend/ascend_helper.h" +#include "pre_activate/common/helper.h" +#include "session/anf_runtime_algorithm.h" + +namespace mindspore { +namespace opt { +AnfNodePtr InsertMemcpyAsyncForGetNextOutputs(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { + if (func_graph == nullptr || node == nullptr) { + return nullptr; + } + + size_t output_num = AnfAlgo::GetOutputTensorNum(node); + if (output_num == 0) { + MS_LOG(DEBUG) << "Output number is zero, no need to insert memcpy_async!"; + return node; + } + + // getnext output is tuple and dynamic + std::vector make_tuple_inputs; + make_tuple_inputs.push_back(NewValueNode(prim::kPrimMakeTuple)); + + for (size_t output_index = 0; output_index < output_num; ++output_index) { + auto tuple_get_item = CreatTupleGetItemNode(func_graph, node, output_index); + auto new_node = CreateMemcpyAsyncOp(func_graph, tuple_get_item); + if (new_node == nullptr) { + MS_LOG(EXCEPTION) << "Create memcpy_async op failed!"; + } + AnfAlgo::SetNodeAttr(kAttrLabelForInsertStreamActive, MakeValue(true), new_node); + make_tuple_inputs.push_back(new_node); + } + AnfNodePtr make_tuple = func_graph->NewCNode(make_tuple_inputs); + return make_tuple; +} + +const BaseRef InsertMemcpyAsyncForGetNext::DefinePattern() const { + std::shared_ptr Xs = std::make_shared(); + auto prim = std::make_shared(kGetNextOpName); + + return VectorRef({prim, Xs}); +} + +const AnfNodePtr InsertMemcpyAsyncForGetNext::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, + const EquivPtr &) const { + if (func_graph == nullptr || node == nullptr || !AnfAlgo::IsRealKernel(node)) { + return nullptr; + } + + if (AnfAlgo::HasNodeAttr(kAttrVisited, node)) { + MS_LOG(DEBUG) << "Node op_name[" << kGetNextOpName << "] has visited."; + return nullptr; + } + AnfAlgo::SetNodeAttr(kAttrVisited, MakeValue(true), node); + + return InsertMemcpyAsyncForGetNextOutputs(func_graph, node); +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.h b/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.h new file mode 100644 index 0000000000..eb3b78d33f --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.h @@ -0,0 +1,35 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_INSERT_MEMCPY_ASYNC_FOR_GETNEXT_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_INSERT_MEMCPY_ASYNC_FOR_GETNEXT_H_ + +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +class InsertMemcpyAsyncForGetNext : public PatternProcessPass { + public: + explicit InsertMemcpyAsyncForGetNext(bool multigraph = true) + : PatternProcessPass("insert_memcpy_async_for_getnext", multigraph) {} + ~InsertMemcpyAsyncForGetNext() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_INSERT_MEMCPY_ASYNC_FOR_GETNEXT_H_ diff --git a/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.cc b/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.cc index fd20611415..83a44029a7 100644 --- a/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.cc +++ b/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.cc @@ -22,6 +22,7 @@ #include "kernel/oplib/oplib.h" #include "session/anf_runtime_algorithm.h" #include "session/kernel_graph.h" +#include "pre_activate/common/helper.h" namespace mindspore { namespace opt { @@ -100,14 +101,12 @@ AnfNodePtr AddAdditionalToRefOutput(const FuncGraphPtr &func_graph, const CNodeP auto origin_type = AnfAlgo::GetOutputDeviceDataType(origin_pair.first, origin_pair.second); auto cur_format = AnfAlgo::GetOutputFormat(cnode, output_index); auto cur_type = AnfAlgo::GetOutputDeviceDataType(cnode, output_index); - auto cur_shape = AnfAlgo::GetOutputInferShape(cnode, 0); + auto cur_shape = AnfAlgo::GetOutputInferShape(cnode, output_index); // insert trans - if (origin_format != cur_format) { + if (origin_format != cur_format && cur_shape.size() > 1) { auto kernel_select = std::make_shared(); - bool need_padding = - (cur_format == kOpFormat_NC1HWC0 && AnfAlgo::GetOutputInferShape(final_node, 0).size() != kShape4dDims); - final_node = AddTransOpNodeToGraph(func_graph, final_node, kernel_select, 0, need_padding, cur_format, - origin_format, kTransDataOpName, false); + final_node = AddTransOpNodeToGraph(func_graph, final_node, kernel_select, 0, cur_format, origin_format, + kTransDataOpName, false); final_index = 0; MS_EXCEPTION_IF_NULL(final_node); MS_LOG(INFO) << "DealRefTransAndCast add trans op, op debug info is " << final_node->DebugString(); @@ -168,11 +167,18 @@ AnfNodePtr DealRefSigleOutput(const FuncGraphPtr &func_graph, const CNodePtr &cn } } // namespace +const BaseRef DealRefTransAndCast::DefinePattern() const { + VarPtr V = std::make_shared(UnVisited); + VarPtr Xs = std::make_shared(); + return VectorRef({V, Xs}); +} + const AnfNodePtr DealRefTransAndCast::Process(const FuncGraphPtr &graph, const AnfNodePtr &node, const EquivPtr &) const { if (node == nullptr || !node->isa()) { return nullptr; } + AnfAlgo::SetNodeAttr(kAttrVisited, MakeValue(true), node); auto cnode = node->cast(); MS_EXCEPTION_IF_NULL(cnode); if (!AnfAlgo::IsRealCNodeKernel(cnode)) { diff --git a/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.h b/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.h index 9ed55d8b29..1b54a7b111 100644 --- a/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.h +++ b/mindspore/ccsrc/pre_activate/ascend/format_type/deal_ref_trans_and_cast.h @@ -28,6 +28,7 @@ class DealRefTransAndCast : public PatternProcessPass { public: explicit DealRefTransAndCast(bool multigraph = true) : PatternProcessPass("deal_ref_trans_and_cast", multigraph) {} ~DealRefTransAndCast() override = default; + const BaseRef DefinePattern() const override; const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; }; } // namespace opt diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fission/add_memcpy_async.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fission/add_memcpy_async.cc index 2ab11b6032..bbea944750 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fission/add_memcpy_async.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fission/add_memcpy_async.cc @@ -18,22 +18,11 @@ #include "utils/utils.h" #include "session/anf_runtime_algorithm.h" #include "optimizer/opt.h" +#include "pre_activate/ascend/ascend_helper.h" namespace mindspore { namespace opt { namespace { -AnfNodePtr CreateMemcpyAsyncOp(const FuncGraphPtr &graph, const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(graph); - MS_EXCEPTION_IF_NULL(node); - auto prim = std::make_shared(kMemCpyAsyncOpName); - std::vector new_node_inputs = {NewValueNode(prim), node}; - auto new_node = graph->NewCNode(new_node_inputs); - MS_EXCEPTION_IF_NULL(new_node); - new_node->set_abstract(node->abstract()); - new_node->set_scope(node->scope()); - return new_node; -} - const AnfNodePtr AddMemcpyAsyncIfInputIsUsedByOthers(const FuncGraphPtr &graph, const CNodePtr &node) { MS_EXCEPTION_IF_NULL(graph); MS_EXCEPTION_IF_NULL(node); diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.cc new file mode 100644 index 0000000000..f6eb6aca64 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.cc @@ -0,0 +1,81 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/ascend/ir_fission/addn_fission.h" +#include +#include +#include "session/anf_runtime_algorithm.h" + +namespace mindspore { +namespace opt { +namespace { +AnfNodePtr CreateNewAddn(const FuncGraphPtr &func_graph, const CNodePtr &origin_addn_cnode, size_t begin_index, + size_t offset) { + MS_EXCEPTION_IF_NULL(func_graph); + MS_EXCEPTION_IF_NULL(origin_addn_cnode); + std::vector new_addn_inputs{NewValueNode(std::make_shared(prim::kPrimAddN->name()))}; + for (size_t i = begin_index; i < begin_index + offset; ++i) { + new_addn_inputs.push_back(origin_addn_cnode->input(i)); + } + CNodePtr new_addn = func_graph->NewCNode(new_addn_inputs); + MS_EXCEPTION_IF_NULL(new_addn); + new_addn->set_scope(origin_addn_cnode->scope()); + new_addn->set_abstract(origin_addn_cnode->abstract()); + AnfAlgo::SetNodeAttr(kAttrN, MakeValue(SizeToInt(offset)), new_addn); + return new_addn; +} +} // namespace + +const BaseRef AddnFission::DefinePattern() const { + VarPtr Xs = std::make_shared(); + return VectorRef({prim::kPrimAddN, Xs}); +} + +const AnfNodePtr AddnFission::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const EquivPtr &) const { + MS_EXCEPTION_IF_NULL(func_graph); + MS_EXCEPTION_IF_NULL(node); + auto cnode = node->cast(); + MS_EXCEPTION_IF_NULL(cnode); + // The real input begins with index 1. + size_t origin_input_size = cnode->inputs().size() - 1; + if (origin_input_size <= inputs_divisor_) { + return nullptr; + } + CNodePtr new_cnode = cnode; + while (origin_input_size > inputs_divisor_) { + std::vector base_addn_inputs{NewValueNode(std::make_shared(prim::kPrimAddN->name()))}; + size_t cur_input_index = 1; + // Divide the inputs of addn by 63. + while (origin_input_size - cur_input_index + 1 > inputs_divisor_) { + base_addn_inputs.push_back(CreateNewAddn(func_graph, new_cnode, cur_input_index, inputs_divisor_)); + cur_input_index += inputs_divisor_; + } + base_addn_inputs.push_back( + CreateNewAddn(func_graph, new_cnode, cur_input_index, origin_input_size - cur_input_index + 1)); + + CNodePtr base_addn = func_graph->NewCNode(base_addn_inputs); + MS_EXCEPTION_IF_NULL(base_addn); + MS_EXCEPTION_IF_NULL(new_cnode); + base_addn->set_scope(new_cnode->scope()); + base_addn->set_abstract(new_cnode->abstract()); + AnfAlgo::SetNodeAttr(kAttrN, MakeValue(SizeToInt(base_addn_inputs.size() - 1)), base_addn); + new_cnode = base_addn; + origin_input_size = base_addn->inputs().size() - 1; + } + + return new_cnode; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.h b/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.h new file mode 100644 index 0000000000..3c62391f9a --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fission/addn_fission.h @@ -0,0 +1,37 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FISSION_ADDN_FISSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FISSION_ADDN_FISSION_H_ + +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +constexpr size_t kAddnInputsDivisor = 63; +class AddnFission : public PatternProcessPass { + public: + explicit AddnFission(bool multigraph = true) + : PatternProcessPass("addn_fission", multigraph), inputs_divisor_(kAddnInputsDivisor) {} + ~AddnFission() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; + + private: + size_t inputs_divisor_; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FISSION_ADDN_FISSION_H_ diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.cc index 1ecf4bbd06..4645167191 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.cc @@ -15,43 +15,9 @@ */ #include "pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h" #include "pre_activate/common/helper.h" -#include "utils/utils.h" namespace mindspore { namespace opt { -namespace { -void GetAdd0AndAdd1(const AnfNodePtr &sub0, AnfNodePtr *add0, AnfNodePtr *add1) { - MS_EXCEPTION_IF_NULL(sub0); - MS_EXCEPTION_IF_NULL(add0); - MS_EXCEPTION_IF_NULL(add1); - auto sub0_cnode = sub0->cast(); - MS_EXCEPTION_IF_NULL(sub0_cnode); - CheckCNodeInputSize(sub0_cnode, kSubInputNum); - AnfNodePtr mul4 = sub0_cnode->input(2); - MS_EXCEPTION_IF_NULL(mul4); - auto mul4_cnode = mul4->cast(); - MS_EXCEPTION_IF_NULL(mul4_cnode); - CheckCNodeInputSize(mul4_cnode, kMulInputNum); - AnfNodePtr true_div0 = mul4_cnode->input(2); - MS_EXCEPTION_IF_NULL(true_div0); - auto true_div0_cnode = true_div0->cast(); - MS_EXCEPTION_IF_NULL(true_div0_cnode); - CheckCNodeInputSize(true_div0_cnode, kRealDivInputNum); - *add0 = true_div0_cnode->input(1); - AnfNodePtr add2 = true_div0_cnode->input(2); - MS_EXCEPTION_IF_NULL(add2); - auto add2_cnode = add2->cast(); - MS_EXCEPTION_IF_NULL(add2_cnode); - CheckCNodeInputSize(add2_cnode, kAddInputNum); - AnfNodePtr sqrt0 = add2_cnode->input(1); - MS_EXCEPTION_IF_NULL(sqrt0); - auto sqrt0_cnode = sqrt0->cast(); - MS_EXCEPTION_IF_NULL(sqrt0_cnode); - CheckCNodeInputSize(sqrt0_cnode, kSqrtInputNum); - *add1 = sqrt0_cnode->input(1); -} -} // namespace - AnfNodePtr AdamApplyOneFusion::CreateAdamApplyOneNode(const FuncGraphPtr &func_graph, const EquivPtr &equiv) const { MS_EXCEPTION_IF_NULL(func_graph); MS_EXCEPTION_IF_NULL(equiv); @@ -76,17 +42,69 @@ AnfNodePtr AdamApplyOneFusion::CreateAdamApplyOneNode(const FuncGraphPtr &func_g const BaseRef AdamApplyOneFusion::DefinePattern() const { const auto prim_sqrt = std::make_shared(kSqrtOpName); - const auto prim_deal_div = std::make_shared(kRealDivOpName); + const auto prim_real_div = std::make_shared(kRealDivOpName); VectorRef mul2 = VectorRef({prim::kPrimMul, mul_x_input_vars_[2], input_vars_[1]}); VectorRef mul3 = VectorRef({prim::kPrimMul, mul_x_input_vars_[3], VectorRef({prim::kPrimSquare, input_vars_[0]})}); - VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({prim::kPrimTensorAdd, mul2, mul3})}); + VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({add1_var_, mul2, mul3})}); VectorRef mul1 = VectorRef({prim::kPrimMul, mul_x_input_vars_[1], input_vars_[0]}); VectorRef mul0 = VectorRef({prim::kPrimMul, mul_x_input_vars_[0], input_vars_[2]}); - VectorRef add0 = VectorRef({prim::kPrimTensorAdd, mul0, mul1}); - VectorRef true_div0 = VectorRef({prim_deal_div, add0, VectorRef({prim::kPrimTensorAdd, sqrt0, add2_y_})}); + VectorRef add0 = VectorRef({add0_var_, mul0, mul1}); + VectorRef true_div0 = VectorRef({prim_real_div, add0, VectorRef({prim::kPrimTensorAdd, sqrt0, add2_y_})}); return VectorRef({prim::kPrimSub, input_vars_[3], VectorRef({prim::kPrimMul, input_vars_[4], true_div0})}); } +const BaseRef AdamApplyOneCond1Fusion::DefinePattern() const { + const auto prim_sqrt = std::make_shared(kSqrtOpName); + const auto prim_real_div = std::make_shared(kRealDivOpName); + VectorRef mul2 = VectorRef({prim::kPrimMul, mul_x_input_vars_[2], input_vars_[1]}); + VectorRef mul3 = VectorRef({prim::kPrimMul, mul_x_input_vars_[3], VectorRef({prim::kPrimSquare, input_vars_[0]})}); + VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({add1_var_, mul2, mul3})}); + VectorRef mul1 = VectorRef({prim::kPrimMul, mul_x_input_vars_[1], input_vars_[0]}); + VectorRef mul0 = VectorRef({prim::kPrimMul, mul_x_input_vars_[0], input_vars_[2]}); + VectorRef add0 = VectorRef({add0_var_, mul0, mul1}); + VectorRef true_div0 = VectorRef({prim_real_div, add0, VectorRef({prim::kPrimTensorAdd, add2_y_, sqrt0})}); + return VectorRef({prim::kPrimSub, input_vars_[3], VectorRef({prim::kPrimMul, input_vars_[4], true_div0})}); +} + +const BaseRef AdamApplyOneCond2Fusion::DefinePattern() const { + const auto prim_sqrt = std::make_shared(kSqrtOpName); + const auto prim_real_div = std::make_shared(kRealDivOpName); + VectorRef mul2 = VectorRef({prim::kPrimMul, mul_x_input_vars_[2], input_vars_[1]}); + VectorRef mul3 = VectorRef({prim::kPrimMul, VectorRef({prim::kPrimSquare, input_vars_[0]}), mul_x_input_vars_[3]}); + VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({add1_var_, mul2, mul3})}); + VectorRef mul1 = VectorRef({prim::kPrimMul, mul_x_input_vars_[1], input_vars_[0]}); + VectorRef mul0 = VectorRef({prim::kPrimMul, mul_x_input_vars_[0], input_vars_[2]}); + VectorRef add0 = VectorRef({add0_var_, mul0, mul1}); + VectorRef true_div0 = VectorRef({prim_real_div, add0, VectorRef({prim::kPrimTensorAdd, sqrt0, add2_y_})}); + return VectorRef({prim::kPrimSub, input_vars_[3], VectorRef({prim::kPrimMul, true_div0, input_vars_[4]})}); +} + +const BaseRef AdamApplyOneCond3Fusion::DefinePattern() const { + const auto prim_sqrt = std::make_shared(kSqrtOpName); + const auto prim_real_div = std::make_shared(kRealDivOpName); + VectorRef mul2 = VectorRef({prim::kPrimMul, mul_x_input_vars_[2], input_vars_[1]}); + VectorRef mul3 = VectorRef({prim::kPrimMul, mul_x_input_vars_[3], VectorRef({prim::kPrimSquare, input_vars_[0]})}); + VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({add1_var_, mul2, mul3})}); + VectorRef mul1 = VectorRef({prim::kPrimMul, mul_x_input_vars_[1], input_vars_[0]}); + VectorRef mul0 = VectorRef({prim::kPrimMul, mul_x_input_vars_[0], input_vars_[2]}); + VectorRef add0 = VectorRef({add0_var_, mul0, mul1}); + VectorRef true_div0 = VectorRef({prim_real_div, add0, VectorRef({prim::kPrimTensorAdd, sqrt0, add2_y_})}); + return VectorRef({prim::kPrimSub, input_vars_[3], VectorRef({prim::kPrimMul, true_div0, input_vars_[4]})}); +} + +const BaseRef AdamApplyOneCond4Fusion::DefinePattern() const { + const auto prim_sqrt = std::make_shared(kSqrtOpName); + const auto prim_real_div = std::make_shared(kRealDivOpName); + VectorRef mul2 = VectorRef({prim::kPrimMul, mul_x_input_vars_[2], input_vars_[1]}); + VectorRef mul3 = VectorRef({prim::kPrimMul, mul_x_input_vars_[3], VectorRef({prim::kPrimSquare, input_vars_[0]})}); + VectorRef sqrt0 = VectorRef({prim_sqrt, VectorRef({add1_var_, mul2, mul3})}); + VectorRef mul1 = VectorRef({prim::kPrimMul, mul_x_input_vars_[1], input_vars_[0]}); + VectorRef mul0 = VectorRef({prim::kPrimMul, mul_x_input_vars_[0], input_vars_[2]}); + VectorRef add0 = VectorRef({add0_var_, mul0, mul1}); + VectorRef true_div0 = VectorRef({prim_real_div, add0, VectorRef({prim::kPrimTensorAdd, add2_y_, sqrt0})}); + return VectorRef({prim::kPrimSub, input_vars_[3], VectorRef({prim::kPrimMul, true_div0, input_vars_[4]})}); +} + const AnfNodePtr AdamApplyOneFusion::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const EquivPtr &equiv) const { MS_EXCEPTION_IF_NULL(func_graph); @@ -96,10 +114,17 @@ const AnfNodePtr AdamApplyOneFusion::Process(const FuncGraphPtr &func_graph, con new_node->set_scope(node->scope()); // Set abstract of new node AbstractBasePtrList new_node_abstract_list; - AnfNodePtr add0 = nullptr; - AnfNodePtr add1 = nullptr; - GetAdd0AndAdd1(node, &add0, &add1); + auto iter_add0 = (*equiv).find(add0_var_); + if (iter_add0 == (*equiv).end()) { + MS_LOG(EXCEPTION) << "The equiv map is expected to contains the add0 var after matched."; + } + auto iter_add1 = (*equiv).find(add1_var_); + if (iter_add1 == (*equiv).end()) { + MS_LOG(EXCEPTION) << "The equiv map is expected to contains the add1 var after matched."; + } + auto add0 = utils::cast(iter_add0->second); MS_EXCEPTION_IF_NULL(add0); + auto add1 = utils::cast(iter_add1->second); MS_EXCEPTION_IF_NULL(add1); new_node_abstract_list.push_back(add1->abstract()); new_node_abstract_list.push_back(add0->abstract()); diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h index 6642561b07..5ee8a86cfb 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_fusion.h @@ -18,34 +18,77 @@ #include #include +#include #include "pre_activate/common/optimizer.h" +#include "utils/utils.h" namespace mindspore { namespace opt { -constexpr size_t kAdamApplyOneInputNum = 5; -constexpr size_t kAdamApplyOneMulInputNum = 4; +constexpr size_t kAdamApplyOneInputVarNum = 5; +constexpr size_t kAdamApplyOneMulInputVarNum = 4; class AdamApplyOneFusion : public PatternProcessPass { public: - explicit AdamApplyOneFusion(bool multigraph = true) : PatternProcessPass("adam_apply_one_fusion", multigraph) { - for (size_t i = 0; i < kAdamApplyOneInputNum; ++i) { + explicit AdamApplyOneFusion(const std::string &name = "adam_apply_one_fusion", bool multigraph = true) + : PatternProcessPass(name, multigraph) { + for (size_t i = 0; i < kAdamApplyOneInputVarNum; ++i) { input_vars_.push_back(std::make_shared()); } - for (size_t i = 0; i < kAdamApplyOneMulInputNum; ++i) { + for (size_t i = 0; i < kAdamApplyOneMulInputVarNum; ++i) { mul_x_input_vars_.push_back(std::make_shared()); } add2_y_ = std::make_shared(); + add0_var_ = std::make_shared(std::make_shared(prim::kPrimTensorAdd->name())); + add1_var_ = std::make_shared(std::make_shared(prim::kPrimTensorAdd->name())); } ~AdamApplyOneFusion() override = default; const BaseRef DefinePattern() const override; const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; - private: + protected: AnfNodePtr CreateAdamApplyOneNode(const FuncGraphPtr &func_graph, const EquivPtr &equiv) const; std::vector input_vars_; std::vector mul_x_input_vars_; VarPtr add2_y_; + VarPtr add0_var_; + VarPtr add1_var_; +}; + +class AdamApplyOneCond1Fusion : public AdamApplyOneFusion { + public: + explicit AdamApplyOneCond1Fusion(bool multigraph = true) + : AdamApplyOneFusion("adam_apply_one_cond1_fusion", multigraph) {} + + ~AdamApplyOneCond1Fusion() override = default; + const BaseRef DefinePattern() const override; +}; + +class AdamApplyOneCond2Fusion : public AdamApplyOneFusion { + public: + explicit AdamApplyOneCond2Fusion(bool multigraph = true) + : AdamApplyOneFusion("adam_apply_one_cond2_fusion", multigraph) {} + + ~AdamApplyOneCond2Fusion() override = default; + const BaseRef DefinePattern() const override; +}; + +class AdamApplyOneCond3Fusion : public AdamApplyOneFusion { + public: + explicit AdamApplyOneCond3Fusion(bool multigraph = true) + : AdamApplyOneFusion("adam_apply_one_cond3_fusion", multigraph) {} + + ~AdamApplyOneCond3Fusion() override = default; + const BaseRef DefinePattern() const override; +}; + +class AdamApplyOneCond4Fusion : public AdamApplyOneFusion { + public: + explicit AdamApplyOneCond4Fusion(bool multigraph = true) + : AdamApplyOneFusion("adam_apply_one_cond4_fusion", multigraph) {} + + ~AdamApplyOneCond4Fusion() override = default; + const BaseRef DefinePattern() const override; }; } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.cc index 442aa64217..4a2387d3cc 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.cc @@ -17,48 +17,13 @@ #include #include -#include #include "session/anf_runtime_algorithm.h" #include "ir/primitive.h" -#include "utils/utils.h" #include "pre_activate/common/helper.h" namespace mindspore { namespace opt { -namespace { -std::tuple GetAdd0Add1Node(const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(node); - auto sub0 = node->cast(); - MS_EXCEPTION_IF_NULL(sub0); - auto mul5_anf = sub0->input(2); - MS_EXCEPTION_IF_NULL(mul5_anf); - auto mul5 = mul5_anf->cast(); - MS_EXCEPTION_IF_NULL(mul5); - auto add3_anf = mul5->input(2); - MS_EXCEPTION_IF_NULL(add3_anf); - auto add3 = add3_anf->cast(); - MS_EXCEPTION_IF_NULL(add3); - auto real_div0_anf = add3->input(1); - MS_EXCEPTION_IF_NULL(real_div0_anf); - auto real_div0 = real_div0_anf->cast(); - MS_EXCEPTION_IF_NULL(real_div0); - auto add0_anf = real_div0->input(1); - MS_EXCEPTION_IF_NULL(add0_anf); - auto add2_anf = real_div0->input(2); - MS_EXCEPTION_IF_NULL(add2_anf); - auto add2 = add2_anf->cast(); - MS_EXCEPTION_IF_NULL(add2); - auto sqrt0_anf = add2->input(1); - MS_EXCEPTION_IF_NULL(sqrt0_anf); - auto sqrt0 = sqrt0_anf->cast(); - MS_EXCEPTION_IF_NULL(sqrt0); - auto add1_anf = sqrt0->input(1); - MS_EXCEPTION_IF_NULL(add1_anf); - return std::make_tuple(add0_anf, add1_anf); -} -} // namespace - std::vector AdamApplyOneWithDecayRule::GetFusionNodeInputs(const EquivPtr &equiv) const { MS_EXCEPTION_IF_NULL(equiv); auto input0 = utils::cast((*equiv)[input0_]); @@ -82,10 +47,10 @@ const BaseRef AdamApplyOneWithDecayRule::DefinePattern() const { VectorRef mul0_pattern({prim::kPrimMul, mul0_x_, input2_}); VectorRef mul1_pattern({prim::kPrimMul, mul1_x_, input0_}); VectorRef square0_pattern({prim::kPrimSquare, input0_}); - VectorRef add0_pattern({prim::kPrimTensorAdd, mul0_pattern, mul1_pattern}); + VectorRef add0_pattern({add0_var_, mul0_pattern, mul1_pattern}); VectorRef mul2_pattern({prim::kPrimMul, mul2_x_, input1_}); VectorRef mul3_pattern({prim::kPrimMul, mul3_x_, square0_pattern}); - VectorRef add1_pattern({prim::kPrimTensorAdd, mul2_pattern, mul3_pattern}); + VectorRef add1_pattern({add1_var_, mul2_pattern, mul3_pattern}); VectorRef sqrt0_pattern({sqrt, add1_pattern}); VectorRef add2_pattern({prim::kPrimTensorAdd, sqrt0_pattern, add2_y_}); VectorRef mul4_pattern({prim::kPrimMul, mul4_x_, input3_}); @@ -107,9 +72,18 @@ const AnfNodePtr AdamApplyOneWithDecayRule::Process(const FuncGraphPtr &graph, c MS_EXCEPTION_IF_NULL(fusion_node); fusion_node->set_scope(node->scope()); - AnfNodePtr add0 = nullptr; - AnfNodePtr add1 = nullptr; - std::tie(add0, add1) = GetAdd0Add1Node(node); + auto iter_add0 = (*equiv).find(add0_var_); + if (iter_add0 == (*equiv).end()) { + MS_LOG(EXCEPTION) << "The equiv map is expected to contains the add0 var after matched."; + } + auto iter_add1 = (*equiv).find(add1_var_); + if (iter_add1 == (*equiv).end()) { + MS_LOG(EXCEPTION) << "The equiv map is expected to contains the add1 var after matched."; + } + auto add0 = utils::cast(iter_add0->second); + MS_EXCEPTION_IF_NULL(add0); + auto add1 = utils::cast(iter_add1->second); + MS_EXCEPTION_IF_NULL(add1); auto types = {AnfAlgo::GetOutputInferDataType(add1, 0), AnfAlgo::GetOutputInferDataType(add0, 0), AnfAlgo::GetOutputInferDataType(node, 0)}; auto shapes = {AnfAlgo::GetOutputInferShape(add1, 0), AnfAlgo::GetOutputInferShape(add0, 0), diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.h index a6bab48770..72c54f3535 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.h +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/adam_apply_one_with_decay_rule.h @@ -19,6 +19,7 @@ #include #include #include "pre_activate/common/optimizer.h" +#include "utils/utils.h" namespace mindspore { namespace opt { class AdamApplyOneWithDecayRule : public PatternProcessPass { @@ -36,6 +37,8 @@ class AdamApplyOneWithDecayRule : public PatternProcessPass { mul3_x_ = std::make_shared(); mul4_x_ = std::make_shared(); add2_y_ = std::make_shared(); + add0_var_ = std::make_shared(std::make_shared(prim::kPrimTensorAdd->name())); + add1_var_ = std::make_shared(std::make_shared(prim::kPrimTensorAdd->name())); } ~AdamApplyOneWithDecayRule() override = default; const BaseRef DefinePattern() const override; @@ -54,6 +57,8 @@ class AdamApplyOneWithDecayRule : public PatternProcessPass { VarPtr mul3_x_; VarPtr mul4_x_; VarPtr add2_y_; + VarPtr add0_var_; + VarPtr add1_var_; }; } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.cc new file mode 100644 index 0000000000..6b7f732a6a --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.cc @@ -0,0 +1,112 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.h" +#include +#include +#include +#include +#include "session/anf_runtime_algorithm.h" +#include "ir/primitive.h" +#include "utils/utils.h" +#include "pipeline/static_analysis/abstract_value.h" +#include "pre_activate/common/helper.h" + +namespace mindspore { +namespace opt { +namespace { +const size_t kConfusionMulGradOutputNum = 2; + +CNodePtr CreateFusionNode(const FuncGraphPtr &graph, const CNodePtr &reduce_sum, const AnfNodePtr &mul0_anf, + const AnfNodePtr &input3) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(reduce_sum); + MS_EXCEPTION_IF_NULL(mul0_anf); + MS_EXCEPTION_IF_NULL(input3); + auto mul0 = mul0_anf->cast(); + MS_EXCEPTION_IF_NULL(mul0); + + auto prim = std::make_shared(kConfusionMulGradOpName); + std::vector inputs = {NewValueNode(prim), mul0->input(1), mul0->input(2), input3}; + auto fusion_node = graph->NewCNode(inputs); + MS_EXCEPTION_IF_NULL(fusion_node); + fusion_node->set_scope(reduce_sum->scope()); + AnfAlgo::CopyNodeAttr(kAttrAxis, reduce_sum, fusion_node); + AnfAlgo::CopyNodeAttr(kAttrKeepDims, reduce_sum, fusion_node); + auto types = {AnfAlgo::GetOutputInferDataType(mul0, 0), AnfAlgo::GetOutputInferDataType(reduce_sum, 0)}; + auto shapes = {AnfAlgo::GetOutputInferShape(mul0, 0), AnfAlgo::GetOutputInferShape(reduce_sum, 0)}; + AnfAlgo::SetOutputInferTypeAndShape(types, shapes, fusion_node.get()); + return fusion_node; +} + +AnfNodePtr GetMul0(const FuncGraphPtr &graph, const AnfNodePtr &input2, const AnfNodePtr &mul1) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(input2); + auto manager = graph->manager(); + MS_EXCEPTION_IF_NULL(manager); + if (manager->node_users().find(input2) == manager->node_users().end()) { + MS_LOG(EXCEPTION) << "node has no output in manager"; + } + + AnfNodePtr mul0 = nullptr; + const AnfNodeIndexSet &outputs_set = manager->node_users()[input2]; + // input2 must be the 2rd input of mul0 + auto it = std::find_if(outputs_set.begin(), outputs_set.end(), [&mul1](const std::pair &node_index) { + return node_index.first != mul1 && node_index.second == 2; + }); + if (it != outputs_set.end() && AnfAlgo::GetCNodeName(it->first) == prim::kPrimMul->name()) { + mul0 = it->first; + } + return mul0; +} +} // namespace + +const BaseRef ConfusionMulGradFusion::DefinePattern() const { + VectorRef mul1({prim::kPrimMul, input3_, input2_}); + VectorRef reduce_sum({prim::kPrimReduceSum, mul1}); + return reduce_sum; +} + +const AnfNodePtr ConfusionMulGradFusion::Process(const FuncGraphPtr &graph, const AnfNodePtr &node, + const EquivPtr &equiv) const { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(node); + MS_EXCEPTION_IF_NULL(equiv); + auto input2 = utils::cast((*equiv)[input2_]); + auto input3 = utils::cast((*equiv)[input3_]); + auto reduce_sum = node->cast(); + MS_EXCEPTION_IF_NULL(reduce_sum); + auto mul1 = reduce_sum->input(1); + if (IsUsedByOthers(graph, mul1)) { + MS_LOG(INFO) << "Mul1 is used by others, quit fusion!"; + return nullptr; + } + auto mul0 = GetMul0(graph, input2, mul1); + if (mul0 == nullptr) { + MS_LOG(INFO) << "Mul0 do not exist, quit fusion"; + return nullptr; + } + + auto fusion_node = CreateFusionNode(graph, reduce_sum, mul0, input3); + std::vector fusion_node_outputs; + CreateMultipleOutputsOfAnfNode(graph, fusion_node, kConfusionMulGradOutputNum, &fusion_node_outputs); + + auto manage = graph->manager(); + MS_EXCEPTION_IF_NULL(manage); + manage->Replace(mul0, fusion_node_outputs[0]); + return fusion_node_outputs[1]; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.h new file mode 100644 index 0000000000..170df5b0e4 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.h @@ -0,0 +1,41 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_CONFUSION_MUL_GRAD_FUSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_CONFUSION_MUL_GRAD_FUSION_H_ + +#include +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +class ConfusionMulGradFusion : public PatternProcessPass { + public: + explicit ConfusionMulGradFusion(bool multigraph = true) + : PatternProcessPass("confusion_mul_grad_fusion", multigraph) { + input2_ = std::make_shared(); + input3_ = std::make_shared(); + } + ~ConfusionMulGradFusion() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; + + private: + VarPtr input2_; + VarPtr input3_; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_CONFUSION_MUL_GRAD_FUSION_H_ diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_softmax_grad_rule.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_softmax_grad_rule.cc index 1270ae77c1..8078247c2a 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_softmax_grad_rule.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/confusion_softmax_grad_rule.cc @@ -21,9 +21,30 @@ #include "session/anf_runtime_algorithm.h" #include "ir/primitive.h" #include "utils/utils.h" +#include "pre_activate/common/helper.h" namespace mindspore { namespace opt { +namespace { +void SetAttrsForFusionNode(const AnfNodePtr &sub_anf, const AnfNodePtr &fusion_node) { + MS_EXCEPTION_IF_NULL(sub_anf); + MS_EXCEPTION_IF_NULL(fusion_node); + auto sub = sub_anf->cast(); + MS_EXCEPTION_IF_NULL(sub); + if (sub->size() != kSubInputNum) { + MS_LOG(EXCEPTION) << "Sub's size is not equal with 3"; + } + auto reduce_sum_anf = sub->input(2); + MS_EXCEPTION_IF_NULL(reduce_sum_anf); + auto reduce_sum = reduce_sum_anf->cast(); + if (reduce_sum == nullptr) { + MS_LOG(EXCEPTION) << "Sub's second input is not a cnode"; + } + AnfAlgo::CopyNodeAttr(kAttrAxis, reduce_sum, fusion_node); + AnfAlgo::CopyNodeAttr(kAttrKeepDims, reduce_sum, fusion_node); +} +} // namespace + const BaseRef ConfusionSoftmaxGradRule::DefinePattern() const { return VectorRef( {prim::kPrimSub, input0_, VectorRef({prim::kPrimReduceSum, VectorRef({prim::kPrimMul, input0_, input1_})})}); @@ -48,6 +69,7 @@ const AnfNodePtr ConfusionSoftmaxGradRule::Process(const FuncGraphPtr &graph, co auto shapes = {AnfAlgo::GetOutputInferShape(node, 0)}; AnfAlgo::SetOutputInferTypeAndShape(types, shapes, confusion_softmax_grad.get()); confusion_softmax_grad->set_scope(node->scope()); + SetAttrsForFusionNode(node, confusion_softmax_grad); return confusion_softmax_grad; } } // namespace opt diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.cc new file mode 100644 index 0000000000..d5ea315de1 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.cc @@ -0,0 +1,105 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/ascend/ir_fusion/derelu_fusion.h" +#include +#include +#include "session/anf_runtime_algorithm.h" +#include "ir/primitive.h" +#include "utils/utils.h" +#include "pipeline/static_analysis/abstract_value.h" +#include "pre_activate/common/helper.h" + +namespace mindspore { +namespace opt { +namespace { +const size_t kReluV2OutputNum = 2; + +CNodePtr GetRelu(const CNodePtr &relu_grad) { + MS_EXCEPTION_IF_NULL(relu_grad); + if (relu_grad->size() != kReluGradInputNum) { + MS_LOG_EXCEPTION << "ReluGrad has wrong input size " << relu_grad->size(); + } + auto relu_anf = relu_grad->input(2); + MS_EXCEPTION_IF_NULL(relu_anf); + return relu_anf->cast(); +} + +CNodePtr CreateReluV2(const FuncGraphPtr &graph, const CNodePtr &relu) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(relu); + if (relu->size() != kReluInputNum) { + MS_LOG_EXCEPTION << "Relu has wrong input size " << relu->size(); + } + + auto prim = std::make_shared(kReluV2OpName); + std::vector inputs = {NewValueNode(prim), relu->input(1)}; + auto new_node = graph->NewCNode(inputs); + MS_EXCEPTION_IF_NULL(new_node); + new_node->set_scope(relu->scope()); + + // ReluV2's 2rd output is mask whose data type is uint8 and value is 0 or 1, so shape is an empty vector + TypeId mask_dtype = kNumberTypeUInt8; + std::vector mask_shape; + auto types = {AnfAlgo::GetOutputInferDataType(relu, 0), mask_dtype}; + auto shapes = {AnfAlgo::GetOutputInferShape(relu, 0), mask_shape}; + AnfAlgo::SetOutputInferTypeAndShape(types, shapes, new_node.get()); + return new_node; +} + +CNodePtr CreateReluGradV2(const FuncGraphPtr &graph, const CNodePtr &relu_grad, const AnfNodePtr &second_input) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(relu_grad); + MS_EXCEPTION_IF_NULL(second_input); + + auto prim = std::make_shared(kReluGradV2OpName); + std::vector inputs = {NewValueNode(prim), relu_grad->input(1), second_input}; + auto new_node = graph->NewCNode(inputs); + MS_EXCEPTION_IF_NULL(new_node); + new_node->set_scope(relu_grad->scope()); + new_node->set_abstract(relu_grad->abstract()); + return new_node; +} +} // namespace + +const BaseRef DereluFusion::DefinePattern() const { + VarPtr i0 = std::make_shared(); + VarPtr i1 = std::make_shared(); + VectorRef relu({prim::kPrimRelu, i1}); + VectorRef relu_grad({prim::kPrimReluGrad, i0, relu}); + return relu_grad; +} + +const AnfNodePtr DereluFusion::Process(const FuncGraphPtr &graph, const AnfNodePtr &node, const EquivPtr &) const { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(node); + auto relu_grad = node->cast(); + MS_EXCEPTION_IF_NULL(relu_grad); + auto relu = GetRelu(relu_grad); + MS_EXCEPTION_IF_NULL(relu); + + auto relu_v2 = CreateReluV2(graph, relu); + std::vector relu_v2_node_outputs; + CreateMultipleOutputsOfAnfNode(graph, relu_v2, kReluV2OutputNum, &relu_v2_node_outputs); + + auto relu_grad_v2 = CreateReluGradV2(graph, relu_grad, relu_v2_node_outputs[1]); + + auto manage = graph->manager(); + MS_EXCEPTION_IF_NULL(manage); + manage->Replace(relu, relu_v2_node_outputs[0]); + return relu_grad_v2; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.h new file mode 100644 index 0000000000..e1811f4db4 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/derelu_fusion.h @@ -0,0 +1,33 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_DERELU_FUSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_DERELU_FUSION_H_ + +#include +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +class DereluFusion : public PatternProcessPass { + public: + explicit DereluFusion(bool multigraph = true) : PatternProcessPass("derelu_fusion", multigraph) {} + ~DereluFusion() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_DERELU_FUSION_H_ diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.cc index ca9c90f4e5..68baeeed99 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.cc @@ -16,36 +16,9 @@ #include "pre_activate/ascend/ir_fusion/lamb_next_right_rule.h" #include #include "pre_activate/common/helper.h" -#include "utils/utils.h" namespace mindspore { namespace opt { -namespace { -AnfNodePtr GetAdd1Node(const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(node); - auto add2_cnode = node->cast(); - MS_EXCEPTION_IF_NULL(add2_cnode); - if (add2_cnode->inputs().size() != kAddInputNum) { - MS_LOG(ERROR) << "The input size of Add2 is not equal to " << kAddInputNum; - } - AnfNodePtr sqrt0 = add2_cnode->input(1); - MS_EXCEPTION_IF_NULL(sqrt0); - auto sqrt0_cnode = sqrt0->cast(); - MS_EXCEPTION_IF_NULL(sqrt0_cnode); - if (sqrt0_cnode->inputs().size() != kSqrtInputNum) { - MS_LOG(ERROR) << "The input size of Sqrt0 is not equal to " << kSqrtInputNum; - } - AnfNodePtr real_div1 = sqrt0_cnode->input(1); - MS_EXCEPTION_IF_NULL(real_div1); - auto real_div1_cnode = real_div1->cast(); - MS_EXCEPTION_IF_NULL(real_div1_cnode); - if (real_div1_cnode->inputs().size() != kMulInputNum) { - MS_LOG(ERROR) << "The input size of RealDiv1 is not equal to " << kMulInputNum; - } - return real_div1_cnode->input(1); -} -} // namespace - AnfNodePtr LambNextRightRule::CreateLambNextRightNode(const FuncGraphPtr &func_graph, const EquivPtr &equiv) const { MS_EXCEPTION_IF_NULL(func_graph); MS_EXCEPTION_IF_NULL(equiv); @@ -79,7 +52,7 @@ const BaseRef LambNextRightRule::DefinePattern() const { const auto prim_sqrt = std::make_shared(kSqrtOpName); MS_EXCEPTION_IF_NULL(prim_sqrt); VectorRef mul3 = VectorRef({prim::kPrimMul, mul3_x_, VectorRef({prim::kPrimSquare, input0_})}); - VectorRef add1 = VectorRef({prim::kPrimTensorAdd, VectorRef({prim::kPrimMul, mul2_x_, input1_}), mul3}); + VectorRef add1 = VectorRef({add1_var_, VectorRef({prim::kPrimMul, mul2_x_, input1_}), mul3}); return VectorRef( {prim::kPrimTensorAdd, VectorRef({prim_sqrt, VectorRef({prim::kPrimMul, add1, true_div1_recip_})}), add2_y_}); } @@ -91,7 +64,11 @@ const AnfNodePtr LambNextRightRule::Process(const FuncGraphPtr &func_graph, cons auto new_node = CreateLambNextRightNode(func_graph, equiv); MS_EXCEPTION_IF_NULL(new_node); // Set abstract of new node - AnfNodePtr add1 = GetAdd1Node(node); + auto iter_add1 = (*equiv).find(add1_var_); + if (iter_add1 == (*equiv).end()) { + MS_LOG(EXCEPTION) << "The equiv map is expected to contains the add1 var after matched."; + } + auto add1 = utils::cast(iter_add1->second); MS_EXCEPTION_IF_NULL(add1); AbstractBasePtrList new_node_abstract_list; new_node_abstract_list.push_back(add1->abstract()); diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.h index f78be7460b..3d15001da2 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.h +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/lamb_next_right_rule.h @@ -18,6 +18,8 @@ #include #include "pre_activate/common/optimizer.h" +#include "utils/utils.h" + namespace mindspore { namespace opt { class LambNextRightRule : public PatternProcessPass { @@ -29,7 +31,8 @@ class LambNextRightRule : public PatternProcessPass { mul2_x_(std::make_shared()), mul3_x_(std::make_shared()), true_div1_recip_(std::make_shared()), - add2_y_(std::make_shared()) {} + add2_y_(std::make_shared()), + add1_var_(std::make_shared(std::make_shared(prim::kPrimTensorAdd->name()))) {} ~LambNextRightRule() override = default; const BaseRef DefinePattern() const override; @@ -44,6 +47,7 @@ class LambNextRightRule : public PatternProcessPass { VarPtr mul3_x_; VarPtr true_div1_recip_; VarPtr add2_y_; + VarPtr add1_var_; }; } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.cc new file mode 100644 index 0000000000..faa1308f8b --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.cc @@ -0,0 +1,120 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.h" +#include +#include "session/anf_runtime_algorithm.h" +#include "utils/utils.h" +#include "operator/ops.h" +#include "device/kernel_info.h" +#include "pre_activate/common/helper.h" +#include "pre_activate/common/optimizer.h" +#include "pre_activate/ascend/ascend_helper.h" + +namespace mindspore { +namespace opt { +const AnfNodePtr ParamTransRoad(const FuncGraphPtr &func_graph, const AnfNodePtr &node, bool first_flag, + std::vector *trans_road) { + if (node == nullptr) { + MS_LOG(ERROR) << "nullptr"; + return nullptr; + } + if (node->isa()) { + auto cnode = node->cast(); + auto op_name = AnfAlgo::GetCNodeName(cnode); + auto manager = func_graph->manager(); + if (manager == nullptr) { + return nullptr; + } + if (op_name == prim::kPrimCast->name() || op_name == prim::kPrimTranspose->name() || + op_name == prim::kPrimReshape->name() || op_name == kTransDataOpName) { + auto users = manager->node_users()[node]; + if (users.size() > 1 && !first_flag) { + return nullptr; + } + trans_road->push_back(cnode); + first_flag = false; + auto next_node = AnfAlgo::GetInputNode(cnode, 0); + if (next_node->isa() || next_node->isa()) { + return next_node; + } + return ParamTransRoad(func_graph, next_node, first_flag, trans_road); + } + } else if (node->isa() || node->isa()) { + return node; + } + return nullptr; +} + +bool ParameterTransOpFusion::Run(const FuncGraphPtr &func_graph) { + if (func_graph == nullptr) { + MS_LOG(ERROR) << "Func graph is nullptr"; + return false; + } + auto manager = func_graph->manager(); + if (manager == nullptr) { + return false; + } + std::vector node_list = TopoSort(func_graph->get_return()); + bool changed = false; + for (auto node : node_list) { + if (node == nullptr || !node->isa()) { + continue; + } + auto cnode = node->cast(); + auto node_name = AnfAlgo::GetCNodeName(cnode); + if (node_name == prim::kPrimCast->name() || node_name == prim::kPrimTranspose->name() || + node_name == prim::kPrimReshape->name() || node_name == kTransDataOpName) { + MS_LOG(DEBUG) << "Skip trans op"; + continue; + } + for (size_t input_index = 0; input_index < AnfAlgo::GetInputTensorNum(cnode); input_index++) { + std::vector trans_road; + bool first_flag = true; + auto final_node = ParamTransRoad(func_graph, AnfAlgo::GetInputNode(cnode, input_index), first_flag, &trans_road); + if (final_node != nullptr && trans_road.size() == 3 && AnfAlgo::GetCNodeName(trans_road[0]) == kTransDataOpName && + AnfAlgo::GetCNodeName(trans_road[1]) == prim::kPrimCast->name() && + AnfAlgo::GetCNodeName(trans_road[2]) == kTransDataOpName) { + auto cur_transop = trans_road[0]; + auto format = AnfAlgo::GetOutputFormat(cur_transop, 0); + auto dtype = AnfAlgo::GetOutputDeviceDataType(cur_transop, 0); + auto param_format = AnfAlgo::GetOutputFormat(final_node, 0); + auto param_dtype = AnfAlgo::GetOutputDeviceDataType(final_node, 0); + + auto cast = trans_road[1]; + auto cast_format = AnfAlgo::GetOutputFormat(cast, 0); + auto cast_build_info = cast->kernel_info()->select_kernel_build_info(); + kernel::KernelBuildInfo::KernelBuildInfoBuilder builder; + builder.SetOutputsFormat({format}); + builder.SetInputsFormat({format}); + builder.SetInputsDeviceType({param_dtype}); + builder.SetOutputsDeviceType({dtype}); + builder.SetKernelType(cast_build_info->kernel_type()); + builder.SetFusionType(cast_build_info->fusion_type()); + builder.SetProcessor(cast_build_info->processor()); + AnfAlgo::SetSelectKernelBuildInfo(builder.Build(), cast.get()); + if (param_format == format && param_dtype != dtype) { + manager->Replace(trans_road[2], final_node); + manager->Replace(cur_transop, cast); + } + changed = true; + } + } + } + return changed; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.h b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.h new file mode 100644 index 0000000000..823ec083b1 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/parameter_and_transop_fusion.h @@ -0,0 +1,41 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_PARAMETER_AND_TRANSOP_FUSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_PARAMETER_AND_TRANSOP_FUSION_H_ + +#include +#include +#include +#include +#include "ir/anf.h" +#include "pre_activate/common/pass.h" + +namespace mindspore { +namespace opt { +class ParameterTransOpFusion : public Pass { + public: + explicit ParameterTransOpFusion(size_t groups = 1) : Pass("Parameter_and_transop_fusion"), groups_(groups) {} + ~ParameterTransOpFusion() override = default; + bool Run(const FuncGraphPtr &graph) override; + + private: + size_t groups_ = 1; +}; +} // namespace opt +} // namespace mindspore + +#endif diff --git a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/transdata_split.cc b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/transdata_split.cc index faef277599..d3990fe898 100644 --- a/mindspore/ccsrc/pre_activate/ascend/ir_fusion/transdata_split.cc +++ b/mindspore/ccsrc/pre_activate/ascend/ir_fusion/transdata_split.cc @@ -1,99 +1,99 @@ -/** - * Copyright 2020 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "pre_activate/ascend/ir_fusion/transdata_split.h" -#include -#include "pre_activate/ascend/ascend_helper.h" -#include "session/anf_runtime_algorithm.h" -#include "debug/anf_ir_dump.h" - -namespace mindspore { -namespace opt { -const std::set> invalid_formats_pair = {{kOpFormat_C1HWNCoC0, kOpFormat_NCHW}, - {kOpFormat_NCHW, kOpFormat_C1HWNCoC0}, - {kOpFormat_C1HWNCoC0, kOpFormat_DEFAULT}, - {kOpFormat_DEFAULT, kOpFormat_C1HWNCoC0}}; - -bool TransDataSplit::Run(const FuncGraphPtr &func_graph) { - MS_EXCEPTION_IF_NULL(func_graph); - bool changed = false; - std::vector node_list = TopoSort(func_graph->get_return()); - for (auto &node : node_list) { - if (node != nullptr && node->isa() && AnfAlgo::GetCNodeName(node) == kTransDataOpName) { - CheckCNodeInputSize(node->cast(), kBackendTransDataInputNum); - if (IsFormatInvaild(node)) { - changed = DoSplit(func_graph, node); - } - } - } - return changed; -} -bool TransDataSplit::IsFormatInvaild(const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(node); - auto cnode = node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - auto input_format = AnfAlgo::GetInputFormat(node, 0); - auto output_format = AnfAlgo::GetOutputFormat(node, 0); - auto format_pair = std::make_pair(input_format, output_format); - - return invalid_formats_pair.find(format_pair) != invalid_formats_pair.end(); -} -// transdata cannot support frac_z to nchw need split transdata(frac_z-HWCN) and transpose(HWCN-NCHW) -bool TransDataSplit::DoSplit(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(func_graph); - MS_EXCEPTION_IF_NULL(node); - auto cnode = node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - auto input_node = node->cast()->input(1); - MS_EXCEPTION_IF_NULL(input_node); - - auto input_format = AnfAlgo::GetInputFormat(node, 0); - auto output_format = AnfAlgo::GetOutputFormat(node, 0); - AnfNodePtr new_transdata_node = nullptr; - AnfNodePtr new_transpose_node = nullptr; - AnfNodePtr new_replace_node = nullptr; - // if output_format=default transdata need split transdata->transpose else transpose->transdata - if (output_format == kOpFormat_DEFAULT || output_format == kOpFormat_NCHW) { - // trans input_format to hwcn - new_transdata_node = AddTransOpNodeToGraph(func_graph, node, kernel_select_, 0, false, input_format, kOpFormat_HWCN, - kTransDataOpName, true); - // trans hwcn to default_format - new_transpose_node = AddTransOpNodeToGraph(func_graph, new_transdata_node, kernel_select_, 0, false, kOpFormat_HWCN, - output_format, prim::kPrimTranspose->name(), false); - AnfAlgo::SetNodeAttr(kAttrPerm, MakeValue(std::vector{3, 2, 0, 1}), new_transpose_node); - new_replace_node = new_transpose_node; - } else { - // trans default to hwcn - new_transpose_node = AddTransOpNodeToGraph(func_graph, node, kernel_select_, 0, false, input_format, kOpFormat_HWCN, - prim::kPrimTranspose->name(), true); - AnfAlgo::SetNodeAttr(kAttrPerm, MakeValue(std::vector{2, 3, 1, 0}), new_transpose_node); - - // trans hwcn to output_format - new_transdata_node = AddTransOpNodeToGraph(func_graph, new_transpose_node, kernel_select_, 0, false, kOpFormat_HWCN, - output_format, kTransDataOpName, false); - new_replace_node = new_transdata_node; - } - FuncGraphManagerPtr manager = func_graph->manager(); - MS_EXCEPTION_IF_NULL(manager); - manager->AddFuncGraph(func_graph); - - if (!manager->Replace(node, new_replace_node)) { - MS_LOG(EXCEPTION) << "manager replace node failed"; - } - MS_LOG(INFO) << "transdata node:" << cnode->DebugString() << "split success."; - return true; -} -} // namespace opt -} // namespace mindspore +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/ascend/ir_fusion/transdata_split.h" +#include +#include "pre_activate/ascend/ascend_helper.h" +#include "session/anf_runtime_algorithm.h" +#include "debug/anf_ir_dump.h" + +namespace mindspore { +namespace opt { +const std::set> invalid_formats_pair = {{kOpFormat_C1HWNCoC0, kOpFormat_NCHW}, + {kOpFormat_NCHW, kOpFormat_C1HWNCoC0}, + {kOpFormat_C1HWNCoC0, kOpFormat_DEFAULT}, + {kOpFormat_DEFAULT, kOpFormat_C1HWNCoC0}}; + +bool TransDataSplit::Run(const FuncGraphPtr &func_graph) { + MS_EXCEPTION_IF_NULL(func_graph); + bool changed = false; + std::vector node_list = TopoSort(func_graph->get_return()); + for (auto &node : node_list) { + if (node != nullptr && node->isa() && AnfAlgo::GetCNodeName(node) == kTransDataOpName) { + CheckCNodeInputSize(node->cast(), kBackendTransDataInputNum); + if (IsFormatInvaild(node)) { + changed = DoSplit(func_graph, node); + } + } + } + return changed; +} +bool TransDataSplit::IsFormatInvaild(const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + auto cnode = node->cast(); + MS_EXCEPTION_IF_NULL(cnode); + auto input_format = AnfAlgo::GetInputFormat(node, 0); + auto output_format = AnfAlgo::GetOutputFormat(node, 0); + auto format_pair = std::make_pair(input_format, output_format); + + return invalid_formats_pair.find(format_pair) != invalid_formats_pair.end(); +} +// transdata cannot support frac_z to nchw need split transdata(frac_z-HWCN) and transpose(HWCN-NCHW) +bool TransDataSplit::DoSplit(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(func_graph); + MS_EXCEPTION_IF_NULL(node); + auto cnode = node->cast(); + MS_EXCEPTION_IF_NULL(cnode); + auto input_node = node->cast()->input(1); + MS_EXCEPTION_IF_NULL(input_node); + + auto input_format = AnfAlgo::GetInputFormat(node, 0); + auto output_format = AnfAlgo::GetOutputFormat(node, 0); + AnfNodePtr new_transdata_node = nullptr; + AnfNodePtr new_transpose_node = nullptr; + AnfNodePtr new_replace_node = nullptr; + // if output_format=default transdata need split transdata->transpose else transpose->transdata + if (output_format == kOpFormat_DEFAULT || output_format == kOpFormat_NCHW) { + // trans input_format to hwcn + new_transdata_node = + AddTransOpNodeToGraph(func_graph, node, kernel_select_, 0, input_format, kOpFormat_HWCN, kTransDataOpName, true); + // trans hwcn to default_format + new_transpose_node = AddTransOpNodeToGraph(func_graph, new_transdata_node, kernel_select_, 0, kOpFormat_HWCN, + output_format, prim::kPrimTranspose->name(), false); + AnfAlgo::SetNodeAttr(kAttrPerm, MakeValue(std::vector{3, 2, 0, 1}), new_transpose_node); + new_replace_node = new_transpose_node; + } else { + // trans default to hwcn + new_transpose_node = AddTransOpNodeToGraph(func_graph, node, kernel_select_, 0, input_format, kOpFormat_HWCN, + prim::kPrimTranspose->name(), true); + AnfAlgo::SetNodeAttr(kAttrPerm, MakeValue(std::vector{2, 3, 1, 0}), new_transpose_node); + + // trans hwcn to output_format + new_transdata_node = AddTransOpNodeToGraph(func_graph, new_transpose_node, kernel_select_, 0, kOpFormat_HWCN, + output_format, kTransDataOpName, false); + new_replace_node = new_transdata_node; + } + FuncGraphManagerPtr manager = func_graph->manager(); + MS_EXCEPTION_IF_NULL(manager); + manager->AddFuncGraph(func_graph); + + if (!manager->Replace(node, new_replace_node)) { + MS_LOG(EXCEPTION) << "Manager replace node failed"; + } + MS_LOG(INFO) << "Transdata node:" << cnode->DebugString() << "split success."; + return true; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/common/common_backend_optimization.cc b/mindspore/ccsrc/pre_activate/common/common_backend_optimization.cc index c3fd292aa9..f622f2f06f 100644 --- a/mindspore/ccsrc/pre_activate/common/common_backend_optimization.cc +++ b/mindspore/ccsrc/pre_activate/common/common_backend_optimization.cc @@ -18,6 +18,7 @@ #include #include "pre_activate/common/optimizer.h" #include "pre_activate/pass/convert_const_input_to_attr.h" +#include "pre_activate/pass/convert_tuple_output_to_maketuple.h" #include "pre_activate/pass/convert_const_input_to_tensor_input.h" #include "pre_activate/pass/convert_tuple_input_to_dynamic_input.h" #include "utils/context/ms_context.h" @@ -42,6 +43,7 @@ void BackendCommonOptimization(const std::shared_ptr &kern common_pm->AddPass(std::make_shared()); common_pm->AddPass(std::make_shared()); common_pm->AddPass(std::make_shared()); + common_pm->AddPass(std::make_shared()); optimizer->AddPassManager(common_pm); (void)optimizer->Optimize(kernel_graph); kernel_graph->SetExecOrderByDefault(); diff --git a/mindspore/ccsrc/pre_activate/common/helper.cc b/mindspore/ccsrc/pre_activate/common/helper.cc index e5f0fafbe0..de45239268 100644 --- a/mindspore/ccsrc/pre_activate/common/helper.cc +++ b/mindspore/ccsrc/pre_activate/common/helper.cc @@ -28,6 +28,7 @@ namespace mindspore { namespace opt { +constexpr size_t kType32Len = 4; std::vector Convert2Int(const std::vector &v) { std::vector result; (void)std::transform(v.begin(), v.end(), std::back_inserter(result), SizeToInt); @@ -264,6 +265,62 @@ void CreateMultipleOutputsOfAnfNode(const FuncGraphPtr &func_graph, const AnfNod } } +template +tensor::TensorPtr CreateTensorWithValueTuple(const ValueTuplePtr &value_tuple_ptr, const TypePtr &type_ptr, + size_t data_length) { + MS_EXCEPTION_IF_NULL(value_tuple_ptr); + MS_EXCEPTION_IF_NULL(type_ptr); + std::vector values; + for (const auto &v : value_tuple_ptr->value()) { + MS_EXCEPTION_IF_NULL(v); + if (v->isa()) { + ScalarPtr scalar = v->cast(); + values.push_back(GetValue(scalar)); + } else { + MS_LOG(WARNING) << "The value " << v << "of tuple is not a scalar"; + return nullptr; + } + } + std::vector tensor_shape = {SizeToInt(values.size())}; + tensor::TensorPtr tensor = std::make_shared(type_ptr->type_id(), tensor_shape); + MS_EXCEPTION_IF_NULL(tensor); + tensor::DeviceInfo device_info{kOpFormat_DEFAULT, type_ptr}; + tensor->set_device_info(device_info); + auto data_ptr = tensor->data_c(true); + MS_EXCEPTION_IF_NULL(data_ptr); + auto elem_num = values.size() * data_length; + auto ret_code = memcpy_s(data_ptr, static_cast(tensor->data().nbytes()), values.data(), elem_num); + if (ret_code != 0) { + MS_LOG(EXCEPTION) << "Failed to copy data into Tensor."; + } + return tensor; +} + +tensor::TensorPtr CreateTupleTensor(const ValueTuplePtr &value_tuple) { + MS_EXCEPTION_IF_NULL(value_tuple); + tensor::TensorPtr tensor = nullptr; + ValuePtr v = *(value_tuple->value().begin()); + MS_EXCEPTION_IF_NULL(v); + // Currently we only deal with the scalar tuple + if (!v->isa()) { + MS_LOG(WARNING) << "The value " << v << "of tuple is not a scalar"; + return nullptr; + } + ScalarPtr scalar = v->cast(); + MS_EXCEPTION_IF_NULL(scalar); + if (scalar->isa()) { + tensor = CreateTensorWithValueTuple(value_tuple, kInt32, kType32Len); + } else if (scalar->isa()) { + tensor = CreateTensorWithValueTuple(value_tuple, kFloat32, kType32Len); + } else { + auto type = scalar->type(); + auto type_str = (type == nullptr) ? "nullptr" : type->ToString(); + MS_LOG(ERROR) << "Invalid scalar type: " << type_str; + return nullptr; + } + return tensor; +} + bool IsNopNode(const AnfNodePtr &node) { auto context_ptr = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(context_ptr); @@ -280,10 +337,6 @@ bool IsNopNode(const AnfNodePtr &node) { if (nop_nodes.find(AnfAlgo::GetCNodeName(cnode)) == nop_nodes.end()) { return false; } - if (cnode->inputs().size() != 2) { - MS_LOG(EXCEPTION) << "Nop node(" + cnode->DebugString() + ") should have only 1 input, but it has " - << cnode->inputs().size() - 1 << " inputs."; - } return true; } @@ -354,5 +407,20 @@ bool IsUsedByOthers(const FuncGraphPtr &graph, const AnfNodePtr &node) { } return manager->node_users()[node].size() > 1; } + +AnfNodePtr CreatTupleGetItemNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, size_t output_idx) { + auto idx = NewValueNode(SizeToInt(output_idx)); + MS_EXCEPTION_IF_NULL(idx); + auto imm = std::make_shared(SizeToInt(output_idx)); + auto abstract_scalar = std::make_shared(imm); + idx->set_abstract(abstract_scalar); + AnfNodePtr tuple_getitem = func_graph->NewCNode({NewValueNode(prim::kPrimTupleGetItem), node, idx}); + MS_EXCEPTION_IF_NULL(tuple_getitem); + tuple_getitem->set_scope(node->scope()); + std::vector origin_shape = AnfAlgo::GetOutputInferShape(node, output_idx); + TypeId origin_type = AnfAlgo::GetOutputInferDataType(node, output_idx); + AnfAlgo::SetOutputInferTypeAndShape({origin_type}, {origin_shape}, tuple_getitem.get()); + return tuple_getitem; +} } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/common/helper.h b/mindspore/ccsrc/pre_activate/common/helper.h index 4f30a935af..04a4dd6c81 100644 --- a/mindspore/ccsrc/pre_activate/common/helper.h +++ b/mindspore/ccsrc/pre_activate/common/helper.h @@ -29,6 +29,7 @@ constexpr size_t kTransOpInputNum = 2; constexpr size_t kCastInputNum = 2; constexpr size_t kDependInputNum = 3; constexpr size_t kReluInputNum = 2; +constexpr size_t kReluGradInputNum = 3; constexpr size_t kAddInputNum = 3; constexpr size_t kAddNInputNum = 3; constexpr size_t kTupleGetitemInputNum = 3; @@ -135,12 +136,19 @@ void CreateOutputsOfFusedBn3(const FuncGraphPtr &graph, const AnfNodePtr &data_i void CreateMultipleOutputsOfAnfNode(const FuncGraphPtr &kernel_graph, const AnfNodePtr &anf_node_ptr, size_t output_num, std::vector *outputs); +tensor::TensorPtr CreateTensorWithValueTuple(const ValueTuplePtr &value_tuple_ptr, const TypePtr &type_ptr, + size_t data_length); + +tensor::TensorPtr CreateTupleTensor(const ValueTuplePtr &value_tuple); + bool IsNopNode(const AnfNodePtr &node); void HideNopNode(session::KernelGraph *const graph); void RemoveNopNode(session::KernelGraph *const graph); +AnfNodePtr CreatTupleGetItemNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, size_t output_idx); + bool IsUsedByOthers(const FuncGraphPtr &graph, const AnfNodePtr &node); } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/common/node_pass.cc b/mindspore/ccsrc/pre_activate/common/node_pass.cc index cd213f8263..a6e93d2f07 100644 --- a/mindspore/ccsrc/pre_activate/common/node_pass.cc +++ b/mindspore/ccsrc/pre_activate/common/node_pass.cc @@ -45,6 +45,7 @@ bool NodePass::Run(const FuncGraphPtr &func_graph) { bool change = (new_node != nullptr); if (new_node != nullptr && new_node != node) { (void)manager->Replace(node, new_node); + (void)seen_node.erase(node); } else if (new_node == nullptr) { new_node = node; } diff --git a/mindspore/ccsrc/pre_activate/common/optimizer.cc b/mindspore/ccsrc/pre_activate/common/optimizer.cc index 62cff76be0..0e74da3fe8 100644 --- a/mindspore/ccsrc/pre_activate/common/optimizer.cc +++ b/mindspore/ccsrc/pre_activate/common/optimizer.cc @@ -30,7 +30,8 @@ namespace mindspore { namespace opt { namespace { -AnfNodePtr HandleSexpVector(const BaseRef &sexp, const BaseRef &graph, bool multigraph); +AnfNodePtr HandleSexpVector(const BaseRef &sexp, const BaseRef &graph, PrimitiveVarMap *primitive_vars, + bool multigraph); ValueNodePtr CreateValueNodeWithSexp(const BaseRef &sexp) { if (utils::isa(sexp)) { @@ -71,12 +72,20 @@ VarNodePtr CreateVarNodeWithSexp(const BaseRef &sexp, const BaseRef &graph) { return nullptr; } -AnfNodePtr SexpToNode(const BaseRef &sexp, const BaseRef &graph, bool multigraph = false) { +AnfNodePtr SexpToNode(const BaseRef &sexp, const BaseRef &graph, PrimitiveVarMap *primitive_vars, + bool multigraph = false) { MS_LOG(DEBUG) << "SexpToNode sexp: " + sexp.ToString() + ", graph " + graph.ToString(); + MS_EXCEPTION_IF_NULL(primitive_vars); if (utils::isa(sexp)) { - return HandleSexpVector(sexp, graph, multigraph); + return HandleSexpVector(sexp, graph, primitive_vars, multigraph); } if (utils::isa(sexp)) { + auto var_ptr = utils::cast(sexp); + MS_EXCEPTION_IF_NULL(var_ptr); + if (var_ptr->primitive()) { + (*primitive_vars)[var_ptr->primitive()] = var_ptr; + return NewValueNode(var_ptr->primitive()); + } return CreateVarNodeWithSexp(sexp, graph); } if (utils::isa(sexp)) { @@ -89,13 +98,14 @@ AnfNodePtr SexpToNode(const BaseRef &sexp, const BaseRef &graph, bool multigraph return value_node; } -AnfNodePtr HandleSexpVector(const BaseRef &sexp, const BaseRef &graph, bool multigraph) { +AnfNodePtr HandleSexpVector(const BaseRef &sexp, const BaseRef &graph, PrimitiveVarMap *primitive_vars, + bool multigraph) { MS_LOG(DEBUG) << "HandleSexpVector sexp: " + sexp.ToString() + ", graph " + graph.ToString(); std::vector input_nodes; const auto &tuple = utils::cast(sexp); if (multigraph && utils::isa(graph)) { for (auto &x : tuple) { - AnfNodePtr node = SexpToNode(x, std::make_shared("G"), true); + AnfNodePtr node = SexpToNode(x, std::make_shared("G"), primitive_vars, true); input_nodes.push_back(node); } VarPtr var_ptr = utils::cast(graph); @@ -103,7 +113,7 @@ AnfNodePtr HandleSexpVector(const BaseRef &sexp, const BaseRef &graph, bool mult } for (auto &x : tuple) { - AnfNodePtr node = SexpToNode(x, graph, multigraph); + AnfNodePtr node = SexpToNode(x, graph, primitive_vars, multigraph); input_nodes.push_back(node); } return CreateCNodeWithGraph(input_nodes, graph); @@ -166,7 +176,8 @@ PatternProcessPass::PatternProcessPass(const std::string &name, bool multigraph) multigraph_(multigraph), pattern_engine_(PatternEngine(std::make_shared(), std::function(AnfEqual), - std::function(CNodeTypeEqual))) {} + std::function(CNodeTypeEqual))), + primitive_vars_(std::make_shared()) {} const BaseRef PatternProcessPass::DefinePattern() const { VarPtr X = std::make_shared(); @@ -176,7 +187,7 @@ const BaseRef PatternProcessPass::DefinePattern() const { void PatternProcessPass::Build() { VarPtr fg = std::make_shared("RootG"); BaseRef pattern = std::move(DefinePattern()); - pattern_ = SexpToNode(pattern, fg, multigraph_); + pattern_ = SexpToNode(pattern, fg, primitive_vars_.get(), multigraph_); } AnfNodePtr PatternProcessPass::Run(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { @@ -185,7 +196,8 @@ AnfNodePtr PatternProcessPass::Run(const FuncGraphPtr &func_graph, const AnfNode } auto empty_equiv = std::make_shared(); - EquivPtr equiv = pattern_engine_.Match(pattern_, node, empty_equiv); + MS_EXCEPTION_IF_NULL(primitive_vars_); + EquivPtr equiv = pattern_engine_.Match(pattern_, node, *primitive_vars_, empty_equiv); if (equiv != nullptr && !equiv->empty()) { return Process(func_graph, node, equiv); } diff --git a/mindspore/ccsrc/pre_activate/common/optimizer.h b/mindspore/ccsrc/pre_activate/common/optimizer.h index 8ef0b6dc34..eade7f7789 100644 --- a/mindspore/ccsrc/pre_activate/common/optimizer.h +++ b/mindspore/ccsrc/pre_activate/common/optimizer.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "ir/anf.h" #include "ir/func_graph.h" @@ -46,6 +47,7 @@ class PatternProcessPass : public NodePass { AnfNodePtr pattern_ = nullptr; bool multigraph_ = true; PatternEngine pattern_engine_; + PrimitiveVarMapPtr primitive_vars_; }; class GraphOptimizer { diff --git a/mindspore/ccsrc/pre_activate/common/pass_manager.cc b/mindspore/ccsrc/pre_activate/common/pass_manager.cc index 0dfe4c763f..f93a1ad51d 100644 --- a/mindspore/ccsrc/pre_activate/common/pass_manager.cc +++ b/mindspore/ccsrc/pre_activate/common/pass_manager.cc @@ -52,17 +52,27 @@ bool PassManager::Run(const FuncGraphPtr &func_graph, const std::vector size_t num = 0; for (const auto &pass : passes) { if (pass != nullptr) { +#if defined(_WIN32) || defined(_WIN64) + auto start_time = std::chrono::steady_clock::now(); +#else struct timeval start_time {}; struct timeval end_time {}; (void)gettimeofday(&start_time, nullptr); +#endif if (pass->Run(func_graph)) { changed = true; } +#if defined(_WIN32) || defined(_WIN64) + auto end_time = std::chrono::steady_clock::now(); + std::chrono::duration> cost = end_time - start_time; + MS_LOG(INFO) << "Run pass hwopt_" + name() + "_" << num << "_" + pass->name() + " in " << cost.count() << " us"; +#else (void)gettimeofday(&end_time, nullptr); const uint64_t kUSecondInSecond = 1000000; uint64_t cost = kUSecondInSecond * static_cast(end_time.tv_sec - start_time.tv_sec); cost += static_cast(end_time.tv_usec - start_time.tv_usec); MS_LOG(INFO) << "Run pass hwopt_" + name() + "_" << num << "_" + pass->name() + " in " << cost << " us"; +#endif if (save_graphs) { auto dump_file_path = save_graphs_path + "/" + "hwopt_" + name() + "_" + std::to_string(num) + "_" + pass->name() + ".ir"; diff --git a/mindspore/ccsrc/pre_activate/common/pattern_engine.cc b/mindspore/ccsrc/pre_activate/common/pattern_engine.cc index e2ff321a89..350332b9d1 100644 --- a/mindspore/ccsrc/pre_activate/common/pattern_engine.cc +++ b/mindspore/ccsrc/pre_activate/common/pattern_engine.cc @@ -42,7 +42,7 @@ void Var::EnsureTag() { } } -bool operator==(const VarPtr& lhs, const VarPtr& rhs) { +bool operator==(const VarPtr &lhs, const VarPtr &rhs) { if (lhs->isa() && rhs->isa()) { CondVarPtr v1 = dyn_cast(lhs); CondVarPtr v2 = dyn_cast(rhs); @@ -63,7 +63,7 @@ std::string SeqVar::ToString() const { return buffer.str(); } -std::ostream& operator<<(std::ostream& os, const VarPtr& var) { +std::ostream &operator<<(std::ostream &os, const VarPtr &var) { if (var == nullptr) { os << ""; } else { @@ -73,10 +73,10 @@ std::ostream& operator<<(std::ostream& os, const VarPtr& var) { } template <> -std::ostream& operator<<(std::ostream& os, const Equiv& equiv) { +std::ostream &operator<<(std::ostream &os, const Equiv &equiv) { os << "[Equiv]" << "\n"; - for (auto& equiv_item : equiv) { + for (auto &equiv_item : equiv) { auto k = equiv_item.first; os << k << ":"; BaseRef x = equiv_item.second; @@ -104,7 +104,7 @@ std::ostream& operator<<(std::ostream& os, const Equiv& equiv) return os; } -static BaseRef GetVar(const BaseRef& x) { +static BaseRef GetVar(const BaseRef &x) { MS_LOG(DEBUG) << "getVar start :%s" + x.ToString(); if (utils::isa(x)) { auto node = utils::cast(x); @@ -129,7 +129,7 @@ static BaseRef GetVar(const BaseRef& x) { return x; } -EquivPtr MatchOnVar(const BaseRef& pattern, const BaseRef& expr, EquivPtr equiv) { +EquivPtr MatchOnVar(const BaseRef &pattern, const BaseRef &expr, EquivPtr equiv) { MS_LOG(DEBUG) << "MatchOnVar pattern " + pattern.ToString() + " expr: " + expr.ToString(); MS_EXCEPTION_IF_NULL(equiv); if (utils::isa(pattern)) { @@ -144,8 +144,8 @@ EquivPtr MatchOnVar(const BaseRef& pattern, const BaseRef& expr, EquivPtr equiv) return nullptr; } -bool PatternEngine::ToVector(const VectorRef& pattern_ref, const VectorRef& expr_ref, VectorRef* const values_pattern, - VectorRef* const values_expr) const { +bool PatternEngine::ToVector(const VectorRef &pattern_ref, const VectorRef &expr_ref, VectorRef *const values_pattern, + VectorRef *const values_expr) const { MS_EXCEPTION_IF_NULL(values_expr); if (utils::isa(pattern_ref)) { *values_pattern = pattern_ref; @@ -155,12 +155,12 @@ bool PatternEngine::ToVector(const VectorRef& pattern_ref, const VectorRef& expr return false; } -bool PatternEngine::ToVector(const BaseRef& pattern_ref, const BaseRef& expr_ref, VectorRef* const values_pattern, - VectorRef* const values_expr) const { +bool PatternEngine::ToVector(const BaseRef &pattern_ref, const BaseRef &expr_ref, VectorRef *const values_pattern, + VectorRef *const values_expr) const { MS_EXCEPTION_IF_NULL(values_expr); // visitor to visite the list - auto appender_pattern = [](VectorRef& values) { - std::function fn = [&](const BaseRef& u) { + auto appender_pattern = [](VectorRef &values) { + std::function fn = [&](const BaseRef &u) { values.push_back(GetVar(u)); return u; }; @@ -174,8 +174,8 @@ bool PatternEngine::ToVector(const BaseRef& pattern_ref, const BaseRef& expr_ref return false; } - auto appender_expr = [](VectorRef& values) { - std::function fn = [&](const BaseRef& u) { + auto appender_expr = [](VectorRef &values) { + std::function fn = [&](const BaseRef &u) { values.push_back(u); return u; }; @@ -187,10 +187,10 @@ bool PatternEngine::ToVector(const BaseRef& pattern_ref, const BaseRef& expr_ref return visitor_->Visit(expr_ref, nullptr); } -static int GetSVarStartIndex(const VectorRef& values) { +static int GetSVarStartIndex(const VectorRef &values) { int index = -1; int count = 0; - for (auto& value : values) { + for (auto &value : values) { if (utils::isa(value) && utils::cast(value)->isa()) { if (index != -1) { MS_LOG(DEBUG) << "Multiple SVars in sequence"; @@ -203,7 +203,35 @@ static int GetSVarStartIndex(const VectorRef& values) { return index; } -EquivPtr PatternEngine::AlignSVar(const VectorRef& values_pattern, const VectorRef& values_expr, EquivPtr equiv) const { +void UpdateEquivMap(const VectorRef &values_pattern, const BaseRef &expr_ref, const PrimitiveVarMap &primitive_vars, + EquivPtr equiv) { + if (equiv == nullptr || values_pattern.empty() || !utils::isa(values_pattern[0]) || + !utils::isa(expr_ref)) { + return; + } + auto real_node = utils::cast(expr_ref); + MS_EXCEPTION_IF_NULL(real_node); + if (!real_node->isa()) { + return; + } + auto prim_node = utils::cast(values_pattern[0]); + MS_EXCEPTION_IF_NULL(prim_node); + if (!IsValueNode(prim_node)) { + return; + } + ValuePtr value = GetValueNode(prim_node); + MS_EXCEPTION_IF_NULL(value); + auto prim = value->cast(); + MS_EXCEPTION_IF_NULL(prim); + auto iter = primitive_vars.find(prim); + if (iter == primitive_vars.end()) { + return; + } + (*equiv)[iter->second] = real_node; +} + +EquivPtr PatternEngine::AlignSVar(const VectorRef &values_pattern, const VectorRef &values_expr, + const PrimitiveVarMap &primitive_vars, EquivPtr equiv) const { int svar_index = GetSVarStartIndex(values_pattern); if (svar_index == kInvalidVarIndex) { return nullptr; @@ -229,12 +257,12 @@ EquivPtr PatternEngine::AlignSVar(const VectorRef& values_pattern, const VectorR if (svar_index != -1 && i == IntToSize(svar_index)) { auto seq = std::vector(values_expr.begin() + svar_index, values_expr.begin() + svar_index + SizeToInt(diff)); - equiv = Match(values_pattern[svar_index], seq, equiv); + equiv = Match(values_pattern[svar_index], seq, primitive_vars, equiv); } else { if (svar_index != -1 && i > IntToSize(svar_index)) { expr_i = i + diff - 1; } - equiv = Match(values_pattern[i], values_expr[expr_i], equiv); + equiv = Match(values_pattern[i], values_expr[expr_i], primitive_vars, equiv); } if (equiv == nullptr) { return nullptr; @@ -243,7 +271,8 @@ EquivPtr PatternEngine::AlignSVar(const VectorRef& values_pattern, const VectorR return equiv; } -EquivPtr PatternEngine::Match(const BaseRef& pattern, const BaseRef& expr, EquivPtr equiv) const { +EquivPtr PatternEngine::Match(const BaseRef &pattern, const BaseRef &expr, const PrimitiveVarMap &primitive_vars, + EquivPtr equiv) const { MS_LOG(DEBUG) << "-----[in Match]"; MS_LOG(DEBUG) << "GetVar w"; BaseRef pattern_ref = GetVar(pattern); @@ -292,10 +321,12 @@ EquivPtr PatternEngine::Match(const BaseRef& pattern, const BaseRef& expr, Equiv // 6. if any svar in both side, find the SeqVar index, // try to pack the Var s in std::vector to a Seq and match elements one by one. // check svar - return AlignSVar(values_pattern, values_expr, equiv); + equiv = AlignSVar(values_pattern, values_expr, primitive_vars, equiv); + UpdateEquivMap(values_pattern, expr_ref, primitive_vars, equiv); + return equiv; } -BaseRef PatternEngine::Replace(const BaseRef& pattern, const EquivPtr& equiv) const { +BaseRef PatternEngine::Replace(const BaseRef &pattern, const EquivPtr &equiv) const { MS_EXCEPTION_IF_NULL(equiv); MS_LOG(DEBUG) << "-----[in Replace]"; BaseRef ref = GetVar(pattern); @@ -304,7 +335,7 @@ BaseRef PatternEngine::Replace(const BaseRef& pattern, const EquivPtr& equiv) co // w is var if (utils::isa(ref)) { - const VarPtr& var = utils::cast(ref); + const VarPtr &var = utils::cast(ref); auto iter = equiv->find(var); if (iter != equiv->end()) { out = iter->second; @@ -316,7 +347,7 @@ BaseRef PatternEngine::Replace(const BaseRef& pattern, const EquivPtr& equiv) co } // visitor to visit the list - std::function fn = [&, this, equiv](const BaseRef& u) { return Replace(u, equiv); }; + std::function fn = [&, this, equiv](const BaseRef &u) { return Replace(u, equiv); }; visitor_->SetFn(fn); BaseRef visit_out; diff --git a/mindspore/ccsrc/pre_activate/common/pattern_engine.h b/mindspore/ccsrc/pre_activate/common/pattern_engine.h index 432746332f..858b1aecb8 100644 --- a/mindspore/ccsrc/pre_activate/common/pattern_engine.h +++ b/mindspore/ccsrc/pre_activate/common/pattern_engine.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "pre_activate/common/visit.h" #include "ir/base.h" @@ -44,16 +45,19 @@ using CondVarPtr = std::shared_ptr; using SVarPtr = std::shared_ptr; const int kInvalidVarIndex = -2; -using ConditionFunc = std::function; +using ConditionFunc = std::function; // Base wildcard variable which could match any anf node. class Var : public Base { friend class VarHasher; public: - explicit Var(const std::string& tag = "") : tag_(tag) { EnsureTag(); } - Var(const Var& other) : Base(other), tag_(other.tag_) {} - virtual Var& operator=(const Var& other) { + explicit Var(std::string tag = "") : tag_(std::move(tag)), primitive_(nullptr) { EnsureTag(); } + explicit Var(const PrimitivePtr &primitive, std::string tag = "") : tag_(std::move(tag)), primitive_(primitive) { + EnsureTag(); + } + Var(const Var &other) : Base(other), tag_(other.tag_) {} + virtual Var &operator=(const Var &other) { if (&other == this) { return *this; } @@ -63,12 +67,13 @@ class Var : public Base { ~Var() override = default; MS_DECLARE_PARENT(Var, Base); - virtual bool matches(const BaseRef&) { return true; } + virtual bool matches(const BaseRef &) { return true; } - virtual bool operator==(const Var& other) const { return tag_ == other.tag_; } - bool operator!=(const Var& other) const { return !(&other == this); } + virtual bool operator==(const Var &other) const { return tag_ == other.tag_; } + bool operator!=(const Var &other) const { return !(&other == this); } std::string tag() const { return tag_; } + PrimitivePtr primitive() const { return primitive_; } std::string ToString() const override { std::ostringstream buffer; buffer << "Var(" << tag_ << ")"; @@ -80,12 +85,13 @@ class Var : public Base { void EnsureTag(); std::string tag_; + PrimitivePtr primitive_; }; // VarNode means variable node, a subclass of AnfNode class VarNode : public AnfNode { public: - VarNode(const VarPtr& value, const FuncGraphPtr& func_graph) : AnfNode(func_graph), var_(value) {} + VarNode(const VarPtr &value, const FuncGraphPtr &func_graph) : AnfNode(func_graph), var_(value) {} ~VarNode() override = default; MS_DECLARE_PARENT(VarNode, AnfNode); @@ -95,16 +101,16 @@ using VarNodePtr = std::shared_ptr; class VarHasher { public: - std::size_t operator()(const Var& var) const { return var.hash(); } + std::size_t operator()(const Var &var) const { return var.hash(); } }; // Condition Var, match an anf node when condition function return true. class CondVar : public Var { public: - explicit CondVar(const ConditionFunc& cond) : cond_fn_(cond) {} + explicit CondVar(const ConditionFunc &cond) : cond_fn_(cond) {} ~CondVar() override = default; MS_DECLARE_PARENT(CondVar, Var); - bool matches(const BaseRef& value) override { + bool matches(const BaseRef &value) override { MS_LOG(DEBUG) << "CondVarPtr match: " + value.ToString(); if (utils::isa(value)) { return false; @@ -124,55 +130,60 @@ class SeqVar : public Var { ~SeqVar() override = default; MS_DECLARE_PARENT(SeqVar, Var); explicit SeqVar(const VarPtr subvar) : subvar_(nullptr) { subvar_ = subvar; } - bool matches(const BaseRef& value) override { + bool matches(const BaseRef &value) override { // match Seq. if (utils::isa(value)) { - const Seq& seq = utils::cast(value); - return std::all_of(seq.begin(), seq.end(), [this](const BaseRef& v) { + const Seq &seq = utils::cast(value); + return std::all_of(seq.begin(), seq.end(), [this](const BaseRef &v) { auto eq = subvar_->matches(v); return eq; }); } return false; } - bool operator==(const SeqVar& other) const { return *subvar_ == *other.subvar_; } + bool operator==(const SeqVar &other) const { return *subvar_ == *other.subvar_; } std::string ToString() const override; private: VarPtr subvar_; }; -bool operator==(const VarPtr& lhs, const VarPtr& rhs); +bool operator==(const VarPtr &lhs, const VarPtr &rhs); -inline bool operator!=(const VarPtr& lhs, const VarPtr& rhs) { return !(lhs == rhs); } +inline bool operator!=(const VarPtr &lhs, const VarPtr &rhs) { return !(lhs == rhs); } -std::ostream& operator<<(std::ostream& os, const VarPtr& var); +std::ostream &operator<<(std::ostream &os, const VarPtr &var); using Equiv = std::map; using EquivPtr = std::shared_ptr; +using PrimitiveVarMap = std::unordered_map; +using PrimitiveVarMapPtr = std::shared_ptr; -inline bool DefaultTypeEq(const BaseRef& x, const BaseRef& y) { return x.type() == y.type(); } +inline bool DefaultTypeEq(const BaseRef &x, const BaseRef &y) { return x.type() == y.type(); } class PatternEngine { public: - PatternEngine(const std::shared_ptr& visitor, const std::function& eq, - const std::function& type_eq = DefaultTypeEq) + PatternEngine(const std::shared_ptr &visitor, + const std::function &eq, + const std::function &type_eq = DefaultTypeEq) : visitor_(visitor), eq_(eq), type_eq_(type_eq) {} ~PatternEngine() = default; - EquivPtr Match(const BaseRef& pattern, const BaseRef& expr, EquivPtr equiv) const; + EquivPtr Match(const BaseRef &pattern, const BaseRef &expr, const PrimitiveVarMap &primitive_vars, + EquivPtr equiv) const; // Replace pattern with equivalent - BaseRef Replace(const BaseRef& pattern, const EquivPtr& equiv) const; + BaseRef Replace(const BaseRef &pattern, const EquivPtr &equiv) const; private: - EquivPtr AlignSVar(const VectorRef& values_pattern, const VectorRef& values_expr, EquivPtr equiv) const; - bool ToVector(const BaseRef& pattern, const BaseRef& expr, VectorRef* const values_pattern, - VectorRef* const values_expr) const; - bool ToVector(const VectorRef& pattern_ref, const VectorRef& expr_ref, VectorRef* const values_pattern, - VectorRef* const values_expr) const; + EquivPtr AlignSVar(const VectorRef &values_pattern, const VectorRef &values_expr, + const PrimitiveVarMap &primitive_vars, EquivPtr equiv) const; + bool ToVector(const BaseRef &pattern, const BaseRef &expr, VectorRef *const values_pattern, + VectorRef *const values_expr) const; + bool ToVector(const VectorRef &pattern_ref, const VectorRef &expr_ref, VectorRef *const values_pattern, + VectorRef *const values_expr) const; std::shared_ptr visitor_; - std::function eq_; - std::function type_eq_; + std::function eq_; + std::function type_eq_; }; } // namespace mindspore namespace std { diff --git a/mindspore/ccsrc/pre_activate/mem_reuse/mem_reuse.cc b/mindspore/ccsrc/pre_activate/mem_reuse/mem_reuse.cc index 2113fec653..d25b60003f 100644 --- a/mindspore/ccsrc/pre_activate/mem_reuse/mem_reuse.cc +++ b/mindspore/ccsrc/pre_activate/mem_reuse/mem_reuse.cc @@ -273,30 +273,21 @@ void MemReuseUtil::SetReuseRefCount() { } void MemReuseUtil::SetGraphOutputRefCount() { - for (const auto &output : graph_->outputs()) { - MS_EXCEPTION_IF_NULL(output); - for (size_t i = 0; i < AnfAlgo::GetInputTensorNum(output); ++i) { - if (!(output->isa())) { - continue; - } - auto cnode = output->cast(); - MS_EXCEPTION_IF_NULL(cnode); - auto input_node = cnode->input(i + 1); - MS_EXCEPTION_IF_NULL(input_node); - auto kernel_input = AnfAlgo::VisitKernel(input_node, 0); - MS_EXCEPTION_IF_NULL(kernel_input.first); - if (!(kernel_input.first->isa())) { - continue; - } - auto ak_node = kernel_input.first->cast(); - auto key = ak_node.get(); - auto iter = kernel_output_refs_.find(key); - if ((iter != kernel_output_refs_.end()) && (kernel_input.second < iter->second.size())) { - auto kernel_ref_count_ptr = kernel_output_refs_[key][kernel_input.second]; - MS_EXCEPTION_IF_NULL(kernel_ref_count_ptr); - kernel_ref_count_ptr->ref_count_ = kMaxRefCount; - kernel_ref_count_ptr->ref_count_dynamic_use_ = kMaxRefCount; - } + auto nodes = AnfAlgo::GetAllOutput(graph_->output(), {prim::kPrimTupleGetItem}); + for (const auto &node : nodes) { + auto kernel_input = AnfAlgo::VisitKernelWithReturnType(node, 0); + MS_EXCEPTION_IF_NULL(kernel_input.first); + if (!kernel_input.first->isa() || !AnfAlgo::IsRealKernel(kernel_input.first)) { + continue; + } + auto ak_node = kernel_input.first->cast(); + auto key = ak_node.get(); + auto iter = kernel_output_refs_.find(key); + if ((iter != kernel_output_refs_.end()) && (kernel_input.second < iter->second.size())) { + auto kernel_ref_count_ptr = kernel_output_refs_[key][kernel_input.second]; + MS_EXCEPTION_IF_NULL(kernel_ref_count_ptr); + kernel_ref_count_ptr->ref_count_ = kMaxRefCount; + kernel_ref_count_ptr->ref_count_dynamic_use_ = kMaxRefCount; } } #ifdef MEM_REUSE_DEBUG diff --git a/mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.cc b/mindspore/ccsrc/pre_activate/pass/allreduce_fusion.cc similarity index 97% rename from mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.cc rename to mindspore/ccsrc/pre_activate/pass/allreduce_fusion.cc index 55efcf9058..70a8974eca 100644 --- a/mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.cc +++ b/mindspore/ccsrc/pre_activate/pass/allreduce_fusion.cc @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "pre_activate/common/ir_fusion/allreduce_fusion.h" +#include "pre_activate/pass/allreduce_fusion.h" #include #include diff --git a/mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.h b/mindspore/ccsrc/pre_activate/pass/allreduce_fusion.h similarity index 86% rename from mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.h rename to mindspore/ccsrc/pre_activate/pass/allreduce_fusion.h index b49b8373c6..e443767e43 100644 --- a/mindspore/ccsrc/pre_activate/common/ir_fusion/allreduce_fusion.h +++ b/mindspore/ccsrc/pre_activate/pass/allreduce_fusion.h @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ -#define MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_PASS_ALLREDUCE_FUSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_PASS_ALLREDUCE_FUSION_H_ #include #include "pre_activate/common/pass.h" @@ -46,4 +46,4 @@ class AllReduceFusion : public Pass { }; } // namespace opt } // namespace mindspore -#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_PASS_ALLREDUCE_FUSION_H_ diff --git a/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.cc b/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.cc index 42d373392c..c2f96e54c6 100644 --- a/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.cc +++ b/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.cc @@ -17,10 +17,46 @@ #include +#include "utils/utils.h" #include "utils/log_adapter.h" +#include "operator/ops.h" namespace mindspore { namespace opt { +ConstInputToAttrInfoRegistry::ConstInputToAttrInfoRegistry() { + Register(prim::kPrimCast->name(), {1}); + Register(prim::kPrimConv2DBackpropInput->name(), {2}); + Register(prim::kPrimConv2DBackpropFilter->name(), {2}); + Register(prim::kPrimDepthwiseConv2dNativeBackpropFilter->name(), {1}); + Register(prim::kPrimDepthwiseConv2dNativeBackpropInput->name(), {0}); + Register(prim::kPrimReshape->name(), {1}); + Register(prim::kPrimReduceMax->name(), {1}); + Register(prim::kPrimReduceMin->name(), {1}); + Register(prim::kPrimReduceSum->name(), {1}); + Register(prim::kPrimReduceMean->name(), {1}); + Register(prim::kPrimGatherV2->name(), {2}); + Register(prim::kPrimTranspose->name(), {1}); + Register(prim::kPrimUnsortedSegmentSum->name(), {2}); + Register(prim::kPrimOneHot->name(), {1}); + Register(kUnsortedSegmentProdOpName, {2}); + Register(kUnsortedSegmentMinOpName, {2}); + Register(kSimpleMeanGradOpName, {1}); + Register(kMeanGradOpName, {1}); + Register(kSliceOpName, {1, 2}); + Register(kSliceGradOpName, {2, 3}); + Register(kTileOpName, {1}); + Register(kScatterNdOpName, {2}); + Register(kStridedSliceAssignOpName, {1, 2, 3}); + Register(kStridedSliceOpName, {1, 2, 3}); + Register(kStridedSliceGradOpName, {1, 2, 3, 4}); + Register(kFlattenGradOpName, {1}); + Register(kExpandDimsOpName, {1}); + Register(kSplitOpName, {0}); + Register(kTopKOpName, {1}); + Register(kSparseApplyAdagradOpName, {2}); + Register(kResizeNearestNeighborGrad, {1}); +} + ConstInputToAttrInfoRegistry &ConstInputToAttrInfoRegistry::Instance() { static ConstInputToAttrInfoRegistry instance; return instance; diff --git a/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.h b/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.h index 48007929fb..bd6cac1322 100644 --- a/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.h +++ b/mindspore/ccsrc/pre_activate/pass/const_input_to_attr_registry.h @@ -54,7 +54,7 @@ class ConstInputToAttrInfoRegistry { bool GetRegisterByOpName(const std::string &op_name, ConstInputToAttrInfoRegister *reg) const; private: - ConstInputToAttrInfoRegistry() = default; + ConstInputToAttrInfoRegistry(); ~ConstInputToAttrInfoRegistry() = default; DISABLE_COPY_AND_ASSIGN(ConstInputToAttrInfoRegistry) std::unordered_map op_input_to_attr_map_; diff --git a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.cc b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.cc index 2bef0d36ca..15d62a164f 100644 --- a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.cc +++ b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.cc @@ -87,37 +87,5 @@ const AnfNodePtr ConvertConstInputToAttr::Process(const FuncGraphPtr &, const An ConstInputToAttr(cnode, reg.GetConstInputAttrInfo()); return cnode; } - -void ConvertConstInputToAttr::Init() { - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimCast->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimConv2DBackpropInput->name(), {2}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimConv2DBackpropFilter->name(), {2}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimReshape->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimReduceMax->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimReduceMin->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimReduceSum->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimReduceMean->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimGatherV2->name(), {2}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimTranspose->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimUnsortedSegmentSum->name(), {2}); - ConstInputToAttrInfoRegistry::Instance().Register(prim::kPrimOneHot->name(), {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kUnsortedSegmentProdOpName, {2}); - ConstInputToAttrInfoRegistry::Instance().Register(kUnsortedSegmentMinOpName, {2}); - ConstInputToAttrInfoRegistry::Instance().Register(kSimpleMeanGradOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kMeanGradOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kSliceOpName, {1, 2}); - ConstInputToAttrInfoRegistry::Instance().Register(kSliceGradOpName, {2, 3}); - ConstInputToAttrInfoRegistry::Instance().Register(kTileOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kScatterNdOpName, {2}); - ConstInputToAttrInfoRegistry::Instance().Register(kStridedSliceAssignOpName, {1, 2, 3}); - ConstInputToAttrInfoRegistry::Instance().Register(kStridedSliceOpName, {1, 2, 3}); - ConstInputToAttrInfoRegistry::Instance().Register(kStridedSliceGradOpName, {1, 2, 3, 4}); - ConstInputToAttrInfoRegistry::Instance().Register(kFlattenGradOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kExpandDimsOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kSplitOpName, {0}); - ConstInputToAttrInfoRegistry::Instance().Register(kTopKOpName, {1}); - ConstInputToAttrInfoRegistry::Instance().Register(kSparseApplyAdagradOpName, {2}); - ConstInputToAttrInfoRegistry::Instance().Register(kResizeNearestNeighborGrad, {1}); -} } // namespace opt } // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.h b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.h index 54caa1633c..e124ff8cf4 100644 --- a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.h +++ b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_attr.h @@ -27,14 +27,11 @@ namespace opt { class ConvertConstInputToAttr : public PatternProcessPass { public: explicit ConvertConstInputToAttr(bool multigraph = true) - : PatternProcessPass("convert_const_input_to_attr", multigraph) { - Init(); - } + : PatternProcessPass("convert_const_input_to_attr", multigraph) {} ~ConvertConstInputToAttr() override = default; const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; private: - void Init(); std::unordered_map> op_input_attr_map_; }; } // namespace opt diff --git a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_tensor_input.cc b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_tensor_input.cc index 431a67792d..56be2e273d 100644 --- a/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_tensor_input.cc +++ b/mindspore/ccsrc/pre_activate/pass/convert_const_input_to_tensor_input.cc @@ -19,69 +19,13 @@ #include #include "utils/graph_utils.h" +#include "pre_activate/common/helper.h" #include "session/anf_runtime_algorithm.h" #include "session/kernel_graph.h" namespace mindspore { namespace opt { namespace { -constexpr size_t kType32Len = 4; -template -tensor::TensorPtr CreateTensorWithValueTuple(const ValueTuplePtr &value_tuple_ptr, const TypePtr &type_ptr, - size_t data_length) { - MS_EXCEPTION_IF_NULL(value_tuple_ptr); - MS_EXCEPTION_IF_NULL(type_ptr); - std::vector values; - for (const auto &v : value_tuple_ptr->value()) { - MS_EXCEPTION_IF_NULL(v); - if (v->isa()) { - ScalarPtr scalar = v->cast(); - values.push_back(GetValue(scalar)); - } else { - MS_LOG(WARNING) << "The value " << v << "of tuple is not a scalar"; - return nullptr; - } - } - std::vector tensor_shape = {SizeToInt(values.size())}; - tensor::TensorPtr tensor = std::make_shared(type_ptr->type_id(), tensor_shape); - MS_EXCEPTION_IF_NULL(tensor); - tensor::DeviceInfo device_info{kOpFormat_DEFAULT, type_ptr}; - tensor->set_device_info(device_info); - auto data_ptr = tensor->data_c(true); - MS_EXCEPTION_IF_NULL(data_ptr); - auto elem_num = values.size() * data_length; - auto ret_code = memcpy_s(data_ptr, static_cast(tensor->data().nbytes()), values.data(), elem_num); - if (ret_code != 0) { - MS_LOG(EXCEPTION) << "Failed to copy data into Tensor."; - } - return tensor; -} - -tensor::TensorPtr CreateTupleTensor(const ValueTuplePtr &value_tuple) { - MS_EXCEPTION_IF_NULL(value_tuple); - tensor::TensorPtr tensor = nullptr; - ValuePtr v = *(value_tuple->value().begin()); - MS_EXCEPTION_IF_NULL(v); - // Currently we only deal with the scalar tuple - if (!v->isa()) { - MS_LOG(WARNING) << "The value " << v << "of tuple is not a scalar"; - return nullptr; - } - ScalarPtr scalar = v->cast(); - MS_EXCEPTION_IF_NULL(scalar); - if (scalar->isa()) { - tensor = CreateTensorWithValueTuple(value_tuple, kInt32, kType32Len); - } else if (scalar->isa()) { - tensor = CreateTensorWithValueTuple(value_tuple, kFloat32, kType32Len); - } else { - auto type = scalar->type(); - auto type_str = (type == nullptr) ? "nullptr" : type->ToString(); - MS_LOG(ERROR) << "Invalid scalar type: " << type_str; - return nullptr; - } - return tensor; -} - AnfNodePtr CreateTensorInput(const KernelGraphPtr &kernel_graph, const AnfNodePtr &input_node) { MS_EXCEPTION_IF_NULL(input_node); auto value_node = input_node->cast(); diff --git a/mindspore/ccsrc/pre_activate/pass/convert_tuple_input_to_dynamic_input.cc b/mindspore/ccsrc/pre_activate/pass/convert_tuple_input_to_dynamic_input.cc index 92579111f6..ccc4fd5265 100644 --- a/mindspore/ccsrc/pre_activate/pass/convert_tuple_input_to_dynamic_input.cc +++ b/mindspore/ccsrc/pre_activate/pass/convert_tuple_input_to_dynamic_input.cc @@ -19,6 +19,7 @@ #include #include "session/anf_runtime_algorithm.h" +#include "pre_activate/common/helper.h" #include "session/kernel_graph.h" namespace mindspore { @@ -40,13 +41,7 @@ void ConvertTupleOuputToPlantInputs(const FuncGraphPtr &graph, const AnfNodePtr convert_inputs = kernel_graph->SplitTupleValueNodeToNodeList(value_node); } else { for (size_t index = 0; index < output_size; ++index) { - auto idx = NewValueNode(SizeToInt(index)); - MS_EXCEPTION_IF_NULL(idx); - auto imm = std::make_shared(SizeToInt(index)); - auto abstract_scalar = std::make_shared(imm); - idx->set_abstract(abstract_scalar); - auto tuple_get_item = - graph->NewCNode(std::vector{NewValueNode(prim::kPrimTupleGetItem), input_node, idx}); + auto tuple_get_item = CreatTupleGetItemNode(graph, input_node, index); AnfAlgo::SetOutputInferTypeAndShape({AnfAlgo::GetOutputInferDataType(input_node, index)}, {AnfAlgo::GetOutputInferShape(input_node, index)}, tuple_get_item.get()); convert_inputs.emplace_back(tuple_get_item); diff --git a/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.cc b/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.cc new file mode 100644 index 0000000000..3f283e5d24 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.cc @@ -0,0 +1,79 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pre_activate/pass/convert_tuple_output_to_maketuple.h" + +#include +#include + +#include "session/anf_runtime_algorithm.h" +#include "pre_activate/common/helper.h" +#include "session/kernel_graph.h" + +namespace mindspore { +namespace opt { +namespace { +CNodePtr ConvertTupleInputToMakeTuple(const FuncGraphPtr &graph, const CNodePtr &cnode_ptr) { + MS_EXCEPTION_IF_NULL(cnode_ptr); + MS_EXCEPTION_IF_NULL(graph); + std::vector convert_inputs = {cnode_ptr->input(0)}; + for (size_t index = 0; index < AnfAlgo::GetInputTensorNum(cnode_ptr); ++index) { + auto input_node = AnfAlgo::GetInputNode(cnode_ptr, index); + if (AnfAlgo::IsTupleOutput(input_node)) { + std::vector types; + std::vector> shapes; + std::vector make_tuple_inputs_list = {NewValueNode(prim::kPrimMakeTuple)}; + for (size_t tuple_out_index = 0; tuple_out_index < AnfAlgo::GetOutputTensorNum(input_node); ++tuple_out_index) { + make_tuple_inputs_list.emplace_back(CreatTupleGetItemNode(graph, input_node, tuple_out_index)); + types.push_back(AnfAlgo::GetOutputInferDataType(input_node, tuple_out_index)); + shapes.emplace_back(AnfAlgo::GetOutputInferShape(input_node, tuple_out_index)); + } + auto make_tuple = graph->NewCNode(make_tuple_inputs_list); + AnfAlgo::SetOutputInferTypeAndShape(types, shapes, make_tuple.get()); + convert_inputs.emplace_back(make_tuple); + } else { + convert_inputs.push_back(input_node); + } + } + cnode_ptr->set_inputs(convert_inputs); + return cnode_ptr; +} +} // namespace + +const BaseRef ConvertTupleOutputToMaketuple::DefinePattern() const { + VarPtr V = std::make_shared(); + VarPtr Xs = std::make_shared(); + return VectorRef({V, Xs}); +} + +const AnfNodePtr ConvertTupleOutputToMaketuple::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, + const EquivPtr &) const { + if (node == nullptr || !node->isa()) { + return nullptr; + } + auto cnode = node->cast(); + MS_EXCEPTION_IF_NULL(cnode); + if (AnfAlgo::GetCNodeName(cnode) == prim::kPrimTupleGetItem->name()) { + return nullptr; + } + if (std::any_of(cnode->inputs().begin() + 1, cnode->inputs().end(), [](const AnfNodePtr &node) { + return AnfAlgo::IsTupleOutput(node) && AnfAlgo::GetCNodeName(node) != prim::kPrimMakeTuple->name(); + })) { + return ConvertTupleInputToMakeTuple(func_graph, cnode); + } + return nullptr; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.h b/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.h new file mode 100644 index 0000000000..a16ffaf674 --- /dev/null +++ b/mindspore/ccsrc/pre_activate/pass/convert_tuple_output_to_maketuple.h @@ -0,0 +1,40 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CONVERT_TUPLE_OUTPUT_TO_MAKETUPLE_H +#define MINDSPORE_CONVERT_TUPLE_OUTPUT_TO_MAKETUPLE_H +#include +#include + +#include "ir/anf.h" +#include "pre_activate/common/optimizer.h" + +namespace mindspore { +namespace opt { +class ConvertTupleOutputToMaketuple : public PatternProcessPass { + public: + explicit ConvertTupleOutputToMaketuple(bool multigraph = true) + : PatternProcessPass("convert_tuple_output_to_maketuple", multigraph) {} + + ~ConvertTupleOutputToMaketuple() override = default; + + const BaseRef DefinePattern() const override; + + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CONVERT_TUPLE_OUTPUT_TO_MAKETUPLE_H diff --git a/mindspore/ccsrc/predict/converter/lite_model/operations/conv2d_packer.cc b/mindspore/ccsrc/predict/converter/lite_model/operations/conv2d_packer.cc index 0fefb89c59..176b235f5f 100644 --- a/mindspore/ccsrc/predict/converter/lite_model/operations/conv2d_packer.cc +++ b/mindspore/ccsrc/predict/converter/lite_model/operations/conv2d_packer.cc @@ -28,8 +28,8 @@ bool Conv2dPacker(const CNodePtr &c_node_ptr, OpDefT *ms_op) { std::vector kernel_size_value = AnfAlgo::GetNodeAttr>(c_node_ptr, "kernel_size"); std::string kernel_pad_mode_value = AnfAlgo::GetNodeAttr(c_node_ptr, "pad_mode"); int kernel_pad_value = AnfAlgo::GetNodeAttr(c_node_ptr, "pad"); - int kernel_stride_value = AnfAlgo::GetNodeAttr(c_node_ptr, "stride"); - int kernel_dilation_value = AnfAlgo::GetNodeAttr(c_node_ptr, "dilation"); + auto kernel_stride_value = AnfAlgo::GetNodeAttr>(c_node_ptr, "stride"); + auto kernel_dilation_value = AnfAlgo::GetNodeAttr>(c_node_ptr, "dilation"); std::string kernel_data_format_value = AnfAlgo::GetNodeAttr(c_node_ptr, "data_format"); std::unique_ptr attr(new Conv2DT()); MS_EXCEPTION_IF_NULL(attr); @@ -43,15 +43,15 @@ bool Conv2dPacker(const CNodePtr &c_node_ptr, OpDefT *ms_op) { attr->channelOut = kernel_channel_value; attr->kernelW = kernel_size_value[0]; attr->kernelH = kernel_size_value[1]; - attr->strideW = kernel_stride_value; - attr->strideH = kernel_stride_value; + attr->strideW = kernel_stride_value[0]; + attr->strideH = kernel_stride_value[1]; attr->padMode = GetAttrPadMode(kernel_pad_mode_value); attr->padUp = kernel_pad_value; attr->padDown = kernel_pad_value; attr->padLeft = kernel_pad_value; attr->padRight = kernel_pad_value; - attr->dilateW = kernel_dilation_value; - attr->dilateH = kernel_dilation_value; + attr->dilateW = kernel_dilation_value[0]; + attr->dilateH = kernel_dilation_value[1]; attr->hasBias = false; ms_op->name = c_node_ptr->fullname_with_scope(); ms_op->attr.type = OpT_Conv2D; diff --git a/mindspore/ccsrc/pynative/pynative_execute.cc b/mindspore/ccsrc/pynative/pynative_execute.cc index e5fb0c6949..6a1ddf6a7e 100644 --- a/mindspore/ccsrc/pynative/pynative_execute.cc +++ b/mindspore/ccsrc/pynative/pynative_execute.cc @@ -20,11 +20,13 @@ #include #include #include +#include #include "utils/any.h" #include "utils/utils.h" #include "utils/context/ms_context.h" #include "operator/ops.h" +#include "operator/composite/do_signature.h" #include "pipeline/parse/data_converter.h" #include "pipeline/static_analysis/prim.h" #include "session/session_factory.h" @@ -37,7 +39,7 @@ const char SINGLE_OP_GRAPH[] = "single_op_graph"; // primitive unable to infer value for constant input in PyNative mode -const std::unordered_set vm_operators = {"partial", "depend"}; +const std::unordered_set vm_operators = {"partial", "depend", "make_ref"}; namespace mindspore { namespace pynative { @@ -50,6 +52,57 @@ inline ValuePtr PyAttrValue(const py::object& obj) { return converted_ret; } +py::tuple ConvertInputs(const PrimitivePyPtr& prim, const py::tuple& py_args) { + auto signature = prim->signatures(); + std::vector dtypes; + (void)std::transform(signature.begin(), signature.end(), std::back_inserter(dtypes), + [](const Signature& sig) { return sig.dtype; }); + int empty_dtype_count = std::count(dtypes.begin(), dtypes.end(), SignatureEnumDType::kDTypeEmptyDefaultValue); + if (dtypes.size() == 0 || static_cast(dtypes.size()) == empty_dtype_count) { + return py_args; + } + std::map> type_indexs; + for (size_t i = 0; i < dtypes.size(); ++i) { + auto it = type_indexs.find(dtypes[i]); + if (it == type_indexs.end()) { + (void)type_indexs.insert(std::make_pair(dtypes[i], std::vector{i})); + } else { + it->second.push_back(i); + } + } + std::map dst_type; + for (auto it = type_indexs.begin(); it != type_indexs.end(); (void)++it) { + auto type = it->first; + auto indexs = it->second; + if (indexs.size() < 2) { + continue; + } + size_t m_index = indexs[0]; + for (size_t i = 1; i < indexs.size(); ++i) { + if (py::isinstance(py_args[indexs[i]])) { + m_index = indexs[i]; + } + } + (void)dst_type.insert(std::make_pair(type, m_index)); + } + py::tuple py_inputs(py_args.size()); + for (size_t i = 0; i < py_args.size(); ++i) { + auto it = dst_type.find(dtypes[i]); + if (it != dst_type.end() && it->second != i && + (py::isinstance(py_args[i]) || py::isinstance(py_args[i]))) { + auto tensor_ptr = py::cast(py_args[it->second]); + if (py::isinstance(py_args[i])) { + py_inputs[i] = std::make_shared(py::cast(py_args[i]), tensor_ptr->Dtype()); + } else { + py_inputs[i] = std::make_shared(py::cast(py_args[i]), tensor_ptr->Dtype()); + } + continue; + } + py_inputs[i] = py_args[i]; + } + return py_inputs; +} + void PynativeInfer(const PrimitivePyPtr& prim, const py::tuple& py_args, OpExecInfo* const op_exec_info) { size_t size = py_args.size(); AbstractBasePtrList args_spec_list; @@ -73,30 +126,22 @@ OpExecInfoPtr GenerateOpExecInfo(const py::args& args) { auto op_exec_info = std::make_shared(); MS_EXCEPTION_IF_NULL(op_exec_info); op_exec_info->op_name = py::cast(args[PY_NAME]); - if (py::isinstance(args[PY_PRIM])) { - py::module ops_mod = py::module::import("mindspore.ops.operations"); - py::object py_primitive = ops_mod.attr(op_exec_info->op_name.c_str())(); - op_exec_info->py_primitive = py::cast(py_primitive); - py::dict none_attrs = py::dict(); - op_exec_info->op_attrs = none_attrs; - } else { - PrimitivePyPtr prim = py::cast(args[PY_PRIM]); - auto pyobj = prim->GetPyObj(); - if (pyobj == nullptr) { - MS_LOG(EXCEPTION) << "pyobj is empty"; - } - py::tuple py_args = args[PY_INPUTS]; - // use python infer method - if (ignore_infer_prim.find(op_exec_info->op_name) == ignore_infer_prim.end()) { - PynativeInfer(prim, py_args, op_exec_info.get()); - } - op_exec_info->py_primitive = prim; - op_exec_info->op_attrs = py::getattr(args[PY_PRIM], "attrs"); + auto prim = py::cast(args[PY_PRIM]); + auto pyobj = prim->GetPyObj(); + if (pyobj == nullptr) { + MS_LOG(EXCEPTION) << "pyobj is empty"; + } + py::tuple py_args = ConvertInputs(prim, args[PY_INPUTS]); + // use python infer method + if (ignore_infer_prim.find(op_exec_info->op_name) == ignore_infer_prim.end()) { + PynativeInfer(prim, py_args, op_exec_info.get()); } - op_exec_info->op_inputs = args[PY_INPUTS]; + op_exec_info->py_primitive = prim; + op_exec_info->op_attrs = py::getattr(args[PY_PRIM], "attrs"); + op_exec_info->op_inputs = py_args; op_exec_info->inputs_mask = args[PY_INPUT_MASK]; if (op_exec_info->op_inputs.size() != op_exec_info->inputs_mask.size()) { - MS_LOG(ERROR) << "" << op_exec_info->op_name << " op_inputs size not equal op_mask"; + MS_LOG(ERROR) << "Op:" << op_exec_info->op_name << " inputs size not equal op_mask"; return nullptr; } return op_exec_info; @@ -118,7 +163,7 @@ std::string GetSingleOpGraphInfo(const OpExecInfoPtr& op_exec_info) { // get prim and abstract info (void)graph_info.append(std::to_string((uintptr_t)(op_exec_info->py_primitive.get())) + "_" + op_exec_info->abstract->ToString()); - MS_LOG(INFO) << "graph info [" << graph_info << "]"; + MS_LOG(INFO) << "Graph info [" << graph_info << "]"; return graph_info; } @@ -158,8 +203,9 @@ py::object RunOpInMs(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* stat session->Init(ms_context->device_id()); std::string graph_info = GetSingleOpGraphInfo(op_exec_info); - session->BuildOp(*op_exec_info, graph_info); - py::tuple result = session->RunOp(*op_exec_info, graph_info); + std::vector input_tensors; + session->BuildOp(*op_exec_info, graph_info, &input_tensors); + py::tuple result = session->RunOp(*op_exec_info, graph_info, input_tensors); ms_context->set_enable_pynative_infer(false); *status = PYNATIVE_SUCCESS; return result; diff --git a/mindspore/ccsrc/session/anf_runtime_algorithm.cc b/mindspore/ccsrc/session/anf_runtime_algorithm.cc index 78922448af..2591f763c5 100644 --- a/mindspore/ccsrc/session/anf_runtime_algorithm.cc +++ b/mindspore/ccsrc/session/anf_runtime_algorithm.cc @@ -84,6 +84,7 @@ KernelWithIndex AnfRuntimeAlgorithm::VisitKernel(const AnfNodePtr &anf_node, siz } KernelWithIndex AnfRuntimeAlgorithm::VisitKernelWithReturnType(const AnfNodePtr &anf_node, size_t index, + bool visit_nop_node, const std::vector &return_types) { MS_EXCEPTION_IF_NULL(anf_node); for (const auto &prim_type : return_types) { @@ -109,9 +110,16 @@ KernelWithIndex AnfRuntimeAlgorithm::VisitKernelWithReturnType(const AnfNodePtr auto value_node = input2->cast(); MS_EXCEPTION_IF_NULL(value_node); int item_idx = GetValue(value_node->value()); - return VisitKernelWithReturnType(cnode->input(kRealInputNodeIndexInTupleGetItem), IntToSize(item_idx)); + return VisitKernelWithReturnType(cnode->input(kRealInputNodeIndexInTupleGetItem), IntToSize(item_idx), + visit_nop_node); } else if (IsPrimitive(input0, prim::kPrimDepend) || IsPrimitive(input0, prim::kPrimControlDepend)) { - return VisitKernelWithReturnType(cnode->input(kRealInputIndexInDepend), 0); + return VisitKernelWithReturnType(cnode->input(kRealInputIndexInDepend), 0, visit_nop_node); + } else if (opt::IsNopNode(cnode) && visit_nop_node) { + if (cnode->inputs().size() == 2) { + return VisitKernelWithReturnType(cnode->input(1), 0, visit_nop_node); + } else { + MS_LOG(EXCEPTION) << cnode->DebugString() << "Invalid nop node"; + } } else { return std::make_pair(anf_node, index); } @@ -126,7 +134,7 @@ std::vector AnfRuntimeAlgorithm::GetAllOutput(const AnfNodePtr &node auto return_prim_type = return_types; // if visited make_tuple should return back return_prim_type.push_back(prim::kPrimMakeTuple); - auto item_with_index = AnfAlgo::VisitKernelWithReturnType(node, 0, return_prim_type); + auto item_with_index = AnfAlgo::VisitKernelWithReturnType(node, 0, false, return_prim_type); if (AnfAlgo::CheckPrimitiveType(item_with_index.first, prim::kPrimMakeTuple)) { MS_EXCEPTION_IF_NULL(item_with_index.first); auto make_tuple = item_with_index.first->cast(); @@ -283,6 +291,11 @@ size_t AnfRuntimeAlgorithm::GetOutputTensorNum(const AnfNodePtr &node) { std::string AnfRuntimeAlgorithm::GetOutputFormat(const AnfNodePtr &node, size_t output_idx) { MS_EXCEPTION_IF_NULL(node); + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "Output index:" << output_idx + << " is out of the node output range :" << GetOutputTensorNum(node) << " #node [" + << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); @@ -292,6 +305,11 @@ std::string AnfRuntimeAlgorithm::GetOutputFormat(const AnfNodePtr &node, size_t std::string AnfRuntimeAlgorithm::GetInputFormat(const AnfNodePtr &node, size_t input_idx) { MS_EXCEPTION_IF_NULL(node); + if (input_idx > GetInputTensorNum(node)) { + MS_LOG(EXCEPTION) << "Input index :" << input_idx + << " is out of the number node Input range :" << GetInputTensorNum(node) << "#node [" + << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); @@ -299,20 +317,23 @@ std::string AnfRuntimeAlgorithm::GetInputFormat(const AnfNodePtr &node, size_t i return build_info->GetInputFormat(input_idx); } -std::string AnfRuntimeAlgorithm::GetPrevNodeOutputFormat(const AnfNodePtr &anf_node, size_t input_idx) { +KernelWithIndex AnfRuntimeAlgorithm::GetPrevNodeOutput(const AnfNodePtr &anf_node, size_t input_idx) { MS_EXCEPTION_IF_NULL(anf_node); if (!anf_node->isa()) { - MS_LOG(EXCEPTION) << "anf_node is not CNode."; + MS_LOG(EXCEPTION) << anf_node->DebugString() << "anf_node is not CNode."; } auto cnode = anf_node->cast(); MS_EXCEPTION_IF_NULL(cnode); if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode) - << "."; + MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode); } auto node = cnode->input(input_idx + 1); MS_EXCEPTION_IF_NULL(node); - KernelWithIndex kernel_with_index = VisitKernel(node, 0); + return VisitKernel(node, 0); +} + +std::string AnfRuntimeAlgorithm::GetPrevNodeOutputFormat(const AnfNodePtr &anf_node, size_t input_idx) { + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(anf_node, input_idx); return AnfRuntimeAlgorithm::GetOutputFormat(kernel_with_index.first, kernel_with_index.second); } @@ -346,80 +367,67 @@ std::vector AnfRuntimeAlgorithm::GetOutputInferShape(const AnfNodePtr &n } std::vector AnfRuntimeAlgorithm::GetPrevNodeOutputInferShape(const AnfNodePtr &node, size_t input_idx) { - MS_EXCEPTION_IF_NULL(node); - if (!node->isa()) { - MS_LOG(EXCEPTION) << "anf_node is not CNode."; - } - auto cnode = node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode) - << "."; - } - auto input_node = cnode->input(input_idx + 1); - KernelWithIndex kernel_with_index = VisitKernel(input_node, 0); + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(node, input_idx); return AnfRuntimeAlgorithm::GetOutputInferShape(kernel_with_index.first, kernel_with_index.second); } std::vector AnfRuntimeAlgorithm::GetOutputDeviceShape(const AnfNodePtr &node, size_t output_idx) { auto format = GetOutputFormat(node, output_idx); auto infer_shape = GetOutputInferShape(node, output_idx); - // if format is default_format or NC1KHKWHWC0,device shape = original shape - if (format == kOpFormat_DEFAULT || format == kOpFormat_NC1KHKWHWC0) { - return infer_shape; - } - // scalar shape if (infer_shape.empty()) { return infer_shape; } - if (format == kOpFormat_FRAC_NZ) { - return trans::TransShapeToDevice(infer_shape, format); + // if format is default_format or NC1KHKWHWC0,device shape = original shape + if (trans::IsNeedPadding(format, infer_shape.size())) { + infer_shape = trans::PaddingShapeTo4d(infer_shape, GetOutputReshapeType(node, output_idx)); } - // else trans infer shape to 4d and then calculate device shape - return trans::TransShapeToDevice(trans::TransShapeTo4d(infer_shape), format); + return trans::TransShapeToDevice(infer_shape, format); } std::vector AnfRuntimeAlgorithm::GetInputDeviceShape(const AnfNodePtr &node, size_t input_idx) { auto format = GetInputFormat(node, input_idx); auto infer_shape = GetPrevNodeOutputInferShape(node, input_idx); - // if format is default_format or NC1KHKWHWC0,device shape = original shape - if (format == kOpFormat_DEFAULT || format == kOpFormat_NC1KHKWHWC0) { - return infer_shape; - } if (infer_shape.empty()) { return infer_shape; } - if (format == kOpFormat_FRAC_NZ) { - return trans::TransShapeToDevice(infer_shape, format); + // if format is default_format or NC1KHKWHWC0,device shape = original shape + if (trans::IsNeedPadding(format, infer_shape.size())) { + infer_shape = trans::PaddingShapeTo4d(infer_shape, GetInputReshapeType(node, input_idx)); } - // else trans infer shape to 4d and then calculate device shape - return trans::TransShapeToDevice(trans::TransShapeTo4d(infer_shape), format); + return trans::TransShapeToDevice(infer_shape, format); } std::vector AnfRuntimeAlgorithm::GetInputReshapeType(const AnfNodePtr &node, size_t input_idx) { MS_EXCEPTION_IF_NULL(node); + if (input_idx > GetInputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index:" << input_idx + << " is out of range of the node's input size : " << GetInputTensorNum(node) << "#node[" + << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); MS_EXCEPTION_IF_NULL(build_info); - std::vector result; - if (!build_info->GetInputReshapeType(input_idx, &result)) { - MS_LOG(EXCEPTION) << "Failed to get the node's[ " << node->DebugString() << "] reshape type !"; + if (build_info->IsInputDefaultPadding()) { + return {}; } - return result; + return build_info->GetInputReshapeType(input_idx); } std::vector AnfRuntimeAlgorithm::GetOutputReshapeType(const AnfNodePtr &node, size_t output_idx) { MS_EXCEPTION_IF_NULL(node); + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << output_idx << "] is out of range of the node's output size [ " + << GetOutputTensorNum(node) << "#node[ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); MS_EXCEPTION_IF_NULL(build_info); - std::vector result; - if (!build_info->GetOutputReshapeType(output_idx, &result)) { - MS_LOG(EXCEPTION) << "Failed to get the node's[ " << node->DebugString() << "] reshape type !"; + if (build_info->IsOutputDefaultPadding()) { + return {}; } - return result; + return build_info->GetOutputReshapeType(output_idx); } TypeId AnfRuntimeAlgorithm::GetOutputInferDataType(const AnfNodePtr &node, size_t output_idx) { @@ -449,7 +457,7 @@ TypeId AnfRuntimeAlgorithm::GetOutputInferDataType(const AnfNodePtr &node, size_ } else if (tuple_i->isa()) { return tuple_i->type_id(); } else { - MS_LOG(EXCEPTION) << "Not support type " << tuple_i->ToString(); + MS_LOG(WARNING) << "Not support type " << tuple_i->ToString(); return tuple_i->type_id(); } } else if (type_ptr->isa()) { @@ -459,22 +467,16 @@ TypeId AnfRuntimeAlgorithm::GetOutputInferDataType(const AnfNodePtr &node, size_ } TypeId AnfRuntimeAlgorithm::GetPrevNodeOutputInferDataType(const AnfNodePtr &node, size_t input_idx) { - MS_EXCEPTION_IF_NULL(node); - if (!node->isa()) { - MS_LOG(EXCEPTION) << node->DebugString() << "is not a CNode"; - } - auto cnode = node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode); - } - auto input_node = cnode->input(input_idx + 1); - KernelWithIndex kernel_with_index = VisitKernel(input_node, 0); + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(node, input_idx); return AnfRuntimeAlgorithm::GetOutputInferDataType(kernel_with_index.first, kernel_with_index.second); } TypeId AnfRuntimeAlgorithm::GetOutputDeviceDataType(const AnfNodePtr &node, size_t output_idx) { MS_EXCEPTION_IF_NULL(node); + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << output_idx << "] is out of range of the node's output size [ " + << GetOutputTensorNum(node) << "#node [ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); @@ -484,6 +486,10 @@ TypeId AnfRuntimeAlgorithm::GetOutputDeviceDataType(const AnfNodePtr &node, size TypeId AnfRuntimeAlgorithm::GetInputDeviceDataType(const AnfNodePtr &node, size_t input_idx) { MS_EXCEPTION_IF_NULL(node); + if (input_idx > GetInputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << input_idx << "] is out of range of the node's input size [ " + << GetInputTensorNum(node) << "#node [ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto build_info = kernel_info->select_kernel_build_info(); @@ -492,17 +498,7 @@ TypeId AnfRuntimeAlgorithm::GetInputDeviceDataType(const AnfNodePtr &node, size_ } TypeId AnfRuntimeAlgorithm::GetPrevNodeOutputDeviceDataType(const AnfNodePtr &anf_node, size_t input_idx) { - if (!anf_node->isa()) { - MS_LOG(EXCEPTION) << anf_node->DebugString() << "anf_node is not CNode."; - } - auto cnode = anf_node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode); - } - auto node = cnode->input(input_idx + 1); - MS_EXCEPTION_IF_NULL(node); - KernelWithIndex kernel_with_index = VisitKernel(node, 0); + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(anf_node, input_idx); return AnfRuntimeAlgorithm::GetOutputDeviceDataType(kernel_with_index.first, kernel_with_index.second); } @@ -518,11 +514,15 @@ const DeviceAddress *AnfRuntimeAlgorithm::GetOutputAddr(const AnfNodePtr &node, MS_LOG(EXCEPTION) << node->DebugString() << "Invalid nop node"; } } + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << output_idx << "] is out of range of the node's output size [ " + << GetOutputTensorNum(node) << "#node:[ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto addr = kernel_info->GetOutputAddr(output_idx); if (addr == nullptr) { - MS_LOG(EXCEPTION) << "output_idx " << output_idx << " of node " << node->DebugString() + MS_LOG(EXCEPTION) << "Output_idx " << output_idx << " of node " << node->DebugString() << " output addr is not exist"; } return addr; @@ -539,11 +539,15 @@ DeviceAddressPtr AnfRuntimeAlgorithm::GetMutableOutputAddr(const AnfNodePtr &nod MS_LOG(EXCEPTION) << node->DebugString() << "Invalid nop node."; } } + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << output_idx << "] is out of range of the node's output size [ " + << GetOutputTensorNum(node) << "#node:[ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); auto addr = kernel_info->GetMutableOutputAddr(output_idx); if (addr == nullptr) { - MS_LOG(EXCEPTION) << "output_idx" << output_idx << " of node " << node->DebugString() + MS_LOG(EXCEPTION) << "Output_idx" << output_idx << " of node " << node->DebugString() << " output addr is not exist"; } return addr; @@ -552,38 +556,22 @@ DeviceAddressPtr AnfRuntimeAlgorithm::GetMutableOutputAddr(const AnfNodePtr &nod // get output device addr of anf_node bool AnfRuntimeAlgorithm::OutputAddrExist(const AnfNodePtr &node, size_t output_idx) { MS_EXCEPTION_IF_NULL(node); + if (output_idx > GetOutputTensorNum(node)) { + MS_LOG(EXCEPTION) << "The index [" << output_idx << "] is out of range of the node's output size [ " + << GetOutputTensorNum(node) << "#node:[ " << node->DebugString() << "]"; + } auto kernel_info = node->kernel_info(); MS_EXCEPTION_IF_NULL(kernel_info); return kernel_info->OutputAddrExist(output_idx); } const DeviceAddress *AnfRuntimeAlgorithm::GetPrevNodeOutputAddr(const AnfNodePtr &anf_node, size_t input_idx) { - if (!anf_node->isa()) { - MS_LOG(EXCEPTION) << anf_node->DebugString() << "anf node is not a CNode"; - } - auto cnode = anf_node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode); - } - auto node = cnode->input(input_idx + 1); - MS_EXCEPTION_IF_NULL(node); - KernelWithIndex kernel_with_index = VisitKernel(node, 0); + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(anf_node, input_idx); return AnfRuntimeAlgorithm::GetOutputAddr(kernel_with_index.first, kernel_with_index.second); } DeviceAddressPtr AnfRuntimeAlgorithm::GetPrevNodeMutableOutputAddr(const AnfNodePtr &anf_node, size_t input_idx) { - if (!anf_node->isa()) { - MS_LOG(EXCEPTION) << anf_node->DebugString() << "anf_node is not CNode."; - } - auto cnode = anf_node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (input_idx + 1 >= cnode->inputs().size()) { - MS_LOG(EXCEPTION) << "Input index " << input_idx << " is larger than input number " << GetInputTensorNum(cnode); - } - auto node = cnode->input(input_idx + 1); - MS_EXCEPTION_IF_NULL(node); - KernelWithIndex kernel_with_index = VisitKernel(node, 0); + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(anf_node, input_idx); return AnfRuntimeAlgorithm::GetMutableOutputAddr(kernel_with_index.first, kernel_with_index.second); } @@ -726,7 +714,8 @@ bool AnfRuntimeAlgorithm::IsRealKernel(const AnfNodePtr &node) { } auto input = cnode->inputs()[0]; bool is_virtual_node = IsPrimitive(input, prim::kPrimImageSummary) || IsPrimitive(input, prim::kPrimScalarSummary) || - IsPrimitive(input, prim::kPrimTensorSummary) || IsPrimitive(input, prim::kPrimMakeTuple) || + IsPrimitive(input, prim::kPrimTensorSummary) || + IsPrimitive(input, prim::kPrimHistogramSummary) || IsPrimitive(input, prim::kPrimMakeTuple) || IsPrimitive(input, prim::kPrimStateSetItem) || IsPrimitive(input, prim::kPrimDepend) || IsPrimitive(input, prim::kPrimTupleGetItem) || IsPrimitive(input, prim::kPrimControlDepend) || IsPrimitive(input, prim::kPrimReturn); @@ -811,22 +800,24 @@ AnfNodePtr AnfRuntimeAlgorithm::GetInputNode(const CNodePtr &node, size_t index) return node->input(get_input_index); } +bool AnfRuntimeAlgorithm::IsFeatureMapOutput(const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + if (node->isa()) { + return false; + } + auto kernel_info = node->kernel_info(); + MS_EXCEPTION_IF_NULL(kernel_info); + return kernel_info->is_feature_map(); +} + bool AnfRuntimeAlgorithm::IsFeatureMapInput(const AnfNodePtr &node, size_t input_index) { if (!node->isa()) { - MS_LOG(EXCEPTION) << "Cannot input a parameter or a valuenode to charge it's input if is a feature"; + MS_LOG(EXCEPTION) << "Cannot input a parameter or a valuenode to charge it's input if is a feature map"; } auto cnode = node->cast(); MS_EXCEPTION_IF_NULL(cnode); auto input_node = cnode->input(input_index + 1); - auto node_with_index = VisitKernel(input_node, 0); - MS_EXCEPTION_IF_NULL(node_with_index.first); - if (node_with_index.first->isa()) { - return false; - } - if (node_with_index.first->isa()) { - return !AnfAlgo::IsParameterWeight(node_with_index.first->cast()); - } - return true; + return IsFeatureMapOutput(input_node); } size_t AnfRuntimeAlgorithm::GetRealInputIndex(const mindspore::AnfNodePtr &anf_node, const size_t cur_index) { @@ -867,5 +858,18 @@ bool AnfRuntimeAlgorithm::IsCommunicationOp(const AnfNodePtr &node) { } return false; } + +bool AnfRuntimeAlgorithm::IsAllReduceOp(const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + if (node->isa() && AnfAlgo::GetCNodeName(node) == kAllReduceOpName) { + return true; + } + return false; +} + +bool AnfRuntimeAlgorithm::IsGetNext(const NotNull &node) { + auto kernel_name = AnfAlgo::GetCNodeName(node); + return kernel_name == kGetNextOpName; +} } // namespace session } // namespace mindspore diff --git a/mindspore/ccsrc/session/anf_runtime_algorithm.h b/mindspore/ccsrc/session/anf_runtime_algorithm.h index 55650ac31e..78359cdd5a 100644 --- a/mindspore/ccsrc/session/anf_runtime_algorithm.h +++ b/mindspore/ccsrc/session/anf_runtime_algorithm.h @@ -31,6 +31,7 @@ #include "kernel/kernel.h" #include "kernel/kernel_build_info.h" #include "operator/ops.h" +#include "utils/contract.h" namespace mindspore { namespace session { @@ -41,6 +42,7 @@ class AnfRuntimeAlgorithm { // get input_anf_node's real kernel by recurse static KernelWithIndex VisitKernel(const AnfNodePtr &input_anf_node, size_t output_index); static KernelWithIndex VisitKernelWithReturnType(const AnfNodePtr &input_anf_node, size_t output_index, + bool visit_nop_node = false, const std::vector &return_types = { prim::kPrimMakeTuple}); static std::vector GetAllOutput(const AnfNodePtr &node, @@ -89,6 +91,8 @@ class AnfRuntimeAlgorithm { static std::string GetOutputFormat(const AnfNodePtr &node, size_t output_idx); // get input format select of anf node static std::string GetInputFormat(const AnfNodePtr &node, size_t input_idx); + // get prev node output width output index + static KernelWithIndex GetPrevNodeOutput(const AnfNodePtr &anf_node, size_t input_idx); // get output format from prev node,input_index is the input index of current node related to prev node static std::string GetPrevNodeOutputFormat(const AnfNodePtr &node, size_t input_idx); // get output shapes inferred by ME from input nodes. @@ -99,7 +103,9 @@ class AnfRuntimeAlgorithm { static std::vector GetOutputDeviceShape(const AnfNodePtr &node, size_t output_idx); // get input shapes which will built and run in device static std::vector GetInputDeviceShape(const AnfNodePtr &node, size_t input_idx); + // Get Input Padding Axis static std::vector GetInputReshapeType(const AnfNodePtr &node, size_t output_idx); + // Get Output Padding Axis static std::vector GetOutputReshapeType(const AnfNodePtr &node, size_t output_idx); // get output data type inferred by ME of anf node static TypeId GetOutputInferDataType(const AnfNodePtr &node, size_t output_idx); @@ -163,10 +169,15 @@ class AnfRuntimeAlgorithm { // get graph id static uint32_t GetGraphId(const AnfNode *node); static AnfNodePtr GetInputNode(const CNodePtr &node, size_t index); + // charge if the node's output is a feature map output + static bool IsFeatureMapOutput(const AnfNodePtr &node); + // charge if the node's input is from a feature map output static bool IsFeatureMapInput(const AnfNodePtr &node, size_t input_index); // get real input index for some tbe ops which input order is different between me and tbe impl static size_t GetRealInputIndex(const AnfNodePtr &anf_node, const size_t cur_index); static bool IsCommunicationOp(const AnfNodePtr &node); + static bool IsAllReduceOp(const AnfNodePtr &node); + static bool IsGetNext(const NotNull &node); }; } // namespace session using AnfAlgo = session::AnfRuntimeAlgorithm; diff --git a/mindspore/ccsrc/session/ascend_session.cc b/mindspore/ccsrc/session/ascend_session.cc old mode 100644 new mode 100755 index 34c05aed08..ad6c58bc93 --- a/mindspore/ccsrc/session/ascend_session.cc +++ b/mindspore/ccsrc/session/ascend_session.cc @@ -18,6 +18,7 @@ #include "operator/ops.h" #include "ir/meta_tensor.h" #include "ir/anf.h" +#include "common/trans.h" #include "device/kernel_runtime.h" #include "device/ascend/kernel_select_ascend.h" #include "device/ascend/kernel_build_ascend.h" @@ -91,6 +92,51 @@ GraphId GetDistinctionLabel(const KernelGraphPtr &graph) { // else use first node of execution order as label return AnfAlgo::GetStreamDistinctionLabel(graph->execution_order()[0].get()); } + +std::vector GetRealArgs(const KernelGraphPtr graph, const VectorRef &args) { + MS_EXCEPTION_IF_NULL(graph); + std::vector graph_inputs = graph->inputs(); + auto valid_inputs = graph->ValidInputs(); + size_t real_args_size = 0; + std::vector real_args = {}; + for (size_t i = 0; i < args.size(); i++) { + if (utils::isa(args[i])) { + auto tmp_args = AnfAlgo::GetAllOutput(utils::cast(args[i]), {prim::kPrimTupleGetItem}); + for (auto &real_arg : tmp_args) { + auto anf_node = utils::cast(real_arg); + MS_EXCEPTION_IF_NULL(anf_node); + auto abstract = anf_node->abstract(); + MS_EXCEPTION_IF_NULL(abstract); + // create multiple parameters if is a tuple output real kernel + if (abstract->isa() && + !AnfAlgo::CheckPrimitiveType(anf_node, prim::kPrimTupleGetItem)) { + auto tuple_abstract = abstract->cast(); + real_args_size += tuple_abstract->size(); + continue; + } + real_args_size += 1; + real_args.push_back(real_arg); + } + } else { + real_args_size += 1; + real_args.push_back(args[i]); + } + } + if (graph_inputs.size() != valid_inputs.size()) { + MS_LOG(EXCEPTION) << "graph_inputs.size(): " << graph_inputs.size() + << ", valid_inputs.size(): " << valid_inputs.size() << " not equal"; + } + if (real_args_size != graph_inputs.size()) { + for (size_t j = 0; j < valid_inputs.size(); j++) { + if (valid_inputs[j]) { + MS_LOG(INFO) << "index: " << j << ", nodes: " << graph_inputs[j]->DebugString(); + } + } + MS_LOG(WARNING) << "real_args_size: " << real_args_size << ", graph_inputs.size(): " << graph_inputs.size() + << " not equal"; + } + return real_args; +} } // namespace GraphId AscendSession::CompileGraph(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) { @@ -186,7 +232,7 @@ void AscendSession::RunGraph(const GraphId &graph_id, const std::vector &kernel_graph) const { MS_LOG(INFO) << "Start"; // data layout optimization - opt::AscendDataLayout(kernel_graph); + opt::RunOpAscendDataLayout(kernel_graph); // mixed precision optimization opt::AscendMixPrecision(kernel_graph); MS_LOG(INFO) << "Finish"; @@ -203,10 +249,12 @@ void AscendSession::RunOpExecTask(const std::shared_ptr &kernel_gra MS_LOG(INFO) << "Finish!"; } -void AscendSession::BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) { +void AscendSession::BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + std::vector *input_tensors) { + MS_EXCEPTION_IF_NULL(input_tensors); MS_LOG(INFO) << "Build op " << op_run_info.op_name << " start !"; // construct graph include one op - auto graph = ConstructSingleOpGraph(op_run_info); + auto graph = ConstructSingleOpGraph(op_run_info, input_tensors); MS_EXCEPTION_IF_NULL(graph); opt::RunOpAscendBackendIRFusionOptimization(graph); // kernel select @@ -221,14 +269,12 @@ void AscendSession::BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph run_op_graphs_[graph_info] = graph; } -py::tuple AscendSession::RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) { +py::tuple AscendSession::RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + const std::vector &input_tensors) { auto graph = run_op_graphs_[graph_info]; MS_EXCEPTION_IF_NULL(graph); MS_LOG(INFO) << "Run op " << op_run_info.op_name << " start!"; // malloc mem - std::vector input_tensors = {}; - std::vector tensors_mask = {}; - ToTensorPtr(op_run_info, &input_tensors, &tensors_mask); RunOpMemoryAlloc(input_tensors, graph.get()); // load input data to device LoadInputData(graph, input_tensors); @@ -506,11 +552,13 @@ void AscendSession::InsertSwitchToGraph(GraphId condition_graph_id, GraphId true kernel_build_info_builder->SetFusionType(kernel::FusionType::OPAQUE); kernel_build_info_builder->SetProcessor(kernel::Processor::AICORE); kernel_build_info_builder->SetKernelType(KernelType::RT_KERNEL); - // condition graph's output must be single output - if (condition_graph->outputs().size() != 1) { - MS_LOG(EXCEPTION) << "Condition_graph output num " << condition_graph_id << " should be 1"; + auto cond_output_it = condition_output_.find(condition_graph_id); + if (cond_output_it == condition_output_.end()) { + MS_LOG(EXCEPTION) << "Can't find condition graph" << condition_graph_id; } - AnfNodePtr cond_output_kernel = condition_graph->outputs()[0]; + auto cond_output_kernel = + AnfAlgo::VisitKernel(condition_graph->GetBackendAnfByFrontAnf(cond_output_it->second), 0).first; + MS_EXCEPTION_IF_NULL(cond_output_kernel); std::vector inputs = {NewValueNode(switch_primitive), cond_output_kernel, counter_const}; CNodePtr switch_node = condition_graph->NewCNode(inputs); AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info_builder->Build(), switch_node.get()); @@ -569,12 +617,14 @@ void AscendSession::CopyOutputOfIf(GraphId false_graph_id) { } } -void AscendSession::SwitchCompile(GraphId cond_graph_id, GraphId true_graph_id, GraphId false_graph_id) { +void AscendSession::SwitchCompile(GraphId cond_graph_id, GraphId true_graph_id, GraphId false_graph_id, + const AnfNodePtr &output) { if (switches_.find(cond_graph_id) != switches_.end()) { MS_LOG(WARNING) << "Condition graph" << cond_graph_id << " has been set before "; return; } switches_[cond_graph_id] = std::pair(true_graph_id, false_graph_id); + condition_output_[cond_graph_id] = output; MS_LOG(INFO) << "New switch compile " << cond_graph_id << " " << true_graph_id << " " << false_graph_id; // set the type of condition graph auto cond_graph_index = ExecOrderOfChildGraph(final_graph_id_, cond_graph_id); @@ -682,12 +732,14 @@ void AscendSession::SetChildGraphParameter(const AnfNodePtr &front_anf, const An auto from_graph_id = GetGraphIdByNode(front_anf); auto from_graph = GetGraph(from_graph_id); MS_EXCEPTION_IF_NULL(from_graph); - + auto to_graph_id = AnfAlgo::GetGraphId(backend_parameter.get()); + auto to_graph = GetGraph(to_graph_id); + auto backend_arg = from_graph->GetBackendAnfByFrontAnf(front_anf); + MS_EXCEPTION_IF_NULL(to_graph); MS_LOG(INFO) << "Set node[" << front_anf->DebugString() << "] of graph[" << from_graph_id << "]to node[" << backend_parameter->DebugString() << "] of graph[" << AnfAlgo::GetGraphId(backend_parameter.get()) << "]"; // a node should not assign to itself - auto backend_arg = from_graph->GetBackendAnfByFrontAnf(front_anf); if (backend_arg.get() == backend_parameter.get()) { return; } @@ -702,17 +754,17 @@ void AscendSession::SetChildGraphParameter(const AnfNodePtr &front_anf, const An << "of graph " << AnfAlgo::GetGraphId(backend_arg.get()); return; } + // if a parameter is a weight and not linked to any executable node,device type will be kTypeUnknown,set it's device + // type same to arg + if (AnfAlgo::GetOutputDeviceDataType(backend_parameter, 0) == kTypeUnknown) { + AnfAlgo::SetSelectKernelBuildInfo(AnfAlgo::GetSelectKernelBuildInfo(backend_arg), backend_parameter.get()); + } + // if front anf is a parameter,we can assign the value back,because backend_parameter won't be change in it's graph + // unless it's a weight.If backend_parameter is a weight,we should assign the value back. + AnfAlgo::SetOutputAddr(AnfAlgo::GetMutableOutputAddr(backend_arg, 0), 0, backend_parameter.get()); + return; } - InsertMultipleAssignToGraph(from_graph_id, backend_arg, backend_parameter); - // if front anf is a parameter, we can assign the value back, because backend_parameter - // won't be changed in it's graph unless it's a weight. If backend_parameter is a weight, - // we do should assign the value back. - auto to_graph_id = AnfAlgo::GetGraphId(backend_parameter.get()); - auto to_graph = GetGraph(to_graph_id); - MS_EXCEPTION_IF_NULL(to_graph); - if (backend_arg->isa() && !to_graph->execution_order().empty()) { - InsertMultipleAssignToGraph(to_graph_id, backend_parameter, backend_arg); - } + InsertAssignToGraph(from_graph_id, backend_arg, backend_parameter); MS_LOG(INFO) << "Finish!"; } @@ -723,8 +775,8 @@ void AscendSession::SetChildGraphParameter(const tensor::TensorPtr &front_tensor size_t tensor_size = front_tensor->data().nbytes(); auto addr = AnfAlgo::GetOutputAddr(backend_parameter, 0); MS_EXCEPTION_IF_NULL(addr); - if (!addr->SyncHostToDevice(front_tensor->shape(), tensor_size, front_tensor->data_type(), - front_tensor->data_c(false))) { + if (!addr->SyncHostToDevice(trans::GetRuntimePaddingShape(backend_parameter, 0), tensor_size, + front_tensor->data_type(), front_tensor->data_c(false))) { MS_LOG(EXCEPTION) << "Tensor SyncHostToDevice fail!"; } MS_LOG(INFO) << "Finish!"; @@ -755,17 +807,27 @@ void AscendSession::SetChildGraphInput(GraphId g, const VectorRef &args) { DumpGraphInputArgs(args); UpdateGraphOrder(g); std::vector graph_inputs = to_graph->inputs(); + auto valid_inputs = to_graph->ValidInputs(); + auto real_args = GetRealArgs(to_graph, args); size_t input_index = 0; - for (size_t i = 0; i < args.size(); i++) { + for (size_t i = 0; i < real_args.size(); i++) { if (input_index >= graph_inputs.size()) { MS_LOG(EXCEPTION) << "input_index " << input_index << " out of range size " << graph_inputs.size(); } - if (utils::isa(args[i])) { + if (utils::isa(real_args[i])) { // arg is a anf node - for (const auto &real_arg : AnfAlgo::GetAllOutput(utils::cast(args[i]), {prim::kPrimTupleGetItem})) { + auto real_arg = utils::cast(real_args[i]); + auto real_arg_output_num = AnfAlgo::GetOutputTensorNum(real_arg); + if (!AnfAlgo::CheckPrimitiveType(real_arg, prim::kPrimTupleGetItem) && real_arg_output_num > 1) { + input_index += real_arg_output_num; + continue; + } + if (valid_inputs[input_index]) { SetChildGraphParameter(real_arg, graph_inputs[input_index]); - input_index++; + } else { + MS_LOG(DEBUG) << "Invalid input arg" << real_arg->DebugString(); } + input_index++; } else if (utils::isa(args[i])) { auto value = utils::cast(args[i]); MS_EXCEPTION_IF_NULL(value); @@ -792,7 +854,7 @@ GraphId AscendSession::GetGraphIdByNode(const AnfNodePtr &front_anf) const { } } MS_EXCEPTION_IF_NULL(front_anf); - MS_LOG(WARNING) << "front_anf " << front_anf->DebugString() << " is not exist in any graph"; + MS_LOG(DEBUG) << "front_anf " << front_anf->DebugString() << " is not exist in any graph"; return kInvalidGraphId; } diff --git a/mindspore/ccsrc/session/ascend_session.h b/mindspore/ccsrc/session/ascend_session.h old mode 100644 new mode 100755 index caec4b35f7..2d24691404 --- a/mindspore/ccsrc/session/ascend_session.h +++ b/mindspore/ccsrc/session/ascend_session.h @@ -41,17 +41,18 @@ class AscendSession : public SessionBasic { GraphId CompileGraph(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) override; void RunGraph(const GraphId &graph_id, const std::vector &inputs, VectorRef *outputs) override; void BuildGraph(GraphId) override; - void BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) override; - py::tuple RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) override; + void BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + std::vector *input_tensors) override; + py::tuple RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + const std::vector &input_tensors) override; // set parameters of final graph GraphId SetFinalGraphInput(const std::vector &args) override; // set output of final graph void SetFinalGraphOutput(const BaseRef &output) override; // insert switch and set the relative active ops - void SwitchCompile(GraphId cond_g, GraphId true_g, GraphId false_g) override; - // set args of child graph. the arg maybe come from a output of other child graphs, - // or from final graph's parameter + void SwitchCompile(GraphId cond_g, GraphId true_g, GraphId false_g, const AnfNodePtr &condition_output) override; + // set args of child graph.the arg maybe come from a output of other child graphs,or from final graph's parameter void SetChildGraphInput(GraphId g, const VectorRef &args) override; // get graph id in child graphs by ME front anf node pointer GraphId GetGraphIdByNode(const AnfNodePtr &front_anf) const override; @@ -116,6 +117,7 @@ class AscendSession : public SessionBasic { std::unordered_map while_condition_graphs_; // record all conditions std::unordered_map> switches_; + std::unordered_map condition_output_; // final_graph_id is used in every root graph has it's own session situation GraphId final_graph_id_; }; diff --git a/mindspore/ccsrc/session/gpu_session.cc b/mindspore/ccsrc/session/gpu_session.cc index bbcf2228cc..f5e8c44231 100644 --- a/mindspore/ccsrc/session/gpu_session.cc +++ b/mindspore/ccsrc/session/gpu_session.cc @@ -17,9 +17,10 @@ #include "device/gpu/kernel_info_setter.h" #include "device/gpu/gpu_kernel_build.h" #include "device/gpu/gpu_kernel_runtime.h" +#include "device/gpu/gpu_stream_assign.h" #include "pre_activate/common/optimizer.h" #include "pre_activate/common/pass_manager.h" -#include "pre_activate/common/ir_fusion/allreduce_fusion.h" +#include "pre_activate/pass/allreduce_fusion.h" #include "device/kernel_runtime_manager.h" #include "predict/predict.h" #include "common/utils.h" @@ -55,6 +56,11 @@ void GPUSession::Optimize(const std::shared_ptr &kernel_graph) { kernel_graph->SetExecOrderByDefault(); } +void GPUSession::AssignStream(const std::shared_ptr &kernel_graph) { + MS_EXCEPTION_IF_NULL(kernel_graph); + device::gpu::AssignGpuStream(kernel_graph); +} + void GPUSession::BuildKernel(const std::shared_ptr &kernel_graph) const { device::gpu::GpuBuild(kernel_graph); } @@ -94,6 +100,8 @@ GraphId GPUSession::CompileGraph(const AnfNodePtrList &lst, const AnfNodePtrList StartKernelRT(); // AllReduce Optimize Optimize(graph); + // Assign CUDA streams + AssignStream(graph); // Build kernel if node is cnode BuildKernel(graph); // Set graph execution order before memory alloc, ensure that memory alloc is according to the reorder graph @@ -124,9 +132,11 @@ void GPUSession::RunGraph(const GraphId &graph_id, const std::vector *input_tensors) { // Prepare the graph - auto kernel_graph = ConstructSingleOpGraph(op_run_info); + MS_EXCEPTION_IF_NULL(input_tensors); + auto kernel_graph = ConstructSingleOpGraph(op_run_info, input_tensors); MS_EXCEPTION_IF_NULL(kernel_graph); SelectKernel(kernel_graph); StartKernelRT(); @@ -134,12 +144,10 @@ void GPUSession::BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_in run_op_graphs_[graph_info] = kernel_graph; } -py::tuple GPUSession::RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) { +py::tuple GPUSession::RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + const std::vector &input_tensors) { auto kernel_graph = run_op_graphs_[graph_info]; MS_EXCEPTION_IF_NULL(kernel_graph); - std::vector input_tensors = {}; - std::vector tensors_mask = {}; - ToTensorPtr(op_run_info, &input_tensors, &tensors_mask); RunOpAllocateMemory(input_tensors, kernel_graph.get()); // Execute the computation LoadInputData(kernel_graph, input_tensors); diff --git a/mindspore/ccsrc/session/gpu_session.h b/mindspore/ccsrc/session/gpu_session.h index e443c1e701..470c9b4799 100644 --- a/mindspore/ccsrc/session/gpu_session.h +++ b/mindspore/ccsrc/session/gpu_session.h @@ -39,8 +39,10 @@ class GPUSession : public SessionBasic { GraphId CompileGraph(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) override; void RunGraph(const GraphId &graph_id, const std::vector &inputs, VectorRef *outputs) override; - void BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) override; - py::tuple RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info) override; + void BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + std::vector *input_tensors) override; + py::tuple RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, + const std::vector &input_tensors) override; private: void SelectKernel(const std::shared_ptr &kernel_graph) const; @@ -49,6 +51,8 @@ class GPUSession : public SessionBasic { void Optimize(const std::shared_ptr &kernel_graph); + void AssignStream(const std::shared_ptr &kernel_graph); + void BuildKernel(const std::shared_ptr &kernel_graph) const; void AllocateMemory(KernelGraph *kernel_graph) const; diff --git a/mindspore/ccsrc/session/kernel_graph.cc b/mindspore/ccsrc/session/kernel_graph.cc old mode 100644 new mode 100755 index 84ff6b81a2..139539ccb2 --- a/mindspore/ccsrc/session/kernel_graph.cc +++ b/mindspore/ccsrc/session/kernel_graph.cc @@ -50,90 +50,127 @@ std::vector KernelGraph::outputs() const { } void KernelGraph::SetExecOrderByDefault() { - BfsToUpdateNodeOutput(); + std::stack seed_nodes; + UpdateNodeEdgeList(&seed_nodes); execution_order_.clear(); - std::queue allreduce_nodes; - std::queue zero_output_nodes; std::unordered_set visited_nodes; - auto clear_output = [&zero_output_nodes, &allreduce_nodes, &visited_nodes, this](const AnfNodePtr &input) -> void { - if (node_output_num_[input] == 0 && visited_nodes.find(input) == visited_nodes.end()) { - MS_EXCEPTION_IF_NULL(input); - MS_LOG(DEBUG) << "Clear output num:" << input->DebugString(); - (void)visited_nodes.insert(input); - if (input->isa() && AnfAlgo::GetCNodeName(input) == kAllReduceOpName) { - allreduce_nodes.push(input); - } else { - zero_output_nodes.push(input); + std::queue zero_input_nodes; + + auto visit_node_descendant = [&visited_nodes, this](const AnfNodePtr &node, std::queue *visit_queue) { + auto it = node_output_edges_.find(node); + if (it == node_output_edges_.end()) { + // value node and parameter has no input,no need to print log + if (node->isa()) { + MS_LOG(DEBUG) << "Can not find node [" << node->DebugString() << "]"; + } + return; + } + + // visit all reduce node first, then other nodes + std::vector active_nodes; + for (const auto &output_edge : it->second) { + auto next_node = output_edge.first; + if (node_input_num_.find(next_node) == node_input_num_.end()) { + MS_EXCEPTION_IF_NULL(next_node); + MS_LOG(EXCEPTION) << "Can't find node[" << next_node->DebugString() << "]"; + } + MS_EXCEPTION_IF_NULL(next_node); + MS_LOG(DEBUG) << "Decrease input:" << next_node->DebugString() << ",node:" << node->DebugString() + << ",num: " << node_input_num_[next_node] << ",decrease num:" << output_edge.second; + if (node_input_num_[next_node] < output_edge.second) { + MS_LOG(EXCEPTION) << "Input node:" << next_node->DebugString() << ",node_output_num" + << node_input_num_[next_node] << ",depend edge:" << output_edge.second; } + node_input_num_[next_node] = node_input_num_[next_node] - output_edge.second; + // allreduce first + if (node_input_num_[next_node] == 0 && visited_nodes.find(next_node) == visited_nodes.end()) { + (void)visited_nodes.insert(next_node); + if (AnfAlgo::IsAllReduceOp(next_node)) { + MS_LOG(DEBUG) << "visit node:" << next_node->DebugString(); + visit_queue->push(next_node); + } else { + active_nodes.emplace_back(next_node); + } + } + } + + for (auto &node : active_nodes) { + MS_LOG(DEBUG) << "visit node:" << node->DebugString(); + visit_queue->push(node); } }; - zero_output_nodes.emplace(get_return()); - while (!zero_output_nodes.empty() || !allreduce_nodes.empty()) { - AnfNodePtr node; - if (!zero_output_nodes.empty()) { - node = zero_output_nodes.front(); - zero_output_nodes.pop(); + + AnfNodePtr last_allreduce_node = nullptr; + std::queue allreduce_descendants; + while (!seed_nodes.empty() || last_allreduce_node != nullptr) { + // seed nodes first, then visit last all reduce node descendant + if (seed_nodes.empty()) { + visit_node_descendant(last_allreduce_node, &allreduce_descendants); + last_allreduce_node = nullptr; } else { - node = allreduce_nodes.front(); - allreduce_nodes.pop(); - } - MS_EXCEPTION_IF_NULL(node); - if (node->isa() && AnfAlgo::IsRealKernel(node)) { - execution_order_.push_back(node->cast()); + zero_input_nodes.push(seed_nodes.top()); + seed_nodes.pop(); } - auto it = node_input_edges_.find(node); - if (it == node_input_edges_.end()) { - // value node and parameter has no input,no need to print log - if (node->isa()) { - MS_LOG(DEBUG) << "Can not find node [" << node->DebugString() << "]"; + + // all reduce node descendant first, then common queue + while (!zero_input_nodes.empty() || !allreduce_descendants.empty()) { + AnfNodePtr node = nullptr; + bool is_allreduce_descendant = false; + if (allreduce_descendants.empty()) { + node = zero_input_nodes.front(); + zero_input_nodes.pop(); + } else { + node = allreduce_descendants.front(); + allreduce_descendants.pop(); + is_allreduce_descendant = true; } - continue; - } - for (const auto &input_edge : it->second) { - if (node_output_num_.find(input_edge.first) == node_output_num_.end()) { - MS_EXCEPTION_IF_NULL(input_edge.first); - MS_LOG(EXCEPTION) << "Can't find node[" << input_edge.first->DebugString() << "]"; + // add execute node + MS_EXCEPTION_IF_NULL(node); + if (node->isa() && AnfAlgo::IsRealKernel(node)) { + execution_order_.push_back(node->cast()); } - MS_EXCEPTION_IF_NULL(input_edge.first); - MS_LOG(DEBUG) << "Decrease input:" << input_edge.first->DebugString() << ",node:" << node->DebugString() - << ",num: " << node_output_num_[input_edge.first] << ",decrease num:" << input_edge.second; - if (node_output_num_[input_edge.first] < input_edge.second) { - MS_LOG(EXCEPTION) << "Input node:" << input_edge.first->DebugString() << ",node_output_num" - << node_output_num_[input_edge.first] << "depend edge:" << input_edge.second; + // for all reduce node, visit last all reduce node descendant + if (AnfAlgo::IsAllReduceOp(node)) { + if (last_allreduce_node != nullptr) { + visit_node_descendant(last_allreduce_node, &allreduce_descendants); + } + last_allreduce_node = node; + } else if (is_allreduce_descendant) { + visit_node_descendant(node, &allreduce_descendants); + } else { + visit_node_descendant(node, &zero_input_nodes); } - node_output_num_[input_edge.first] = node_output_num_[input_edge.first] - input_edge.second; - clear_output(input_edge.first); } } + CheckLoop(); - std::reverse(execution_order_.begin(), execution_order_.end()); } void KernelGraph::CheckLoop() { - std::map none_zero_output; - if (node_output_edges_.size() != node_output_num_.size()) { - MS_LOG(EXCEPTION) << "node_output_edges_ size :" << node_output_edges_.size() - << "not equal to node_output_num_ size:" << node_output_num_.size(); + std::map none_zero_nodes; + if (node_input_edges_.size() != node_input_num_.size()) { + MS_LOG(EXCEPTION) << "node_input_edges_ size :" << node_input_edges_.size() + << "not equal to node_input_num_ size:" << node_input_num_.size(); } - for (auto &it : node_output_num_) { + for (auto &it : node_input_num_) { MS_EXCEPTION_IF_NULL(it.first); string str; - auto node_output_it = node_output_edges_.find(it.first); - if (node_output_it == node_output_edges_.end()) { + auto node_input_it = node_input_edges_.find(it.first); + if (node_input_it == node_input_edges_.end()) { MS_LOG(EXCEPTION) << "Can't find node [" << it.first->DebugString() << "]"; } - for (const auto &output_edge : node_output_edges_[it.first]) { - MS_EXCEPTION_IF_NULL(output_edge.first); - str = str.append(output_edge.first->DebugString()).append("|"); + for (const auto &input_edge : node_input_edges_[it.first]) { + MS_EXCEPTION_IF_NULL(input_edge.first); + str = str.append(input_edge.first->DebugString()).append("|"); } if (it.second != 0) { - MS_LOG(WARNING) << "Node:" << it.first->DebugString() << ",outputs:" << str << ",output num:" << it.second; - none_zero_output[it.first] = it.second; + MS_LOG(WARNING) << "Node:" << it.first->DebugString() << ",inputs:" << str << ",input num:" << it.second; + none_zero_nodes[it.first] = it.second; } } // if don't consider control depend and loop exit,a exception will be throw - if (!none_zero_output.empty()) { - MS_LOG(EXCEPTION) << "Nodes have loop, left node num:" << none_zero_output.size(); + if (!none_zero_nodes.empty()) { + MS_LOG(EXCEPTION) << "Nodes have loop, left node num:" << none_zero_nodes.size(); } } @@ -143,6 +180,12 @@ CNodePtr KernelGraph::NewCNode(const std::vector &inputs) { cnode->set_abstract(std::make_shared()); // create kernel_info from new parameter auto kernel_info = std::make_shared(); + // if the node only has the primitive(such as getNext) or the node's input has a feature map input + // then the node's output is a feature map output + if (inputs.size() == 1 || std::any_of(inputs.begin() + 1, inputs.end(), + [&](const AnfNodePtr &node) { return AnfAlgo::IsFeatureMapOutput(node); })) { + kernel_info->SetFeatureMapFlag(true); + } cnode->set_kernel_info(kernel_info); AnfAlgo::SetGraphId(graph_id_, cnode.get()); return cnode; @@ -162,22 +205,26 @@ CNodePtr KernelGraph::NewCNode(const CNodePtr &cnode) { ParameterPtr KernelGraph::NewParameter(const ParameterPtr ¶meter) { ParameterPtr new_parameter = add_parameter(); MS_EXCEPTION_IF_NULL(new_parameter); + // create kernel_info form new parameter + auto kernel_info = std::make_shared(); size_t output_tensor_num = 1; // if use default parameter = nullptr,it remarks create a new parameter from no parameter if (parameter == nullptr) { new_parameter->set_abstract(std::make_shared()); + kernel_info->SetFeatureMapFlag(true); } else { // if don't use default parameter = nullptr,it remarks create a new parameter from a old parameter new_parameter->set_abstract(parameter->abstract()); new_parameter->set_name(parameter->name()); - if (parameter->has_default()) { + if (AnfAlgo::IsParameterWeight(parameter)) { new_parameter->set_default_param(parameter->default_param()); + kernel_info->SetFeatureMapFlag(false); + } else { + kernel_info->SetFeatureMapFlag(true); } // if output is a tuple tensor,now can use for loop to handle tuple tensor output_tensor_num = AnfAlgo::GetOutputTensorNum(parameter); } - // create kernel_info form new parameter - auto kernel_info = std::make_shared(); new_parameter->set_kernel_info(kernel_info); // create kernel_build_info for new parameter auto kernel_build_info_builder = std::make_shared(); @@ -217,6 +264,7 @@ std::vector KernelGraph::SplitTupleValueNodeToNodeList(const ValueNo AddValueNodeToGraph(new_value_node); auto kernel_info = std::make_shared(); new_value_node->set_kernel_info(kernel_info); + kernel_info->SetFeatureMapFlag(false); // create kernel_build_info for new value node auto kernel_build_info_builder = std::make_shared(); // set the format of value_node to DEFAULT_FORMAT @@ -228,7 +276,7 @@ std::vector KernelGraph::SplitTupleValueNodeToNodeList(const ValueNo AddValueNodeToGraph(new_value_node); convert_inputs.emplace_back(new_value_node); } - if (RemoveValueNodeFromGraph(value_node)) { + if (!RemoveValueNodeFromGraph(value_node)) { MS_LOG(WARNING) << "failed to remove the value_node " << value_node->DebugString(); } return convert_inputs; @@ -240,6 +288,7 @@ ValueNodePtr KernelGraph::NewValueNode(const ValueNodePtr &value_node) { new_value_node->set_abstract(value_node->abstract()); // create kernel_info fo new value node auto kernel_info = std::make_shared(); + kernel_info->SetFeatureMapFlag(false); new_value_node->set_kernel_info(kernel_info); // create kernel_build_info for new value node auto kernel_build_info_builder = std::make_shared(); @@ -334,12 +383,13 @@ void KernelGraph::AddDependEdge(const AnfNodePtr &node, const AnfNodePtr &input, } else { input_it->second.push_back(input_depend_edge); } - // add the depend sum of node - auto depend_it = node_output_num_.find(input); - if (depend_it == node_output_num_.end()) { - node_output_num_[input] = 0; + // add node input depend num + auto depend_it = node_input_num_.find(node); + if (depend_it == node_input_num_.end()) { + node_input_num_[node] = depend_edge_num; + } else { + depend_it->second += depend_edge_num; } - node_output_num_[input] += depend_edge_num; } std::vector KernelGraph::GetOutputNodes(const AnfNodePtr &node) { @@ -372,8 +422,7 @@ void KernelGraph::UpdateControlDependRelations(const std::vector &de MS_EXCEPTION_IF_NULL(depend_node); std::vector prior_nodes = {prior_node}; std::vector depend_nodes = {depend_node}; - MS_LOG(INFO) << "Prior node[" << prior_node->DebugString() << "],depend node[" << depend_node->DebugString() - << "],depend_mode=[" << AnfAlgo::GetNodeAttr(cnode, "depend_mode") << "]"; + MS_LOG(INFO) << "Prior node[" << prior_node->DebugString() << "], depend node[" << depend_node->DebugString(); if (prior_node->isa()) { prior_nodes = GetOutputNodes(prior_node); } @@ -418,9 +467,9 @@ bool KernelGraph::HandleControlDependNode(const AnfNodePtr &node, std::queue *seed_nodes) { node_output_edges_.clear(); - node_output_num_.clear(); + node_input_num_.clear(); node_input_edges_.clear(); std::vector control_depends; std::unordered_set visited_nodes; @@ -430,6 +479,11 @@ void KernelGraph::BfsToUpdateNodeOutput() { auto node = que.front(); que.pop(); MS_EXCEPTION_IF_NULL(node); + if (node->isa() || node->isa()) { + seed_nodes->push(node); + continue; + } + if (!node->isa()) { continue; } @@ -443,10 +497,6 @@ void KernelGraph::BfsToUpdateNodeOutput() { control_depends.push_back(input); depend_edge_num = 0; } - // the 2rd input of depend is no depend edge - if (AnfAlgo::CheckPrimitiveType(node, prim::kPrimDepend) && input == cnode->input(kDependAttachNodeIndex)) { - depend_edge_num = 0; - } PushNoVisitedNode(input, &que, &visited_nodes); AddDependEdge(node, input, depend_edge_num); } diff --git a/mindspore/ccsrc/session/kernel_graph.h b/mindspore/ccsrc/session/kernel_graph.h old mode 100644 new mode 100755 index e11f6807f5..54b16014a3 --- a/mindspore/ccsrc/session/kernel_graph.h +++ b/mindspore/ccsrc/session/kernel_graph.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "ir/func_graph.h" @@ -86,12 +87,15 @@ class KernelGraph : public FuncGraph { bool executable() const { return executable_; } // set executable of graph void set_executable(bool executable) { executable_ = executable; } + // set invalid inputs for control sink + std::vector *MutableValidInputs() { return &valid_inputs_; } + std::vector ValidInputs() { return valid_inputs_; } private: // remove value node form graph bool RemoveValueNodeFromGraph(const ValueNodePtr &value_node); - // BFS to update all nodes' output - void BfsToUpdateNodeOutput(); + // update node edge list + void UpdateNodeEdgeList(std::stack *seed_nodes); // add node depend edge by data edge or control depend void AddDependEdge(const AnfNodePtr &node, const AnfNodePtr &input, size_t depend_edge_num); // handle control depend @@ -111,13 +115,15 @@ class KernelGraph : public FuncGraph { std::unordered_map tensor_to_value_node_map_; // include all value nodes std::unordered_set graph_value_nodes_; - std::unordered_map node_output_num_; + std::unordered_map node_input_num_; std::unordered_map>> node_input_edges_; // record map between ref final output anf with index and ref origin input with index std::map ref_out_in_map_; std::unordered_map>> node_output_edges_; // graph needn't execute bool executable_; + // valid inputs + std::vector valid_inputs_; }; } // namespace session using KernelGraphPtr = std::shared_ptr; diff --git a/mindspore/ccsrc/session/session_basic.cc b/mindspore/ccsrc/session/session_basic.cc old mode 100644 new mode 100755 index ede3ae7419..0ef0ad97ea --- a/mindspore/ccsrc/session/session_basic.cc +++ b/mindspore/ccsrc/session/session_basic.cc @@ -17,14 +17,17 @@ #include #include #include +#include #include "pipeline/parse/data_converter.h" #include "ir/manager.h" #include "operator/ops.h" +#include "common/trans.h" #include "utils/context/ms_context.h" #include "utils/config_manager.h" #include "session/anf_runtime_algorithm.h" #include "kernel/oplib/oplib.h" #include "pre_activate/common/common_backend_optimization.h" +#include "pre_activate/pass/const_input_to_attr_registry.h" #include "pre_activate/common/helper.h" #include "common/utils.h" #include "ir/dtype.h" @@ -42,7 +45,7 @@ void GetSummaryNodes(const KernelGraph *graph, std::unordered_mapcast(); MS_EXCEPTION_IF_NULL(cnode); @@ -80,7 +83,7 @@ bool ExistSummaryNode(const KernelGraph *graph) { auto all_nodes = DeepLinkedGraphSearch(ret); for (auto &n : all_nodes) { if (IsPrimitiveCNode(n, prim::kPrimScalarSummary) || IsPrimitiveCNode(n, prim::kPrimTensorSummary) || - IsPrimitiveCNode(n, prim::kPrimImageSummary)) { + IsPrimitiveCNode(n, prim::kPrimImageSummary) || IsPrimitiveCNode(n, prim::kPrimHistogramSummary)) { return true; } } @@ -124,7 +127,8 @@ BaseRef CreateOneTensor(const AnfNodePtr &node, size_t output_index, const Kerne MS_EXCEPTION_IF_NULL(ms_context); if (ms_context->enable_pynative_infer()) { tensor->set_device_address(AnfAlgo::GetMutableOutputAddr(node, output_index)); - } else if (!address->SyncDeviceToHost(tensor->shape(), LongToSize(tensor->data().nbytes()), tensor->data_type(), + } else if (!address->SyncDeviceToHost(trans::GetRuntimePaddingShape(node, output_index), + LongToSize(tensor->data().nbytes()), tensor->data_type(), tensor->data_c(true))) { MS_LOG(INFO) << "output sync device to host error!!!"; tensor->set_dirty(false); @@ -176,56 +180,113 @@ BaseRef CreatTupleForOutput(const AnfNodePtr &anf, const KernelGraph &graph, return ret; } -std::string FindOpInputParameterType(const std::string &op_name, kernel::OpImplyType implyType, size_t index) { - std::string para_type; - auto op_info = kernel::OpLib::FindOp(op_name, implyType); - if (op_info == nullptr) { - return para_type; +bool RunOpConvertConstInputToAttr(const py::object &input_object, size_t input_index, const PrimitivePtr &op_prim, + const std::unordered_set &input_attrs) { + MS_EXCEPTION_IF_NULL(op_prim); + auto input_names_value = op_prim->GetAttr(kAttrInputNames); + if (input_names_value == nullptr) { + return false; + } + auto input_names_vec = GetValue>(input_names_value); + if (input_index >= input_names_vec.size()) { + MS_LOG(EXCEPTION) << "The input index: " << input_index << " is large than the input names vector size!"; } - auto op_inputs_info_vec = op_info->inputs_ptr(); - if (index >= op_inputs_info_vec.size()) { - return para_type; + + if (input_attrs.find(input_index) != input_attrs.end()) { + ValuePtr value = parse::data_converter::PyDataToValue(input_object); + MS_EXCEPTION_IF_NULL(value); + auto input_name = input_names_vec[input_index]; + op_prim->set_attr(input_name, value); + return true; } - auto op_io_info = op_inputs_info_vec[index]; - MS_EXCEPTION_IF_NULL(op_io_info); - para_type = op_io_info->param_type(); - return para_type; + return false; } -void RunOpConvertConstInputToAttr(const OpRunInfo &op_run_info, const std::shared_ptr &cnode) { - MS_EXCEPTION_IF_NULL(cnode); - auto op_inputs = op_run_info.op_inputs; - // get input names vector from attrs - auto primitive = AnfAlgo::GetCNodePrimitive(cnode); - MS_EXCEPTION_IF_NULL(primitive); - auto input_names_value = primitive->GetAttr(kAttrInputNames); - if (input_names_value == nullptr) { +void PlantTensorTupleToVector(const py::tuple &tuple_inputs, const PrimitivePtr &op_prim, + std::vector *input_tensor) { + MS_EXCEPTION_IF_NULL(op_prim); + MS_EXCEPTION_IF_NULL(input_tensor); + for (const auto &input_object : tuple_inputs) { + if (!py::isinstance(input_object)) { + MS_LOG(EXCEPTION) << "The input object is not a tensor!"; + } + auto tensor = py::cast(input_object); + MS_EXCEPTION_IF_NULL(tensor); + input_tensor->push_back(tensor); + } + op_prim->set_attr(kAttrDynInputSizes, MakeValue(std::vector{SizeToInt(tuple_inputs.size())})); +} + +void ConvertValueTupleToTensor(const py::object &input_object, std::vector *input_tensor) { + MS_EXCEPTION_IF_NULL(input_tensor); + ValuePtr input_value = parse::data_converter::PyDataToValue(input_object); + MS_EXCEPTION_IF_NULL(input_value); + if (!input_value->isa()) { + MS_LOG(EXCEPTION) << "The input object is not a value tuple!"; + } + auto value_tuple = input_value->cast(); + MS_EXCEPTION_IF_NULL(value_tuple); + tensor::TensorPtr tensor_ptr = nullptr; + tensor_ptr = opt::CreateTupleTensor(value_tuple); + MS_EXCEPTION_IF_NULL(tensor_ptr); + input_tensor->push_back(tensor_ptr); +} + +void ConvertPyObjectToTensor(const py::object &input_object, const PrimitivePtr &op_prim, + std::vector *input_tensor) { + MS_EXCEPTION_IF_NULL(op_prim); + MS_EXCEPTION_IF_NULL(input_tensor); + tensor::TensorPtr tensor_ptr = nullptr; + if (py::isinstance(input_object)) { + tensor_ptr = py::cast(input_object); + } else if (py::isinstance(input_object)) { + tensor_ptr = std::make_shared(py::cast(input_object), kFloat32); + } else if (py::isinstance(input_object)) { + tensor_ptr = std::make_shared(py::cast(input_object), nullptr); + } else if (py::isinstance(input_object)) { + tensor_ptr = std::make_shared(py::cast(input_object), nullptr); + } else if (py::isinstance(input_object)) { + tensor_ptr = std::make_shared(py::cast(input_object), nullptr); + } else if (py::isinstance(input_object)) { + auto tuple_inputs = py::cast(input_object); + if (py::isinstance(tuple_inputs[0])) { + PlantTensorTupleToVector(tuple_inputs, op_prim, input_tensor); + } else { + ConvertValueTupleToTensor(input_object, input_tensor); + } return; + } else { + MS_LOG(EXCEPTION) << "Run op inputs type is invalid!"; } - auto input_names_vec = GetValue>(input_names_value); - // convert const input to attr - size_t input_num = op_inputs.size(); - if (input_num != input_names_vec.size()) { - MS_LOG(EXCEPTION) << "input name number " << input_names_vec.size() << "is not equal to input value number " - << input_num; + MS_EXCEPTION_IF_NULL(tensor_ptr); + input_tensor->push_back(tensor_ptr); +} + +void ConvertInputPyobject(const OpRunInfo &op_run_info, const PrimitivePtr &op_prim, + std::vector *input_tensors, std::vector *tensors_mask) { + MS_EXCEPTION_IF_NULL(op_prim); + MS_EXCEPTION_IF_NULL(input_tensors); + MS_EXCEPTION_IF_NULL(tensors_mask); + if (op_run_info.op_inputs.size() != op_run_info.inputs_mask.size()) { + MS_LOG(EXCEPTION) << "Op input size " << op_run_info.op_inputs.size() << " should be equal to op input mask size " + << op_run_info.inputs_mask.size(); } + opt::ConstInputToAttrInfoRegister reg; + bool reg_exist = opt::ConstInputToAttrInfoRegistry::Instance().GetRegisterByOpName(op_run_info.op_name, ®); + size_t input_num = op_run_info.op_inputs.size(); + MS_LOG(INFO) << "py input size: " << input_num; for (size_t index = 0; index < input_num; ++index) { - // skip tensor - if (py::isinstance(op_inputs[index])) { - continue; - } - // convert to attr - auto para_type = FindOpInputParameterType(op_run_info.op_name, kernel::OpImplyType::kTBE, index); - if (!para_type.empty() && para_type == kAttrDynInput) { - auto tuple_inputs = py::cast(op_inputs[index]); - primitive->set_attr(kAttrDynInputSizes, MakeValue(std::vector{SizeToInt(tuple_inputs.size())})); + // convert const input to attr + if (reg_exist && + RunOpConvertConstInputToAttr(op_run_info.op_inputs[index], index, op_prim, reg.GetConstInputAttrInfo())) { continue; } - ValuePtr value = parse::data_converter::PyDataToValue(op_inputs[index]); - MS_EXCEPTION_IF_NULL(value); - auto input_name = input_names_vec[index]; - // set the input node as attr of the cnode, key is name of input node,value is input node's value - primitive->set_attr(input_name, value); + // convert const and tuple input to tensor + ConvertPyObjectToTensor(op_run_info.op_inputs[index], op_prim, input_tensors); + // make tensors, weight : 1, data : 0 + std::vector new_mask(input_tensors->size() - tensors_mask->size(), + py::cast(op_run_info.inputs_mask[index])); + tensors_mask->insert(tensors_mask->end(), new_mask.begin(), new_mask.end()); } } @@ -243,29 +304,42 @@ ValueNodePtr CreateNewValueNode(const AnfNodePtr &anf, KernelGraph *graph) { return new_value_node; } -ParameterPtr CreateNewParameterFromParameter(const AnfNodePtr &anf, KernelGraph *graph) { +ParameterPtr CreateNewParameterFromParameter(const AnfNodePtr &anf, bool valid_input, KernelGraph *graph) { MS_EXCEPTION_IF_NULL(anf); if (!anf->isa()) { MS_LOG(EXCEPTION) << "anf[" << anf->DebugString() << "] is not a parameter"; } auto graph_inputs = graph->MutableInputs(); MS_EXCEPTION_IF_NULL(graph_inputs); + auto valid_inputs = graph->MutableValidInputs(); + MS_EXCEPTION_IF_NULL(valid_inputs); ParameterPtr new_parameter = graph->NewParameter(anf->cast()); - graph->FrontBackendlMapAdd(anf, new_parameter); graph_inputs->push_back(new_parameter); + valid_inputs->push_back(valid_input); return new_parameter; } -std::vector CreateParameterFromTuple(const AnfNodePtr &node, KernelGraph *graph) { +std::vector CreateParameterFromTuple(const AnfNodePtr &node, bool valid_input, KernelGraph *graph) { MS_EXCEPTION_IF_NULL(node); MS_EXCEPTION_IF_NULL(graph); std::vector parameters; - std::vector pre_graph_out = AnfAlgo::GetAllOutput(node, {prim::kPrimTupleGetItem}); + std::vector pre_graph_out = {node}; + // If a cnode is a call, it's input0 is a cnode too, so it doesn't have primitive + if (!AnfAlgo::IsRealKernel(node)) { + pre_graph_out = AnfAlgo::GetAllOutput(node, {prim::kPrimTupleGetItem}); + } + auto valid_inputs = graph->MutableValidInputs(); + MS_EXCEPTION_IF_NULL(valid_inputs); + auto graph_inputs = graph->MutableInputs(); + MS_EXCEPTION_IF_NULL(graph_inputs); auto create_parameter = [&](const AbstractBasePtr &abstract) -> void { auto parameter = graph->NewParameter(); MS_EXCEPTION_IF_NULL(parameter); parameter->set_abstract(abstract); - parameters.push_back(graph->NewParameter(parameter)); + auto new_parameter = graph->NewParameter(parameter); + parameters.push_back(new_parameter); + valid_inputs->push_back(valid_input); + graph_inputs->push_back(new_parameter); }; for (const auto &out_node : pre_graph_out) { MS_EXCEPTION_IF_NULL(out_node); @@ -287,18 +361,15 @@ std::vector CreateParameterFromTuple(const AnfNodePtr &node, KernelG return parameters; } -AnfNodePtr CreateNewParameterFromCNode(const AnfNodePtr &anf, KernelGraph *graph) { +AnfNodePtr CreateNewParameterFromCNode(const AnfNodePtr &anf, bool valid_input, KernelGraph *graph) { MS_EXCEPTION_IF_NULL(anf); if (!anf->isa()) { - MS_LOG(EXCEPTION) << "anf[" << anf->DebugString() << "] is not a cnode"; + MS_LOG(EXCEPTION) << "Anf[" << anf->DebugString() << "] is not a cnode"; } - MS_LOG(INFO) << "create a new parameter from cnode[" << anf->DebugString() << "]"; - auto parameters = CreateParameterFromTuple(anf, graph); - auto graph_inputs = graph->MutableInputs(); - MS_EXCEPTION_IF_NULL(graph_inputs); - (void)std::copy(parameters.begin(), parameters.end(), std::back_inserter(*graph_inputs)); + MS_LOG(INFO) << "Create a new parameter from cnode[" << anf->DebugString() << "]"; + auto parameters = CreateParameterFromTuple(anf, valid_input, graph); if (parameters.empty()) { - MS_LOG(EXCEPTION) << "no parameter exist!!"; + MS_LOG(EXCEPTION) << "No parameter exist!!"; } if (parameters.size() == 1) { return parameters[0]; @@ -307,7 +378,7 @@ AnfNodePtr CreateNewParameterFromCNode(const AnfNodePtr &anf, KernelGraph *graph (void)std::copy(parameters.begin(), parameters.end(), std::back_inserter(make_tuple_input)); auto make_tuple = graph->NewCNode(make_tuple_input); MS_EXCEPTION_IF_NULL(make_tuple); - MS_LOG(INFO) << "new make tuple [" << make_tuple->DebugString() << "] of parameters"; + MS_LOG(INFO) << "New make tuple [" << make_tuple->DebugString() << "] of parameters"; return make_tuple; } @@ -363,7 +434,7 @@ ParameterPtr ConstructRunOpParameter(const std::shared_ptr &graph, kernel_build_info_builder->SetOutputsDeviceType(std::vector{input_tensor->device_address()->type_id()}); } AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info_builder->Build(), param.get()); - // construct abstract of parameter + // ftruct abstract of parameter auto abstract = std::make_shared(input_tensor); param->set_abstract(abstract); return param; @@ -397,14 +468,20 @@ void DumpGraphOutput(const Any &any, size_t recurse_level = 0) { GraphId SessionBasic::graph_sum_ = 0; -CNodePtr SessionBasic::CreateNewCNode(const CNodePtr &cnode, KernelGraph *graph) { +CNodePtr SessionBasic::CreateNewCNode(const CNodePtr &cnode, bool valid_input, KernelGraph *graph, + bool *from_other_graph, + std::unordered_map *other_graph_cnode) { MS_EXCEPTION_IF_NULL(cnode); MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(from_other_graph); + MS_EXCEPTION_IF_NULL(other_graph_cnode); + *from_other_graph = false; // get primitive of old node auto prim = AnfAlgo::GetCNodePrimitive(cnode); MS_EXCEPTION_IF_NULL(prim); // push attr to inputs[0] of new cnode std::vector cnode_inputs = {std::make_shared(std::make_shared(*prim))}; + // if has multiple depends,only select first depend as parameter for (size_t input_idx = 1; input_idx < cnode->inputs().size(); input_idx++) { auto anf = cnode->inputs()[input_idx]; MS_EXCEPTION_IF_NULL(anf); @@ -412,6 +489,9 @@ CNodePtr SessionBasic::CreateNewCNode(const CNodePtr &cnode, KernelGraph *graph) if (graph->GetBackendAnfByFrontAnf(anf) != nullptr) { cnode_inputs.emplace_back(graph->GetBackendAnfByFrontAnf(anf)); continue; + } else if (other_graph_cnode->find(anf) != other_graph_cnode->end()) { + cnode_inputs.push_back((*other_graph_cnode)[anf]); + continue; } else if (anf->isa() && !IsValueNode(anf)) { // if input is a value node, auto new_value_node = CreateNewValueNode(anf, graph); @@ -421,38 +501,60 @@ CNodePtr SessionBasic::CreateNewCNode(const CNodePtr &cnode, KernelGraph *graph) continue; } else if (anf->isa()) { // if anf is a parameter - cnode_inputs.emplace_back(CreateNewParameterFromParameter(anf, graph)); + auto new_parameter = CreateNewParameterFromParameter(anf, valid_input, graph); + cnode_inputs.push_back(new_parameter); + if (GetGraphIdByNode(anf) == kInvalidGraphId) { + graph->FrontBackendlMapAdd(anf, new_parameter); + } else { + (*other_graph_cnode)[anf] = new_parameter; + } continue; } else if (anf->isa()) { + *from_other_graph = true; // the input node is a cnode from other graph - cnode_inputs.emplace_back(CreateNewParameterFromCNode(anf, graph)); + auto parameter_from_cnode = CreateNewParameterFromCNode(anf, valid_input, graph); + cnode_inputs.push_back(parameter_from_cnode); + (*other_graph_cnode)[anf] = parameter_from_cnode; continue; } - MS_LOG(EXCEPTION) << "unexpected input[" << anf->DebugString() << "]"; + MS_LOG(EXCEPTION) << "Unexpected input[" << anf->DebugString() << "]"; } - return graph->NewCNode(cnode_inputs); + TraceManager::DebugTrace(std::make_shared(cnode->debug_info())); + auto new_cnode = graph->NewCNode(cnode_inputs); + TraceManager::EndTrace(); + return new_cnode; } KernelGraphPtr SessionBasic::ConstructKernelGraph(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) { + std::unordered_map other_graph_cnode; auto graph = std::make_shared(); graph->set_graph_id(graph_sum_); + MS_LOG(INFO) << "Create graph: " << graph_sum_; + size_t from_other_graph_depend_num = 0; for (const auto &node : lst) { MS_EXCEPTION_IF_NULL(node); - MS_LOG(DEBUG) << "start create new cnode,node = " << node->DebugString(); + MS_LOG(DEBUG) << "Start create new cnode, node = " << node->DebugString(); if (!node->isa()) { - MS_LOG(EXCEPTION) << "Inst node " << node->DebugString() << " is not CNode"; + MS_LOG(EXCEPTION) << "Node " << node->DebugString() << " is not CNode"; } auto cnode = node->cast(); MS_EXCEPTION_IF_NULL(cnode); - TraceManager::DebugTrace(std::make_shared(cnode->debug_info())); // create a new cnode object - auto new_cnode = CreateNewCNode(cnode, graph.get()); + bool from_other_graph = false; + // only first depend from other graph can create + bool valid_input = true; + if (from_other_graph_depend_num != 0 && AnfAlgo::CheckPrimitiveType(node, prim::kPrimDepend)) { + valid_input = false; + } + auto new_cnode = CreateNewCNode(cnode, valid_input, graph.get(), &from_other_graph, &other_graph_cnode); + if (AnfAlgo::CheckPrimitiveType(node, prim::kPrimDepend) && from_other_graph) { + from_other_graph_depend_num++; + } MS_EXCEPTION_IF_NULL(new_cnode); new_cnode->set_abstract(cnode->abstract()); new_cnode->set_scope(cnode->scope()); // record map relations between anf from ME and new anf node used in backend graph->FrontBackendlMapAdd(node, new_cnode); - TraceManager::EndTrace(); } // add a make_tuple at the end of graph as output graph->set_output(ConstructOutput(outputs, graph)); @@ -511,7 +613,8 @@ void SessionBasic::LoadInputData(const std::shared_ptr &kernel_grap if (need_sync) { tensor->set_device_address(device_address); MS_EXCEPTION_IF_NULL(device_address); - if (!device_address->SyncHostToDevice(tensor->shape(), LongToSize(tensor->data().nbytes()), tensor->data_type(), + if (!device_address->SyncHostToDevice(trans::GetRuntimePaddingShape(pk_node, 0), + LongToSize(tensor->data().nbytes()), tensor->data_type(), tensor->data_c(false))) { MS_LOG(EXCEPTION) << "SyncHostToDevice failed."; } @@ -583,8 +686,8 @@ void SessionBasic::Summary(KernelGraph *graph) { (void)std::copy(shape.begin(), shape.end(), std::back_inserter(temp_shape)); tensor::TensorPtr tensor = std::make_shared(type_id, temp_shape); MS_EXCEPTION_IF_NULL(address); - if (!address->SyncDeviceToHost(tensor->shape(), LongToSize(tensor->data().nbytes()), tensor->data_type(), - tensor->data_c(true))) { + if (!address->SyncDeviceToHost(trans::GetRuntimePaddingShape(node, index), LongToSize(tensor->data().nbytes()), + tensor->data_type(), tensor->data_c(true))) { MS_LOG(ERROR) << "Failed to sync output from device to host."; } tensor->set_dirty(false); @@ -594,49 +697,18 @@ void SessionBasic::Summary(KernelGraph *graph) { summary_callback_(0, params_list); } -void SessionBasic::ToTensorPtr(const OpRunInfo &op_run_info, std::vector *inputs, - std::vector *tensor_mask) { - MS_EXCEPTION_IF_NULL(inputs); - MS_EXCEPTION_IF_NULL(tensor_mask); - if (op_run_info.op_inputs.size() != op_run_info.inputs_mask.size()) { - MS_LOG(EXCEPTION) << "Op input size " << op_run_info.op_inputs.size() << " should be equal to op input mask size " - << op_run_info.inputs_mask.size(); - } - size_t input_num = op_run_info.op_inputs.size(); - // get tensors from op_inputs - for (size_t i = 0; i < input_num; ++i) { - tensor::TensorPtr tensor_ptr = nullptr; - auto param_type = FindOpInputParameterType(op_run_info.op_name, kernel::OpImplyType::kTBE, i); - if (py::isinstance(op_run_info.op_inputs[i])) { - tensor_ptr = py::cast(op_run_info.op_inputs[i]); - } else if (!param_type.empty() && param_type == kAttrDynInput) { - auto tuple_inputs = py::cast(op_run_info.op_inputs[i]); - for (auto &&tuple_input : tuple_inputs) { - tensor_ptr = py::cast(tuple_input); - MS_EXCEPTION_IF_NULL(tensor_ptr); - inputs->push_back(tensor_ptr); - tensor_mask->push_back(py::cast(op_run_info.inputs_mask[i])); - } - continue; - } else if (op_run_info.op_name == kApplyMomentumOpName && py::isinstance(op_run_info.op_inputs[i])) { - tensor_ptr = std::make_shared(py::cast(op_run_info.op_inputs[i]), kFloat32); - } - if (tensor_ptr != nullptr) { - inputs->push_back(tensor_ptr); - tensor_mask->push_back(py::cast(op_run_info.inputs_mask[i])); - } - } -} - CNodePtr SessionBasic::ConstructOutput(const AnfNodePtrList &outputs, const std::shared_ptr &graph) { MS_EXCEPTION_IF_NULL(graph); std::vector output_args; - auto FindEqu = [graph](const AnfNodePtr &out) -> AnfNodePtr { + auto FindEqu = [graph, outputs](const AnfNodePtr &out) -> AnfNodePtr { auto backend_anf = graph->GetBackendAnfByFrontAnf(out); if (backend_anf != nullptr) { return backend_anf; } - MS_LOG(EXCEPTION) << "Can not find the node in the equiv map!"; + for (const auto &output : outputs) { + MS_LOG(INFO) << "output:" << output->DebugString(); + } + MS_LOG(EXCEPTION) << "Can't find the node in the equiv map!"; }; output_args.push_back(NewValueNode(prim::kPrimMakeTuple)); (void)std::transform(outputs.begin(), outputs.end(), std::back_inserter(output_args), @@ -677,30 +749,27 @@ void SessionBasic::CreateOutputNode(const CNodePtr &cnode, const std::shared_ptr MS_LOG(INFO) << "Finish!"; } -std::shared_ptr SessionBasic::ConstructSingleOpGraph(const OpRunInfo &op_run_info) { +std::shared_ptr SessionBasic::ConstructSingleOpGraph(const OpRunInfo &op_run_info, + std::vector *input_tensors) { + MS_EXCEPTION_IF_NULL(input_tensors); auto graph = std::make_shared(); std::vector inputs; - if (op_run_info.op_inputs.size() != op_run_info.inputs_mask.size()) { - MS_LOG(EXCEPTION) << "op_run_info inputs.size" << op_run_info.op_inputs.size() - << " should be equal to parameter_mask.size " << op_run_info.inputs_mask.size(); - } // set input[0] - if (op_run_info.py_primitive == nullptr) { - inputs.push_back(std::make_shared(std::make_shared(op_run_info.op_name))); - } else { - inputs.push_back(std::make_shared(op_run_info.py_primitive)); + PrimitivePtr op_prim = op_run_info.py_primitive; + if (op_prim == nullptr) { + op_prim = std::make_shared(op_run_info.op_name); } + inputs.push_back(std::make_shared(op_prim)); // set input parameter - std::vector input_tensors; std::vector tensors_mask; - ToTensorPtr(op_run_info, &input_tensors, &tensors_mask); - MS_LOG(INFO) << "Input tensor size" << input_tensors.size(); - if (input_tensors.size() != tensors_mask.size()) { - MS_LOG(EXCEPTION) << "Input tensors size " << input_tensors.size() << " should be equal to tensors mask size " + ConvertInputPyobject(op_run_info, op_prim, input_tensors, &tensors_mask); + MS_LOG(INFO) << "Input tensor size: " << input_tensors->size(); + if (input_tensors->size() != tensors_mask.size()) { + MS_LOG(EXCEPTION) << "Input tensors size " << input_tensors->size() << " should be equal to tensors mask size " << tensors_mask.size(); } - for (size_t i = 0; i < input_tensors.size(); ++i) { - auto parameter = ConstructRunOpParameter(graph, input_tensors[i], tensors_mask[i]); + for (size_t i = 0; i < input_tensors->size(); ++i) { + auto parameter = ConstructRunOpParameter(graph, input_tensors->at(i), tensors_mask[i]); inputs.push_back(parameter); graph->MutableInputs()->push_back(parameter); } @@ -709,8 +778,6 @@ std::shared_ptr SessionBasic::ConstructSingleOpGraph(const OpRunInf MS_EXCEPTION_IF_NULL(cnode); // set abstract,which include inferred shapes and types cnode->set_abstract(op_run_info.abstract); - // set const input to attr if value is not a tensor,such as scalar or tuple - RunOpConvertConstInputToAttr(op_run_info, cnode); // set execution order std::vector exe_order = {cnode}; graph->set_execution_order(exe_order); diff --git a/mindspore/ccsrc/session/session_basic.h b/mindspore/ccsrc/session/session_basic.h old mode 100644 new mode 100755 index 9aadb78cb2..aa359c74d9 --- a/mindspore/ccsrc/session/session_basic.h +++ b/mindspore/ccsrc/session/session_basic.h @@ -61,22 +61,25 @@ class SessionBasic { virtual void RunGraph(const GraphId &graph_id, const std::vector &inputs, VectorRef *outputs) = 0; - virtual void BuildOp(const OpRunInfo &, const GraphInfo &) {} + virtual void BuildOp(const OpRunInfo &, const GraphInfo &, std::vector *input_tensors) {} - virtual py::tuple RunOp(const OpRunInfo &, const GraphInfo &) { return py::tuple(); } + virtual py::tuple RunOp(const OpRunInfo &, const GraphInfo &, const std::vector &input_tensors) { + return py::tuple(); + } virtual void RegisterSummaryCallBackFunc(const CallBackFunc &callback); std::shared_ptr ConstructKernelGraph(const AnfNodePtrList &lst, const AnfNodePtrList &outputs); - CNodePtr CreateNewCNode(const CNodePtr &cnode, KernelGraph *graph); + CNodePtr CreateNewCNode(const CNodePtr &cnode, bool valid_input, KernelGraph *graph, bool *from_other_graph, + std::unordered_map *other_graph_cnode); // set parameters of final graph virtual GraphId SetFinalGraphInput(const std::vector &) { return kInvalidGraphId; } // set output of final graph virtual void SetFinalGraphOutput(const BaseRef &) {} // insert switch and set the relative active ops - virtual void SwitchCompile(GraphId, GraphId, GraphId) {} + virtual void SwitchCompile(GraphId, GraphId, GraphId, const AnfNodePtr &) {} // set args of child graph.the arg maybe come from a output of other child graphs,or from final graph's parameter virtual void SetChildGraphInput(GraphId, const VectorRef &) {} // get graph id in child graphs by ME front anf node pointer @@ -95,10 +98,8 @@ class SessionBasic { void CreateOutputNode(const CNodePtr &cnode, const std::shared_ptr &graph); CNodePtr ConstructOutput(const AnfNodePtrList &outputs, const std::shared_ptr &graph); // create a single run op graph - std::shared_ptr ConstructSingleOpGraph(const OpRunInfo &op_run_info); - // get tensors from op inputs - void ToTensorPtr(const OpRunInfo &op_run_info, std::vector *inputs, - std::vector *tensor_mask); + std::shared_ptr ConstructSingleOpGraph(const OpRunInfo &op_run_info, + std::vector *input_tensor); // trans BaseRef list to py::tuple BaseRef TransformBaseRefListToTuple(const BaseRef &base_ref); diff --git a/mindspore/ccsrc/transform/convert.cc b/mindspore/ccsrc/transform/convert.cc index 20adec5b97..2270e6719b 100755 --- a/mindspore/ccsrc/transform/convert.cc +++ b/mindspore/ccsrc/transform/convert.cc @@ -173,9 +173,9 @@ const char kNameAbsGrad[] = "AbsGrad"; const char kNameBinaryCrossEntropy[] = "BinaryCrossEntropy"; const char kNameBinaryCrossEntropyGrad[] = "BinaryCrossEntropyGrad"; const char kNameSparseApplyAdagrad[] = "SparseApplyAdagrad"; +const char kNameSparseApplyFtrlD[] = "SparseApplyFtrlD"; const char kNameAcosh[] = "Acosh"; const char kNameFloorMod[] = "FloorMod"; -const char kNameSparseApplyFtrlD[] = "SparseApplyFtrlD"; const char kNameSpaceToDepth[] = "SpaceToDepth"; const char kNameDepthToSpace[] = "DepthToSpace"; const char kNameSign[] = "Sign"; @@ -191,7 +191,6 @@ const char kNameAtan2[] = "Atan2"; const char kNameApplyRMSProp[] = "ApplyRMSProp"; const char kNameApplyCenteredRMSProp[] = "ApplyCenteredRMSProp"; - // -----------------OpAdapter initialization-------------- std::unordered_map &DfGraphConvertor::get_adpt_map() { static std::unordered_map adpt_map = { @@ -205,6 +204,7 @@ std::unordered_map &DfGraphConvertor::get_adpt_ma {string(kNameMaxPoolWithArgmax), ADPT_DESC(MaxPoolWithArgmax)}, {string(kNameTopK), ADPT_DESC(TopK)}, {string(kNamePack), ADPT_DESC(Pack)}, + {string(kNameUnpack), ADPT_DESC(Unpack)}, {string(kNameSplitD), ADPT_DESC(SplitD)}, {string(kNameAllReduce), ADPT_DESC(HcomAllReduce)}, {string(kNameBroadcast), ADPT_DESC(HcomBroadcast)}, @@ -348,6 +348,7 @@ std::unordered_map &DfGraphConvertor::get_adpt_ma {prim::kPrimScalarSummary->name(), ADPT_DESC(Summary)}, {prim::kPrimImageSummary->name(), ADPT_DESC(Summary)}, {prim::kPrimTensorSummary->name(), ADPT_DESC(Summary)}, + {prim::kPrimHistogramSummary->name(), ADPT_DESC(Summary)}, {prim::kPrimTensorAdd->name(), std::make_shared(std::make_shared>(ExtraAttr({{"mode", MakeValue(1)}})), std::make_shared>(ExtraAttr({{"mode", MakeValue(1)}})))}, @@ -1023,8 +1024,8 @@ DfGraphConvertor &DfGraphConvertor::BuildGraph() { } } - // set up dependencies - MS_LOG(DEBUG) << "set up dependencies"; + // set up dependices + MS_LOG(DEBUG) << "set up dependices"; std::vector nodes = ::mindspore::TopoSort(anf_graph_->get_return()); for (auto &it : nodes) { SetNodeInput(it); diff --git a/mindspore/ccsrc/transform/op_adapter.h b/mindspore/ccsrc/transform/op_adapter.h index 7f20a88035..421e4c4569 100644 --- a/mindspore/ccsrc/transform/op_adapter.h +++ b/mindspore/ccsrc/transform/op_adapter.h @@ -322,18 +322,12 @@ class OpAdapter : public BaseOpAdapter { Status UpdateSingleOutputDesc(const OperatorPtr& op, const abstract::BaseShapePtr& shp, const TypePtr& type) { MS_EXCEPTION_IF_NULL(type); - TypeId me_type = type->type_id(); - if (kObjectTypeTensorType == me_type) { - me_type = dyn_cast(type)->element()->type_id(); - } - - std::vector shape; - auto normal_shape_ptr = dyn_cast(shp); - if (nullptr != normal_shape_ptr) { - shape = normal_shape_ptr->shape(); + std::string format = "NCHW"; + if (op->GetOpType() == kExtractImagePatchesOpName) { + format = "NHWC"; } - auto desc = TransformUtil::GetGeTensorDesc(shape, me_type, "NCHW"); + auto desc = CreateOutputDesc(dyn_cast(shp), type, format); if (desc == nullptr) { MS_LOG(ERROR) << "Update output descriptor failed!"; return FAILED; @@ -410,14 +404,15 @@ class OpAdapter : public BaseOpAdapter { MS_LOG(ERROR) << "output_map is not equal tuple_shape size"; return FAILED; } + std::string format = "NCHW"; + if (op->GetOpType() == kTopKOpName) { + format = "NHWC"; + } for (size_t i = 0; i < tuple_shp->shape().size(); ++i) { auto tuple_type = dyn_cast(type); MS_EXCEPTION_IF_NULL(tuple_type); TypePtr type_elem = tuple_type->elements()[i]; - std::string format = "NCHW"; - if (op->GetOpType() == kTopKOpName) { - format = "NHWC"; - } + auto desc = CreateOutputDesc(dyn_cast(tuple_shp->shape()[i]), type_elem, format); if (desc == nullptr) { MS_LOG(ERROR) << "Create output descriptor failed!"; @@ -476,6 +471,9 @@ class OpAdapter : public BaseOpAdapter { if (desc == nullptr) { continue; } + if (op->GetOpType() == kExtractImagePatchesOpName) { + desc->SetFormat(ge::Format::FORMAT_NHWC); + } it->second.update_input_desc(op, *desc); } } diff --git a/mindspore/ccsrc/utils/callbacks_ge.cc b/mindspore/ccsrc/utils/callbacks_ge.cc index 50fd2f0b11..36bbcbf297 100644 --- a/mindspore/ccsrc/utils/callbacks_ge.cc +++ b/mindspore/ccsrc/utils/callbacks_ge.cc @@ -131,7 +131,7 @@ static TensorPtr GetMeTensorForSummary(const std::string& name, const std::share auto shape = std::vector({ONE_SHAPE}); return TransformUtil::ConvertGeTensor(ge_tensor_ptr, shape); } - if (tname == "[:Tensor]") { + if (tname == "[:Tensor]" || tname == "[:Histogram]") { MS_LOG(DEBUG) << "The summary(" << name << ") is Tensor"; // process the tensor summary // Now we can't get the real shape, so we keep same shape with GE diff --git a/mindspore/ccsrc/utils/context/ms_context.cc b/mindspore/ccsrc/utils/context/ms_context.cc index 6c15e16714..bee5875f60 100644 --- a/mindspore/ccsrc/utils/context/ms_context.cc +++ b/mindspore/ccsrc/utils/context/ms_context.cc @@ -65,7 +65,7 @@ MsContext::MsContext(const std::string& policy, const std::string& target) { } backend_policy_ = policy_map_[policy]; device_target_ = target; - execution_mode_ = kGraphMode; + execution_mode_ = kPynativeMode; enable_task_sink_ = true; ir_fusion_flag_ = true; enable_hccl_ = false; @@ -75,7 +75,7 @@ MsContext::MsContext(const std::string& policy, const std::string& target) { precompile_only_ = false; auto_mixed_precision_flag_ = true; enable_pynative_infer_ = false; - enable_dynamic_mem_pool_ = false; + enable_dynamic_mem_pool_ = true; graph_memory_max_size_ = "0"; variable_memory_max_size_ = "0"; MS_LOG(INFO) << "Create context with backend policy:" << policy << ", device target:" << target << "."; diff --git a/mindspore/ccsrc/utils/convert_utils.h b/mindspore/ccsrc/utils/convert_utils.h index fbd4485a3f..55f478d5fe 100644 --- a/mindspore/ccsrc/utils/convert_utils.h +++ b/mindspore/ccsrc/utils/convert_utils.h @@ -81,6 +81,7 @@ inline size_t FloatToSize(float u) { } return static_cast(u); } +inline float IntToFloat(int32_t v) { return static_cast(v); } inline uint32_t IntToUint(int32_t u) { if (u < 0) { diff --git a/mindspore/ccsrc/utils/log_adapter.cc b/mindspore/ccsrc/utils/log_adapter.cc index 19482ec193..704ab24d52 100644 --- a/mindspore/ccsrc/utils/log_adapter.cc +++ b/mindspore/ccsrc/utils/log_adapter.cc @@ -26,12 +26,19 @@ namespace mindspore { #ifdef USE_GLOG static std::string GetTime() { #define BUFLEN 80 + static char buf[BUFLEN]; +#if defined(_WIN32) || defined(_WIN64) + time_t time_seconds = time(0); + struct tm now_time; + localtime_s(&now_time, &time_seconds); + sprintf_s(buf, BUFLEN, "%d-%d-%d %d:%d:%d", now_time.tm_year + 1900, now_time.tm_mon + 1, now_time.tm_mday, + now_time.tm_hour, now_time.tm_min, now_time.tm_sec); +#else struct timeval cur_time; (void)gettimeofday(&cur_time, NULL); struct tm now; (void)localtime_r(&cur_time.tv_sec, &now); - static char buf[BUFLEN]; (void)strftime(buf, BUFLEN, "%Y-%m-%d-%H:%M:%S", &now); // format date and time // set micro-second buf[27] = '\0'; @@ -44,6 +51,7 @@ static std::string GetTime() { buf[idx--] = '.'; } } +#endif return std::string(buf); } @@ -96,6 +104,13 @@ static int GetGlogLevel(MsLogLevel level) { } } #else + +#undef Dlog +#define Dlog(module_id, level, format, ...) \ + do { \ + DlogInner((module_id), (level), (format), ##__VA_ARGS__); \ + } while (0) + // convert MsLogLevel to corresponding slog level static int GetSlogLevel(MsLogLevel level) { switch (level) { diff --git a/mindspore/ccsrc/utils/log_adapter.h b/mindspore/ccsrc/utils/log_adapter.h index 61c253782e..2122870c3b 100644 --- a/mindspore/ccsrc/utils/log_adapter.h +++ b/mindspore/ccsrc/utils/log_adapter.h @@ -22,6 +22,7 @@ #include #include #include +#include "./overload.h" #include "./securec.h" #ifdef USE_GLOG #include "glog/logging.h" diff --git a/mindspore/ccsrc/utils/profile.cc b/mindspore/ccsrc/utils/profile.cc index 7a2bb2aa66..ba490549f8 100644 --- a/mindspore/ccsrc/utils/profile.cc +++ b/mindspore/ccsrc/utils/profile.cc @@ -30,6 +30,7 @@ namespace mindspore { namespace { +constexpr size_t TIME_INFO_PREFIX_NUM_LEN = 4; const char KEY_PROF_TOTAL[] = "__total__"; void PrintProfile(std::ostringstream& oss, const TimeInfo& time_info, int indent = 0, @@ -42,15 +43,16 @@ void PrintTimeInfoMap(std::ostringstream& oss, const TimeInfoMap& dict, int inde continue; } // indent by multiples of 4 spaces. + auto name = iter->first.substr(TIME_INFO_PREFIX_NUM_LEN); oss << std::setw(indent * 4) << "" - << "[" << iter->first << "]: " << iter->second->time_; + << "[" << name << "]: " << iter->second->time_; if (iter->second->dict_ != nullptr) { oss << ", [" << iter->second->dict_->size() << "]"; } oss << "\n"; std::string newPrefix = prefix; - if (iter->first.find("Cycle ") != 0) { + if (iter->first.find("Cycle ") == std::string::npos) { newPrefix = prefix.empty() ? iter->first : prefix + "." + iter->first; } PrintProfile(oss, *iter->second, indent + 1, sums, newPrefix); @@ -94,7 +96,14 @@ void PrintProfile(std::ostringstream& oss, const TimeInfo& time_info, int indent oss << "Sums\n"; if (total >= 0.0 + DBL_EPSILON) { for (auto& iter : *sums) { - oss << " " << std::left << std::setw(36) << iter.first << " : " << std::right << std::setw(12) << std::fixed + std::string name = iter.first; + name.erase(0, TIME_INFO_PREFIX_NUM_LEN); + std::size_t pos = 0; + while ((pos = name.find('.', pos)) != std::string::npos) { + pos++; + name.erase(pos, TIME_INFO_PREFIX_NUM_LEN); + } + oss << " " << std::left << std::setw(36) << name << " : " << std::right << std::setw(12) << std::fixed << std::setprecision(6) << iter.second << "s : " << std::right << std::setw(5) << std::fixed << std::setprecision(2) << iter.second / total * 100 << "%\n"; } @@ -241,14 +250,18 @@ void ProfContext::Insert(const std::string& name, const TimeInfo* time) noexcept } } - auto iter = time_info_->dict_->find(name); + std::stringstream ss; + ss << std::setw(TIME_INFO_PREFIX_NUM_LEN) << std::setfill('0') << time_info_->actionNum_; + std::string sorted_name(ss.str() + name); + time_info_->actionNum_++; + auto iter = time_info_->dict_->find(sorted_name); // if contains item with same name, delete it if (iter != time_info_->dict_->end()) { delete iter->second; iter->second = nullptr; (void)time_info_->dict_->erase(iter); } - (*time_info_->dict_)[name] = time; + (*time_info_->dict_)[sorted_name] = time; } bool ProfContext::IsTopContext() const noexcept { return (prof_ != nullptr) && (this == &prof_->context_); } diff --git a/mindspore/ccsrc/utils/profile.h b/mindspore/ccsrc/utils/profile.h index 4824f1f6ab..6892b0b4f6 100644 --- a/mindspore/ccsrc/utils/profile.h +++ b/mindspore/ccsrc/utils/profile.h @@ -34,12 +34,13 @@ extern double GetTime(); class ProfileBase; struct TimeInfo { - explicit TimeInfo(double time = -1.0) : time_(time), dict_(nullptr) {} + explicit TimeInfo(double time = -1.0) : time_(time), dict_(nullptr), actionNum_(0) {} TimeInfo(const TimeInfo&) = delete; ~TimeInfo(); double time_; TimeInfoMap* dict_; + size_t actionNum_; }; // Utility class for Profile. diff --git a/mindspore/ccsrc/utils/summary.proto b/mindspore/ccsrc/utils/summary.proto index f7fb733597..6ea6ce08b8 100644 --- a/mindspore/ccsrc/utils/summary.proto +++ b/mindspore/ccsrc/utils/summary.proto @@ -61,6 +61,30 @@ message Summary { required bytes encoded_image = 4; } + message Histogram { + message bucket{ + // Count number of values fallen in [left, left + width). + // For the right most bucket, range is [left, left + width]. + required double left = 1; + required double width = 2; + required int64 count = 3; + } + + repeated bucket buckets = 1; + optional int64 nan_count = 2; + optional int64 pos_inf_count = 3; + optional int64 neg_inf_count = 4; + + // max, min, sum will not take nan and inf into account. + // If there is no valid value in tensor, max will be nan, min will be nan, sum will be 0. + optional double max = 5; + optional double min = 6; + optional double sum = 7; + + // total number of values, including nan and inf + optional int64 count = 8; + } + message Value { // Tag name for the data. required string tag = 1; @@ -70,6 +94,7 @@ message Summary { float scalar_value = 3; Image image = 4; TensorProto tensor = 8; + Histogram histogram = 9; } } diff --git a/mindspore/ccsrc/utils/utils.h b/mindspore/ccsrc/utils/utils.h index ea5e969e52..10ef4abf62 100644 --- a/mindspore/ccsrc/utils/utils.h +++ b/mindspore/ccsrc/utils/utils.h @@ -42,12 +42,14 @@ constexpr auto kBNGrad2OpName = "BNGrad2"; constexpr auto kBNGrad3OpName = "BNGrad3"; constexpr auto kClearZeroOpName = "ClearZero"; constexpr auto kAtomicAddrCleanOpName = "AtomicAddrClean"; +constexpr auto kGetNextOpName = "GetNext"; constexpr auto kAllReduceOpName = "AllReduce"; constexpr auto kAllGatherOpName = "AllGather"; constexpr auto kBroadcastOpName = "Broadcast"; constexpr auto kReduceScatterOpName = "ReduceScatter"; constexpr auto kMemCpyAsyncOpName = "memcpy_async"; constexpr auto kTopKOpName = "TopK"; +constexpr auto kExtractImagePatchesOpName = "ExtractImagePatches"; constexpr auto kBNTrainingReduceOpName = "BNTrainingReduce"; constexpr auto kBNTrainingUpdateOpName = "BNTrainingUpdate"; constexpr auto kSimpleMeanGradOpName = "SimpleMeanGrad"; @@ -111,6 +113,11 @@ constexpr auto kFusedMulAddOpName = "FusedMulAdd"; constexpr auto kFusedMulAddNOpName = "FusedMulAddN"; constexpr auto kFusedMulApplyMomentumOpName = "FusedMulApplyMomentum"; constexpr auto kBiasAddOpName = "BiasAdd"; +constexpr auto kConfusionMulGradOpName = "ConfusionMulGrad"; +constexpr auto kSendOpName = "Send"; +constexpr auto kRecvOpName = "Recv"; +constexpr auto kReluV2OpName = "ReluV2"; +constexpr auto kReluGradV2OpName = "ReluGradV2"; // attr key name constexpr auto kAttrInputNames = "input_names"; @@ -142,6 +149,8 @@ constexpr auto kAttrDynInputSizes = "dyn_input_sizes"; constexpr auto kAttrSrcFormat = "src_format"; constexpr auto kAttrOutputUsedNum = "output_used_num"; constexpr auto kAttrHasBias = "has_bias"; +constexpr auto kAttrN = "N"; +constexpr auto kAttrLabelForInsertStreamActive = "label_for_insert_stream_active"; // attr value constexpr auto kValueTargetSwitch = "target_switch"; @@ -176,8 +185,11 @@ constexpr auto kOpFormat_NC1HWC0 = "NC1HWC0"; constexpr auto kOpFormat_FRAC_Z = "FracZ"; constexpr auto kOpFormat_FRAC_NZ = "FRACTAL_NZ"; constexpr auto kOpFormat_C1HWNCoC0 = "C1HWNCoC0"; -const std::set k1DSupportFormat = {kOpFormat_DEFAULT, kOpFormat_NCHW, kOpFormat_NHWC, - kOpFormat_FRAC_Z, kOpFormat_NC1KHKWHWC0, kOpFormat_NC1HWC0}; +constexpr auto kOpFormat_NC1HWC0_C04 = "NC1HWC0_C04"; +const std::set k1DSupportFormat = {kOpFormat_DEFAULT, kOpFormat_NCHW, kOpFormat_NHWC, + kOpFormat_FRAC_Z, kOpFormat_NC1KHKWHWC0, kOpFormat_NC1HWC0, + kOpFormat_C1HWNCoC0}; + const std::set k2DSupportFormat = {kOpFormat_DEFAULT, kOpFormat_NCHW, kOpFormat_NHWC, kOpFormat_FRAC_Z, kOpFormat_NC1KHKWHWC0}; const std::set k3DSupportFormat = {kOpFormat_DEFAULT, kOpFormat_NC1KHKWHWC0}; @@ -195,8 +207,8 @@ const std::set kOptOperatorSet = { kApplyRMSPropOpName, }; -const std::set kSpecialFormatSet = {kOpFormat_FRAC_Z, kOpFormat_NC1KHKWHWC0, kOpFormat_NC1HWC0, - kOpFormat_FRAC_NZ, kOpFormat_C1HWNCoC0}; +const std::set kNeedTransFormatSet = {kOpFormat_FRAC_Z, kOpFormat_NC1KHKWHWC0, kOpFormat_NC1HWC0, + kOpFormat_FRAC_NZ, kOpFormat_C1HWNCoC0}; static inline void ChangeFileMode(const std::string& file_name, mode_t mode) { if (access(file_name.c_str(), F_OK) != 0) { diff --git a/mindspore/ccsrc/vm/backend.cc b/mindspore/ccsrc/vm/backend.cc old mode 100644 new mode 100755 index 9355cca99c..e69d25d2dc --- a/mindspore/ccsrc/vm/backend.cc +++ b/mindspore/ccsrc/vm/backend.cc @@ -136,7 +136,7 @@ void MsBackend::SetSwitchGraph() { MS_LOG(EXCEPTION) << "cond not a anf node:" << curr_switch_.ToString(); } MS_LOG(DEBUG) << "switch compile:" << cond_g << ", " << true_g << ", " << false_g; - sess_->SwitchCompile(cond_g, true_g, false_g); + sess_->SwitchCompile(cond_g, true_g, false_g, utils::cast(curr_switch_)); } is_switch_call_ = false; MS_LOG(DEBUG) << "end SetSwitchGraph:" << curr_cond << ", " << is_switch_call_; diff --git a/mindspore/ccsrc/vm/transform.cc b/mindspore/ccsrc/vm/transform.cc index be7aaf5baa..92976e0ddb 100644 --- a/mindspore/ccsrc/vm/transform.cc +++ b/mindspore/ccsrc/vm/transform.cc @@ -41,8 +41,10 @@ using TypedPrimitiveAbstractClosurePtr = std::shared_ptr nonlinear_ops = {prim::kPrimReturn, prim::kPrimPartial, prim::kPrimSwitch, prim::kPrimMakeTuple}; - -std::vector ms_nonlinear_ops = {prim::kPrimReturn, prim::kPrimPartial, prim::kPrimSwitch}; +const std::vector& GetMsNonlinearOps() { + static const std::vector ms_nonlinear_ops = {prim::kPrimReturn, prim::kPrimPartial, prim::kPrimSwitch}; + return ms_nonlinear_ops; +} CompileGraph::CompileGraph(const BackendPtr& backend, const std::vector& cut_list) : backend_(backend), cut_list_(cut_list) { diff --git a/mindspore/ccsrc/vm/transform.h b/mindspore/ccsrc/vm/transform.h index f862444a82..290af10049 100644 --- a/mindspore/ccsrc/vm/transform.h +++ b/mindspore/ccsrc/vm/transform.h @@ -42,7 +42,7 @@ extern const char kGeVm[]; // A sub namespace in ME to support compile related definition. namespace compile { extern std::vector nonlinear_ops; -extern std::vector ms_nonlinear_ops; +const std::vector& GetMsNonlinearOps(); using VmEvalFunc = std::function; using VmEvalFuncPtr = std::shared_ptr>; diff --git a/mindspore/common/parameter.py b/mindspore/common/parameter.py index c8ddf0eac6..c354bcd235 100644 --- a/mindspore/common/parameter.py +++ b/mindspore/common/parameter.py @@ -14,7 +14,7 @@ # ============================================================================ """Parameter for cell.""" -from copy import copy +from copy import copy, deepcopy import numpy as np from .initializer import initializer from .tensor import Tensor @@ -156,16 +156,24 @@ class Parameter: return self.default_input def __add__(self, other): - return self.default_input + other + res = deepcopy(self) + res.default_input = res.default_input + other + return res def __sub__(self, other): - return self.default_input - other + res = deepcopy(self) + res.default_input = res.default_input - other + return res def __mul__(self, other): - return self.default_input * other + res = deepcopy(self) + res.default_input = res.default_input * other + return res def __truediv__(self, other): - return self.default_input / other + res = deepcopy(self) + res.default_input = res.default_input / other + return res def set_parameter_data(self, data): if isinstance(data, (Tensor, list, int, float, diff --git a/mindspore/common/tensor.py b/mindspore/common/tensor.py index 709b2ae280..70b8b169ca 100644 --- a/mindspore/common/tensor.py +++ b/mindspore/common/tensor.py @@ -70,45 +70,60 @@ class Tensor(Tensor_): return str(self.__str__()) def __add__(self, other): - if not isinstance(other, Tensor): - raise TypeError("input_data must be a tensor") + check_type('tensor input_data', other, (Tensor, float, int)) out = tensor_operator_registry.get('__add__')(self, other) return out def __mul__(self, other): - if not isinstance(other, Tensor): - raise TypeError("input_data must be a tensor") + check_type('tensor input_data', other, (Tensor, float, int)) out = tensor_operator_registry.get('__mul__')(self, other) return out + def __neg__(self): + return Tensor(-self.asnumpy()) + def __iadd__(self, other): out = self.__add__(other) return out + def __radd__(self, other): + check_type('tensor operation input', other, (Tensor, float, int)) + out = tensor_operator_registry.get('__add__')(other, self) + return out + def __imul__(self, other): out = self.__mul__(other) return out + def __rmul__(self, other): + check_type('tensor operation input', other, (Tensor, float, int)) + out = tensor_operator_registry.get('__mul__')(other, self) + return out + def __truediv__(self, other): - if isinstance(other, (int, float)): - other_tensor = Tensor(other, self.dtype()) - elif isinstance(other, Tensor): - other_tensor = other - else: - raise TypeError("unsupported type for div operation") - out = tensor_operator_registry.get('__div__')(self, other_tensor) + check_type('tensor operation input', other, (Tensor, float, int)) + out = tensor_operator_registry.get('__div__')(self, other) + return out + + def __rtruediv__(self, other): + check_type('tensor operation input', other, (Tensor, float, int)) + out = tensor_operator_registry.get('__div__')(other, self) return out def __sub__(self, other): - if not isinstance(other, Tensor): - raise TypeError("input_data must be a tensor") - out = self.__add__(Tensor(-other.asnumpy())) + check_type('tensor operation input', other, (Tensor, float, int)) + out = self.__add__(-other) return out def __isub__(self, other): out = self.__sub__(other) return out + def __rsub__(self, other): + check_type('tensor operation input', other, (Tensor, float, int)) + out = tensor_operator_registry.get('__add__')(other, Tensor(-self.asnumpy())) + return out + def __str__(self): if self.dtype() == mstype.type_none: return "Unknown Tensor type!" diff --git a/mindspore/context.py b/mindspore/context.py index 2938b87119..ba0ac36b66 100644 --- a/mindspore/context.py +++ b/mindspore/context.py @@ -487,8 +487,8 @@ def set_context(**kwargs): enable_loop_sink (bool): Whether to enable loop sink. Default: False. enable_task_sink (bool): Whether to enable task sink. Default: True. enable_mem_reuse (bool): Whether to enable memory reuse. Default: True. - save_ms_model (bool): Whether to save model converted by graph. Default: False. - save_ms_model_path (str): Path to save converted model. Default: "." + save_ms_model (bool): Whether to save lite model converted by graph. Default: False. + save_ms_model_path (str): Path to save converted lite model. Default: "." enable_gpu_summary (bool): Whether to enable gpu summary. Default: True. save_graphs_path (str): Path to save graphs. Default: "." enable_auto_mixed_precision (bool): Whether to enable auto mixed precision. Default: True. diff --git a/mindspore/dataset/engine/datasets.py b/mindspore/dataset/engine/datasets.py index 2058bbf826..8de56a6dff 100644 --- a/mindspore/dataset/engine/datasets.py +++ b/mindspore/dataset/engine/datasets.py @@ -35,8 +35,8 @@ from mindspore._c_expression import typing from mindspore import log as logger from . import samplers from .iterators import DictIterator, TupleIterator -from .validators import check, check_batch, check_shuffle, check_map, check_repeat, check_zip, check_rename, \ - check_project, check_imagefolderdatasetv2, check_mnist_cifar_dataset, check_manifestdataset, \ +from .validators import check, check_batch, check_shuffle, check_map, check_repeat, check_skip, check_zip, check_rename, \ + check_take, check_project, check_imagefolderdatasetv2, check_mnist_cifar_dataset, check_manifestdataset, \ check_tfrecorddataset, check_vocdataset, check_celebadataset, check_minddataset, check_generatordataset, \ check_zip_dataset, check_add_column from ..core.datatypes import mstype_to_detype, mstypelist_to_detypelist @@ -394,6 +394,8 @@ class Dataset: The order of using repeat and batch reflects the number of batches. Recommend that repeat operation should be used after batch operation. If dataset_sink_mode is False, here repeat operation is invalid. + If dataset_sink_mode is True, repeat count should be euqal to the epoch of training. Otherwise, + errors could occur since the amount of data is not the amount training requires. Args: count (int): Number of times the dataset should be repeated (default=None). @@ -417,8 +419,56 @@ class Dataset: >>> repeat_and_shuffle = data.repeat(50) >>> repeat_and_shuffle = repeat_and_shuffle.shuffle(10) """ + if count == 1: + return self return RepeatDataset(self, count) + @check_skip + def skip(self, count): + """ + Skip the first N elements of this dataset. + + Args: + count (int): Number of elements the dataset should be skipped. + + Returns: + SkipDataset, dataset skipped. + + Examples: + >>> import mindspore.dataset as ds + >>> # data is an instance of Dataset object. + >>> # creates a dataset which skips first 3 elements from data + >>> data = data.skip(3) + """ + return SkipDataset(self, count) + + @check_take + def take(self, count=-1): + """ + Takes at most given numbers of elements from the dataset. + + Note: + 1. If count is greater than the number of element in dataset or equal to -1, + all the element in dataset will be taken. + 2. The order of using take and batch effects. If take before batch operation, + then taken given number of rows, otherwise take given number of batches. + + Args: + count (int, optional): Number of elements to be taken from the dataset (default=-1). + + Returns: + TakeDataset, dataset taken. + + Examples: + >>> import mindspore.dataset as ds + >>> # data is an instance of Dataset object. + >>> # creates a dataset where the dataset including 50 elements. + >>> data = data.take(50) + """ + if count == -1: + return self + return TakeDataset(self, count) + @check_zip_dataset def zip(self, datasets): """ @@ -497,14 +547,55 @@ class Dataset: return ProjectDataset(self, columns) + def apply(self, apply_func): + """ + Apply a function in this dataset. + + The specified apply_func is a function that must take one 'Dataset' as an argument + and return a preprogressing 'Dataset'. + + Args: + apply_func (function): A function that must take one 'Dataset' as an argument and + return a preprogressing 'Dataset'. + + Returns: + Dataset, applied by the function. + + Examples: + >>> import mindspore.dataset as ds + >>> # data is an instance of Dataset object + >>> # declare an apply_func function which returns a Dataset object + >>> def apply_func(ds): + >>> ds = ds.batch(2) + >>> return ds + >>> # use apply to call apply_func + >>> data = data.apply(apply_func) + + Raises: + TypeError: If apply_func is not a function. + TypeError: If apply_func doesn't return a Dataset. + """ + + if not hasattr(apply_func, '__call__'): + raise TypeError("apply_func must be a function.") + + dataset = apply_func(self) + if not isinstance(dataset, Dataset): + raise TypeError("apply_func must return a dataset.") + return dataset + def device_que(self, prefetch_size=None): """ - Returns a transferredDataset that transfer data through tdt. + Returns a transferredDataset that transfer data through device. Args: prefetch_size (int, optional): prefetch number of records ahead of the user's request (default=None). + Note: + If device is Ascend, features of data will be transferred one by one. The limitation + of data transmission per time is 256M. + Return: TransferDataset, dataset for transferring. """ @@ -517,6 +608,10 @@ class Dataset: Args: num_batch (int, optional): limit the number of batch to be sent to device (default=None). + Note: + If device is Ascend, features of data will be transferred one by one. The limitation + of data transmission per time is 256M. + Returns: TransferDataset, dataset for transferring. @@ -550,9 +645,9 @@ class Dataset: def get_distribution(output_dataset): dev_id = 0 - if isinstance(output_dataset, (StorageDataset, GeneratorDataset, MindDataset)): + if isinstance(output_dataset, (StorageDataset, MindDataset)): return output_dataset.distribution, dev_id - if isinstance(output_dataset, (Cifar10Dataset, Cifar100Dataset, ImageFolderDatasetV2, + if isinstance(output_dataset, (Cifar10Dataset, Cifar100Dataset, GeneratorDataset, ImageFolderDatasetV2, ManifestDataset, MnistDataset, VOCDataset, CelebADataset)): sampler = output_dataset.sampler if isinstance(sampler, samplers.DistributedSampler): @@ -780,7 +875,7 @@ class Dataset: """ if self.input: return self.input[0].get_class_indexing() - return None + raise NotImplementedError("Dataset {} has not supported api get_class_indexing yet.".format(type(self))) def reset(self): """Reset the dataset for next epoch""" @@ -1033,6 +1128,75 @@ class RepeatDataset(DatasetOp): return self.count +class SkipDataset(DatasetOp): + """ + The result of applying Skip operator to the input Dataset. + + Args: + datasets (tuple): A tuple of datasets to be skipped. + count (int): Number of rows the dataset should be skipped. + """ + + def __init__(self, input_dataset, count): + super().__init__() + self.count = count + self.input.append(input_dataset) + input_dataset.output.append(self) + self._input_indexs = input_dataset.input_indexs + + def get_args(self): + args = super().get_args() + args["count"] = self.count + return args + + def get_dataset_size(self): + """ + Get the number of batches in an epoch. + + Return: + Number, number of batches. + """ + child_size = self.input[0].get_dataset_size() + output_size = 0 + if self.count >= 0 and self.count < child_size: + output_size = child_size - self.count + return output_size + + +class TakeDataset(DatasetOp): + """ + The result of applying Take operator to the input Dataset. + + Args: + input_dataset (Dataset): Input Dataset to be taken element from. + count (int): Number of elements to be taken from the dataset. + """ + + def __init__(self, input_dataset, count): + super().__init__() + self.count = count + self.input.append(input_dataset) + input_dataset.output.append(self) + self._input_indexs = input_dataset.input_indexs + + def get_args(self): + args = super().get_args() + args["count"] = self.count + return args + + def get_dataset_size(self): + """ + Get the number of batches in an epoch. + + Return: + Number, number of batches. + """ + child_size = self.input[0].get_dataset_size() + if child_size < self.count: + return child_size + return self.count + + class ZipDataset(DatasetOp): """ The result of applying Zip operator to the input Dataset. @@ -1363,7 +1527,6 @@ def _select_sampler(num_samples, input_sampler, shuffle, num_shards, shard_id): return samplers.SequentialSampler() - class ImageFolderDatasetV2(SourceDataset): """ A source dataset that reads images from a tree of directories. @@ -1621,6 +1784,9 @@ class MindDataset(SourceDataset): shard_id (int, optional): The shard ID within num_shards (default=None). This argument should be specified only when num_shards is also specified. block_reader (bool, optional): Whether read data by block mode (default=False). + sampler (Sampler, optional): Object used to choose samples from the + dataset (default=None, sampler is exclusive + with shuffle and block_reader). Support list: SubsetRandomSampler. Raises: ValueError: If num_shards is specified but shard_id is None. @@ -1630,14 +1796,16 @@ class MindDataset(SourceDataset): @check_minddataset def __init__(self, dataset_file, columns_list=None, num_parallel_workers=None, - shuffle=None, num_shards=None, shard_id=None, block_reader=False): + shuffle=None, num_shards=None, shard_id=None, + block_reader=False, sampler=None): super().__init__(num_parallel_workers) self.dataset_file = dataset_file self.columns_list = columns_list - self.global_shuffle = not bool(shuffle is False) + self.global_shuffle = shuffle self.distribution = "" + self.sampler = sampler - if num_shards is None: + if num_shards is None or shard_id is None: self.partitions = None else: self.partitions = [num_shards, shard_id] @@ -1645,9 +1813,25 @@ class MindDataset(SourceDataset): if block_reader is True and self.partitions is not None: raise ValueError("block reader not allowed true when use partitions") + if block_reader is True and shuffle is True: + raise ValueError("block reader not allowed true when use shuffle") + if block_reader is True: logger.warning("WARN: global shuffle is not used.") + if sampler is not None and isinstance(sampler, samplers.SubsetRandomSampler) is False: + raise ValueError("the sampler is not supported yet.") + + # sampler exclusive + if block_reader is True and sampler is not None: + raise ValueError("block reader not allowed true when use sampler") + + if shuffle is True and sampler is not None: + raise ValueError("shuffle not allowed true when use sampler") + + if block_reader is False and sampler is None: + self.global_shuffle = not bool(shuffle is False) + self.num_shards = num_shards self.shard_id = shard_id self.block_reader = block_reader @@ -1661,6 +1845,7 @@ class MindDataset(SourceDataset): args["block_reader"] = self.block_reader args["num_shards"] = self.num_shards args["shard_id"] = self.shard_id + args["sampler"] = self.sampler return args def get_dataset_size(self): @@ -1680,14 +1865,70 @@ class MindDataset(SourceDataset): return num_rows -def ds_fn(dataset): - for val in dataset: - # convert output tensors to ndarrays - yield tuple([np.array(x) for x in val]) +def _iter_fn(dataset, num_samples): + """ + Generator function wrapper for iterable dataset + """ + if num_samples is not None: + ds_iter = iter(dataset) + for _ in range(num_samples): + try: + val = next(ds_iter) + except StopIteration: + return + # convert output tensors to ndarrays + yield tuple([np.array(x) for x in val]) + else: + for val in dataset: + # convert output tensors to ndarrays + yield tuple([np.array(x) for x in val]) + + +def _generator_fn(generator, num_samples): + """ + Generator function wrapper for generator function dataset + """ + if num_samples is not None: + gen_iter = generator() + for _ in range(num_samples): + try: + val = next(gen_iter) + except StopIteration: + return + yield val + else: + gen_iter = generator() + for val in gen_iter: + yield val -def sampler_fn(sampler, dataset): - for i in sampler: +def _py_sampler_fn(sampler, num_samples, dataset): + """ + Generator function wrapper for mappable dataset with python sampler + """ + if num_samples is not None: + sampler_iter = iter(sampler) + for _ in range(num_samples): + try: + idx = next(sampler_iter) + except StopIteration: + return + val = dataset[idx] + # convert output tensors to ndarrays + yield tuple([np.array(x) for x in val]) + else: + for i in sampler: + val = dataset[i] + # convert output tensors to ndarrays + yield tuple([np.array(x) for x in val]) + + +def _cpp_sampler_fn(sampler, dataset): + """ + Generator function wrapper for mappable dataset with cpp sampler + """ + indices = sampler.get_indices() + for i in indices: val = dataset[i] # convert output tensors to ndarrays yield tuple([np.array(x) for x in val]) @@ -1695,49 +1936,122 @@ def sampler_fn(sampler, dataset): class GeneratorDataset(SourceDataset): """ - A source dataset that generate data from calling generator function each epoch. + A source dataset that generate data from python by invoking python data source each epoch. + + This dataset can take in a sampler. sampler and shuffle are mutually exclusive. Table + below shows what input args are allowed and their expected behavior. + + .. list-table:: Expected Order Behavior of Using 'sampler' and 'shuffle' + :widths: 25 25 50 + :header-rows: 1 + + * - Parameter 'sampler' + - Parameter 'shuffle' + - Expected Order Behavior + * - None + - None + - random order + * - None + - True + - random order + * - None + - False + - sequential order + * - Sampler object + - None + - order defined by sampler + * - Sampler object + - True + - not allowed + * - Sampler object + - False + - not allowed Args: - generator_function (callable): - A callable object that returns an Generator object that supports the iter() protocol. - Generator object is required to return a tuple of numpy array as a row of the dataset on next(). + source (Callable/Iterable/Random Accessible): + A generator callable object, an iterable python object or a random accessible python object. + Callable source is required to return a tuple of numpy array as a row of the dataset on source().next(). + Iterable source is required to return a tuple of numpy array as a row of the dataset on iter(source).next(). + Random accessible source is required to return a tuple of numpy array as a row of the dataset on + source[idx]. column_names (list[str]): List of column names of the dataset. column_types (list[mindspore.dtype], optional): List of column data types of the dataset (default=None). If provided, sanity check will be performed on generator output. - prefetch_size (int, optional): Prefetch number of records ahead of the user's request (default=None). - sampler (Sampler, optional): Object used to choose samples from the dataset (default=None). + schema (Schema/String, optional): Path to the json schema file or schema object (default=None). + If the schema is not provided, the meta data from column_names and column_types is considered the schema. + num_samples (int, optional): The number of samples to be included in the dataset + (default=None, all images). + shuffle (bool, optional): Whether or not to perform shuffle on the dataset. Random accessible input is required. + (default=None, expected order behavior shown in the table). + sampler (Sampler/Iterable, optional): Object used to choose samples from the dataset. Random accessible input is + required. + (default=None, expected order behavior shown in the table). + num_shards (int, optional): Number of shards that the dataset should be divided into (default=None). + This argument should be specified only when 'num_samples' is "None". Random accessible input is required. + shard_id (int, optional): The shard ID within num_shards (default=None). This argument should be specified only + when num_shards is also specified. Random accessible input is required. Examples: - >>> import mindspore.dataset as ds - >>> # 1) generator function that generates multi-dimensional data + >>> import mindspore.dataengine as de + >>> # 1) Multidimensional generator function as callable input >>> def generator_md(): >>> for i in range(64): >>> yield (np.array([[i, i + 1], [i + 2, i + 3]]),) - >>> # create multi_dimension_generator_dataset with GeneratorMD() and column name "multi_dimensional_data" - >>> multi_dimension_generator_dataset = ds.GeneratorDataset(generator_md, ["multi_dimensional_data"]) - >>> # 2) generator function that generates multi-columns data + >>> # create multi_dimension_generator_dataset with GeneratorMD and column name "multi_dimensional_data" + >>> multi_dimension_generator_dataset = de.GeneratorDataset(generator_md, ["multi_dimensional_data"]) + >>> # 2) Multi-column generator function as callable input >>> def generator_mc(maxid = 64): >>> for i in range(maxid): >>> yield (np.array([i]), np.array([[i, i + 1], [i + 2, i + 3]])) - >>> # create multi_column_generator_dataset with GeneratorMC() and column names "col1" and "col2" - >>> multi_column_generator_dataset = ds.GeneratorDataset(generator_mc, ["col1, col2"]) + >>> # create multi_column_generator_dataset with GeneratorMC and column names "col1" and "col2" + >>> multi_column_generator_dataset = de.GeneratorDataset(generator_mc, ["col1", "col2"]) + >>> # 3) Iterable dataset as iterable input + >>> class MyIterable(): + >>> def __iter__(self): + >>> return # User implementation + >>> # create iterable_generator_dataset with MyIterable object + >>> iterable_generator_dataset = de.GeneratorDataset(MyIterable(), ["col1"]) + >>> # 4) Random accessible dataset as Random accessible input + >>> class MyRA(): + >>> def __getitem__(self, index): + >>> return # User implementation + >>> # create ra_generator_dataset with MyRA object + >>> ra_generator_dataset = de.GeneratorDataset(MyRA(), ["col1"]) + >>> # List/Dict/Tuple is also random accessible + >>> list_generator = de.GeneratorDataset([(np.array(0),), (np.array(1)), (np.array(2))], ["col1"]) + >>> # 5) Built-in Sampler + >>> my_generator = de.GeneratorDataset(my_ds, ["img", "label"], sampler=samplers.RandomSampler()) + >>> """ @check_generatordataset - def __init__(self, generator_function, column_names, column_types=None, prefetch_size=None, sampler=None): - super().__init__(1) - if sampler is not None: - self.generator_function = (lambda: sampler_fn(sampler, generator_function)) + def __init__(self, source, column_names, column_types=None, schema=None, num_samples=None, num_parallel_workers=1, + shuffle=None, sampler=None, num_shards=None, shard_id=None): + super().__init__(num_parallel_workers) + self.sampler = _select_sampler(num_samples, sampler, shuffle, num_shards, shard_id) + if self.sampler is not None and hasattr(source, "__getitem__"): + if isinstance(self.sampler, (samplers.SequentialSampler, samplers.DistributedSampler, + samplers.RandomSampler, samplers.SubsetRandomSampler, + samplers.WeightedRandomSampler)): + if num_samples is None: + num_samples = len(source) + sampler_instance = self.sampler.create() + sampler_instance.set_num_rows(len(source)) + sampler_instance.set_num_samples(num_samples) + sampler_instance.initialize() + self.source = (lambda: _cpp_sampler_fn(sampler_instance, source)) + else: + self.source = (lambda: _py_sampler_fn(self.sampler, num_samples, source)) else: try: - # test to see if generator_function is iterable - iter(generator_function) + iter(source) except TypeError: - # generator_function was not iterable, assume it is a function - self.generator_function = generator_function + # Use generator function if input callable + self.source = (lambda: _generator_fn(source, num_samples)) else: - # generator_function was iterable, build a function around it - self.generator_function = (lambda: ds_fn(generator_function)) + # Use iterator function if input is iterable + # Random accessible input is also iterable + self.source = (lambda: _iter_fn(source, num_samples)) self.column_names = column_names @@ -1745,17 +2059,12 @@ class GeneratorDataset(SourceDataset): self.column_types = mstypelist_to_detypelist(column_types) else: self.column_types = column_types - self.distribution = "" - self.prefetch_size = prefetch_size - self.sampler = sampler def get_args(self): args = super().get_args() - args["generator_function"] = self.generator_function + args["source"] = self.source args["column_names"] = self.column_names args["column_types"] = self.column_types - args["prefetch_size"] = self.prefetch_size - args["sampler"] = self.sampler return args def get_dataset_size(self): @@ -2394,47 +2703,58 @@ class Schema: Parse the columns and add it to self. Args: - columns (dict or list[str]): names of columns. + columns (dict or list[dict]): dataset attribution information, decoded from schema file. + + - list[dict], 'name' and 'type' must be in keys, 'shape' optional. + + - dict, columns.keys() as name, columns.values() is dict, and 'type' inside, 'shape' optional. Raises: - RuntimeError: If failed to parse schema file. - RuntimeError: If unknown items in schema file. + RuntimeError: If failed to parse columns. + RuntimeError: If unknown items in columns. RuntimeError: If column's name field is missing. RuntimeError: If column's type field is missing. + + Example: + >>> schema = Schema() + >>> columns1 = [{'name': 'image', 'type': 'int8', 'shape': [3, 3]}, + >>> {'name': 'label', 'type': 'int8', 'shape': [1]}] + >>> schema.parse_columns(columns1) + >>> columns2 = {'image': {'shape': [3, 3], 'type': 'int8'}, 'label': {'shape': [1], 'type': 'int8'}} + >>> schema.parse_columns(columns2) """ - if columns is None: - raise TypeError("Expected non-empty dict or string list.") self.columns = [] - for col in columns: - name = None - shape = None - data_type = None - col_details = None - if isinstance(columns, list): - col_details = col - if "name" in col: - name = col["name"] - elif isinstance(columns, dict): - col_details = columns[col] - name = col - else: - raise RuntimeError("Error parsing the schema file") - - for k, v in col_details.items(): - if k == "shape": - shape = v - elif k == "type": - data_type = v - elif k in ("t_impl", "rank"): - pass - else: - raise RuntimeError("Unknown field %s" % k) - - if name is None: - raise RuntimeError("Column's name field is missing.") - if data_type is None: - raise RuntimeError("Column's type field is missing.") - self.add_column(name, data_type, shape) + if isinstance(columns, list): + for column in columns: + try: + name = column.pop("name") + except KeyError: + raise RuntimeError("Column's name is missing") + try: + de_type = column.pop("type") + except KeyError: + raise RuntimeError("Column' type is missing") + shape = column.pop("shape", None) + column.pop("t_impl", None) + column.pop("rank", None) + if column: + raise RuntimeError("Unknown field {}".format(",".join(column.keys()))) + self.add_column(name, de_type, shape) + elif isinstance(columns, dict): + for key, value in columns.items(): + name = key + try: + de_type = value.pop("type") + except KeyError: + raise RuntimeError("Column' type is missing") + shape = value.pop("shape", None) + value.pop("t_impl", None) + value.pop("rank", None) + if value: + raise RuntimeError("Unknown field {}".format(",".join(value.keys()))) + self.add_column(name, de_type, shape) + else: + raise RuntimeError("columns must be dict or list, columns contain name, type, shape(optional).") def from_json(self, json_obj): """ diff --git a/mindspore/dataset/engine/iterators.py b/mindspore/dataset/engine/iterators.py index 268a66c0cf..2bb130f303 100644 --- a/mindspore/dataset/engine/iterators.py +++ b/mindspore/dataset/engine/iterators.py @@ -15,6 +15,8 @@ """Built-in iterators. """ from abc import abstractmethod +import copy +import weakref from mindspore._c_dataengine import DEPipeline from mindspore._c_dataengine import OpName @@ -26,8 +28,10 @@ ITERATORS_LIST = list() def _cleanup(): - for itr in ITERATORS_LIST: - itr.release() + for itr_ref in ITERATORS_LIST: + itr = itr_ref() + if itr is not None: + itr.release() def alter_tree(node): @@ -73,8 +77,10 @@ class Iterator: """ def __init__(self, dataset): - ITERATORS_LIST.append(self) - self.dataset = alter_tree(dataset) + ITERATORS_LIST.append(weakref.ref(self)) + # create a copy of tree and work on it. + self.dataset = copy.deepcopy(dataset) + self.dataset = alter_tree(self.dataset) if not self.__is_tree(): raise ValueError("The data pipeline is not a tree (i.e., one node has 2 consumers)") self.depipeline = DEPipeline() @@ -121,6 +127,10 @@ class Iterator: op_type = OpName.MAP elif isinstance(dataset, de.RepeatDataset): op_type = OpName.REPEAT + elif isinstance(dataset, de.SkipDataset): + op_type = OpName.SKIP + elif isinstance(dataset, de.TakeDataset): + op_type = OpName.TAKE elif isinstance(dataset, de.StorageDataset): op_type = OpName.STORAGE elif isinstance(dataset, de.ImageFolderDatasetV2): @@ -223,6 +233,9 @@ class Iterator: def num_classes(self): return self.depipeline.GetNumClasses() + def __deepcopy__(self, memo): + return Iterator(copy.deepcopy(self.dataset, memo)) + class DictIterator(Iterator): """ diff --git a/mindspore/dataset/engine/samplers.py b/mindspore/dataset/engine/samplers.py index 62a3dbed18..0bba559210 100644 --- a/mindspore/dataset/engine/samplers.py +++ b/mindspore/dataset/engine/samplers.py @@ -20,7 +20,6 @@ SequentialSampler, SubsetRandomSampler, WeightedRandomSampler. import mindspore._c_dataengine as cde - class DistributedSampler(): """ Sampler that access a shard of the dataset. @@ -113,8 +112,7 @@ class RandomSampler(): Args: replacement (bool, optional): If True, put the sample ID back for the next draw (default=False). - num_samples (int, optional): Number of elements to sample (default=None, all elements). This - argument should be specified only when 'replacement' is "True". + num_samples (int, optional): Number of elements to sample (default=None, all elements). Examples: >>> import mindspore.dataset as ds @@ -195,6 +193,8 @@ class SubsetRandomSampler(): def create(self): return cde.SubsetRandomSampler(self.indices) + def _create_for_minddataset(self): + return cde.MindrecordSubsetRandomSampler(self.indices) class WeightedRandomSampler(): """ diff --git a/mindspore/dataset/engine/serializer_deserializer.py b/mindspore/dataset/engine/serializer_deserializer.py index d1ed5c47cd..61417e4d52 100644 --- a/mindspore/dataset/engine/serializer_deserializer.py +++ b/mindspore/dataset/engine/serializer_deserializer.py @@ -127,9 +127,12 @@ def serialize_operations(node_repr, key, val): def serialize_sampler(node_repr, val): """Serialize sampler object to dictionary.""" - node_repr['sampler'] = val.__dict__ - node_repr['sampler']['sampler_module'] = type(val).__module__ - node_repr['sampler']['sampler_name'] = type(val).__name__ + if val is None: + node_repr['sampler'] = None + else: + node_repr['sampler'] = val.__dict__ + node_repr['sampler']['sampler_module'] = type(val).__module__ + node_repr['sampler']['sampler_name'] = type(val).__name__ def traverse(node): @@ -253,9 +256,10 @@ def create_node(node): node.get('shuffle'), sampler, node.get('num_shards'), node.get('shard_id')) elif dataset_op == 'MindDataset': - pyobj = pyclass(node['dataset_file'], node.get('column_list'), + sampler = construct_sampler(node.get('sampler')) + pyobj = pyclass(node['dataset_file'], node.get('columns_list'), node.get('num_parallel_workers'), node.get('seed'), node.get('num_shards'), - node.get('shard_id'), node.get('block_reader')) + node.get('shard_id'), node.get('block_reader'), sampler) elif dataset_op == 'TFRecordDataset': pyobj = pyclass(node['dataset_files'], node.get('schema'), node.get('column_list'), @@ -297,6 +301,12 @@ def create_node(node): elif dataset_op == 'RepeatDataset': pyobj = de.Dataset().repeat(node.get('count')) + elif dataset_op == 'SkipDataset': + pyobj = de.Dataset().skip(node.get('count')) + + elif dataset_op == 'TakeDataset': + pyobj = de.Dataset().take(node.get('count')) + elif dataset_op == 'MapDataset': tensor_ops = construct_tensor_ops(node.get('operations')) pyobj = de.Dataset().map(node.get('input_columns'), tensor_ops, node.get('output_columns'), @@ -341,24 +351,25 @@ def create_node(node): def construct_sampler(in_sampler): """Instantiate Sampler object based on the information from dictionary['sampler']""" - sampler_name = in_sampler['sampler_name'] - sampler_module = in_sampler['sampler_module'] - sampler_class = getattr(sys.modules[sampler_module], sampler_name) sampler = None - if sampler_name == 'DistributedSampler': - sampler = sampler_class(in_sampler['num_shards'], in_sampler['shard_id'], in_sampler.get('shuffle')) - elif sampler_name == 'PKSampler': - sampler = sampler_class(in_sampler['num_val'], in_sampler.get('num_class'), in_sampler('shuffle')) - elif sampler_name == 'RandomSampler': - sampler = sampler_class(in_sampler.get('replacement'), in_sampler.get('num_samples')) - elif sampler_name == 'SequentialSampler': - sampler = sampler_class() - elif sampler_name == 'SubsetRandomSampler': - sampler = sampler_class(in_sampler['indices']) - elif sampler_name == 'WeightedRandomSampler': - sampler = sampler_class(in_sampler['weights'], in_sampler['num_samples'], in_sampler.get('replacement')) - else: - raise ValueError("Sampler type is unknown: " + sampler_name) + if in_sampler is not None: + sampler_name = in_sampler['sampler_name'] + sampler_module = in_sampler['sampler_module'] + sampler_class = getattr(sys.modules[sampler_module], sampler_name) + if sampler_name == 'DistributedSampler': + sampler = sampler_class(in_sampler['num_shards'], in_sampler['shard_id'], in_sampler.get('shuffle')) + elif sampler_name == 'PKSampler': + sampler = sampler_class(in_sampler['num_val'], in_sampler.get('num_class'), in_sampler('shuffle')) + elif sampler_name == 'RandomSampler': + sampler = sampler_class(in_sampler.get('replacement'), in_sampler.get('num_samples')) + elif sampler_name == 'SequentialSampler': + sampler = sampler_class() + elif sampler_name == 'SubsetRandomSampler': + sampler = sampler_class(in_sampler['indices']) + elif sampler_name == 'WeightedRandomSampler': + sampler = sampler_class(in_sampler['weights'], in_sampler['num_samples'], in_sampler.get('replacement')) + else: + raise ValueError("Sampler type is unknown: " + sampler_name) return sampler diff --git a/mindspore/dataset/engine/validators.py b/mindspore/dataset/engine/validators.py index 63d7c58270..b74e913202 100644 --- a/mindspore/dataset/engine/validators.py +++ b/mindspore/dataset/engine/validators.py @@ -543,28 +543,48 @@ def check_generatordataset(method): def new_method(*args, **kwargs): param_dict = make_param_dict(method, args, kwargs) - nreq_param_int = ['prefetch_size'] - nreq_param_list = ['column_names', 'column_types'] - # check generator_function; required argument - generator_function = param_dict.get('generator_function') - if generator_function is None: - raise ValueError("generator_function is not provided.") + source = param_dict.get('source') + if source is None: + raise ValueError("source is not provided.") + if not callable(source): + try: + iter(source) + except TypeError: + raise TypeError("source should be callable, iterable or random accessible") # check column_names; required argument column_names = param_dict.get('column_names') if column_names is None: raise ValueError("column_names is not provided.") - # check prefetch_size range - prefetch_size = param_dict.get('prefetch_size') - if prefetch_size is not None and (prefetch_size <= 0 or prefetch_size > 1024): - raise ValueError("prefetch_size exceeds the boundary.") - + # check optional argument + nreq_param_int = ["num_samples", "num_parallel_workers", "num_shards", "shard_id"] check_param_type(nreq_param_int, param_dict, int) - + nreq_param_list = ["column_types"] check_param_type(nreq_param_list, param_dict, list) + num_shards = param_dict.get("num_shards") + shard_id = param_dict.get("shard_id") + if (num_shards is None) != (shard_id is None): + # These two parameters appear together. + raise ValueError("num_shards and shard_id need to be passed in together") + if num_shards is not None: + if shard_id >= num_shards: + raise ValueError("shard_id should be less than num_shards") + + sampler = param_dict.get("sampler") + if sampler is not None: + if isinstance(sampler, samplers.PKSampler): + raise ValueError("PKSampler is not supported by GeneratorDataset") + if not isinstance(sampler, (samplers.SequentialSampler, samplers.DistributedSampler, + samplers.RandomSampler, samplers.SubsetRandomSampler, + samplers.WeightedRandomSampler)): + try: + iter(sampler) + except TypeError: + raise TypeError("sampler should be either iterable or from dataset.samplers.py") + return method(*args, **kwargs) return new_method @@ -582,7 +602,7 @@ def check_batch_size(batch_size): def check_count(count): check_type(count, 'count', int) if (count <= 0 and count != -1) or count > INT32_MAX: - raise ValueError("repeat count should be either -1 or positive integer.") + raise ValueError("count should be either -1 or positive integer.") def check_columns(columns, name): @@ -690,6 +710,36 @@ def check_repeat(method): return new_method +def check_skip(method): + """check the input arguments of skip.""" + @wraps(method) + def new_method(*args, **kwargs): + param_dict = make_param_dict(method, args, kwargs) + + count = param_dict.get('count') + check_type(count, 'count', int) + if count < 0: + raise ValueError("Skip count must be positive integer or 0.") + + return method(*args, **kwargs) + + return new_method + + +def check_take(method): + """check the input arguments of take.""" + @wraps(method) + def new_method(*args, **kwargs): + param_dict = make_param_dict(method, args, kwargs) + + count = param_dict.get('count') + check_count(count) + + return method(*args, **kwargs) + + return new_method + + def check_zip(method): """check the input arguments of zip.""" @wraps(method) @@ -725,6 +775,7 @@ def check_zip_dataset(method): return new_method + def check_rename(method): """check the input arguments of rename.""" @wraps(method) diff --git a/mindspore/log.py b/mindspore/log.py index 38455e2e18..9731b04ac1 100644 --- a/mindspore/log.py +++ b/mindspore/log.py @@ -19,11 +19,13 @@ import sys import os import stat import time -import fcntl import logging from logging.handlers import RotatingFileHandler import traceback import threading +import platform +if platform.system() != "Windows": + import fcntl __all__ = ['get_level', 'get_log_config'] @@ -90,7 +92,8 @@ class _MultiCompatibleRotatingFileHandler(RotatingFileHandler): # Attain an exclusive lock with bloking mode by `fcntl` module. with open(self.baseFilename, 'a') as file_pointer: - fcntl.lockf(file_pointer.fileno(), fcntl.LOCK_EX) + if platform.system() != "Windows": + fcntl.lockf(file_pointer.fileno(), fcntl.LOCK_EX) if self.backupCount > 0: self.rolling_rename() diff --git a/mindspore/mindrecord/filewriter.py b/mindspore/mindrecord/filewriter.py index 4056825ff3..90bca48038 100644 --- a/mindspore/mindrecord/filewriter.py +++ b/mindspore/mindrecord/filewriter.py @@ -26,8 +26,7 @@ from .shardheader import ShardHeader from .shardindexgenerator import ShardIndexGenerator from .shardutils import MIN_SHARD_COUNT, MAX_SHARD_COUNT, VALID_ATTRIBUTES, VALID_ARRAY_ATTRIBUTES, \ check_filename, VALUE_TYPE_MAP -from .common.exceptions import ParamValueError, ParamTypeError, MRMInvalidSchemaError, MRMDefineIndexError, \ - MRMValidateDataError +from .common.exceptions import ParamValueError, ParamTypeError, MRMInvalidSchemaError, MRMDefineIndexError __all__ = ['FileWriter'] @@ -201,52 +200,13 @@ class FileWriter: raw_data.pop(i) logger.warning(v) - def _verify_based_on_blob_fields(self, raw_data): + def write_raw_data(self, raw_data): """ - Verify data according to blob fields which is sub set of schema's fields. - - Raise exception if validation failed. - 1) allowed data type contains: "int32", "int64", "float32", "float64", "string", "bytes". - - Args: - raw_data (list[dict]): List of raw data. - - Raises: - MRMValidateDataError: If data does not match blob fields. - """ - schema_content = self._header.schema - for field in schema_content: - for i, v in enumerate(raw_data): - if field not in v: - raise MRMValidateDataError("for schema, {} th data is wrong: "\ - "there is not '{}' object in the raw data.".format(i, field)) - if field in self._header.blob_fields: - field_type = type(v[field]).__name__ - if field_type not in VALUE_TYPE_MAP: - raise MRMValidateDataError("for schema, {} th data is wrong: "\ - "data type for '{}' is not matched.".format(i, field)) - if schema_content[field]["type"] not in VALUE_TYPE_MAP[field_type]: - raise MRMValidateDataError("for schema, {} th data is wrong: "\ - "data type for '{}' is not matched.".format(i, field)) - if field_type == 'ndarray': - if 'shape' not in schema_content[field]: - raise MRMValidateDataError("for schema, {} th data is wrong: " \ - "data type for '{}' is not matched.".format(i, field)) - try: - # tuple or list - np.reshape(v[field], schema_content[field]['shape']) - except ValueError: - raise MRMValidateDataError("for schema, {} th data is wrong: " \ - "data type for '{}' is not matched.".format(i, field)) - - def write_raw_data(self, raw_data, validate=True): - """ - Write raw data and generate sequential pair of MindRecord File. + Write raw data and generate sequential pair of MindRecord File and \ + validate data based on predefined schema by default. Args: raw_data (list[dict]): List of raw data. - validate (bool, optional): Validate data according schema if it equals to True, - or validate data according to blob fields (default=True). Raises: ParamTypeError: If index field is invalid. @@ -264,11 +224,8 @@ class FileWriter: for each_raw in raw_data: if not isinstance(each_raw, dict): raise ParamTypeError('raw_data item', 'dict') - if validate is True: - self._verify_based_on_schema(raw_data) - elif validate is False: - self._verify_based_on_blob_fields(raw_data) - return self._writer.write_raw_data(raw_data, validate) + self._verify_based_on_schema(raw_data) + return self._writer.write_raw_data(raw_data, True) def set_header_size(self, header_size): """ diff --git a/mindspore/mindrecord/mindpage.py b/mindspore/mindrecord/mindpage.py index 2d19006af4..4baaa6013b 100644 --- a/mindspore/mindrecord/mindpage.py +++ b/mindspore/mindrecord/mindpage.py @@ -133,15 +133,15 @@ class MindPage: Raises: ParamValueError: If any parameter is invalid. - MRMFetchDataError: If failed to read by category id. + MRMFetchDataError: If failed to fetch data by category. MRMUnsupportedSchemaError: If schema is invalid. """ - if category_id < 0: - raise ParamValueError("Category id should be greater than 0.") - if page < 0: - raise ParamValueError("Page should be greater than 0.") - if num_row < 0: - raise ParamValueError("num_row should be greater than 0.") + if not isinstance(category_id, int) or category_id < 0: + raise ParamValueError("Category id should be int and greater than or equal to 0.") + if not isinstance(page, int) or page < 0: + raise ParamValueError("Page should be int and greater than or equal to 0.") + if not isinstance(num_row, int) or num_row <= 0: + raise ParamValueError("num_row should be int and greater than 0.") return self._segment.read_at_page_by_id(category_id, page, num_row) def read_at_page_by_name(self, category_name, page, num_row): @@ -157,8 +157,10 @@ class MindPage: Returns: str, read at page. """ - if page < 0: - raise ParamValueError("Page should be greater than 0.") - if num_row < 0: - raise ParamValueError("num_row should be greater than 0.") + if not isinstance(category_name, str): + raise ParamValueError("Category name should be str.") + if not isinstance(page, int) or page < 0: + raise ParamValueError("Page should be int and greater than or equal to 0.") + if not isinstance(num_row, int) or num_row <= 0: + raise ParamValueError("num_row should be int and greater than 0.") return self._segment.read_at_page_by_name(category_name, page, num_row) diff --git a/mindspore/model_zoo/Bert_NEZHA/bert_for_pre_training.py b/mindspore/model_zoo/Bert_NEZHA/bert_for_pre_training.py index bc51ba5d48..046b2adbe2 100644 --- a/mindspore/model_zoo/Bert_NEZHA/bert_for_pre_training.py +++ b/mindspore/model_zoo/Bert_NEZHA/bert_for_pre_training.py @@ -370,7 +370,7 @@ class BertTrainOneStepWithLossScaleCell(nn.Cell): self.parallel_mode = context.get_auto_parallel_context("parallel_mode") if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: self.reducer_flag = True - self.grad_reducer = None + self.grad_reducer = F.identity if self.reducer_flag: mean = context.get_auto_parallel_context("mirror_mean") degree = get_group_size() @@ -428,9 +428,8 @@ class BertTrainOneStepWithLossScaleCell(nn.Cell): mstype.float32)) grads = self.hyper_map(F.partial(grad_scale, scaling_sens), grads) grads = self.clip_gradients(grads, GRADIENT_CLIP_TYPE, GRADIENT_CLIP_VALUE) - if self.reducer_flag: - # apply grad reducer on grads - grads = self.grad_reducer(grads) + # apply grad reducer on grads + grads = self.grad_reducer(grads) self.get_status(init) flag_sum = self.reduce_sum(init, (0,)) if self.is_distributed: diff --git a/mindspore/model_zoo/Bert_NEZHA/bert_model.py b/mindspore/model_zoo/Bert_NEZHA/bert_model.py index d7f9355b3c..b9c6e8c4a1 100644 --- a/mindspore/model_zoo/Bert_NEZHA/bert_model.py +++ b/mindspore/model_zoo/Bert_NEZHA/bert_model.py @@ -194,7 +194,7 @@ class EmbeddingPostprocessor(nn.Cell): self.dropout = nn.Dropout(1 - dropout_prob) self.gather = P.GatherV2() self.use_relative_positions = use_relative_positions - self.slice = P.Slice() + self.slice = P.StridedSlice() self.full_position_embeddings = Parameter(initializer (TruncatedNormal(initializer_range), [max_position_embeddings, @@ -216,7 +216,7 @@ class EmbeddingPostprocessor(nn.Cell): output += token_type_embeddings if not self.use_relative_positions: _, seq, width = self.shape - position_embeddings = self.slice(self.full_position_embeddings, [0, 0], [seq, width]) + position_embeddings = self.slice(self.full_position_embeddings, (0, 0), (seq, width), (1, 1)) position_embeddings = self.reshape(position_embeddings, (1, seq, width)) output += position_embeddings output = self.layernorm(output) diff --git a/mindspore/nn/cell.py b/mindspore/nn/cell.py index 088f3f3e57..5507d12af8 100755 --- a/mindspore/nn/cell.py +++ b/mindspore/nn/cell.py @@ -140,7 +140,10 @@ class Cell: if context.get_context("mode") == context.GRAPH_MODE: out = self.compile_and_run(*inputs) return out - return self.construct(*inputs) + output = self.construct(*inputs) + if isinstance(output, Parameter): + output = output.data + return output def __setattr__(self, name, value): cells = self.__dict__.get('_cells') diff --git a/mindspore/nn/dynamic_lr.py b/mindspore/nn/dynamic_lr.py new file mode 100644 index 0000000000..cf25f1f50e --- /dev/null +++ b/mindspore/nn/dynamic_lr.py @@ -0,0 +1,300 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""dynamic learning rate""" +import math + +from mindspore._checkparam import ParamValidator as validator +from mindspore._checkparam import Rel + + +def piecewise_constant_lr(milestone, learning_rates): + r""" + Get piecewise constant learning rate. + + Calculate learning rate by given `milestone` and `learning_rates`. Let the value of `milestone` be + :math:`(M_1, M_2, ..., M_N)` and the value of `learning_rates` be :math:`(x_1, x_2, ..., x_N)`. N is the length of + `milestone`. Let the output learning rate be `y`. + + .. math:: + y[i] = x_t for i \in [M_{t-1}, M_t) + + Args: + milestone (list[int]): A list of milestone. This list is a monotone increasing list. + learning_rates (list[float]): A list of learning rates. + + Returns: + list[float]. The size of list is :math:`M_N`. + + Examples: + >>> milestone = [2, 5, 10] + >>> learning_rates = [0.1, 0.05, 0.01] + >>> lr = piecewise_constant_lr(milestone, learning_rates) + [0.1, 0.1, 0.05, 0.05, 0.05, 0.01, 0.01, 0.01, 0.01, 0.01] + """ + validator.check_type('milestone', milestone, (tuple, list)) + validator.check_type('learning_rates', learning_rates, (tuple, list)) + if len(milestone) != len(learning_rates): + raise ValueError('The size of `milestone` must be same with the size of `learning_rates`.') + + lr = [] + last_item = 0 + for i, item in enumerate(milestone): + validator.check_integer(f'milestone[{i}]', item, 0, Rel.GT) + validator.check_type(f'learning_rates[{i}]', learning_rates[i], [float]) + if item < last_item: + raise ValueError(f'The value of milestone[{i}] must be greater than milestone[{i - 1}]') + lr += [learning_rates[i]] * (item - last_item) + last_item = item + + return lr + + +def _check_inputs(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair): + validator.check_integer('total_step', total_step, 0, Rel.GT) + validator.check_integer('step_per_epoch', step_per_epoch, 0, Rel.GT) + validator.check_integer('decay_epoch', decay_epoch, 0, Rel.GT) + validator.check_float_positive('learning_rate', learning_rate) + validator.check_float_positive('decay_rate', decay_rate) + validator.check_type('is_stair', is_stair, [bool]) + + +def exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair=False): + r""" + Calculate learning rate base on exponential decay function. + + For the i-th step, the formula of computing decayed_learning_rate[i] is: + + .. math:: + decayed\_learning\_rate[i] = learning\_rate * decay\_rate^{\frac{current\_epoch}{decay\_epoch}} + + Where :math:`current\_epoch=floor(\frac{i}{step\_per\_epoch})`. + + Args: + learning_rate (float): The initial value of learning rate. + decay_rate (float): The decay rate. + total_step (int): The total number of steps. + step_per_epoch (int): The number of steps in per epoch. + decay_epoch (int): A value used to calculate decayed learning rate. + is_stair (bool): If true, learning rate decay once every `decay_epoch` times. Default: False. + + Returns: + list[float]. The size of list is `total_step`. + + Examples: + >>> learning_rate = 0.1 + >>> decay_rate = 0.9 + >>> total_step = 6 + >>> step_per_epoch = 2 + >>> decay_epoch = 1 + >>> lr = exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch) + [0.1, 0.1, 0.09000000000000001, 0.09000000000000001, 0.08100000000000002, 0.08100000000000002] + """ + _check_inputs(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair) + + lr = [] + for i in range(total_step): + if is_stair: + lr.append(learning_rate * decay_rate ** math.floor(math.floor(i / step_per_epoch) / decay_epoch)) + else: + lr.append(learning_rate * decay_rate ** (math.floor(i / step_per_epoch) / decay_epoch)) + return lr + + +def natural_exp_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair=False): + r""" + Calculate learning rate base on natural exponential decay function. + + For the i-th step, the formula of computing decayed_learning_rate[i] is: + + .. math:: + decayed\_learning\_rate[i] = learning\_rate * e^{-decay\_rate * current\_epoch} + + Where :math:`current\_epoch=floor(\frac{i}{step\_per\_epoch})`. + + Args: + learning_rate (float): The initial value of learning rate. + decay_rate (float): The decay rate. + total_step (int): The total number of steps. + step_per_epoch (int): The number of steps in per epoch. + decay_epoch (int): A value used to calculate decayed learning rate. + is_stair (bool): If true, learning rate decay once every `decay_epoch` times. Default: False. + + Returns: + list[float]. The size of list is `total_step`. + + Examples: + >>> learning_rate = 0.1 + >>> decay_rate = 0.9 + >>> total_step = 6 + >>> step_per_epoch = 2 + >>> decay_epoch = 2 + >>> lr = natural_exp_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, True) + [0.1, 0.1, 0.1, 0.1, 0.016529888822158657, 0.016529888822158657] + """ + _check_inputs(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair) + + function = lambda x, y: x + if is_stair: + function = lambda x, y: math.floor(x / y) * y + + lr = [] + for i in range(total_step): + lr.append(learning_rate * math.e ** (-decay_rate * function(math.floor(i / step_per_epoch), decay_epoch))) + return lr + + +def inverse_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair=False): + r""" + Calculate learning rate base on inverse-time decay function. + + For the i-th step, the formula of computing decayed_learning_rate[i] is: + + .. math:: + decayed\_learning\_rate[i] = learning\_rate / (1 + decay\_rate * current\_epoch / decay\_epoch) + + Where :math:`current\_epoch=floor(\frac{i}{step\_per\_epoch})`. + + Args: + learning_rate (float): The initial value of learning rate. + decay_rate (float): The decay rate. + total_step (int): The total number of steps. + step_per_epoch (int): The number of steps in per epoch. + decay_epoch (int): A value used to calculate decayed learning rate. + is_stair (bool): If true, learning rate decay once every `decay_epoch` times. Default: False. + + Returns: + list[float]. The size of list is `total_step`. + + Examples: + >>> learning_rate = 0.1 + >>> decay_rate = 0.5 + >>> total_step = 6 + >>> step_per_epoch = 1 + >>> decay_epoch = 1 + >>> lr = inverse_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, True) + [0.1, 0.06666666666666667, 0.05, 0.04, 0.03333333333333333, 0.028571428571428574] + """ + _check_inputs(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair) + + lr = [] + for i in range(total_step): + if is_stair: + lr.append(learning_rate / (1 + decay_rate * math.floor(math.floor(i / step_per_epoch) / decay_epoch))) + else: + lr.append(learning_rate / (1 + decay_rate * math.floor(i / step_per_epoch) / decay_epoch)) + return lr + + +def cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch, decay_epoch): + r""" + Calculate learning rate base on cosine decay function. + + For the i-th step, the formula of computing decayed_learning_rate[i] is: + + .. math:: + decayed\_learning\_rate[i] = min\_learning\_rate + 0.5 * (max\_learning\_rate - min\_learning\_rate) * + (1 + cos(\frac{current\_epoch}{decay\_epoch}\pi)) + + Where :math:`current\_epoch=floor(\frac{i}{step\_per\_epoch})`. + + Args: + min_lr (float): The minimum value of learning rate. + max_lr (float): The maximum value of learning rate. + total_step (int): The total number of steps. + step_per_epoch (int): The number of steps in per epoch. + decay_epoch (int): A value used to calculate decayed learning rate. + + Returns: + list[float]. The size of list is `total_step`. + + Examples: + >>> min_lr = 0.01 + >>> max_lr = 0.1 + >>> total_step = 6 + >>> step_per_epoch = 2 + >>> decay_epoch = 2 + >>> lr = cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch, decay_epoch) + [0.1, 0.1, 0.05500000000000001, 0.05500000000000001, 0.01, 0.01] + """ + validator.check_float_positive('min_lr', min_lr) + validator.check_float_positive('max_lr', max_lr) + validator.check_integer('total_step', total_step, 0, Rel.GT) + validator.check_integer('step_per_epoch', step_per_epoch, 0, Rel.GT) + validator.check_integer('decay_epoch', decay_epoch, 0, Rel.GT) + + delta = 0.5 * (max_lr - min_lr) + lr = [] + for i in range(total_step): + tmp_epoch = min(math.floor(i / step_per_epoch), decay_epoch) + lr.append(min_lr + delta * (1 + math.cos(math.pi * tmp_epoch / decay_epoch))) + return lr + + +def polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, power, + update_decay_epoch=False): + r""" + Calculate learning rate base on polynomial decay function. + + For the i-th step, the formula of computing decayed_learning_rate[i] is: + + .. math:: + decayed\_learning\_rate[i] = (learning\_rate - end\_learning\_rate) * + (1 - tmp\_epoch / decay\_epoch)^{power} + end\_learning\_rate + + Where :math:`tmp\_epoch=min(current\_epoch, decay\_epoch), current\_epoch=floor(\frac{i}{step\_per\_epoch})`. + If `update_decay_epoch` is true, update the value of `decay_epoch` every epoch. The formula is + :math:`decay\_epoch = decay\_epoch * ceil(current\_epoch / decay\_epoch)` + + Args: + learning_rate (float): The initial value of learning rate. + end_learning_rate (float): The end value of learning rate. + total_step (int): The total number of steps. + step_per_epoch (int): The number of steps in per epoch. + decay_epoch (int): A value used to calculate decayed learning rate. + power (float): A value used to calculate decayed learning rate. + update_decay_epoch (bool): If true, update `decay_epoch`. Default: False. + + Returns: + list[float]. The size of list is `total_step`. + + Examples: + >>> learning_rate = 0.1 + >>> end_learning_rate = 0.01 + >>> total_step = 6 + >>> step_per_epoch = 2 + >>> decay_epoch = 2 + >>> power = 0.5 + >>> lr = polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, power) + [0.1, 0.1, 0.07363961030678928, 0.07363961030678928, 0.01, 0.01] + """ + validator.check_float_positive('learning_rate', learning_rate) + validator.check_float_positive('end_learning_rate', end_learning_rate) + validator.check_integer('total_step', total_step, 0, Rel.GT) + validator.check_integer('step_per_epoch', step_per_epoch, 0, Rel.GT) + validator.check_integer('decay_epoch', decay_epoch, 0, Rel.GT) + validator.check_type('power', power, [float]) + validator.check_type('update_decay_epoch', update_decay_epoch, [bool]) + + function = lambda x, y: (x, min(x, y)) + if update_decay_epoch: + function = lambda x, y: (x * max(math.ceil(y / x), 1), y) + + lr = [] + delta = learning_rate - end_learning_rate + for i in range(total_step): + current_epoch = math.floor(i / step_per_epoch) + decay_epoch, tmp_epoch = function(decay_epoch, current_epoch) + lr.append(delta * (1 - tmp_epoch / decay_epoch) ** power + end_learning_rate) + return lr diff --git a/mindspore/nn/layer/__init__.py b/mindspore/nn/layer/__init__.py index dae18fe663..098489a91d 100644 --- a/mindspore/nn/layer/__init__.py +++ b/mindspore/nn/layer/__init__.py @@ -17,21 +17,24 @@ Layer. The high-level components(Cells) used to construct the neural network. """ -from .activation import Softmax, LogSoftmax, ReLU, ReLU6, Tanh, GELU, ELU, Sigmoid, PReLU, get_activation, LeakyReLU -from .normalization import BatchNorm1d, BatchNorm2d, LayerNorm +from .activation import Softmax, LogSoftmax, ReLU, ReLU6, Tanh, GELU, ELU, Sigmoid, PReLU, get_activation, LeakyReLU, HSigmoid, HSwish +from .normalization import BatchNorm1d, BatchNorm2d, LayerNorm, GroupNorm, GlobalBatchNorm from .container import SequentialCell, CellList from .conv import Conv2d, Conv2dTranspose from .lstm import LSTM -from .basic import Dropout, Flatten, Dense, ClipByNorm, Norm, OneHot, ImageGradients +from .basic import Dropout, Flatten, Dense, ClipByNorm, Norm, OneHot, Pad, Unfold from .embedding import Embedding from .pooling import AvgPool2d, MaxPool2d +from .image import ImageGradients, SSIM, PSNR -__all__ = ['Softmax', 'LogSoftmax', 'ReLU', 'ReLU6', 'Tanh', 'GELU', 'Sigmoid', 'PReLU', 'get_activation', 'LeakyReLU', - 'BatchNorm1d', 'BatchNorm2d', 'LayerNorm', 'ELU', +__all__ = ['Softmax', 'LogSoftmax', 'ReLU', 'ReLU6', 'Tanh', 'GELU', 'Sigmoid', + 'PReLU', 'get_activation', 'LeakyReLU', 'HSigmoid', 'HSwish', 'ELU', + 'BatchNorm1d', 'BatchNorm2d', 'LayerNorm', 'GroupNorm', 'GlobalBatchNorm', 'SequentialCell', 'CellList', 'Conv2d', 'Conv2dTranspose', 'LSTM', - 'Dropout', 'Flatten', 'Dense', 'ClipByNorm', 'Norm', 'OneHot', 'ImageGradients', + 'Dropout', 'Flatten', 'Dense', 'ClipByNorm', 'Norm', 'OneHot', 'Embedding', - 'AvgPool2d', 'MaxPool2d', + 'AvgPool2d', 'MaxPool2d', 'Pad', 'Unfold', + 'ImageGradients', 'SSIM', 'PSNR', ] diff --git a/mindspore/nn/layer/_quant.py b/mindspore/nn/layer/_quant.py new file mode 100644 index 0000000000..f27af8b269 --- /dev/null +++ b/mindspore/nn/layer/_quant.py @@ -0,0 +1,703 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Aware quantization.""" + +import numpy as np +import mindspore.nn as nn +import mindspore.common.dtype as mstype +from mindspore.ops import operations as P +from mindspore.ops import functional as F +from mindspore.common.parameter import Parameter +from mindspore.common.initializer import initializer +from mindspore.common.tensor import Tensor +from mindspore._checkparam import check_int_positive, check_bool, twice +from mindspore.nn.cell import Cell +from mindspore.nn.layer.conv import _Conv +from mindspore.nn.layer.activation import get_activation + +__all__ = [ + 'FakeQuantWithMinMax', + 'Conv2dBatchNormQuant', + 'Conv2dQuant', + 'DenseQuant', + 'ReLUQuant', + 'ReLU6Quant', + 'HSwishQuant', + 'HSigmoidQuant', + 'TensorAddQuant', +] + + +class FakeQuantWithMinMax(Cell): + r""" + Aware Quantization training op. This OP provide Fake quantization observer function on data with min and max. + + Args: + min_init (int, list): The dimension of channel or 1(layer). Default: -6. + max_init (int, list): The dimension of channel or 1(layer). Default: 6. + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + ema (bool): Exponential Moving Average algorithm update min and max. Default: False. + ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.9999. + per_channel (bool): Quantization by layer or channel. Default: False. + channel_size (int): declarate the min and max channel size, Default: 1. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of FakeQuantWithMinMax. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, + min_init=-6, + max_init=6, + num_bits=8, + ema=False, + ema_decay=0.999, + per_channel=False, + channel_size=1, + quant_delay=0, + symmetric=False, + narrow_range=False): + super(FakeQuantWithMinMax, self).__init__() + + self.min_init = min_init + self.num_bits = num_bits + self.max_init = max_init + self.ema = ema + self.ema_decay = ema_decay + self.per_channel = per_channel + self.channel_size = channel_size + self.quant_delay = quant_delay + self.symmetric = symmetric + self.narrow_range = narrow_range + + if per_channel: + min_array = np.array([self.min_init for i in range( + 0, self.channel_size)]).astype(np.float32) + max_array = np.array([self.max_init for i in range( + 0, self.channel_size)]).astype(np.float32) + self.fake_quant_train = P.FakeQuantWithMinMaxPerChannel(num_bits=self.num_bits, + ema=self.ema, + ema_decay=self.ema_decay, + quant_delay=self.quant_delay, + symmetric=self.symmetric, + narrow_range=self.narrow_range, + training=True) + self.fake_quant_infer = P.FakeQuantWithMinMaxPerChannel(num_bits=self.num_bits, + ema=self.ema, + ema_decay=ema_decay, + quant_delay=quant_delay, + symmetric=self.symmetric, + narrow_range=self.narrow_range, + training=False) + else: + min_array = np.array([min_init]).reshape(1).astype(np.float32) + max_array = np.array([max_init]).reshape(1).astype(np.float32) + self.fake_quant_train = P.FakeQuantWithMinMax(num_bits=self.num_bits, + ema=self.ema, + ema_decay=self.ema_decay, + quant_delay=self.quant_delay, + symmetric=self.symmetric, + narrow_range=self.narrow_range, + training=True) + self.fake_quant_infer = P.FakeQuantWithMinMax(num_bits=self.num_bits, + ema=self.ema, + ema_decay=ema_decay, + quant_delay=quant_delay, + symmetric=self.symmetric, + narrow_range=self.narrow_range, + training=False) + + self.min = Parameter( + Tensor(min_array), name='quant_min', requires_grad=False) + self.max = Parameter( + Tensor(max_array), name='quant_max', requires_grad=False) + + def extend_repr(self): + s = 'min_init={}, max_init={}, ema={}, ema_decay={}, per_channel={}, channel_size={}, quant_delay={}'.format( + self.min_init, self.max_init, self.ema, self.ema_decay, self.per_channel, self.channel_size, + self.quant_delay) + return s + + def construct(self, x): + if self.training: + out = self.fake_quant_train(x, self.min, self.max) + else: + out = self.fake_quant_infer(x, self.min, self.max) + return out + + +class Conv2dBatchNormQuant(Cell): + r""" + 2D convolution with BatchNormal op folded layer. + + For a more Detailed overview of Conv2d op. + + Args: + in_channels (int): The number of input channel :math:`C_{in}`. + out_channels (int): The number of output channel :math:`C_{out}`. + kernel_size (Union[int, tuple]): Specifies the height and width of the 2D convolution window. + stride (int): Specifies stride for all spatial dimensions with the same value. + pad_mode: (str): Specifies padding mode. The optional values are "same", "valid", "pad". Default: "same". + padding: (int): Implicit paddings on both sides of the input. Default: 0. + eps (int): Parameters for BatchNormal. Default: 1e-5. + momentum (int): Parameters for BatchNormal op. Default: 0.9. + weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the + convolution kernel. Default: 'None'. + beta_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the + beta vector. Default: 'None'. + gamma_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the + gamma vector. Default: 'None'. + mean_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the + mean vector. Default: 'None'. + var_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the + variance vector. Default: 'None'. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + freeze_bn (int): Quantization freeze BatchNormal op according by global step. Default: 100000. + fake (bool): Conv2dBatchNormQuant Cell add FakeQuantWithMinMax op or not. Default: True. + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + per_channel (bool): FakeQuantWithMinMax Parameters. Default: False. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride, + pad_mode, + padding=0, + eps=1e-5, + momentum=0.9, + weight_init=None, + beta_init=None, + gamma_init=None, + mean_init=None, + var_init=None, + group=1, + quant_delay=0, + freeze_bn=100000, + fake=True, + num_bits=8, + per_channel=False, + symmetric=False, + narrow_range=False): + super(Conv2dBatchNormQuant, self).__init__() + self.stride = stride + self.conv = P.Conv2D(out_channel=out_channels, + kernel_size=kernel_size, + mode=1, + pad_mode=pad_mode, + pad=padding, + stride=stride, + dilation=1, + group=group) + self.fake = fake + self.freeze_bn = freeze_bn + if isinstance(kernel_size, int): + kernel_size = (kernel_size, kernel_size) + + if weight_init is None: + weight_init = initializer( + 'normal', [out_channels, in_channels // group, *kernel_size]) + self.weight = Parameter(weight_init, name='weight') + if gamma_init is None: + gamma_init = initializer('ones', [out_channels]) + self.gamma = Parameter(gamma_init, name='gamma') + if beta_init is None: + beta_init = initializer('zeros', [out_channels]) + self.beta = Parameter(beta_init, name='beta') + if mean_init is None: + mean_init = initializer('zeros', [out_channels]) + self.moving_mean = Parameter( + mean_init, name='moving_mean', requires_grad=False) + if var_init is None: + var_init = initializer('ones', [out_channels]) + self.moving_variance = Parameter( + var_init, name='moving_variance', requires_grad=False) + + self.step = Parameter(initializer( + 'normal', [1], dtype=mstype.int32), name='step', requires_grad=False) + + self.fake_quant_weight = nn.FakeQuantWithMinMax(min_init=-6, + max_init=6, + ema=False, + num_bits=num_bits, + quant_delay=quant_delay, + per_channel=per_channel, + channel_size=out_channels, + symmetric=symmetric, + narrow_range=narrow_range) + + self.batchnorm_fold_train = P.BatchNormFold(epsilon=eps, + momentum=momentum, + is_training=True, + freeze_bn=freeze_bn) + self.batchnorm_fold_infer = P.BatchNormFold(epsilon=eps, + momentum=momentum, + is_training=False, + freeze_bn=freeze_bn) + self.correct_mul = P.CorrectionMul() + self.relu = P.ReLU() + self.batchnorm_fold2 = P.BatchNormFold2(freeze_bn=freeze_bn) + self.batchnorm_fold2_infer = P.BatchNormFold2(freeze_bn=0) + self.one = Tensor(1, mstype.int32) + self.assignadd = P.AssignAdd() + + def extend_repr(self): + s = 'fake={}, freeze_bn={}'.format(self.fake, self.freeze_bn) + return s + + def construct(self, x): + if self.training: + beta = self.beta + gamma = self.gamma + gmean = self.moving_mean + gvar = self.moving_variance + step = self.step + out_conv = self.conv(x, self.weight) + batch_mean, batch_std, running_mean, running_std = self.batchnorm_fold_train( + out_conv, gmean, gvar, step) + # BN fold1 + weight = self.correct_mul(self.weight, gamma, running_std) + if self.fake: + weight = self.fake_quant_weight(weight) + out = self.conv(x, weight) + # BN fold2 + out = self.batchnorm_fold2( + out, beta, gamma, batch_std, batch_mean, running_std, running_mean, step) + F.control_depend(out, self.assignadd(self.step, self.one)) + else: + step = self.step + out_conv = self.conv(x, self.weight) + batch_mean, batch_std, running_mean, running_std = self.batchnorm_fold_infer( + out_conv, self.moving_mean, self.moving_variance, step) + weight = self.correct_mul(self.weight, self.gamma, running_std) + if self.fake: + weight = self.fake_quant_weight(weight) + out = self.conv(x, weight) + out = self.batchnorm_fold2_infer(out, self.beta, self.gamma, batch_std, batch_mean, + running_std, running_mean, step) + return out + + +class Conv2dQuant(_Conv): + r""" + 2D convolution with fake quant op layer. + + For a more Detailed overview of Conv2d op. + + Args: + in_channels (int): The number of input channel :math:`C_{in}`. + out_channels (int): The number of output channel :math:`C_{out}`. + kernel_size (Union[int, tuple]): Specifies the height and width of the 2D convolution window. + stride (int): Specifies stride for all spatial dimensions with the same value. Default: 1. + pad_mode: (str): Specifies padding mode. The optional values are "same", "valid", "pad". Default: "same". + padding: (int): Implicit paddings on both sides of the input. Default: 0. + dilation (int): Specifying the dilation rate to use for dilated convolution. Default: 1. + group (int): Split filter into groups, `in_ channels` and `out_channels` should be + divisible by the number of groups. Default: 1. + has_bias (bool): Specifies whether the layer uses a bias vector. Default: False. + weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the convolution kernel. + Default: 'normal'. + bias_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the bias vector. Default: 'zeros'. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + per_channel (bool): FakeQuantWithMinMax Parameters. Default: False. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. + + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + pad_mode='same', + padding=0, + dilation=1, + group=1, + has_bias=False, + weight_init='normal', + bias_init='zeros', + quant_delay=0, + num_bits=8, + per_channel=False, + symmetric=False, + narrow_range=False): + kernel_size = twice(kernel_size) + super(Conv2dQuant, self).__init__(in_channels, out_channels, kernel_size, stride, pad_mode, padding, dilation, + group, has_bias, weight_init, bias_init) + self.conv2d = P.Conv2D(out_channel=self.out_channels, kernel_size=self.kernel_size, mode=1, + pad_mode=self.pad_mode, pad=self.padding, stride=self.stride, dilation=self.dilation, + group=self.group) + self.bias_add = P.BiasAdd() + if pad_mode not in ('valid', 'same', 'pad'): + raise ValueError('Attr \'pad_mode\' of \'Conv2d\' Op passed ' + + str(pad_mode) + ', should be one of values in \'valid\', \'same\', \'pad\'.') + self.fake_quant_weight = nn.FakeQuantWithMinMax(min_init=-6, + max_init=6, + ema=False, + num_bits=num_bits, + quant_delay=quant_delay, + per_channel=per_channel, + channel_size=out_channels, + symmetric=symmetric, + narrow_range=narrow_range) + + def construct(self, x): + weight_q = self.fake_quant_weight(self.weight) + out = self.conv2d(x, weight_q) + if self.has_bias: + return self.bias_add(out, self.bias) + return out + + +class DenseQuant(Cell): + r""" + The fully connected layer with fake quant op. + + For a more Detailed overview of Dense op. + + Args: + in_channels (int): The dimension of the input space. + out_channels (int): The dimension of the output space. + weight_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable weight_init parameter. The dtype + is same as input x. The values of str refer to the function `initializer`. Default: 'normal'. + bias_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable bias_init parameter. The dtype is + same as input x. The values of str refer to the function `initializer`. Default: 'zeros'. + has_bias (bool): Specifies whether the layer uses a bias vector. Default: True. + activation (str): Regularizer function applied to the output of the layer, eg. 'relu'. Default: None. + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + per_channel (bool): FakeQuantWithMinMax Parameters. Default: False. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. + """ + + def __init__( + self, + in_channels, + out_channels, + weight_init='normal', + bias_init='zeros', + has_bias=True, + activation=None, + num_bits=8, + quant_delay=0, + per_channel=False, + symmetric=False, + narrow_range=False): + super(DenseQuant, self).__init__() + self.in_channels = check_int_positive(in_channels) + self.out_channels = check_int_positive(out_channels) + self.has_bias = check_bool(has_bias) + + if isinstance(weight_init, Tensor): + if weight_init.dim() != 2 or weight_init.shape()[0] != out_channels or \ + weight_init.shape()[1] != in_channels: + raise ValueError("weight_init shape error") + + self.weight = Parameter(initializer( + weight_init, [out_channels, in_channels]), name="weight") + + if self.has_bias: + if isinstance(bias_init, Tensor): + if bias_init.dim() != 1 or bias_init.shape()[0] != out_channels: + raise ValueError("bias_init shape error") + + self.bias = Parameter(initializer( + bias_init, [out_channels]), name="bias") + + self.matmul = P.MatMul(transpose_b=True) + self.bias_add = P.BiasAdd() + + self.activation = get_activation(activation) + self.activation_flag = self.activation is not None + self.fake_quant_weight = nn.FakeQuantWithMinMax(min_init=-6, + max_init=6, + ema=False, + num_bits=num_bits, + quant_delay=quant_delay, + per_channel=per_channel, + channel_size=out_channels, + symmetric=symmetric, + narrow_range=narrow_range) + + def construct(self, x): + """Use operators to construct to Dense layer.""" + output = self.fake_quant_weight(self.weight) + output = self.matmul(x, output) + if self.has_bias: + output = self.bias_add(output, self.bias) + if self.activation_flag: + return self.activation(output) + return output + + def extend_repr(self): + """A pretty print for Dense layer.""" + str_info = 'in_channels={}, out_channels={}, weight={}, has_bias={}'.format( + self.in_channels, self.out_channels, self.weight, self.has_bias) + if self.has_bias: + str_info = str_info + ', bias={}'.format(self.bias) + if self.activation_flag: + str_info = str_info + ', activation={}'.format(self.activation) + + return str_info + + +class ReLUQuant(Cell): + r""" + ReLUQuant activation function. Add Fake Quant OP after Relu OP. + + For a more Detailed overview of ReLU op. + + Args: + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of ReLUQuant. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, + num_bits=8, + quant_delay=0, + symmetric=False, + narrow_range=False): + super(ReLUQuant, self).__init__() + self.fake_quant_act = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.relu = P.ReLU() + + def construct(self, x): + x = self.relu(x) + x = self.fake_quant_act(x) + return x + + +class ReLU6Quant(Cell): + r""" + ReLU6Quant activation function. + + Add Fake Quant OP after Relu6. Not Recommand to used these cell for Fake Quant Op + Will climp the max range of the activation and the relu6 do the same operation. + For a more Detailed overview of ReLU6 op. + + Args: + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of ReLU6Quant. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, num_bits=8, quant_delay=0, symmetric=False, + narrow_range=False): + super(ReLU6Quant, self).__init__() + self.fake_quant_act = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.relu6 = P.ReLU6() + + def construct(self, x): + x = self.relu6(x) + x = self.fake_quant_act(x) + return x + + +class HSwishQuant(Cell): + r""" + HSwishQuant activation function. Add Fake Quant OP after HSwish OP. + + For a more Detailed overview of HSwish op. + + Args: + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of HSwishQuant. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, + num_bits=8, + quant_delay=0, + symmetric=False, + narrow_range=False): + super(HSwishQuant, self).__init__() + self.fake_quant_act_before = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.fake_quant_act_after = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.act = P.HSwish() + + def construct(self, x): + x = self.fake_quant_act_before(x) + x = self.act(x) + x = self.fake_quant_act_after(x) + return x + + +class HSigmoidQuant(Cell): + r""" + HSigmoidQuant activation function. Add Fake Quant OP before and after HSigmoid OP. + + For a more Detailed overview of HSigmoid op. + + Args: + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of HSigmoidQuant. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, + num_bits=8, + quant_delay=0, + symmetric=False, + narrow_range=False): + super(HSigmoidQuant, self).__init__() + self.fake_quant_act_before = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.fake_quant_act_after = nn.FakeQuantWithMinMax(min_init=0, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.act = P.HSigmoid() + + def construct(self, x): + x = self.fake_quant_act_before(x) + x = self.act(x) + x = self.fake_quant_act_after(x) + return x + + +class TensorAddQuant(Cell): + r""" + Add Fake Quant OP after TensorAdd OP. + + For a more Detailed overview of TensorAdd op. + + Args: + num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8. + quant_delay (int): Quantization delay parameters according by global step. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + + Inputs: + - **x** (Tensor) - The input of TensorAddQuant. + + Outputs: + Tensor, with the same type and shape as the `x`. + + """ + + def __init__(self, + num_bits=8, + quant_delay=0, + symmetric=False, + narrow_range=False): + super(TensorAddQuant, self).__init__() + self.fake_quant_act = nn.FakeQuantWithMinMax(min_init=-6, + max_init=6, + num_bits=num_bits, + quant_delay=quant_delay, + ema=True, + symmetric=symmetric, + narrow_range=narrow_range) + self.add = P.TensorAdd() + + def construct(self, x1, x2): + x = self.add(x1, x2) + x = self.fake_quant_act(x) + return x diff --git a/mindspore/nn/layer/activation.py b/mindspore/nn/layer/activation.py index ad63dde8bc..6485e27228 100644 --- a/mindspore/nn/layer/activation.py +++ b/mindspore/nn/layer/activation.py @@ -234,7 +234,7 @@ class Tanh(Cell): class GELU(Cell): - """ + r""" Gaussian error linear unit activation function. Applies GELU function to each element of the input. The input is a Tensor with any valid shape. @@ -332,15 +332,74 @@ class PReLU(Cell): return v +class HSwish(Cell): + r""" + rHard swish activation function. + + Applies hswish-type activation element-wise. The input is a Tensor with any valid shape. + + Hard swish is defined as: + + .. math:: + \text{hswish}(x_{i}) = x_{i} * \frac{ReLU6(x_{i} + 3)}{6}, + + where :math:`x_{i}` is the :math:`i`-th slice along the given dim of the input Tensor. + + Inputs: + - **input_data** (Tensor) - The input of Hswish. + + Outputs: + Tensor, with the same type and shape as the `input_data`. + + """ + def __init__(self): + super(HSwish, self).__init__() + self.hswish = P.HSwish() + + def construct(self, x): + return self.hswish(x) + + +class HSigmoid(Cell): + r""" + Hard sigmoid activation function. + + Applies hard sigmoid activation element-wise. The input is a Tensor with any valid shape. + + Hard sigmoid is defined as: + + .. math:: + \text{hsigmoid}(x_{i}) = max(0, min(1, \frac{2 * x_{i} + 5}{10})), + + where :math:`x_{i}` is the :math:`i`-th slice along the given dim of the input Tensor. + + Inputs: + - **input_data** (Tensor) - The input of HSigmoid. + + Outputs: + Tensor, with the same type and shape as the `input_data`. + + """ + def __init__(self): + super(HSigmoid, self).__init__() + self.hsigmoid = P.HSigmoid() + + def construct(self, x): + return self.hsigmoid(x) + + _activation = { 'softmax': Softmax, 'logsoftmax': LogSoftmax, 'relu': ReLU, + 'relu6': ReLU6, 'tanh': Tanh, 'gelu': GELU, 'sigmoid': Sigmoid, 'prelu': PReLU, - 'leakyrelu': LeakyReLU + 'leakyrelu': LeakyReLU, + 'hswish': HSwish, + 'hsigmoid': HSigmoid, } diff --git a/mindspore/nn/layer/basic.py b/mindspore/nn/layer/basic.py index de49685dac..5ac52acac7 100644 --- a/mindspore/nn/layer/basic.py +++ b/mindspore/nn/layer/basic.py @@ -372,46 +372,118 @@ class OneHot(Cell): return self.onehot(indices, self.depth, self.on_value, self.off_value) -class ImageGradients(Cell): - r""" - Returns two tensors, the first is along the height dimension and the second is along the width dimension. +class Pad(Cell): + """ + Pads the input tensor according to the paddings and mode. - Assume an image shape is :math:`h*w`. The gradients along the height and the width are :math:`dy` and :math:`dx`, - respectively. + Args: + paddings (tuple): The shape of parameter `paddings` is (N, 2). N is the rank of input data. All elements of + paddings are int type. For `D` th dimension of input, paddings[D, 0] indicates how many sizes to be + extended ahead of the `D` th dimension of the input tensor, and paddings[D, 1] indicates how many sizes to + be extended behind of the `D` th dimension of the input tensor. + mode (string): Specifies padding mode. The optional values are "CONSTANT", "REFLECT", "SYMMETRIC". + Default: "CONSTANT". - .. math:: - dy[i] = \begin{cases} image[i+1, :]-image[i, :], &if\ 0<=i>> from mindspore import Tensor + >>> from mindspore.ops import operations as P + >>> import mindspore.nn as nn + >>> import numpy as np + >>> class Net(nn.Cell): + >>> def __init__(self): + >>> super(Net, self).__init__() + >>> self.pad = nn.Pad(paddings=((1,1),(2,2)), mode="CONSTANT") + >>> def construct(self, x): + >>> return self.pad(x) + >>> x = np.random.random(size=(2, 3)).astype(np.float32) + >>> pad = Net() + >>> ms_output = pad(Tensor(x)) + """ + + def __init__(self, paddings, mode="CONSTANT"): + super(Pad, self).__init__() + self.mode = mode + self.paddings = paddings + validator.check_string('mode', self.mode, ["CONSTANT", "REFLECT", "SYMMETRIC"]) + if not isinstance(paddings, tuple): + raise TypeError('Paddings must be tuple type.') + for item in paddings: + if len(item) != 2: + raise ValueError('The shape of paddings must be (n, 2).') + if mode == "CONSTANT": + self.pad = P.Pad(self.paddings) + else: + self.paddings = Tensor(np.array(self.paddings)) + self.pad = P.MirrorPad(mode=mode) + + def construct(self, x): + if self.mode == "CONSTANT": + x = self.pad(x) + else: + x = self.pad(x, self.paddings) + return x + + +class Unfold(Cell): + """ + Extract patches from images. + The input tensor must be a 4-D tensor and the data format is NCHW. + + Args: + ksizes (Union[tuple[int], list[int]]): The size of sliding window, should be a tuple or list of int, + and the format is [1, ksize_row, ksize_col, 1]. + strides (Union[tuple[int], list[int]]): Distance between the centers of the two consecutive patches, + should be a tuple or list of int, and the format is [1, stride_row, stride_col, 1]. + rates (Union[tuple[int], list[int]]): In each extracted patch, the gap between the corresponding dim + pixel positions, should be a tuple or list of int, and the format is [1, rate_row, rate_col, 1]. + padding (str): The type of padding algorithm, is a string whose value is "same" or "valid", + not case sensitive. Default: "valid". + + - same: Means that the patch can take the part beyond the original image, and this part is filled with 0. + + - valid: Means that the patch area taken must be completely contained in the original image. Inputs: - - **images** (Tensor) - The input image data, with format 'NCHW'. + - **input_x** (Tensor) - A 4-D tensor whose shape is [in_batch, in_depth, in_row, in_col] and + data type is int8, float16, uint8. Outputs: - - **dy** (Tensor) - vertical image gradients, the same type and shape as input. - - **dx** (Tensor) - horizontal image gradients, the same type and shape as input. + Tensor, a 4-D tensor whose data type is same as 'input_x', + and the shape is [out_batch, out_depth, out_row, out_col], the out_batch is same as the in_batch. Examples: - >>> net = nn.ImageGradients() - >>> image = Tensor(np.array([[[[1,2],[3,4]]]]), dtype=mstype.int32) + >>> net = Unfold(ksizes=[1, 2, 2, 1], strides=[1, 1, 1, 1], rates=[1, 1, 1, 1]) + >>> image = Tensor(np.ones([1, 1, 3, 3]), dtype=mstype.float16) >>> net(image) - [[[[2,2] - [0,0]]]] - [[[[1,0] - [1,0]]]] + Tensor ([[[[1, 1] [1, 1]] [[1, 1], [1, 1]] [[1, 1] [1, 1]], [[1, 1], [1, 1]]]], + shape=(1, 4, 2, 2), dtype=mstype.float16) """ - def __init__(self): - super(ImageGradients, self).__init__() - - def construct(self, images): - batch_size, depth, height, width = P.Shape()(images) - dy = images[:, :, 1:, :] - images[:, :, :height - 1, :] - dy_last = P.Fill()(P.DType()(images), (batch_size, depth, 1, width), 0) - dy = P.Concat(2)((dy, dy_last)) - - dx = images[:, :, :, 1:] - images[:, :, :, :width - 1] - dx_last = P.Fill()(P.DType()(images), (batch_size, depth, height, 1), 0) - dx = P.Concat(3)((dx, dx_last)) - return dy, dx + def __init__(self, ksizes, strides, rates, padding="valid"): + super(Unfold, self).__init__() + self.extract_image_patches = P.ExtractImagePatches(ksizes, strides, rates, padding) + self.transpose = P.Transpose() + self.format_NHWC = (0, 2, 3, 1) + self.format_NCHW = (0, 3, 1, 2) + + def construct(self, input_x): + x_transpose = self.transpose(input_x, self.format_NHWC) + ret = self.extract_image_patches(x_transpose) + ret_transpose = self.transpose(ret, self.format_NCHW) + return ret_transpose diff --git a/mindspore/nn/layer/conv.py b/mindspore/nn/layer/conv.py index eb73a9ce5a..fbf6ad2a0c 100644 --- a/mindspore/nn/layer/conv.py +++ b/mindspore/nn/layer/conv.py @@ -17,7 +17,7 @@ from mindspore import log as logger from mindspore.ops import operations as P from mindspore.common.parameter import Parameter from mindspore.common.initializer import initializer -from mindspore._checkparam import check_bool, twice, check_int_positive, check_int_non_negative, check_int +from mindspore._checkparam import check_bool, twice, check_int_positive, check_int_non_negative from mindspore._extends import cell_attr_register from ..cell import Cell @@ -42,17 +42,23 @@ class _Conv(Cell): self.in_channels = check_int_positive(in_channels) self.out_channels = check_int_positive(out_channels) self.kernel_size = kernel_size - self.stride = check_int_positive(stride) + self.stride = stride self.pad_mode = pad_mode self.padding = check_int_non_negative(padding) - self.dilation = check_int(dilation) + self.dilation = dilation self.group = check_int_positive(group) self.has_bias = has_bias - if (not isinstance(kernel_size, tuple)) or len(kernel_size) != 2 or \ - (not isinstance(kernel_size[0], int)) or (not isinstance(kernel_size[1], int)) or \ - kernel_size[0] < 1 or kernel_size[1] < 1: + if (not isinstance(kernel_size[0], int)) or (not isinstance(kernel_size[1], int)) or \ + kernel_size[0] < 1 or kernel_size[1] < 1: raise ValueError("Attr 'kernel_size' of 'Conv2D' Op passed " + str(self.kernel_size) + ", should be a int or tuple and equal to or greater than 1.") + if (not isinstance(stride[0], int)) or (not isinstance(stride[1], int)) or stride[0] < 1 or stride[1] < 1: + raise ValueError("Attr 'stride' of 'Conv2D' Op passed " + + str(self.stride) + ", should be a int or tuple and equal to or greater than 1.") + if (not isinstance(dilation[0], int)) or (not isinstance(dilation[1], int)) or \ + dilation[0] < 1 or dilation[1] < 1: + raise ValueError("Attr 'dilation' of 'Conv2D' Op passed " + + str(self.dilation) + ", should equal to or greater than 1.") if in_channels % group != 0: raise ValueError("Attr 'in_channels' of 'Conv2D' Op must be divisible by " "attr 'group' of 'Conv2D' Op.") @@ -107,12 +113,13 @@ class Conv2d(_Conv): Args: in_channels (int): The number of input channel :math:`C_{in}`. out_channels (int): The number of output channel :math:`C_{out}`. - kernel_size (Union[int, tuple]): The data type is int or tuple with 2 integers. Specifies the height + kernel_size (Union[int, tuple[int]]): The data type is int or tuple with 2 integers. Specifies the height and width of the 2D convolution window. Single int means the value if for both height and width of the kernel. A tuple of 2 ints means the first value is for the height and the other is for the width of the kernel. - stride (int): Specifies stride for all spatial dimensions with the same value. Value of stride should be - greater or equal to 1 but bounded by the height and width of the input. Default: 1. + stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents + the height and width of movement are both strides, or a tuple of two int numbers that + represent height and width of movement respectively. Default: 1. pad_mode (str): Specifies padding mode. The optional values are "same", "valid", "pad". Default: "same". @@ -130,9 +137,11 @@ class Conv2d(_Conv): Tensor borders. `padding` should be greater than or equal to 0. padding (int): Implicit paddings on both sides of the input. Default: 0. - dilation (int): Specifying the dilation rate to use for dilated convolution. If set to be :math:`k > 1`, - there will be :math:`k - 1` pixels skipped for each sampling location. Its value should be greater - or equal to 1 and bounded by the height and width of the input. Default: 1. + dilation (Union[int, tuple[int]]): The data type is int or tuple with 2 integers. Specifies the dilation rate + to use for dilated convolution. If set to be :math:`k > 1`, there will + be :math:`k - 1` pixels skipped for each sampling location. Its value should + be greater or equal to 1 and bounded by the height and width of the + input. Default: 1. group (int): Split filter into groups, `in_ channels` and `out_channels` should be divisible by the number of groups. Default: 1. has_bias (bool): Specifies whether the layer uses a bias vector. Default: False. @@ -172,6 +181,8 @@ class Conv2d(_Conv): weight_init='normal', bias_init='zeros'): kernel_size = twice(kernel_size) + stride = twice(stride) + dilation = twice(dilation) super(Conv2d, self).__init__( in_channels, out_channels, @@ -241,7 +252,9 @@ class Conv2dTranspose(_Conv): and width of the 2D convolution window. Single int means the value is for both height and width of the kernel. A tuple of 2 ints means the first value is for the height and the other is for the width of the kernel. - stride (int): Specifies the same value for all spatial dimensions. Default: 1. + stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents + the height and width of movement are both strides, or a tuple of two int numbers that + represent height and width of movement respectively. Default: 1. pad_mode (str): Select the mode of the pad. The optional values are "pad", "same", "valid". Default: "same". @@ -251,8 +264,11 @@ class Conv2dTranspose(_Conv): - valid: Adopted the way of discarding. padding (int): Implicit paddings on both sides of the input. Default: 0. - dilation (int): Specifies the dilation rate to use for dilated - convolution. Default: 1. + dilation (Union[int, tuple[int]]): The data type is int or tuple with 2 integers. Specifies the dilation rate + to use for dilated convolution. If set to be :math:`k > 1`, there will + be :math:`k - 1` pixels skipped for each sampling location. Its value should + be greater or equal to 1 and bounded by the height and width of the + input. Default: 1. group (int): Split filter into groups, `in_channels` and `out_channels` should be divisible by the number of groups. Default: 1. has_bias (bool): Specifies whether the layer uses a bias vector. Default: False. @@ -290,6 +306,8 @@ class Conv2dTranspose(_Conv): weight_init='normal', bias_init='zeros'): kernel_size = twice(kernel_size) + stride = twice(stride) + dilation = twice(dilation) # out_channels and in_channels swap. # cause Conv2DBackpropInput's out_channel refers to Conv2D's out_channel, # then Conv2dTranspose's out_channel refers to Conv2DBackpropInput's in_channel. @@ -333,26 +351,26 @@ class Conv2dTranspose(_Conv): self.conv2d_transpose.set_strategy(strategy) return self - def _deconv_output_length(self, input_length, filter_size): + def _deconv_output_length(self, input_length, filter_size, stride_size, dilation_size): """Calculate the width and height of output.""" length = 0 if self.is_valid: - if filter_size - self.stride > 0: - length = input_length * self.stride + filter_size - self.stride + if filter_size - stride_size > 0: + length = input_length * stride_size + filter_size - stride_size else: - length = input_length * self.stride + length = input_length * stride_size elif self.is_same: - length = input_length * self.stride + length = input_length * stride_size elif self.is_pad: - length = input_length * self.stride - 2 * self.padding + filter_size + \ - (filter_size - 1) * (self.dilation - 1) - self.stride + length = input_length * stride_size - 2 * self.padding + filter_size + \ + (filter_size - 1) * (dilation_size - 1) - stride_size return length def construct(self, x): n, _, h, w = self.shape(x) - h_out = self._deconv_output_length(h, self.kernel_size[0]) - w_out = self._deconv_output_length(w, self.kernel_size[1]) + h_out = self._deconv_output_length(h, self.kernel_size[0], self.stride[0], self.dilation[0]) + w_out = self._deconv_output_length(w, self.kernel_size[1], self.stride[1], self.dilation[1]) if self.has_bias: return self.bias_add(self.conv2d_transpose(x, self.weight, (n, self.out_channels, h_out, w_out)), self.bias) diff --git a/mindspore/nn/layer/image.py b/mindspore/nn/layer/image.py new file mode 100644 index 0000000000..72c4c6d8e2 --- /dev/null +++ b/mindspore/nn/layer/image.py @@ -0,0 +1,247 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""image""" +import numpy as np +import mindspore.common.dtype as mstype +from mindspore.common.tensor import Tensor +from mindspore.ops import operations as P +from mindspore.ops import functional as F +from mindspore.ops.primitive import constexpr +from mindspore._checkparam import ParamValidator as validator +from mindspore._checkparam import Rel +from ..cell import Cell + + +class ImageGradients(Cell): + r""" + Returns two tensors, the first is along the height dimension and the second is along the width dimension. + + Assume an image shape is :math:`h*w`. The gradients along the height and the width are :math:`dy` and :math:`dx`, + respectively. + + .. math:: + dy[i] = \begin{cases} image[i+1, :]-image[i, :], &if\ 0<=i>> net = nn.ImageGradients() + >>> image = Tensor(np.array([[[[1,2],[3,4]]]]), dtype=mstype.int32) + >>> net(image) + [[[[2,2] + [0,0]]]] + [[[[1,0] + [1,0]]]] + """ + def __init__(self): + super(ImageGradients, self).__init__() + + def construct(self, images): + batch_size, depth, height, width = P.Shape()(images) + dy = images[:, :, 1:, :] - images[:, :, :height - 1, :] + dy_last = P.Fill()(P.DType()(images), (batch_size, depth, 1, width), 0) + dy = P.Concat(2)((dy, dy_last)) + + dx = images[:, :, :, 1:] - images[:, :, :, :width - 1] + dx_last = P.Fill()(P.DType()(images), (batch_size, depth, height, 1), 0) + dx = P.Concat(3)((dx, dx_last)) + return dy, dx + + +def _convert_img_dtype_to_float32(img, max_val): + """convert img dtype to float32""" + # Ususally max_val is 1.0 or 255, we will do the scaling if max_val > 1. + # We will scale img pixel value if max_val > 1. and just cast otherwise. + ret = F.cast(img, mstype.float32) + max_val = F.scalar_cast(max_val, mstype.float32) + if max_val > 1.: + scale = 1. / max_val + ret = ret * scale + return ret + + +@constexpr +def _gauss_kernel_helper(filter_size): + """gauss kernel helper""" + filter_size = F.scalar_cast(filter_size, mstype.int32) + coords = () + for i in range(filter_size): + i_cast = F.scalar_cast(i, mstype.float32) + offset = F.scalar_cast(filter_size-1, mstype.float32)/2.0 + element = i_cast-offset + coords = coords+(element,) + g = np.square(coords).astype(np.float32) + g = Tensor(g) + return filter_size, g + + +class SSIM(Cell): + r""" + Returns SSIM index between img1 and img2. + + Its implementation is based on Wang, Z., Bovik, A. C., Sheikh, H. R., & Simoncelli, E. P. (2004). `Image quality + assessment: from error visibility to structural similarity `_. + IEEE transactions on image processing. + + .. math:: + + l(x,y)&=\frac{2\mu_x\mu_y+C_1}{\mu_x^2+\mu_y^2+C_1}, C_1=(K_1L)^2.\\ + c(x,y)&=\frac{2\sigma_x\sigma_y+C_2}{\sigma_x^2+\sigma_y^2+C_2}, C_2=(K_2L)^2.\\ + s(x,y)&=\frac{\sigma_{xy}+C_3}{\sigma_x\sigma_y+C_3}, C_3=C_2/2.\\ + SSIM(x,y)&=l*c*s\\&=\frac{(2\mu_x\mu_y+C_1)(2\sigma_{xy}+C_2}{(\mu_x^2+\mu_y^2+C_1)(\sigma_x^2+\sigma_y^2+C_2)}. + + Args: + max_val (Union[int, float]): The dynamic range of the pixel values (255 for 8-bit grayscale images). + Default: 1.0. + filter_size (int): The size of the Gaussian filter. Default: 11. + filter_sigma (float): The standard deviation of Gaussian kernel. Default: 1.5. + k1 (float): The constant used to generate c1 in the luminance comparison function. Default: 0.01. + k2 (float): The constant used to generate c2 in the contrast comparison function. Default: 0.03. + + Inputs: + - **img1** (Tensor) - The first image batch with format 'NCHW'. It should be the same shape and dtype as img2. + - **img2** (Tensor) - The second image batch with format 'NCHW'. It should be the same shape and dtype as img1. + + Outputs: + Tensor, has the same dtype as img1. It is a 1-D tensor with shape N, where N is the batch num of img1. + + Examples: + >>> net = nn.SSIM() + >>> img1 = Tensor(np.random.random((1,3,16,16))) + >>> img2 = Tensor(np.random.random((1,3,16,16))) + >>> ssim = net(img1, img2) + """ + def __init__(self, max_val=1.0, filter_size=11, filter_sigma=1.5, k1=0.01, k2=0.03): + super(SSIM, self).__init__() + validator.check_type('max_val', max_val, [int, float]) + validator.check('max_val', max_val, '', 0.0, Rel.GT) + self.max_val = max_val + self.filter_size = validator.check_integer('filter_size', filter_size, 1, Rel.GE) + self.filter_sigma = validator.check_float_positive('filter_sigma', filter_sigma) + validator.check_type('k1', k1, [float]) + self.k1 = validator.check_number_range('k1', k1, 0.0, 1.0, Rel.INC_NEITHER) + validator.check_type('k2', k2, [float]) + self.k2 = validator.check_number_range('k2', k2, 0.0, 1.0, Rel.INC_NEITHER) + self.mean = P.DepthwiseConv2dNative(channel_multiplier=1, kernel_size=filter_size) + + def construct(self, img1, img2): + max_val = _convert_img_dtype_to_float32(self.max_val, self.max_val) + img1 = _convert_img_dtype_to_float32(img1, self.max_val) + img2 = _convert_img_dtype_to_float32(img2, self.max_val) + + kernel = self._fspecial_gauss(self.filter_size, self.filter_sigma) + kernel = P.Tile()(kernel, (1, P.Shape()(img1)[1], 1, 1)) + + mean_ssim = self._calculate_mean_ssim(img1, img2, kernel, max_val, self.k1, self.k2) + + return mean_ssim + + def _calculate_mean_ssim(self, x, y, kernel, max_val, k1, k2): + """calculate mean ssim""" + c1 = (k1 * max_val) * (k1 * max_val) + c2 = (k2 * max_val) * (k2 * max_val) + + # SSIM luminance formula + # (2 * mean_{x} * mean_{y} + c1) / (mean_{x}**2 + mean_{y}**2 + c1) + mean_x = self.mean(x, kernel) + mean_y = self.mean(y, kernel) + square_sum = F.square(mean_x)+F.square(mean_y) + luminance = (2*mean_x*mean_y+c1)/(square_sum+c1) + + # SSIM contrast*structure formula (when c3 = c2/2) + # (2 * conv_{xy} + c2) / (conv_{xx} + conv_{yy} + c2), equals to + # (2 * (mean_{xy} - mean_{x}*mean_{y}) + c2) / (mean_{xx}-mean_{x}**2 + mean_{yy}-mean_{y}**2 + c2) + mean_xy = self.mean(x*y, kernel) + mean_square_add = self.mean(F.square(x)+F.square(y), kernel) + + cs = (2*(mean_xy-mean_x*mean_y)+c2)/(mean_square_add-square_sum+c2) + + # SSIM formula + # luminance * cs + ssim = luminance*cs + + mean_ssim = P.ReduceMean()(ssim, (-3, -2, -1)) + + return mean_ssim + + def _fspecial_gauss(self, filter_size, filter_sigma): + """get gauss kernel""" + filter_size, g = _gauss_kernel_helper(filter_size) + + square_sigma_scale = -0.5/(filter_sigma * filter_sigma) + g = g*square_sigma_scale + g = F.reshape(g, (1, -1))+F.reshape(g, (-1, 1)) + g = F.reshape(g, (1, -1)) + g = P.Softmax()(g) + ret = F.reshape(g, (1, 1, filter_size, filter_size)) + return ret + + +class PSNR(Cell): + r""" + Returns Peak Signal-to-Noise Ratio of two image batches. + + It produces a PSNR value for each image in batch. + Assume inputs are :math:`I` and :math:`K`, both with shape :math:`h*w`. + :math:`MAX` represents the dynamic range of pixel values. + + .. math:: + + MSE&=\frac{1}{hw}\sum\limits_{i=0}^{h-1}\sum\limits_{j=0}^{w-1}[I(i,j)-K(i,j)]^2\\ + PSNR&=10*log_{10}(\frac{MAX^2}{MSE}) + + Args: + max_val (Union[int, float]): The dynamic range of the pixel values (255 for 8-bit grayscale images). + Default: 1.0. + + Inputs: + - **img1** (Tensor) - The first image batch with format 'NCHW'. It should be the same shape and dtype as img2. + - **img2** (Tensor) - The second image batch with format 'NCHW'. It should be the same shape and dtype as img1. + + Outputs: + Tensor, with dtype mindspore.float32. It is a 1-D tensor with shape N, where N is the batch num of img1. + + Examples: + >>> net = nn.PSNR() + >>> img1 = Tensor(np.random.random((1,3,16,16))) + >>> img2 = Tensor(np.random.random((1,3,16,16))) + >>> psnr = net(img1, img2) + + """ + def __init__(self, max_val=1.0): + super(PSNR, self).__init__() + validator.check_type('max_val', max_val, [int, float]) + validator.check('max_val', max_val, '', 0.0, Rel.GT) + self.max_val = max_val + + def construct(self, img1, img2): + max_val = _convert_img_dtype_to_float32(self.max_val, self.max_val) + img1 = _convert_img_dtype_to_float32(img1, self.max_val) + img2 = _convert_img_dtype_to_float32(img2, self.max_val) + + mse = P.ReduceMean()(F.square(img1 - img2), (-3, -2, -1)) + # 10*log_10(max_val^2/MSE) + psnr = 10 * P.Log()(F.square(max_val) / mse) / F.scalar_log(10.0) + + return psnr diff --git a/mindspore/nn/layer/normalization.py b/mindspore/nn/layer/normalization.py index 1ca2221122..6456a3603d 100644 --- a/mindspore/nn/layer/normalization.py +++ b/mindspore/nn/layer/normalization.py @@ -18,9 +18,13 @@ from mindspore.ops import functional as F from mindspore.common.parameter import Parameter from mindspore.common.initializer import initializer from mindspore.common.tensor import Tensor -import mindspore.common.dtype as DT +import mindspore.common.dtype as mstype import mindspore.context as context +from mindspore._checkparam import check_bool, check_typename from mindspore._extends import cell_attr_register +from mindspore.communication.management import get_group_size, get_rank +from mindspore.communication import management +from mindspore._checkparam import check_int_positive from ..cell import Cell @@ -29,6 +33,7 @@ class _BatchNorm(Cell): @cell_attr_register def __init__(self, num_features, + group=1, eps=1e-5, momentum=0.9, affine=True, @@ -55,10 +60,25 @@ class _BatchNorm(Cell): gamma_init, num_features), name="gamma", requires_grad=affine) self.beta = Parameter(initializer( beta_init, num_features), name="beta", requires_grad=affine) + self.group = check_int_positive(group) + if self.group != 1: + self.rank_id = get_rank() + self.rank_size = get_group_size() + self.device_list = [i for i in range(0, self.rank_size)] + self.rank_list = self.list_group(self.device_list, self.group) + self.rank_list_idx = len(self.rank_list) + for i in range(self.rank_list_idx): + if self.rank_id in self.rank_list[i] and self.group != 1: + self.is_global = True + management.create_group('group' + str(i), self.rank_list[i]) + self.all_reduce = P.AllReduce(P.ReduceOp.SUM, 'group' + str(i)).add_prim_attr('fusion', 1) + self.shape = P.Shape() + self.reduce_mean = P.ReduceMean() + self.square = P.Square() if context.get_context("enable_ge"): self.is_ge_backend = True - self.momentum = Tensor(1.0 - momentum, DT.float32) + self.momentum = Tensor(1.0 - momentum, mstype.float32) self.bn_train = P.BatchNorm(is_training=True, epsilon=self.eps) else: @@ -81,22 +101,53 @@ class _BatchNorm(Cell): def _check_data_dim(self, x): raise NotImplementedError + def list_group(self, world_rank, group_size): + if group_size > get_group_size(): + raise ValueError("group size can not be greater than local rank size, group size is {}, " + "local_rank_size is {}".format(group_size, get_group_size())) + if len(world_rank) % group_size != 0: + raise ValueError("please make your group size correct.") + world_rank_list = zip(*(iter(world_rank),) *group_size) + group_list = [list(i) for i in world_rank_list] + return group_list + def construct(self, x): if self.training and self.use_batch_statistics: if self.is_ge_backend: - y, batch_mean, batch_var, _, _ = \ - self.bn_train(x, - self.gamma, - self.beta, - None, - None) - - mean_sub = self.sub_mean(self.moving_mean, batch_mean) - temp_mean = self.mul_mean(mean_sub, self.momentum) - mean_sub2 = self.sub_var(self.moving_variance, batch_var) - temp_variance = self.mul_var(mean_sub2, self.momentum) - y = F.depend(y, self.assign_sub_mean(self.moving_mean, temp_mean)) - y = F.depend(y, self.assign_sub_var(self.moving_variance, temp_variance)) + if self.is_global: + x_mean = self.reduce_mean(x) + x_mean_square = self.reduce_mean(self.square(x)) + global_batch_mean = self.all_reduce(x_mean) / self.group + global_batch_mean_square = self.all_reduce(x_mean_square) / self.group + global_mean = global_batch_mean + global_var = global_batch_mean_square - self.square(global_batch_mean) + y, batch_mean, batch_var, _, _ = \ + self.bn_train(x, + self.gamma, + self.beta, + None, + None) + + mean_sub = self.sub_mean(self.moving_mean, global_mean) + temp_mean = self.mul_mean(mean_sub, self.momentum) + mean_sub2 = self.sub_var(self.moving_variance, global_var) + temp_variance = self.mul_var(mean_sub2, self.momentum) + y = F.depend(y, self.assign_sub_mean(self.moving_mean, temp_mean)) + y = F.depend(y, self.assign_sub_var(self.moving_variance, temp_variance)) + else: + y, batch_mean, batch_var, _, _ = \ + self.bn_train(x, + self.gamma, + self.beta, + None, + None) + + mean_sub = self.sub_mean(self.moving_mean, batch_mean) + temp_mean = self.mul_mean(mean_sub, self.momentum) + mean_sub2 = self.sub_var(self.moving_variance, batch_var) + temp_variance = self.mul_var(mean_sub2, self.momentum) + y = F.depend(y, self.assign_sub_mean(self.moving_mean, temp_mean)) + y = F.depend(y, self.assign_sub_var(self.moving_variance, temp_variance)) else: y = self.bn_train(x, self.gamma, @@ -136,6 +187,7 @@ class BatchNorm1d(_BatchNorm): eps (float): A value added to the denominator for numerical stability. Default: 1e-5. momentum (float): A floating hyperparameter of the momentum for the running_mean and running_var computation. Default: 0.9. + affine (bool): A bool value when set to True, gamma and beta can be learnable. Default: True. gamma_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the gamma weight. The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', 'he_uniform', etc. Default: 'ones'. @@ -187,6 +239,7 @@ class BatchNorm2d(_BatchNorm): eps (float): A value added to the denominator for numerical stability. Default: 1e-5. momentum (float): A floating hyperparameter of the momentum for the running_mean and running_var computation. Default: 0.9. + affine (bool): A bool value when set to True, gamma and beta can be learnable. Default: True. gamma_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the gamma weight. The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', 'he_uniform', etc. Default: 'ones'. @@ -218,6 +271,55 @@ class BatchNorm2d(_BatchNorm): pass +class GlobalBatchNorm(_BatchNorm): + r""" + Global normalization layer over a N-dimension input. + + Global Normalization is cross device synchronized batch normalization. Batch Normalization implementation + only normalize the data within each device. Global normalization will normalize the input within the group. + It has been described in the paper `Batch Normalization: Accelerating Deep Network Training by + Reducing Internal Covariate Shift `_. It rescales and recenters the + feature using a mini-batch of data and the learned parameters which can be described in the following formula. + + .. math:: + y = \frac{x - \mathrm{E}[x]}{\sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta + + Args: + num_features (int): `C` from an expected input of size (N, C, H, W). + group (int): The number of device in each group. + eps (float): A value added to the denominator for numerical stability. Default: 1e-5. + momentum (float): A floating hyperparameter of the momentum for the + running_mean and running_var computation. Default: 0.9. + gamma_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the gamma weight. + The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', + 'he_uniform', etc. Default: 'ones'. + beta_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the beta weight. + The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', + 'he_uniform', etc. Default: 'zeros'. + moving_mean_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the moving mean. + The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', + 'he_uniform', etc. Default: 'zeros'. + moving_var_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the moving variance. + The values of str refer to the function `initializer` including 'zeros', 'ones', 'xavier_uniform', + 'he_uniform', etc. Default: 'ones'. + use_batch_statistics (bool): If true, use the mean value and variance value of current batch data, else use + the mean value and variance value of specified value. Default: True. + + Inputs: + - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. + + Outputs: + Tensor, the normalized, scaled, offset tensor, of shape :math:`(N, C_{out}, H_{out}, W_{out})`. + + Examples: + >>> global_bn_op = nn.GlobalBatchNorm(num_features=3, group=4) + >>> input = Tensor(np.random.randint(0, 255, [1, 3, 224, 224]), mindspore.float32) + >>> global_bn_op(input) + """ + def _check_data_dim(self, x): + if x.dim == 0: + pass + class LayerNorm(Cell): r""" Applies Layer Normalization over a mini-batch of inputs. @@ -256,7 +358,7 @@ class LayerNorm(Cell): Tensor, the normalized and scaled offset tensor, has the same shape and data type as the `input_x`. Examples: - >>> x = Tensor(np.ones([20, 5, 10, 10], np.float32)) + >>> x = Tensor(np.ones([20, 5, 10, 10]), mindspore.float32) >>> shape1 = x.shape()[1:] >>> m = nn.LayerNorm(shape1, begin_norm_axis=1, begin_params_axis=1) >>> m(x) @@ -287,3 +389,73 @@ class LayerNorm(Cell): s = 'normalized_shape={}, begin_norm_axis={}, begin_params_axis={}, gamma{}, beta={}'.format( self.normalized_shape, self.begin_norm_axis, self.begin_params_axis, self.gamma, self.beta) return s + +class GroupNorm(Cell): + r""" + Group Normalization over a mini-batch of inputs. + + Group normalization is widely used in recurrent neural networks. It applies + normalization over a mini-batch of inputs for each single training case as described + in the paper `Group Normalization `_. Group normalization + divides the channels into groups and computes within each group the mean and variance for normalization, + and it performs very stable over a wide range of batch size. It can be described using the following formula. + + .. math:: + y = \frac{x - \mathrm{E}[x]}{\sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta + + Args: + num_groups (int): The number of groups to be divided along the channel dimension. + num_channels (int): The number of channels per group. + eps (float): A value added to the denominator for numerical stability. Default: 1e-5. + affine (bool): A bool value, this layer will has learnable affine parameters when set to true. Default: True. + + Inputs: + - **input_x** (Tensor) - The input feature with shape [N, C, H, W]. + + Outputs: + Tensor, the normalized and scaled offset tensor, has the same shape and data type as the `input_x`. + + Examples: + >>> goup_norm_op = nn.GroupNorm(16, 64) + >>> x = Tensor(np.ones([1, 64, 256, 256], np.float32)) + >>> goup_norm_op(x) + """ + def __init__(self, num_groups, num_channels, eps=1e-05, affine=True): + super(GroupNorm, self).__init__() + self.num_groups = check_int_positive(num_groups) + self.num_channels = check_int_positive(num_channels) + if num_channels % num_groups != 0: + raise ValueError("num_channels should be divided by num_groups") + self.eps = Tensor(check_typename('eps', eps, (float,)), mstype.float32) + self.affine = check_bool(affine) + + gamma = initializer('ones', [num_channels, 1, 1], mstype.float32) + beta = initializer('zeros', [num_channels, 1, 1], mstype.float32) + if self.affine: + self.gamma = Parameter(gamma, name='gamma') + self.beta = Parameter(beta, name='beta') + else: + self.gamma = gamma + self.beta = beta + self.shape = F.shape + self.reshape = F.reshape + self.reduce_mean = P.ReduceMean(keep_dims=True) + self.square = F.square + self.reduce_sum = P.ReduceSum(keep_dims=True) + self.sqrt = P.Sqrt() + + def construct(self, x): + batch, channel, height, width = self.shape(x) + x = self.reshape(x, (batch, self.num_groups, channel*height*width/self.num_groups)) + mean = self.reduce_mean(x, 2) + var = self.reduce_sum(self.square(x - mean), 2) / (channel * height * width / self.num_groups - 1) + std = self.sqrt(var + self.eps) + x = (x - mean) / std + x = self.reshape(x, (batch, channel, height, width)) + output = x * self.gamma + self.beta + return output + + def extend_repr(self): + """Display instance object as string.""" + s = 'num_groups={}, num_channels={}'.format(self.num_groups, self.num_channels) + return s diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index bf90fcc9de..746b6d240f 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -58,7 +58,7 @@ class _PoolNd(Cell): pass def extend_repr(self): - return 'kernel_size={kernel_size}, strides={strides}, pad_mode={pad_mode}'.format(**self.__dict__) + return 'kernel_size={kernel_size}, stride={stride}, pad_mode={pad_mode}'.format(**self.__dict__) class MaxPool2d(_PoolNd): @@ -104,7 +104,7 @@ class MaxPool2d(_PoolNd): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> pool = MaxPool2d(kernel_size=3, stride=1) + >>> pool = nn.MaxPool2d(kernel_size=3, stride=1) >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) [[[[1. 5. 5. 1.] [0. 3. 4. 8.] @@ -186,7 +186,7 @@ class AvgPool2d(_PoolNd): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> pool = AvgPool2d(kernel_size=3, strides=1) + >>> pool = nn.AvgPool2d(kernel_size=3, strides=1) >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) [[[[5. 5. 9. 9.] [8. 4. 3. 0.] diff --git a/mindspore/nn/loss/loss.py b/mindspore/nn/loss/loss.py index 806456e561..9a3de36f47 100644 --- a/mindspore/nn/loss/loss.py +++ b/mindspore/nn/loss/loss.py @@ -284,7 +284,7 @@ class SoftmaxCrossEntropyExpand(Cell): Tensor, a scalar tensor including the mean loss. Examples: - >>> loss = SoftmaxCrossEntropyExpand(sparse=True) + >>> loss = nn.SoftmaxCrossEntropyExpand(sparse=True) >>> input_data = Tensor(np.ones([64, 512]), dtype=mindspore.float32) >>> label = Tensor(np.ones([64]), dtype=mindspore.int32) >>> loss(input_data, label) diff --git a/mindspore/nn/metrics/__init__.py b/mindspore/nn/metrics/__init__.py index 490e1620fa..06429e200e 100755 --- a/mindspore/nn/metrics/__init__.py +++ b/mindspore/nn/metrics/__init__.py @@ -83,7 +83,7 @@ def get_metric_fn(name, *args, **kwargs): Metric object, class instance of the metric method. Examples: - >>> metric = get_metric_fn('precision', eval_type='classification') + >>> metric = nn.get_metric_fn('precision', eval_type='classification') """ if name not in __factory__: raise KeyError("Unknown Metric:", name) diff --git a/mindspore/nn/metrics/error.py b/mindspore/nn/metrics/error.py index c803000192..8ed175bc27 100644 --- a/mindspore/nn/metrics/error.py +++ b/mindspore/nn/metrics/error.py @@ -97,7 +97,7 @@ class MSE(Metric): Examples: >>> x = Tensor(np.array([0.1, 0.2, 0.6, 0.9]), mindspore.float32) >>> y = Tensor(np.array([0.1, 0.25, 0.5, 0.9]), mindspore.float32) - >>> error = MSE() + >>> error = nn.MSE() >>> error.clear() >>> error.update(x, y) >>> result = error.eval() diff --git a/mindspore/nn/optim/adam.py b/mindspore/nn/optim/adam.py index 86ce2b2147..eb4e33751f 100755 --- a/mindspore/nn/optim/adam.py +++ b/mindspore/nn/optim/adam.py @@ -13,7 +13,6 @@ # limitations under the License. # ============================================================================ """adam""" -from typing import Iterable import numpy as np from mindspore.common import dtype as mstype @@ -25,7 +24,7 @@ from mindspore.common.parameter import Parameter from mindspore.common.tensor import Tensor from mindspore._checkparam import ParamValidator as validator from mindspore._checkparam import Rel -from .optimizer import Optimizer, apply_decay, grad_scale +from .optimizer import Optimizer _learning_rate_update_func = ['linear', 'cos', 'sin'] @@ -166,23 +165,15 @@ class Adam(Optimizer): """ def __init__(self, params, learning_rate=1e-3, beta1=0.9, beta2=0.999, eps=1e-8, use_locking=False, - use_nesterov=False, weight_decay=0.0, loss_scale=1.0): - super(Adam, self).__init__(learning_rate, params) + use_nesterov=False, weight_decay=0.0, loss_scale=1.0, + decay_filter=lambda x: 'beta' not in x.name and 'gamma' not in x.name): + super(Adam, self).__init__(learning_rate, params, weight_decay, loss_scale, decay_filter) _check_param_value(beta1, beta2, eps, weight_decay) validator.check_type("use_locking", use_locking, [bool]) validator.check_type("use_nesterov", use_nesterov, [bool]) validator.check_type("loss_scale", loss_scale, [float]) validator.check_number_range("loss_scale", loss_scale, 1.0, float("inf"), Rel.INC_LEFT) - self.dynamic_lr = False - if isinstance(learning_rate, Iterable) or \ - (isinstance(learning_rate, Tensor) and learning_rate.dim() == 1): - self.dynamic_lr = True - self.gather = P.GatherV2() - self.assignadd = P.AssignAdd() - self.global_step = Parameter(initializer(0, [1], mstype.int32), name="global_step") - self.axis = 0 - self.beta1 = Tensor(beta1, mstype.float32) self.beta2 = Tensor(beta2, mstype.float32) self.beta1_power = Parameter(initializer(1, [1], mstype.float32), name="beta1_power") @@ -192,10 +183,9 @@ class Adam(Optimizer): self.moment1 = self.parameters.clone(prefix="moment1", init='zeros') self.moment2 = self.parameters.clone(prefix="moment2", init='zeros') + self.decay_tf = tuple(decay_filter(x) for x in self.parameters) self.hyper_map = C.HyperMap() self.opt = P.Adam(use_locking, use_nesterov) - self.weight_decay = weight_decay * loss_scale - self.reciprocal_scale = 1.0 / loss_scale self.pow = P.Pow() self.sqrt = P.Sqrt() @@ -206,15 +196,9 @@ class Adam(Optimizer): params = self.parameters moment1 = self.moment1 moment2 = self.moment2 - if self.weight_decay > 0: - gradients = self.hyper_map(F.partial(apply_decay, self.weight_decay), self.decay_tf, params, gradients) - if self.reciprocal_scale != 1.0: - gradients = self.hyper_map(F.partial(grad_scale, self.reciprocal_scale), gradients) - - lr = self.learning_rate - if self.dynamic_lr: - lr = self.gather(self.learning_rate, self.global_step, self.axis) - F.control_depend(lr, self.assignadd(self.global_step, self.one)) + gradients = self.decay_weight(gradients) + gradients = self.scale_grad(gradients) + lr = self.get_lr() beta1_power = self.beta1_power * self.beta1 self.beta1_power = beta1_power diff --git a/mindspore/nn/optim/momentum.py b/mindspore/nn/optim/momentum.py index 21d3cc864e..bac8e74a42 100755 --- a/mindspore/nn/optim/momentum.py +++ b/mindspore/nn/optim/momentum.py @@ -13,14 +13,9 @@ # limitations under the License. # ============================================================================ """momentum""" -from typing import Iterable - from mindspore.ops import functional as F, composite as C, operations as P -from mindspore.common.initializer import initializer from mindspore.common.parameter import Parameter -import mindspore.common.dtype as mstype -from mindspore.common import Tensor -from .optimizer import Optimizer, apply_decay, grad_scale +from .optimizer import Optimizer momentum_opt = C.MultitypeFuncGraph("momentum_opt") @@ -88,43 +83,20 @@ class Momentum(Optimizer): """ def __init__(self, params, learning_rate, momentum, weight_decay=0.0, loss_scale=1.0, decay_filter=lambda x: 'beta' not in x.name and 'gamma' not in x.name): - super(Momentum, self).__init__(learning_rate, params) + super(Momentum, self).__init__(learning_rate, params, weight_decay, loss_scale, decay_filter) if isinstance(momentum, float) and momentum < 0.0: raise ValueError("momentum should be at least 0.0, but got momentum {}".format(momentum)) - if isinstance(learning_rate, Iterable) or \ - (isinstance(learning_rate, Tensor) and learning_rate.dim() == 1): - self.dynamic_lr = True - self.gather = P.GatherV2() - self.assignadd = P.AssignAdd() - self.global_step = Parameter(initializer(0, [1], mstype.int32), name="global_step") - self.axis = 0 - else: - self.dynamic_lr = False - self.gather = None - self.assignadd = None - self.global_step = None - self.axis = None self.momentum = Parameter(momentum, name="momentum") self.params = self.parameters self.moments = self.params.clone(prefix="moments", init='zeros') - self.decay_tf = tuple(decay_filter(x) for x in self.parameters) self.hyper_map = C.HyperMap() self.opt = P.ApplyMomentum() - self.weight_decay = weight_decay * loss_scale - self.reciprocal_scale = 1.0 / loss_scale - self.one = Tensor(1, mstype.int32) def construct(self, gradients): params = self.params moments = self.moments - if self.weight_decay > 0: - gradients = self.hyper_map(F.partial(apply_decay, self.weight_decay), self.decay_tf, params, gradients) - if self.reciprocal_scale != 1.0: - gradients = self.hyper_map(F.partial(grad_scale, self.reciprocal_scale), gradients) - if self.dynamic_lr: - lr = self.gather(self.learning_rate, self.global_step, self.axis) - F.control_depend(lr, self.assignadd(self.global_step, self.one)) - else: - lr = self.learning_rate + gradients = self.decay_weight(gradients) + gradients = self.scale_grad(gradients) + lr = self.get_lr() success = self.hyper_map(F.partial(momentum_opt, self.opt, lr, self.momentum), gradients, params, moments) return success diff --git a/mindspore/nn/optim/optimizer.py b/mindspore/nn/optim/optimizer.py index 4b1fc5e12c..00d3fd3b7b 100755 --- a/mindspore/nn/optim/optimizer.py +++ b/mindspore/nn/optim/optimizer.py @@ -14,18 +14,19 @@ # ============================================================================ """optimizer""" from typing import Iterable -import logging import numpy as np +import mindspore from mindspore.ops import functional as F, composite as C, operations as P from mindspore.nn.cell import Cell from mindspore.common.parameter import Parameter, ParameterTuple +from mindspore.common.initializer import initializer from mindspore._checkparam import ParamValidator as validator from mindspore._checkparam import Rel from mindspore.common.tensor import Tensor +from mindspore import log as logger -logger = logging.getLogger('Optimizer') __all__ = ['Optimizer'] @@ -43,34 +44,124 @@ class Optimizer(Cell): Args: learning_rate (float): A floating point value for the learning rate. Should be greater than 0. parameters (list): A list of parameter, which will be updated. The element in `parameters` - should be class mindspore.Parameter. + should be class mindspore.Parameter. + weight_decay (float): A floating point value for the weight decay. Default: 0.0. + loss_scale (float): A floating point value for the loss scale. Default: 1.0. Should be greater than 0. + decay_filter (Function): A function to determine whether to apply weight decay on parameters. Default: lambda + x: 'beta' not in x.name and 'gamma' not in x.name. Raises: ValueError: If the learning_rate is a Tensor, but the dims of tensor is greater than 1. TypeError: If the learning_rate is not any of the three types: float, Tensor, Iterable. """ - def __init__(self, learning_rate, parameters): + def __init__(self, learning_rate, parameters, weight_decay=0.0, loss_scale=1.0, + decay_filter=lambda x: 'beta' not in x.name and 'gamma' not in x.name): super(Optimizer, self).__init__(auto_prefix=False) if isinstance(learning_rate, float): + self.dynamic_lr = False + self.gather = None + self.assignadd = None + self.global_step = None validator.check_number_range("learning rate", learning_rate, 0.0, float("inf"), Rel.INC_LEFT) - elif isinstance(learning_rate, Iterable): - learning_rate = Tensor(np.array(list(learning_rate)).astype(np.float32)) - elif isinstance(learning_rate, Tensor): - if learning_rate.dim() > 1: - raise ValueError("Learning rate should be a 0 or 1 dim `Tensor`," - f"but got {learning_rate.dim()}.") else: - raise TypeError("Learning rate should be float, Tensor or Iterable.") + self.dynamic_lr = True + self.gather = P.GatherV2() + self.assignadd = P.AssignAdd() + self.global_step = Parameter(initializer(0, [1], mindspore.int32), name='global_step') + if isinstance(learning_rate, Iterable): + learning_rate = Tensor(np.array(list(learning_rate)).astype(np.float32)) + elif isinstance(learning_rate, Tensor): + if learning_rate.dim() > 1: + raise ValueError("Learning rate should be a 0 or 1 dim `Tensor`," + f"but got {learning_rate.dim()}.") + if learning_rate.dim() == 1 and learning_rate.size() < 2: + logger.warning("If want to use the dynamic learning rate, please make sure that the number " + "of elements in the list, tuple or tensor passed is greater than 1.") + else: + raise TypeError("Learning rate should be float, Tensor or Iterable.") + + if isinstance(weight_decay, int): + weight_decay = float(weight_decay) + + if not isinstance(weight_decay, float): + raise TypeError("weight_decay should be a float number!") + + if isinstance(loss_scale, int): + loss_scale = float(loss_scale) + + if not isinstance(loss_scale, float): + raise TypeError("loss_scale should be a float number!") + + if loss_scale <= 0.0: + raise ValueError("Loss scale should be greater than 0, but got {}".format(loss_scale)) + self.loss_scale = loss_scale + + if weight_decay < 0.0: + raise ValueError("Weight decay should be equal or greater than 0, but got {}".format(weight_decay)) - if isinstance(learning_rate, Tensor) and learning_rate.dim() == 1 and learning_rate.size() < 2: - logger.warning("If want to use the dynamic learning rate, please make sure that " - "the number of elements in the list, tuple or tensor passed is greater than 1.") self.learning_rate = Parameter(learning_rate, name="learning_rate") self.parameters = ParameterTuple(parameters) + self.reciprocal_scale = 1.0 / loss_scale + self.weight_decay = weight_decay * loss_scale + self.decay_flags = tuple(decay_filter(x) for x in self.parameters) + if not self.parameters: raise ValueError("optimizer got an empty parameter list.") + def decay_weight(self, gradients): + """ + Weight decay. + + An approach to reduce the overfitting of a deep learning neural network model. + + Args: + gradients (tuple[Tensor]): The gradients of `self.parameters`, and have the same shape with + `self.parameters`. + + Returns: + tuple[Tensor], The gradients after weight decay. + """ + if self.weight_decay > 0: + params = self.parameters + gradients = self.hyper_map(F.partial(apply_decay, self.weight_decay), self.decay_flags, params, gradients) + + return gradients + + def scale_grad(self, gradients): + """ + Loss scale for mixed precision. + + An approach of mixed precision training to improve the speed and energy efficiency of training deep neural + network. + + Args: + gradients (tuple[Tensor]): The gradients of `self.parameters`, and have the same shape with + `self.parameters`. + + Returns: + tuple[Tensor], The gradients after loss scale. + + """ + if self.reciprocal_scale != 1.0: + gradients = self.hyper_map(F.partial(grad_scale, self.reciprocal_scale), gradients) + + return gradients + + def get_lr(self): + """ + Get the learning rate of current step. + + Returns: + float, the learning rate of current step. + """ + lr = self.learning_rate + if self.dynamic_lr: + lr = self.gather(self.learning_rate, self.global_step, 0) + F.control_depend(lr, self.assignadd(self.global_step, 1)) + + return lr + def construct(self, *hyper_params): raise NotImplementedError diff --git a/mindspore/nn/optim/rmsprop.py b/mindspore/nn/optim/rmsprop.py index b17a101708..a68dc6f7c4 100644 --- a/mindspore/nn/optim/rmsprop.py +++ b/mindspore/nn/optim/rmsprop.py @@ -14,12 +14,8 @@ # ============================================================================ """rmsprop""" from mindspore.ops import functional as F, composite as C, operations as P -from mindspore.common.initializer import initializer -from mindspore.common.parameter import Parameter from mindspore._checkparam import ParamValidator as validator -import mindspore.common.dtype as mstype -from mindspore.common import Tensor -from .optimizer import Optimizer, grad_scale, apply_decay +from .optimizer import Optimizer rmsprop_opt = C.MultitypeFuncGraph("rmsprop_opt") centered_rmsprop_opt = C.MultitypeFuncGraph("rmsprop_opt") @@ -138,7 +134,7 @@ class RMSProp(Optimizer): def __init__(self, params, learning_rate=0.1, decay=0.9, momentum=0.0, epsilon=1e-10, use_locking=False, centered=False, loss_scale=1.0, weight_decay=0.0, decay_filter=lambda x: 'beta' not in x.name and 'gamma' not in x.name): - super(RMSProp, self).__init__(learning_rate, params) + super(RMSProp, self).__init__(learning_rate, params, weight_decay, loss_scale, decay_filter) if isinstance(momentum, float) and momentum < 0.0: raise ValueError("momentum should be at least 0.0, but got momentum {}".format(momentum)) @@ -157,15 +153,6 @@ class RMSProp(Optimizer): else: self.opt = P.ApplyRMSProp(use_locking) - self.dynamic_lr = False - if not isinstance(learning_rate, float): - self.dynamic_lr = True - self.gather = P.GatherV2() - self.assignadd = P.AssignAdd() - self.global_step = Parameter(initializer(0, [1], mstype.int32), name="global_step") - self.axis = 0 - self.one = Tensor(1, mstype.int32) - self.momentum = momentum self.ms = self.parameters.clone(prefix="mean_square", init='zeros') @@ -173,21 +160,12 @@ class RMSProp(Optimizer): self.hyper_map = C.HyperMap() self.decay = decay - self.decay_tf = tuple(decay_filter(x) for x in self.parameters) - self.reciprocal_scale = 1.0 / loss_scale - self.weight_decay = weight_decay * loss_scale def construct(self, gradients): params = self.parameters - if self.weight_decay > 0: - gradients = self.hyper_map(F.partial(apply_decay, self.weight_decay), self.decay_tf, params, gradients) - if self.reciprocal_scale != 1.0: - gradients = self.hyper_map(F.partial(grad_scale, self.reciprocal_scale), gradients) - if self.dynamic_lr: - lr = self.gather(self.learning_rate, self.global_step, self.axis) - F.control_depend(lr, self.assignadd(self.global_step, self.one)) - else: - lr = self.learning_rate + gradients = self.decay_weight(gradients) + gradients = self.scale_grad(gradients) + lr = self.get_lr() if self.centered: success = self.hyper_map(F.partial(centered_rmsprop_opt, self.opt, lr, self.decay, self.epsilon, self.momentum), params, self.mg, self.ms, self.moment, gradients) diff --git a/mindspore/nn/optim/sgd.py b/mindspore/nn/optim/sgd.py index dbc81ecdd6..983be4bf80 100755 --- a/mindspore/nn/optim/sgd.py +++ b/mindspore/nn/optim/sgd.py @@ -14,11 +14,9 @@ # ============================================================================ """sgd""" from mindspore.ops import functional as F, composite as C, operations as P -from mindspore.common.initializer import initializer from mindspore.common.parameter import Parameter from mindspore._checkparam import ParamValidator as validator -import mindspore.common.dtype as mstype -from .optimizer import Optimizer, grad_scale +from .optimizer import Optimizer sgd_opt = C.MultitypeFuncGraph("sgd_opt") @@ -63,7 +61,8 @@ class SGD(Optimizer): dampening (float): A floating point value of dampening for momentum. Default: 0. weight_decay (float): Weight decay (L2 penalty). Default: 0. nesterov (bool): Enables the Nesterov momentum. Default: False. - loss_scale (float): A floating point value for the loss scale. Default: 1.0. + loss_scale (float): A floating point value for the loss scale, which should be larger + than 0.0. Default: 1.0. Inputs: - **gradients** (tuple[Tensor]) - The gradients of `params`, the shape is the same as `params`. @@ -83,53 +82,40 @@ class SGD(Optimizer): def __init__(self, params, learning_rate=0.1, momentum=0.0, dampening=0.0, weight_decay=0.0, nesterov=False, loss_scale=1.0): - super(SGD, self).__init__(learning_rate, params) + super(SGD, self).__init__(learning_rate, params, weight_decay, loss_scale) + + if not isinstance(momentum, float): + raise TypeError("momentum should be float number!") if isinstance(momentum, float) and momentum < 0.0: raise ValueError("momentum should be at least 0.0, but got momentum {}".format(momentum)) + if not isinstance(dampening, float): + raise TypeError("dampening should be float number") + + if isinstance(dampening, int): + dampening = float(dampening) + if dampening < 0.0: raise ValueError("dampening should be at least 0.0, but got dampening {}".format(dampening)) self.dampening = dampening - if weight_decay < 0.0: - raise ValueError("weight_decay should be at least 0.0, but got weight_decay {}".format(weight_decay)) - self.weight_decay = weight_decay - validator.check_type("nesterov", nesterov, [bool]) self.nesterov = nesterov self.opt = P.SGD(dampening, weight_decay, nesterov) - self.dynamic_lr = False - self.gather = None - self.global_step = None - self.axis = None - if not isinstance(learning_rate, float): - self.dynamic_lr = True - self.gather = P.GatherV2() - self.assignadd = P.AssignAdd() - self.global_step = Parameter(initializer(0, [1], mstype.int32), name="global_step") - self.axis = 0 self.momentum = Parameter(momentum, name="momentum") - self.params = self.parameters - self.accum = self.params.clone(prefix="accum", init='zeros') - self.stat = self.params.clone(prefix="stat", init='ones') + self.accum = self.parameters.clone(prefix="accum", init='zeros') + self.stat = self.parameters.clone(prefix="stat", init='ones') self.hyper_map = C.HyperMap() - self.weight_decay = weight_decay * loss_scale - self.reciprocal_scale = 1.0 / loss_scale - def construct(self, gradients): - params = self.params + params = self.parameters accum = self.accum stat = self.stat - if self.reciprocal_scale != 1.0: - gradients = self.hyper_map(F.partial(grad_scale, self.reciprocal_scale), gradients) - if self.dynamic_lr: - lr = self.gather(self.learning_rate, self.global_step, self.axis) - F.control_depend(lr, self.assignadd(self.global_step, 1)) - else: - lr = self.learning_rate + gradients = self.decay_weight(gradients) + gradients = self.scale_grad(gradients) + lr = self.get_lr() success = self.hyper_map(F.partial(sgd_opt, self.opt, lr, self.momentum), gradients, params, accum, stat) return success diff --git a/mindspore/nn/wrap/cell_wrapper.py b/mindspore/nn/wrap/cell_wrapper.py index 53a535781d..64c382557a 100644 --- a/mindspore/nn/wrap/cell_wrapper.py +++ b/mindspore/nn/wrap/cell_wrapper.py @@ -14,15 +14,23 @@ # ============================================================================ """Cell_wrapper.""" import copy + import numpy as np + +from mindspore.parallel._utils import (_get_device_num, _get_mirror_mean, + _get_parallel_mode) from mindspore.train.parallel_utils import ParallelMode -from mindspore.parallel._utils import _get_device_num, _get_parallel_mode, _get_mirror_mean -from ...ops import composite as C, functional as F, operations as P -from ...common import Tensor, dtype as mstype -from ..cell import Cell + +from ...common import Tensor +from ...common import dtype as mstype from ...common.initializer import initializer from ...common.parameter import Parameter, ParameterTuple +from ...ops import composite as C +from ...ops import functional as F +from ...ops import operations as P +from ...ops.composite.base import _mp_cast_helper from ...ops.operations.comm_ops import _VirtualDataset +from ..cell import Cell from .grad_reducer import DistributedGradReducer @@ -310,8 +318,8 @@ class WithEvalCell(Cell): def construct(self, data, label): outputs = self._network(data) - loss = self._loss_fn(outputs, label) - + label = _mp_cast_helper(mstype.float32, label) + loss = self._loss_fn(F.cast(outputs, mstype.float32), label) return loss, outputs, label diff --git a/mindspore/nn/wrap/loss_scale.py b/mindspore/nn/wrap/loss_scale.py index c6d61e6983..ba8e6cbb7c 100644 --- a/mindspore/nn/wrap/loss_scale.py +++ b/mindspore/nn/wrap/loss_scale.py @@ -220,7 +220,7 @@ class TrainOneStepWithLossScaleCell(Cell): self.depend_parameter_use = ControlDepend(depend_mode=1) self.allreduce = P.AllReduce() self.parallel_mode = _get_parallel_mode() - self.grad_reducer = None + self.grad_reducer = F.identity self.reducer_flag = self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL] if self.reducer_flag: mean = _get_mirror_mean() @@ -250,9 +250,8 @@ class TrainOneStepWithLossScaleCell(Cell): scaling_sens = sens grads = self.grad(self.network, weights)(data, label, F.cast(scaling_sens, F.dtype(loss))) grads = self.hyper_map(F.partial(_grad_scale, scaling_sens), grads) - if self.reducer_flag: - # apply grad reducer on grads - grads = self.grad_reducer(grads) + # apply grad reducer on grads + grads = self.grad_reducer(grads) # get the overflow buffer if not self.gpu_target: self.get_status(init) diff --git a/mindspore/ops/__init__.py b/mindspore/ops/__init__.py index 0e6c114566..b73d683284 100644 --- a/mindspore/ops/__init__.py +++ b/mindspore/ops/__init__.py @@ -26,11 +26,13 @@ Note: - The Primitive operators in operations need to be used after instantiation. - The composite operators are pre-defined combination of operator. - The functional operators are the pre-instantiated Primitive operators, which can be used directly like a function. + - For functional operators usage, please refer to + https://gitee.com/mindspore/mindspore/blob/master/mindspore/ops/functional.py """ from .primitive import Primitive, PrimitiveWithInfer, prim_attr_register from .vm_impl_registry import get_vm_impl_fn, vm_impl_registry -from .op_info_register import op_info_register, AiCPURegOp, TBERegOp, DataType +from .op_info_register import op_info_register, AkgRegOp, AiCPURegOp, TBERegOp, DataType from .primitive import constexpr from .._c_expression import signature_rw, signature_kind @@ -40,6 +42,6 @@ __primitive__ = [ ] __all__ = ["get_vm_impl_fn", "vm_impl_registry", - "op_info_register", "AiCPURegOp", "TBERegOp", "DataType", + "op_info_register", "AkgRegOp", "AiCPURegOp", "TBERegOp", "DataType", "constexpr"] __all__.extend(__primitive__) diff --git a/mindspore/ops/_grad/grad_array_ops.py b/mindspore/ops/_grad/grad_array_ops.py index abad030ae9..35d37b3ada 100644 --- a/mindspore/ops/_grad/grad_array_ops.py +++ b/mindspore/ops/_grad/grad_array_ops.py @@ -191,7 +191,7 @@ def get_bprop_concat(self): def bprop(x, out, dout): dx = () - out_offset = P.ConcatOffset(F.tuple_len(x), axis)(x) + out_offset = G.ConcatOffset(F.tuple_len(x), axis)(x) for i in range(F.tuple_len(x)): slice_out = P.Slice()(dout, out_offset[i], shape_op(x[i])) dx = dx + (slice_out,) diff --git a/mindspore/ops/_grad/grad_debug_ops.py b/mindspore/ops/_grad/grad_debug_ops.py index 431d82192f..1cb756219a 100644 --- a/mindspore/ops/_grad/grad_debug_ops.py +++ b/mindspore/ops/_grad/grad_debug_ops.py @@ -49,6 +49,15 @@ def get_bprop_image_summary(self): return bprop +@bprop_getters.register(P.HistogramSummary) +def get_bprop_histogram_summary(self): + """Generate bprop for HistogramSummary""" + + def bprop(tag, x, out, dout): + return tag, zeros_like(x) + return bprop + + @bprop_getters.register(P.InsertGradientOf) def get_bprop_insert_gradient_of(self): """Generate bprop for InsertGradientOf""" diff --git a/mindspore/ops/_grad/grad_math_ops.py b/mindspore/ops/_grad/grad_math_ops.py index 1863ac8fdd..2d819718c8 100755 --- a/mindspore/ops/_grad/grad_math_ops.py +++ b/mindspore/ops/_grad/grad_math_ops.py @@ -336,14 +336,13 @@ def get_bprop_log(self): @bprop_getters.register(P.Pow) def get_bprop_pow(self): """Grad definition for `Pow` operation.""" - pow_ = P.Pow() - cast = P.Cast() - dtype = P.DType() + pow_op = P.Pow() + ln = P.Log() def bprop(x, power, out, dout): - g = cast(F.tuple_to_array((power,)), dtype(x)) * pow_(x, power-1.0) - dx = g * dout - return dx, 0 + bc_dx = power * pow_op(x, power - 1.0) * dout + bc_dpower = out * ln(x) * dout + return binop_grad_common(x, power, bc_dx, bc_dpower) return bprop diff --git a/mindspore/ops/_grad/grad_nn_ops.py b/mindspore/ops/_grad/grad_nn_ops.py index fbe48aff97..ae730d78a7 100755 --- a/mindspore/ops/_grad/grad_nn_ops.py +++ b/mindspore/ops/_grad/grad_nn_ops.py @@ -14,7 +14,7 @@ # ============================================================================ """Define the grad rules of neural network related operations.""" - +from mindspore.common import dtype as mstype from .. import functional as F from .. import operations as P from ..operations import _grad_ops as G @@ -52,6 +52,61 @@ def get_bprop_conv2d(self): return bprop +@bprop_getters.register(P.ExtractImagePatches) +def get_bprop_extract_image_patches(self): + """Grad definition for `ExtractImagePatches` operation.""" + get_shape = P.Shape() + reshape = P.Reshape() + extract_image_patches = P.ExtractImagePatches(ksizes=self.ksizes, + strides=self.strides, + rates=self.rates, + padding=self.padding) + concat = P.Concat(axis=-1) + expand_dims = P.ExpandDims() + scatter_nd = P.ScatterNd() + dtype = P.DType() + fill = P.Fill() + slice_op = P.Slice() + transpose = P.Transpose() + matmul = P.MatMul() + cast = P.Cast() + _, ksizes_row, ksizes_col, _ = self.ksizes + + def bprop(x, out, dout): + x_shape = get_shape(x) + x_batch, x_row, x_col, x_depth = x_shape + x_indices_num = x_row * x_col + 1 + x_idx = F.tuple_to_array(range(1, x_indices_num)) + x_idx = reshape(x_idx, (1, x_row, x_col, 1)) + x_idx = cast(x_idx, mstype.float16) + x_idx_patch = extract_image_patches(x_idx) + x_idx_patch = transpose(x_idx_patch, (0, 3, 1, 2)) + x_idx_patch = cast(x_idx_patch, mstype.int32) + + out_shape = get_shape(out) + _, out_row, out_col, _ = out_shape + out_indices_num = out_row * out_col * ksizes_row * ksizes_col + out_idx = F.tuple_to_array(range(out_indices_num)) + out_idx = reshape(out_idx, (1, ksizes_row * ksizes_col, out_row, out_col)) + + idx_tensor = concat((expand_dims(x_idx_patch, -1), expand_dims(out_idx, -1))) + idx_tensor = reshape(idx_tensor, (-1, 2)) + sp_shape = (x_indices_num, out_indices_num) + sp_tensor = scatter_nd(idx_tensor, fill(dtype(dout), (out_indices_num,), 1), sp_shape) + sp_tensor = slice_op(sp_tensor, (1, 0), (x_indices_num - 1, out_indices_num)) + + grad = reshape(dout, (x_batch, out_row, out_col, ksizes_row, ksizes_col, x_depth)) + grad = transpose(grad, (1, 2, 3, 4, 0, 5)) + grad = reshape(grad, (-1, x_batch * x_depth)) + + jac = matmul(sp_tensor, grad) + dx = reshape(jac, (x_row, x_col, x_batch, x_depth)) + dx = transpose(dx, (2, 0, 1, 3)) + + return (dx,) + return bprop + + @bprop_getters.register(P.DepthwiseConv2dNative) def get_bprop_depthwise_conv2d_native(self): """Grad definition for `DepthwiseConv2dNative` operation.""" @@ -172,6 +227,28 @@ def get_bprop_relu6(self): return bprop +@bprop_getters.register(P.HSwish) +def get_bprop_hswish(self): + """Grad definition for `HSwish` operation.""" + input_grad = G.HSwishGrad() + + def bprop(x, out, dout): + dx = input_grad(dout, x) + return (dx,) + return bprop + + +@bprop_getters.register(P.HSigmoid) +def get_bprop_hsigmoid(self): + """Grad definition for `HSigmoid` operation.""" + input_grad = G.HSigmoidGrad() + + def bprop(x, out, dout): + dx = input_grad(dout, x) + return (dx,) + return bprop + + @bprop_getters.register(P.Elu) def get_bprop_elu(self): """Grad definition for `Elu` operation.""" @@ -448,6 +525,17 @@ def get_bprop_pad(self): return bprop +@bprop_getters.register(P.MirrorPad) +def get_bprop_mirror_pad(self): + """Grad definition for `MirrorPad` operation.""" + mirror_pad_grad = G.MirrorPadGrad(self.mode) + + def bprop(x, paddings, out, dout): + dx = mirror_pad_grad(dout, paddings, x) + return (dx, zeros_like(paddings)) + return bprop + + @bprop_getters.register(P.ROIAlign) def get_bprop_roi_align(self): """Grad definition for `ROIAlign` operation.""" diff --git a/mindspore/ops/_grad/grad_quant_ops.py b/mindspore/ops/_grad/grad_quant_ops.py new file mode 100644 index 0000000000..5d4ad22392 --- /dev/null +++ b/mindspore/ops/_grad/grad_quant_ops.py @@ -0,0 +1,82 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Generate bprop for aware quantization ops""" + +from .. import operations as P +from .grad_base import bprop_getters +from ..composite.multitype_ops.zeros_like_impl import zeros_like + + +@bprop_getters.register(P.FakeQuantWithMinMax) +def get_bprop_fakequant_with_minmax(self): + """Generate bprop for FakeQuantWithMinMax""" + op = P.FakeQuantWithMinMaxGrad(num_bits=self.num_bits, quant_delay=self.quant_delay) + + def bprop(x, x_min, x_max, out, dout): + dx = op(dout, x, x_min, x_max) + return dx, zeros_like(x_min), zeros_like(x_max) + + return bprop + + +@bprop_getters.register(P.FakeQuantWithMinMaxPerChannel) +def get_bprop_fakequant_with_minmax_perchannel(self): + """Generate bprop for FakeQuantWithMinMaxPerChannel""" + op = P.FakeQuantWithMinMaxPerChannelGrad(num_bits=self.num_bits, quant_delay=self.quant_delay) + + def bprop(x, x_min, x_max, out, dout): + dx = op(dout, x, x_min, x_max) + return dx, zeros_like(x_min), zeros_like(x_max) + + return bprop + + +@bprop_getters.register(P.BatchNormFold) +def get_bprop_batchnorm_fold(self): + """Generate bprop for BatchNormFold""" + op = P.BatchNormFoldGrad(self.epsilon, self.is_training, self.freeze_bn) + + def bprop(x, mean, variance, global_step, out, dout): + dx = op(dout[0], dout[1], x, out[0], out[1], global_step) + return dx, zeros_like(mean), zeros_like(variance), zeros_like(global_step) + + return bprop + + +@bprop_getters.register(P.CorrectionMul) +def get_bprop_correction_mul(self): + """Generate bprop for CorrectionMul""" + grad = P.CorrectionMulGrad() + + def bprop(x, batch_std, running_std, out, dout): + dx, d_batch_std = grad(dout, x, batch_std, running_std) + return dx, d_batch_std, zeros_like(running_std) + + return bprop + + +@bprop_getters.register(P.BatchNormFold2) +def get_bprop_batchnorm_fold2(self): + """Generate bprop for CorrectionAdd""" + op_f = P.BatchNormFold2Grad(freeze_bn=self.freeze_bn) + + def bprop(x, beta, gamma, batch_std, batch_mean, running_std, running_mean, global_step, out, dout): + d_batch_std, d_batch_mean, d_beta, d_gamma, d_x = op_f(dout, x, gamma, batch_std, batch_mean, running_std, + running_mean, global_step) + return d_x, d_beta, d_gamma, d_batch_std, d_batch_mean, zeros_like(running_std), zeros_like(running_mean), \ + zeros_like(global_step) + + return bprop diff --git a/mindspore/ops/_op_impl/__init__.py b/mindspore/ops/_op_impl/__init__.py index 76444881cc..65a12cd73c 100644 --- a/mindspore/ops/_op_impl/__init__.py +++ b/mindspore/ops/_op_impl/__init__.py @@ -14,8 +14,10 @@ # ============================================================================ """Operators info register.""" -from .akg.gpu import * -from .tbe import * +import platform from .aicpu import * +if "Windows" not in platform.system(): + from .akg.gpu import * + from .tbe import * __all__ = [] diff --git a/mindspore/ops/_op_impl/akg/gpu/cast.py b/mindspore/ops/_op_impl/akg/gpu/cast.py index fb4b221be6..b9ce4cf464 100644 --- a/mindspore/ops/_op_impl/akg/gpu/cast.py +++ b/mindspore/ops/_op_impl/akg/gpu/cast.py @@ -13,45 +13,19 @@ # limitations under the License. """Cast op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "Cast", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - { - "name": "dst_type", - "param_type": "required", - "type": "str" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +cast_op_info = AkgRegOp("Cast") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .attr("dst_type", "required", "str") \ + .dtype_format(DataType.F16_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_Default, DataType.F16_Default) \ + .get_op_info() + + +@op_info_register(cast_op_info) def _cast_akg(): """Cast AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/equal.py b/mindspore/ops/_op_impl/akg/gpu/equal.py index c6cffdad24..fa20392411 100644 --- a/mindspore/ops/_op_impl/akg/gpu/equal.py +++ b/mindspore/ops/_op_impl/akg/gpu/equal.py @@ -13,50 +13,19 @@ # limitations under the License. """Equal op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "Equal", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - }, - { - "index": 1, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +equal_op_info = AkgRegOp("Equal") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .input(1, "y") \ + .output(0, "output") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.BOOL_Default) \ + .get_op_info() + + +@op_info_register(equal_op_info) def _equal_akg(): """Equal AutoDiff register""" return diff --git a/py_filter b/mindspore/ops/_op_impl/akg/gpu/hsigmoid.py similarity index 51% rename from py_filter rename to mindspore/ops/_op_impl/akg/gpu/hsigmoid.py index 8301a0a257..4e802c1cad 100644 --- a/py_filter +++ b/mindspore/ops/_op_impl/akg/gpu/hsigmoid.py @@ -1,17 +1,30 @@ -#!/bin/bash -# Copyright 2019 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================ - -echo "\"\"\"doc\"\"\"" && python3 -m doxypypy.doxypypy -a -c $1 \ No newline at end of file +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""HSigmoid op""" +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType + +hsigmoid_op_info = AkgRegOp("HSigmoid") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .get_op_info() + + +@op_info_register(hsigmoid_op_info) +def _hsigmoid_akg(): + """HSigmoid AutoDiff register""" + return diff --git a/mindspore/ops/_op_impl/akg/gpu/hsigmoid_grad.py b/mindspore/ops/_op_impl/akg/gpu/hsigmoid_grad.py new file mode 100644 index 0000000000..39b819138e --- /dev/null +++ b/mindspore/ops/_op_impl/akg/gpu/hsigmoid_grad.py @@ -0,0 +1,31 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""HSigmoidGrad op""" +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType + +hsigmoidgrad_op_info = AkgRegOp("HSigmoidGrad") \ + .fusion_type("OPAQUE") \ + .input(0, "y_grad") \ + .input(1, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .get_op_info() + + +@op_info_register(hsigmoidgrad_op_info) +def _hsigmoid_grad_akg(): + """HSigmoidGrad AutoDiff register""" + return diff --git a/autogen.sh b/mindspore/ops/_op_impl/akg/gpu/hswish.py old mode 100755 new mode 100644 similarity index 51% rename from autogen.sh rename to mindspore/ops/_op_impl/akg/gpu/hswish.py index 65ee17a72a..29f20bafae --- a/autogen.sh +++ b/mindspore/ops/_op_impl/akg/gpu/hswish.py @@ -1,5 +1,4 @@ -#!/bin/bash -# Copyright 2019 Huawei Technologies Co., Ltd +# Copyright 2020 Huawei Technologies Co., Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,8 +11,20 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# ============================================================================ -git submodule update --init --recursive +"""HSwish op""" +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType +hswish_op_info = AkgRegOp("HSwish") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .get_op_info() + +@op_info_register(hswish_op_info) +def _hswish_akg(): + """HSwish AutoDiff register""" + return diff --git a/mindspore/ops/_op_impl/akg/gpu/hswish_grad.py b/mindspore/ops/_op_impl/akg/gpu/hswish_grad.py new file mode 100644 index 0000000000..38e8c78e28 --- /dev/null +++ b/mindspore/ops/_op_impl/akg/gpu/hswish_grad.py @@ -0,0 +1,31 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""HSwishGrad op""" +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType + +hswish_grad_op_info = AkgRegOp("HSwishGrad") \ + .fusion_type("OPAQUE") \ + .input(0, "y_grad") \ + .input(1, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .get_op_info() + + +@op_info_register(hswish_grad_op_info) +def _hswish_grad_akg(): + """HSwishGrad AutoDiff register""" + return diff --git a/mindspore/ops/_op_impl/akg/gpu/mean.py b/mindspore/ops/_op_impl/akg/gpu/mean.py index 244af290bb..b46b701b91 100644 --- a/mindspore/ops/_op_impl/akg/gpu/mean.py +++ b/mindspore/ops/_op_impl/akg/gpu/mean.py @@ -13,40 +13,18 @@ # limitations under the License. """SimpleMean op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "SimpleMean", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +mean_op_info = AkgRegOp("SimpleMean") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(mean_op_info) def _simple_mean_akg(): """SimpleMean AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/mean_grad.py b/mindspore/ops/_op_impl/akg/gpu/mean_grad.py index 27c0674632..e3e0121c20 100644 --- a/mindspore/ops/_op_impl/akg/gpu/mean_grad.py +++ b/mindspore/ops/_op_impl/akg/gpu/mean_grad.py @@ -13,45 +13,19 @@ # limitations under the License. """SimpleMeanGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "SimpleMeanGrad", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - { - "name": "input_shape", - "param_type": "required", - "type": "listInt" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "HEAD" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +mean_grad_op_info = AkgRegOp("SimpleMeanGrad") \ + .fusion_type("OPAQUE") \ + .input(0, "HEAD") \ + .output(0, "output") \ + .attr("input_shape", "required", "listInt") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(mean_grad_op_info) def _simple_mean_grad_akg(): """SimpleMeanGrad AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/mul.py b/mindspore/ops/_op_impl/akg/gpu/mul.py index d9e1a0b5d6..db5b1460ed 100644 --- a/mindspore/ops/_op_impl/akg/gpu/mul.py +++ b/mindspore/ops/_op_impl/akg/gpu/mul.py @@ -13,50 +13,19 @@ # limitations under the License. """Mul op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "Mul", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - }, - { - "index": 1, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +mul_op_info = AkgRegOp("Mul") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .input(1, "y") \ + .output(0, "output") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(mul_op_info) def _mul_akg(): """Mul AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/relu6.py b/mindspore/ops/_op_impl/akg/gpu/relu6.py index 0de0a7e400..31bfebcd8d 100644 --- a/mindspore/ops/_op_impl/akg/gpu/relu6.py +++ b/mindspore/ops/_op_impl/akg/gpu/relu6.py @@ -13,40 +13,18 @@ # limitations under the License. """ReLU6 op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "ReLU6", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +relu_op_info = AkgRegOp("ReLU6") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(relu_op_info) def _relu6_akg(): """ReLU6 AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/relu6_grad.py b/mindspore/ops/_op_impl/akg/gpu/relu6_grad.py index 4d3c5e9a00..83d93f3077 100644 --- a/mindspore/ops/_op_impl/akg/gpu/relu6_grad.py +++ b/mindspore/ops/_op_impl/akg/gpu/relu6_grad.py @@ -13,50 +13,19 @@ # limitations under the License. """ReLU6Grad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "ReLU6Grad", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y_grad" - }, - { - "index": 1, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +relu_grad_op_info = AkgRegOp("ReLU6Grad") \ + .fusion_type("OPAQUE") \ + .input(0, "y_grad") \ + .input(1, "x") \ + .output(0, "output") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(relu_grad_op_info) def _relu6_grad_akg(): """ReLU6Grad AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/squeeze.py b/mindspore/ops/_op_impl/akg/gpu/squeeze.py index 9e766cdfd7..cebf6ff1f3 100644 --- a/mindspore/ops/_op_impl/akg/gpu/squeeze.py +++ b/mindspore/ops/_op_impl/akg/gpu/squeeze.py @@ -13,45 +13,19 @@ # limitations under the License. """Squeeze op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "Squeeze", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +squeeze_op_info = AkgRegOp("Squeeze") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .attr("axis", "optional", "listInt") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(squeeze_op_info) def _squeeze_akg(): """Squeeze AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/squeeze_grad.py b/mindspore/ops/_op_impl/akg/gpu/squeeze_grad.py index 7584bd05f9..ef397ea0a7 100644 --- a/mindspore/ops/_op_impl/akg/gpu/squeeze_grad.py +++ b/mindspore/ops/_op_impl/akg/gpu/squeeze_grad.py @@ -13,50 +13,20 @@ # limitations under the License. """SqueezeGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "SqueezeGrad", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - { - "name": "x_shape", - "param_type": "required", - "type": "listInt" - }, - { - "name": "axis", - "param_type": "optional", - "type": "listInt" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y_grad" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +squeeze_grad_op_info = AkgRegOp("SqueezeGrad") \ + .fusion_type("OPAQUE") \ + .input(0, "y_grad") \ + .output(0, "output") \ + .attr("x_shape", "required", "listInt") \ + .attr("axis", "optional", "listInt") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(squeeze_grad_op_info) def _squeeze_grad_akg(): """SqueezeGrad AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/akg/gpu/tile.py b/mindspore/ops/_op_impl/akg/gpu/tile.py index f110e9314e..8c9de00979 100644 --- a/mindspore/ops/_op_impl/akg/gpu/tile.py +++ b/mindspore/ops/_op_impl/akg/gpu/tile.py @@ -13,45 +13,19 @@ # limitations under the License. """Tile op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, AkgRegOp, DataType -@op_info_register("""{ - "op_name": "Tile", - "imply_type": "AutoDiff", - "fusion_type": "OPAQUE", - "processor": "cuda", - "attr": [ - { - "name": "multiples", - "param_type": "required", - "type": "listInt" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32", "float16" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output" - } - ] -}""") +tile_op_info = AkgRegOp("Tile") \ + .fusion_type("OPAQUE") \ + .input(0, "x") \ + .output(0, "output") \ + .attr("multiples", "required", "listInt") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(tile_op_info) def _tile_akg(): """Tile AutoDiff register""" return diff --git a/mindspore/ops/_op_impl/tbe/__init__.py b/mindspore/ops/_op_impl/tbe/__init__.py index 0b79ae845b..2cffc37491 100644 --- a/mindspore/ops/_op_impl/tbe/__init__.py +++ b/mindspore/ops/_op_impl/tbe/__init__.py @@ -14,6 +14,8 @@ # ============================================================================ """tbe ops""" +from .abs import _abs_tbe +from .abs_grad import _abs_grad_tbe from .adam_apply_one_with_decay import _adam_apply_one_with_decay_tbe from .add import _add_tbe from .add_n import _add_n_tbe @@ -42,12 +44,14 @@ from .mul import _mul_tbe from .real_div import _real_div_tbe from .relu import _relu_tbe from .relu_grad import _relu_grad_tbe +from .relu6 import _relu6_tbe +from .relu6_grad import _relu6_grad_tbe from .softmax_cross_entropy_with_logits import _softmax_cross_entropy_with_logits_tbe from .sigmoid_cross_entropy_with_logits import _sigmoid_cross_entropy_with_logits_tbe from .sigmoid_cross_entropy_with_logits_grad import _sigmoid_cross_entropy_with_logits_grad_tbe from .tensor_add import _tensor_add_tbe from .trans_data import _trans_data_tbe -from .topkv2 import _topk_v2_tbe +from .top_k import _top_k_tbe from .matmul import _matmul_tbe from .sub import _sub_tbe from .reduce_mean_d import _reduce_mean_d_tbe @@ -105,6 +109,7 @@ from .minimum_grad import _minimum_grad_tbe from .maximum_grad import _maximum_grad_tbe from .concat import _concat_tbe from .slice import _slice_tbe +from .sign import _sign_tbe from .greater import _greater_tbe from .clip_by_norm_no_div_sum import _clip_by_norm_no_div_sum_tbe from .clip_by_value import _clip_by_value_tbe @@ -128,6 +133,11 @@ from .resize_nearest_neighbor_grad_d import _resize_nearest_neighbor_grad_d_tbe from .pad_d import _pad_d_tbe from .arg_max_with_value import _arg_max_with_value_tbe from .arg_min_with_value import _arg_min_with_value_tbe +from .smooth_l1_loss import _smooth_l1_loss_tbe +from .smooth_l1_loss_grad import _smooth_l1_loss_grad_tbe from .fused_mul_add import _fused_mul_add_tbe from .fused_mul_add_n import _fused_mul_add_n_tbe from .fused_mul_apply_momentum import _fused_mul_apply_momentum_tbe +from .depthwise_conv2d import _depthwise_conv2d_tbe +from .depthwise_conv2d_backprop_filter import _depthwise_conv2d_backprop_filter_tbe +from .depthwise_conv2d_backprop_input import _depthwise_conv2d_backprop_input_tbe diff --git a/mindspore/ops/_op_impl/tbe/abs.py b/mindspore/ops/_op_impl/tbe/abs.py new file mode 100644 index 0000000000..30a75812bd --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/abs.py @@ -0,0 +1,41 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Abs op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +abs_op_info = TBERegOp("Abs") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("abs.so") \ + .compute_cost(10) \ + .kernel_name("abs") \ + .partial_flag(True) \ + .op_pattern("formatAgnostic") \ + .input(0, "x", None, "required", None) \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .get_op_info() + + +@op_info_register(abs_op_info) +def _abs_tbe(): + """Abs TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/abs_grad.py b/mindspore/ops/_op_impl/tbe/abs_grad.py new file mode 100644 index 0000000000..ba630f6570 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/abs_grad.py @@ -0,0 +1,44 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""AbsGrad op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +abs_grad_op_info = TBERegOp("AbsGrad") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("abs_grad.so") \ + .compute_cost(10) \ + .kernel_name("abs_grad") \ + .partial_flag(True) \ + .op_pattern("formatAgnostic") \ + .input(0, "y", None, "required", None) \ + .input(1, "dy", None, "required", None) \ + .output(0, "z", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(abs_grad_op_info) +def _abs_grad_tbe(): + """AbsGrad TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/add.py b/mindspore/ops/_op_impl/tbe/add.py index 95c31d8974..63e1efb1c6 100644 --- a/mindspore/ops/_op_impl/tbe/add.py +++ b/mindspore/ops/_op_impl/tbe/add.py @@ -14,71 +14,28 @@ # ============================================================================ """Add op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +add_op_info = TBERegOp("Add") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("add.so") \ + .compute_cost(10) \ + .kernel_name("add") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Add", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "add.so", - "compute_cost": 10, - "kernel_name": "add", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", - "float", "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(add_op_info) def _add_tbe(): """Add TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/add_n.py b/mindspore/ops/_op_impl/tbe/add_n.py index 9177ed14c7..3e8a6c0016 100644 --- a/mindspore/ops/_op_impl/tbe/add_n.py +++ b/mindspore/ops/_op_impl/tbe/add_n.py @@ -14,61 +14,33 @@ # ============================================================================ """AddN op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +add_n_op_info = TBERegOp("AddN") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("add_n.so") \ + .compute_cost(10) \ + .kernel_name("add_n") \ + .partial_flag(True) \ + .attr("n", "required", "int", "all") \ + .input(0, "x", False, "dynamic", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_FracZ, DataType.I32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "AddN", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "add_n.so", - "compute_cost": 10, - "kernel_name": "add_n", - "partial_flag": true, - "attr": [ - { - "name": "n", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float","int32","int32","int32" - ], - "format": [ - "DefaultFormat","NC1HWC0","FracZ","FRACTAL_NZ", - "DefaultFormat","NC1HWC0","FracZ","FRACTAL_NZ","DefaultFormat","NC1HWC0","FracZ" - ], - "name": "x", - "need_compile": false, - "param_type": "dynamic", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float","int32","int32","int32" - ], - "format": [ - "DefaultFormat","NC1HWC0","FracZ","FRACTAL_NZ", - "DefaultFormat","NC1HWC0","FracZ","FRACTAL_NZ","DefaultFormat","NC1HWC0","FracZ" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(add_n_op_info) def _add_n_tbe(): """AddN TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/apply_adam.py b/mindspore/ops/_op_impl/tbe/apply_adam.py index ae6b7d782e..6fd7205567 100644 --- a/mindspore/ops/_op_impl/tbe/apply_adam.py +++ b/mindspore/ops/_op_impl/tbe/apply_adam.py @@ -14,182 +14,66 @@ # ============================================================================ """ApplyAdam op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +apply_adam_op_info = TBERegOp("Adam") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("apply_adam.so") \ + .compute_cost(10) \ + .kernel_name("apply_adam") \ + .partial_flag(True) \ + .attr("use_locking", "optional", "bool", "true,false", "false") \ + .attr("use_nesterov", "optional", "bool", "true,false", "false") \ + .input(0, "var", False, "required", "all") \ + .input(1, "m", False, "required", "all") \ + .input(2, "v", False, "required", "all") \ + .input(3, "beta1_power", False, "required", "all") \ + .input(4, "beta2_power", False, "required", "all") \ + .input(5, "lr", False, "required", "all") \ + .input(6, "beta1", False, "required", "all") \ + .input(7, "beta2", False, "required", "all") \ + .input(8, "epsilon", False, "required", "all") \ + .input(9, "grad", False, "required", "all") \ + .output(0, "var", False, "required", "all") \ + .output(1, "m", False, "required", "all") \ + .output(2, "v", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, + DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ, + DataType.F16_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, + DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ, + DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Adam", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "apply_adam.so", - "compute_cost": 10, - "kernel_name": "apply_adam", - "partial_flag": true, - "attr": [ - { - "name": "use_locking", - "param_type": "optional", - "type": "bool", - "value": "true,false", - "default_value":"false" - }, - { - "name": "use_nesterov", - "param_type": "optional", - "type": "bool", - "value": "true,false", - "default_value":"false" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "m", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "v", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "beta1_power", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "beta2_power", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 5, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "lr", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 6, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "beta1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 7, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "beta2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 8, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "epsilon", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 8, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(apply_adam_op_info) def _apply_adam_tbe(): """ApplyAdam TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/apply_momentum.py b/mindspore/ops/_op_impl/tbe/apply_momentum.py index f2c6f5b15e..42ce9d0e41 100644 --- a/mindspore/ops/_op_impl/tbe/apply_momentum.py +++ b/mindspore/ops/_op_impl/tbe/apply_momentum.py @@ -14,112 +14,42 @@ # ============================================================================ """ApplyMomentum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +apply_momentum_op_info = TBERegOp("ApplyMomentum") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("apply_momentum.so") \ + .compute_cost(10) \ + .kernel_name("apply_momentum") \ + .partial_flag(True) \ + .attr("use_nesterov", "optional", "bool", "true,false", "false") \ + .input(0, "var", False, "required", "all") \ + .input(1, "accum", False, "required", "all") \ + .input(2, "lr", False, "required", "all") \ + .input(3, "grad", False, "required", "all") \ + .input(4, "momentum", False, "required", "all") \ + .output(0, "var", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_Default, DataType.F16_5HD, + DataType.F16_Default, DataType.F16_5HD) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_Default, DataType.F16_C1HWNCoC0, + DataType.F16_Default, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_Default, DataType.F16_FracZ, + DataType.F16_Default, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_Default, DataType.F32_5HD, + DataType.F32_Default, DataType.F32_5HD) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_Default, DataType.F32_C1HWNCoC0, + DataType.F32_Default, DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_Default, DataType.F32_FracZ, + DataType.F32_Default, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ApplyMomentum", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "apply_momentum.so", - "compute_cost": 10, - "kernel_name": "apply_momentum", - "partial_flag": true, - "attr": [ - { - "name": "use_nesterov", - "param_type": "optional", - "type": "bool", - "value": "true,false", - "default_value":"false" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "DefaultFormat", "FracZ", "C1HWNCoC0" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "DefaultFormat", "FracZ", "C1HWNCoC0" - ], - "name": "accum", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat" - ], - "name": "lr", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "DefaultFormat", "FracZ", "C1HWNCoC0" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float16","float16","float16","float16","float","float","float", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat" - ], - "name": "momentum", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "NC1HWC0", "C1HWNCoC0", "DefaultFormat", "FracZ", "NC1HWC0", "DefaultFormat", "FracZ", "C1HWNCoC0" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(apply_momentum_op_info) def _apply_momentum_tbe(): """ApplyMomentum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/arg_max_with_value.py b/mindspore/ops/_op_impl/tbe/arg_max_with_value.py index e5ffe3d36f..ca393f3356 100644 --- a/mindspore/ops/_op_impl/tbe/arg_max_with_value.py +++ b/mindspore/ops/_op_impl/tbe/arg_max_with_value.py @@ -14,70 +14,25 @@ # ============================================================================ """ArgMaxWithValue op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +arg_max_with_value_op_info = TBERegOp("ArgMaxWithValue") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("arg_max_with_value.so") \ + .compute_cost(10) \ + .kernel_name("arg_max_with_value") \ + .partial_flag(True) \ + .attr("axis", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "indice", False, "required", "all") \ + .output(1, "values", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ArgMaxWithValue", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "arg_max_with_value.so", - "compute_cost": 10, - "kernel_name": "arg_max_with_value", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "indice", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "values", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(arg_max_with_value_op_info) def _arg_max_with_value_tbe(): """ArgMaxWithValue TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/arg_min_with_value.py b/mindspore/ops/_op_impl/tbe/arg_min_with_value.py index 3d66b4534d..b0c23ef301 100644 --- a/mindspore/ops/_op_impl/tbe/arg_min_with_value.py +++ b/mindspore/ops/_op_impl/tbe/arg_min_with_value.py @@ -14,70 +14,25 @@ # ============================================================================ """ArgMinWithValue op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +arg_min_with_value_op_info = TBERegOp("ArgMinWithValue") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("arg_min_with_value.so") \ + .compute_cost(10) \ + .kernel_name("arg_min_with_value") \ + .partial_flag(True) \ + .attr("axis", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "indice", False, "required", "all") \ + .output(1, "values", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ArgMinWithValue", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "arg_min_with_value.so", - "compute_cost": 10, - "kernel_name": "arg_min_with_value", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "indice", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "values", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(arg_min_with_value_op_info) def _arg_min_with_value_tbe(): """ArgMinWithValue TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/assign.py b/mindspore/ops/_op_impl/tbe/assign.py index 610a221a1c..41a9a0fecd 100644 --- a/mindspore/ops/_op_impl/tbe/assign.py +++ b/mindspore/ops/_op_impl/tbe/assign.py @@ -14,93 +14,43 @@ # ============================================================================ """Assign op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +assign_op_info = TBERegOp("Assign") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("assign.so") \ + .compute_cost(10) \ + .kernel_name("assign") \ + .partial_flag(True) \ + .input(0, "resource", False, "required", "all") \ + .input(1, "value", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.I16_5HD, DataType.I16_5HD, DataType.I16_5HD) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.U16_5HD, DataType.U16_5HD, DataType.U16_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U32_5HD, DataType.U32_5HD, DataType.U32_5HD) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.I64_5HD, DataType.I64_5HD, DataType.I64_5HD) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.U64_5HD, DataType.U64_5HD, DataType.U64_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Assign", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "assign.so", - "compute_cost": 10, - "kernel_name": "assign", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32", "uint32", "uint32", "uint32", "uint32", "int8", - "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8", "int16", "int16", "int16", - "int16", "uint16", "uint16", "uint16", "uint16", "int64", "int64", "int64", "int64", - "uint64", "uint64", "uint64", "uint64", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "FRACTAL_NZ" - ], - "name": "resource", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32", "uint32", "uint32", "uint32", "uint32", "int8", "int8", "int8", "int8", "uint8", - "uint8", "uint8", "uint8", "int16", "int16", "int16", "int16", "uint16", "uint16", "uint16", - "uint16", "int64", "int64", "int64", "int64", "uint64", "uint64", "uint64", "uint64", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "FRACTAL_NZ" - ], - "name": "value", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32", "uint32", "uint32", "uint32", "uint32", "int8", "int8", "int8", - "int8", "uint8", "uint8", "uint8", "uint8", "int16", "int16", "int16", "int16", "uint16", - "uint16", "uint16", "uint16", "int64", "int64", "int64", "int64", - "uint64", "uint64", "uint64", "uint64", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "FRACTAL_NZ" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(assign_op_info) def _assign_tbe(): """Assign TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/assign_add.py b/mindspore/ops/_op_impl/tbe/assign_add.py index 94e0e781f5..fbbb9a997f 100644 --- a/mindspore/ops/_op_impl/tbe/assign_add.py +++ b/mindspore/ops/_op_impl/tbe/assign_add.py @@ -14,80 +14,34 @@ # ============================================================================ """AssignAdd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +assign_add_op_info = TBERegOp("AssignAdd") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("assignadd.so") \ + .compute_cost(10) \ + .kernel_name("assignadd") \ + .partial_flag(True) \ + .input(0, "ref", False, "required", "all") \ + .input(1, "value", False, "required", "all") \ + .output(0, "output_ref", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.I64_5HD, DataType.I64_5HD, DataType.I64_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "AssignAdd", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "assignadd.so", - "compute_cost": 10, - "kernel_name": "assignadd", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32", "int8", "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8", "int64", - "int64", "int64", "int64" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "ref", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32", "int8", "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8", "int64", - "int64", "int64", "int64" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "value", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32", "int8", "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8", "int64", - "int64", "int64", "int64" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "output_ref", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(assign_add_op_info) def _assign_add_tbe(): """AssignAdd TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/assign_sub.py b/mindspore/ops/_op_impl/tbe/assign_sub.py index 85104f6eb3..126a6b7a9a 100644 --- a/mindspore/ops/_op_impl/tbe/assign_sub.py +++ b/mindspore/ops/_op_impl/tbe/assign_sub.py @@ -14,65 +14,27 @@ # ============================================================================ """AssignSub op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +assign_sub_op_info = TBERegOp("AssignSub") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("assign_sub.so") \ + .compute_cost(10) \ + .kernel_name("assign_sub") \ + .partial_flag(True) \ + .input(0, "var", False, "required", "all") \ + .input(1, "value", False, "required", "all") \ + .output(0, "output_ref", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "AssignSub", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "assign_sub.so", - "compute_cost": 10, - "kernel_name": "assign_sub", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "value", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "out_ref", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(assign_sub_op_info) def _assign_sub_tbe(): """AssignSub TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/atomic_addr_clean.py b/mindspore/ops/_op_impl/tbe/atomic_addr_clean.py index 90186e6526..e707a1f26f 100644 --- a/mindspore/ops/_op_impl/tbe/atomic_addr_clean.py +++ b/mindspore/ops/_op_impl/tbe/atomic_addr_clean.py @@ -14,31 +14,20 @@ # ============================================================================ """AtomicAddrClean op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp +atomic_addr_clean_op_info = TBERegOp("AtomicAddrClean") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("atomic_addr_clean.so") \ + .compute_cost(10) \ + .kernel_name("atomic_addr_clean") \ + .partial_flag(True) \ + .attr("automic_add_mem_size", "required", "listInt", "all") \ + .get_op_info() -@op_info_register("""{ - "op_name": "AtomicAddrClean", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "atomic_addr_clean.so", - "compute_cost": 10, - "kernel_name": "atomic_addr_clean", - "partial_flag": true, - "attr": [ - { - "name": "automic_add_mem_size", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - ], - "outputs": [ - ] -}""") + +@op_info_register(atomic_addr_clean_op_info) def _atomic_addr_clean_tbe(): """AtomicAddrClean TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/batch_matmul.py b/mindspore/ops/_op_impl/tbe/batch_matmul.py index 668791b659..4efcf8031c 100644 --- a/mindspore/ops/_op_impl/tbe/batch_matmul.py +++ b/mindspore/ops/_op_impl/tbe/batch_matmul.py @@ -14,88 +14,29 @@ # ============================================================================ """BatchMatMul op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +batch_matmul_op_info = TBERegOp("BatchMatMul") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("batch_matmul.so") \ + .compute_cost(10) \ + .kernel_name("batch_matmul") \ + .attr("transpose_x1", "required", "bool", "all") \ + .attr("transpose_x2", "required", "bool", "all") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "bias", False, "optional", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_Default, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BatchMatMul", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "batch_matmul.so", - "compute_cost": 10, - "kernel_name": "batch_matmul", - "partial_flag": true, - "attr": [ - { - "name": "transpose_x1", - "param_type": "required", - "type": "bool", - "value": "all" - }, - { - "name": "transpose_x2", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","int32","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","FRACTAL_NZ","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","int32","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","FRACTAL_NZ","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","int32","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "bias", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","int32","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","FRACTAL_NZ","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(batch_matmul_op_info) def _batch_matmul_tbe(): """BatchMatMul TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/batchnorm.py b/mindspore/ops/_op_impl/tbe/batchnorm.py index 263fcfb0f2..6dd79245a3 100644 --- a/mindspore/ops/_op_impl/tbe/batchnorm.py +++ b/mindspore/ops/_op_impl/tbe/batchnorm.py @@ -14,174 +14,45 @@ # ============================================================================ """BatchNorm op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +batch_norm_op_info = TBERegOp("BatchNorm") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("batch_norm.so") \ + .compute_cost(10) \ + .kernel_name("batch_norm") \ + .partial_flag(True) \ + .attr("epsilon", "optional", "float", "all") \ + .attr("data_format", "optional", "str", "all") \ + .attr("is_training", "optional", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "scale", False, "required", "all") \ + .input(2, "offset", False, "required", "all") \ + .input(3, "mean", False, "optional", "all") \ + .input(4, "variance", False, "optional", "all") \ + .output(0, "y", False, "required", "all") \ + .output(1, "batch_mean", False, "required", "all") \ + .output(2, "batch_variance", False, "required", "all") \ + .output(3, "reserve_space_1", False, "optional", "all") \ + .output(4, "reserve_space_2", False, "optional", "all") \ + .output(5, "reserve_space_3", False, "optional", "all") \ + .dtype_format(DataType.F16_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F16_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BatchNorm", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "batch_norm.so", - "compute_cost": 10, - "kernel_name": "batch_norm", - "partial_flag": true, - "attr": [ - { - "name": "epsilon", - "param_type": "required", - "type": "float", - "value": "all" - }, - { - "name": "data_format", - "param_type": "required", - "type": "str", - "value": "all" - }, - { - "name": "is_training", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0", "DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float","float","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat", "NC1HWC0" - ], - "name": "scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float","float","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "offset", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float","float","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "optional", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float","float","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat","NC1HWC0", "DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required" - }, - { - "index": 1, - "dtype": [ - "float","float","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "batch_mean", - "param_type": "required" - }, - { - "index": 2, - "dtype": [ - "float", "float", "float", "float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "batch_variance", - "param_type": "required" - }, - { - "index": 3, - "dtype": [ - "float", "float", "float", "float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_1", - "param_type": "optional" - }, - { - "index": 4, - "dtype": [ - "float", "float", "float", "float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_2", - "param_type": "optional" - }, - { - "index": 5, - "dtype": [ - "float", "float", "float", "float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_3", - "param_type": "optional" - } - ] -}""") + +@op_info_register(batch_norm_op_info) def _batch_norm_tbe(): """BatchNorm TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/batchnorm_grad.py b/mindspore/ops/_op_impl/tbe/batchnorm_grad.py index cc560c5283..6063c0e750 100644 --- a/mindspore/ops/_op_impl/tbe/batchnorm_grad.py +++ b/mindspore/ops/_op_impl/tbe/batchnorm_grad.py @@ -14,181 +14,45 @@ # ============================================================================ """BatchNormGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +batch_norm_grad_op_info = TBERegOp("BatchNormGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("batchnormgrad.so") \ + .compute_cost(10) \ + .kernel_name("batchnormgrad") \ + .partial_flag(True) \ + .attr("epsilon", "optional", "float", "all") \ + .attr("data_format", "optional", "str", "all") \ + .attr("is_training", "optional", "bool", "all") \ + .input(0, "y_backprop", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "scale", False, "required", "all") \ + .input(3, "reserve_space_1", False, "required", "all") \ + .input(4, "reserve_space_2", False, "required", "all") \ + .input(5, "reserve_space_3", False, "required", "all") \ + .output(0, "x_backprop", False, "required", "all") \ + .output(1, "scale_backprop", False, "required", "all") \ + .output(2, "offset_backprop", False, "required", "all") \ + .output(3, "reserve_space_4", False, "optional", "all") \ + .output(4, "reserve_space_5", False, "optional", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F16_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F16_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BatchNormGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "batchnormgrad.so", - "compute_cost": 10, - "kernel_name": "batchnormgrad", - "partial_flag": true, - "attr": [ - { - "name": "epsilon", - "param_type": "optional", - "type": "float", - "value": "all" - }, - { - "name": "data_format", - "param_type": "optional", - "type": "str", - "value": "all" - }, - { - "name": "is_training", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "y_backprop", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 5, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_3", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "x_backprop", - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "scale_backprop", - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "offset_backprop", - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_4", - "param_type": "optional", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "reserve_space_5", - "param_type": "optional", - "shape": "all" - } - ] -}""") + +@op_info_register(batch_norm_grad_op_info) def _batch_norm_grad_tbe(): """BatchNormGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bias_add.py b/mindspore/ops/_op_impl/tbe/bias_add.py index 9081ed2c13..24607af141 100644 --- a/mindspore/ops/_op_impl/tbe/bias_add.py +++ b/mindspore/ops/_op_impl/tbe/bias_add.py @@ -14,70 +14,26 @@ # ============================================================================ """BiasAdd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bias_add_grad_op_info = TBERegOp("BiasAdd") \ + .fusion_type("COMMREDUCE") \ + .async_flag(False) \ + .binfile_name("bias_add.so") \ + .compute_cost(10) \ + .kernel_name("bias_add") \ + .partial_flag(True) \ + .attr("data_format", "required", "str", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "bias", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BiasAdd", - "imply_type": "TBE", - "fusion_type": "COMMREDUCE", - "async_flag": false, - "binfile_name": "bias_add.so", - "compute_cost": 10, - "kernel_name": "bias_add", - "partial_flag": true, - "attr": [ - { - "name": "data_format", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32", "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "int32", "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "bias", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "int32", "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(bias_add_grad_op_info) def _bias_add_tbe(): """BiasAdd TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bias_add_grad.py b/mindspore/ops/_op_impl/tbe/bias_add_grad.py index 4a24e361bb..e59c197bce 100644 --- a/mindspore/ops/_op_impl/tbe/bias_add_grad.py +++ b/mindspore/ops/_op_impl/tbe/bias_add_grad.py @@ -14,57 +14,26 @@ # ============================================================================ """BiasAddGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bias_add_grad_op_info = TBERegOp("BiasAddGrad") \ + .fusion_type("COMMREDUCE") \ + .async_flag(False) \ + .binfile_name("biasaddgrad.so") \ + .compute_cost(10) \ + .kernel_name("biasaddgrad") \ + .partial_flag(True) \ + .attr("data_format", "required", "str", "all") \ + .input(0, "output_backprop", False, "required", "all") \ + .output(0, "output", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BiasAddGrad", - "imply_type": "TBE", - "fusion_type": "COMMREDUCE", - "async_flag": false, - "binfile_name": "biasaddgrad.so", - "compute_cost": 10, - "kernel_name": "biasaddgrad", - "partial_flag": true, - "attr": [ - { - "name": "data_format", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","FRACTAL_NZ","DefaultFormat" - ], - "name": "out_backprop", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "output", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(bias_add_grad_op_info) def _bias_add_grad_tbe(): """BiasAddGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bn_training_reduce.py b/mindspore/ops/_op_impl/tbe/bn_training_reduce.py index 3228ccd791..16d75d06be 100644 --- a/mindspore/ops/_op_impl/tbe/bn_training_reduce.py +++ b/mindspore/ops/_op_impl/tbe/bn_training_reduce.py @@ -14,60 +14,24 @@ # ============================================================================ """BatchNorm op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bn_training_reduce_op_info = TBERegOp("BNTrainingReduce") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("bn_training_reduce.so") \ + .compute_cost(10) \ + .kernel_name("bn_training_reduce") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "sum", False, "required", "all") \ + .output(1, "square_sum", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BNTrainingReduce", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "bn_training_reduce.so", - "compute_cost": 10, - "kernel_name": "bn_training_reduce", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float","float" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "sum", - "param_type": "required" - }, - { - "index": 1, - "dtype": [ - "float","float" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "square_sum", - "param_type": "required" - } - ] -}""") + +@op_info_register(bn_training_reduce_op_info) def _bn_training_reduce_tbe(): """BNTrainingReduce TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bn_training_reduce_grad.py b/mindspore/ops/_op_impl/tbe/bn_training_reduce_grad.py index 3bb43fbb94..e92054670d 100644 --- a/mindspore/ops/_op_impl/tbe/bn_training_reduce_grad.py +++ b/mindspore/ops/_op_impl/tbe/bn_training_reduce_grad.py @@ -14,134 +14,32 @@ # ============================================================================ """BatchNormGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bn_training_reduce_grad_op_info = TBERegOp("BNTrainingReduceGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("bn_training_reduce_grad.so") \ + .compute_cost(10) \ + .kernel_name("bn_training_reduce_grad") \ + .partial_flag(True) \ + .attr("epsilon", "optional", "float", "all") \ + .input(0, "grads", False, "required", "all") \ + .input(1, "x_norm", False, "required", "all") \ + .input(2, "diff_scale", False, "required", "all") \ + .input(3, "diff_offset", False, "required", "all") \ + .input(4, "scale", False, "required", "all") \ + .input(5, "batch_mean", False, "required", "all") \ + .input(6, "batch_variance", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BNTrainingReduceGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "bn_training_reduce_grad.so", - "compute_cost": 10, - "kernel_name": "bn_training_reduce_grad", - "partial_flag": true, - "attr": [ - { - "name": "epsilon", - "param_type": "optional", - "type": "float", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "grads", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "x_norm", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "diff_scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "diff_offset", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 5, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 6, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(bn_training_reduce_grad_op_info) def _bn_training_reduce_grad_tbe(): """BNTrainingReduceGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bn_training_update.py b/mindspore/ops/_op_impl/tbe/bn_training_update.py index 9d6838f0e4..49b572e31e 100644 --- a/mindspore/ops/_op_impl/tbe/bn_training_update.py +++ b/mindspore/ops/_op_impl/tbe/bn_training_update.py @@ -14,200 +14,40 @@ # ============================================================================ """BatchNormGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bn_training_update_op_info = TBERegOp("BNTrainingUpdate") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("bn_training_update.so") \ + .compute_cost(10) \ + .kernel_name("bn_training_update") \ + .partial_flag(True) \ + .attr("factor", "optional", "float", "all") \ + .attr("epsilon", "optional", "float", "all") \ + .attr("isRef", "optional", "bool", "all", "true") \ + .input(0, "x", False, "required", "all") \ + .input(1, "sum", False, "required", "all") \ + .input(2, "square_sum", False, "required", "all") \ + .input(3, "scale", False, "required", "all") \ + .input(4, "offset", False, "required", "all") \ + .input(5, "mean", False, "required", "all") \ + .input(6, "variance", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .output(1, "mean", False, "required", "all") \ + .output(2, "variance", False, "required", "all") \ + .output(3, "batch_mean", False, "required", "all") \ + .output(4, "batch_variance", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F16_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BNTrainingUpdate", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "bn_training_update.so", - "compute_cost": 10, - "kernel_name": "bn_training_update", - "partial_flag": true, - "attr": [ - { - "name": "factor", - "param_type": "optional", - "type": "float", - "value": "all" - }, - { - "name": "epsilon", - "param_type": "optional", - "type": "float", - "value": "all" - }, - { - "name": "isRef", - "param_type": "optional", - "type": "bool", - "default_value":"true", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "sum", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "square_sum", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "offset", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 5, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 6, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(bn_training_update_op_info) def _bn_training_update_tbe(): """BNTrainingUpdate TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/bn_training_update_grad.py b/mindspore/ops/_op_impl/tbe/bn_training_update_grad.py index 802ef6e91f..5e693bea42 100644 --- a/mindspore/ops/_op_impl/tbe/bn_training_update_grad.py +++ b/mindspore/ops/_op_impl/tbe/bn_training_update_grad.py @@ -14,109 +14,30 @@ # ============================================================================ """BatchNormGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +bn_training_update_grad_op_info = TBERegOp("BNTrainingUpdateGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("bn_training_update_grad.so") \ + .compute_cost(10) \ + .kernel_name("bn_training_update_grad") \ + .partial_flag(True) \ + .attr("epsilon", "optional", "float", "all") \ + .input(0, "grads", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "batch_mean", False, "required", "all") \ + .input(3, "batch_variance", False, "required", "all") \ + .output(0, "diff_scale", False, "required", "all") \ + .output(1, "diff_offset", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "BNTrainingUpdateGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "bn_training_update_grad.so", - "compute_cost": 10, - "kernel_name": "bn_training_update_grad", - "partial_flag": true, - "attr": [ - { - "name": "epsilon", - "param_type": "optional", - "type": "float", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "grads", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "batch_variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "diff_scale", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float", "float" - ], - "format": [ - "NC1HWC0","NC1HWC0" - ], - "name": "diff_offset", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(bn_training_update_grad_op_info) def _bn_training_update_grad_tbe(): """BNTrainingUpdateGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/cast.py b/mindspore/ops/_op_impl/tbe/cast.py index e443d776ae..07e14139da 100644 --- a/mindspore/ops/_op_impl/tbe/cast.py +++ b/mindspore/ops/_op_impl/tbe/cast.py @@ -14,69 +14,48 @@ # ============================================================================ """Cast op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +cast_op_info = TBERegOp("Cast") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("cast.so") \ + .compute_cost(10) \ + .kernel_name("cast") \ + .partial_flag(True) \ + .attr("dst_type", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.F16_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U8_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F32_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I32_Default) \ + .dtype_format(DataType.I8_Default, DataType.F16_Default) \ + .dtype_format(DataType.I8_Default, DataType.F32_Default) \ + .dtype_format(DataType.I8_Default, DataType.I32_Default) \ + .dtype_format(DataType.U8_Default, DataType.F16_Default) \ + .dtype_format(DataType.U8_Default, DataType.F32_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.F16_Default, DataType.U8_Default) \ + .dtype_format(DataType.F16_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Cast", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "cast.so", - "compute_cost": 10, - "kernel_name": "cast", - "partial_flag": true, - "attr": [ - { - "name": "dst_type", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", - "int32", "int32", "int32", "int32", "int32", - "int8", "int8", "int8", "uint8", "uint8", "uint8", - "bool", "bool", "bool", "bool", "float16" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float", "int32", "float16", "int32", - "float16", "float", "int8", "uint8", "bool", - "float16", "float", "int32", "float16", "float", "int32", - "float16", "float", "int32", "uint8", "uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(cast_op_info) def _cast_tbe(): """Cast TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/clip_by_norm_no_div_sum.py b/mindspore/ops/_op_impl/tbe/clip_by_norm_no_div_sum.py index 859315fb7b..92fb9a59ee 100644 --- a/mindspore/ops/_op_impl/tbe/clip_by_norm_no_div_sum.py +++ b/mindspore/ops/_op_impl/tbe/clip_by_norm_no_div_sum.py @@ -14,90 +14,28 @@ # ============================================================================ """ClipByNormNoDivSum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +clip_by_norm_no_div_sum_op_info = TBERegOp("ClipByNormNoDivSum") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("clip_by_norm_no_div_sum.so") \ + .compute_cost(10) \ + .kernel_name("clip_by_norm_no_div_sum") \ + .partial_flag(True) \ + .input(0, "input_x", False, "required", "all") \ + .input(1, "input1", False, "required", "all") \ + .input(2, "input2", False, "required", "all") \ + .input(3, "input3", False, "required", "all") \ + .output(0, "output_y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ClipByNormNoDivSum", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "clip_by_norm_no_div_sum.so", - "compute_cost": 10, - "kernel_name": "clip_by_norm_no_div_sum", - "partial_flag": true, - "attr":[ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input_x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input3", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output_y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(clip_by_norm_no_div_sum_op_info) def _clip_by_norm_no_div_sum_tbe(): """ClipByNormNoDivSum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/clip_by_value.py b/mindspore/ops/_op_impl/tbe/clip_by_value.py index 02ec0158a9..4ddc6c3c0f 100644 --- a/mindspore/ops/_op_impl/tbe/clip_by_value.py +++ b/mindspore/ops/_op_impl/tbe/clip_by_value.py @@ -14,85 +14,30 @@ # ============================================================================ """ClipByValue op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +clip_by_value_op_info = TBERegOp("ClipByValue") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("clip_by_value.so") \ + .compute_cost(10) \ + .kernel_name("clip_by_value") \ + .partial_flag(True) \ + .attr("dst_type", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "clip_value_min", False, "required", "all") \ + .input(2, "clip_value_max", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ClipByValue", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "clip_by_value.so", - "compute_cost": 10, - "kernel_name": "clip_by_value", - "partial_flag": true, - "attr":[ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "clip_value_min", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "clip_value_max", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(clip_by_value_op_info) def _clip_by_value_tbe(): """ClipByValue TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/concat.py b/mindspore/ops/_op_impl/tbe/concat.py index 3e5c577476..56807b15fc 100644 --- a/mindspore/ops/_op_impl/tbe/concat.py +++ b/mindspore/ops/_op_impl/tbe/concat.py @@ -14,141 +14,44 @@ # ============================================================================ """Concat op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +concat_op_info = TBERegOp("Concat") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("concat_d.so") \ + .compute_cost(10) \ + .kernel_name("concat_d") \ + .partial_flag(True) \ + .attr("axis", "required", "int", "all") \ + .input(0, "input_values", False, "dynamic", "all") \ + .output(0, "output_data", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.I16_5HD, DataType.I16_5HD) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.U16_5HD, DataType.U16_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U32_5HD, DataType.U32_5HD) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.I64_5HD, DataType.I64_5HD) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.U64_5HD, DataType.U64_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Concat", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "concat_d.so", - "compute_cost": 10, - "kernel_name": "concat_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", - "float16", - "float", - "float", - "int32", - "int32", - "int8", - "int8", - "int16", - "int16", - "int64", - "int64", - "uint8", - "uint8", - "uint16", - "uint16", - "uint32", - "uint32", - "uint64", - "uint64", - "bool", - "bool" - ], - "format": [ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0" - ], - "name": "input_values", - "need_compile": false, - "param_type": "dynamic", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", - "float16", - "float", - "float", - "int32", - "int32", - "int8", - "int8", - "int16", - "int16", - "int64", - "int64", - "uint8", - "uint8", - "uint16", - "uint16", - "uint32", - "uint32", - "uint64", - "uint64", - "bool", - "bool" - ], - "format": [ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "NC1HWC0" - ], - "name": "output_data", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(concat_op_info) def _concat_tbe(): """Concat TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/confusion_softmax_grad.py b/mindspore/ops/_op_impl/tbe/confusion_softmax_grad.py index cbd518d541..55d9562a44 100644 --- a/mindspore/ops/_op_impl/tbe/confusion_softmax_grad.py +++ b/mindspore/ops/_op_impl/tbe/confusion_softmax_grad.py @@ -14,65 +14,28 @@ # ============================================================================ """ConfusionSoftmaxGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +confusion_softmax_grad_op_info = TBERegOp("ConfusionSoftmaxGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("confusion_softmax_grad.so") \ + .compute_cost(10) \ + .kernel_name("confusion_softmax_grad") \ + .partial_flag(True) \ + .input(0, "grad", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ConfusionSoftmaxGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "confusion_softmax_grad.so", - "compute_cost": 10, - "kernel_name": "confusion_softmax_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "NC1HWC0", "FRACTAL_NZ", "DefaultFormat", "NC1HWC0" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "NC1HWC0", "FRACTAL_NZ", "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "NC1HWC0", "FRACTAL_NZ", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(confusion_softmax_grad_op_info) def _confusion_softmax_grad_tbe(): """ConfusionSoftmaxGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/confusion_transpose_d.py b/mindspore/ops/_op_impl/tbe/confusion_transpose_d.py index db35107b5d..e52ae01520 100644 --- a/mindspore/ops/_op_impl/tbe/confusion_transpose_d.py +++ b/mindspore/ops/_op_impl/tbe/confusion_transpose_d.py @@ -14,79 +14,44 @@ # ============================================================================ """ConfusionTransposeD op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +confusion_transpose_d_op_info = TBERegOp("ConfusionTransposeD") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("confusion_transpose_d.so") \ + .compute_cost(10) \ + .kernel_name("confusion_transpose_d") \ + .partial_flag(True) \ + .attr("perm", "required", "listInt", "all") \ + .attr("shape", "required", "listInt", "all") \ + .attr("transpose_first", "required", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_FracNZ, DataType.I8_FracNZ) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_FracNZ, DataType.U8_FracNZ) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I16_FracNZ, DataType.I16_FracNZ) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.U16_FracNZ, DataType.U16_FracNZ) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.I32_FracNZ, DataType.I32_FracNZ) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.U32_FracNZ, DataType.U32_FracNZ) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.I64_FracNZ, DataType.I64_FracNZ) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U64_FracNZ, DataType.U64_FracNZ) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ConfusionTransposeD", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "confusion_transpose_d.so", - "compute_cost": 10, - "kernel_name": "confusion_transpose_d", - "partial_flag": true, - "attr":[ - { - "name":"perm", - "param_type":"required", - "type":"listInt", - "value":"all" - }, - { - "name":"shape", - "param_type":"required", - "type":"listInt", - "value":"all" - }, - { - "name":"transpose_first", - "param_type":"required", - "type":"bool", - "value":"all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", - "uint64", "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", - "uint32", "uint64" - ], - "format": [ - "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", - "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", - "uint64", "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", - "uint32", "uint64" - ], - "format": [ - "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", - "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "FRACTAL_NZ", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(confusion_transpose_d_op_info) def _confusion_transpose_d_tbe(): """ConfusionTransposeD TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/conv2d.py b/mindspore/ops/_op_impl/tbe/conv2d.py index 52a9eac1fa..425521901d 100644 --- a/mindspore/ops/_op_impl/tbe/conv2d.py +++ b/mindspore/ops/_op_impl/tbe/conv2d.py @@ -14,114 +14,30 @@ # ============================================================================ """Conv2D op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +conv2d_op_info = TBERegOp("Conv2D") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("conv2d.so") \ + .compute_cost(10) \ + .kernel_name("conv2d") \ + .partial_flag(True) \ + .attr("stride", "required", "listInt", "all") \ + .attr("pad_list", "required", "listInt", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .attr("offset_a", "optional", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "filter", False, "required", "all") \ + .input(2, "bias", False, "optional", "all") \ + .input(3, "offset_w", False, "optional", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_FracZ, DataType.F16_Default, DataType.I8_Default, + DataType.F16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Conv2D", - "imply_type": "TBE", - "fusion_type": "CONVLUTION", - "async_flag": false, - "binfile_name": "conv2d.so", - "compute_cost": 10, - "kernel_name": "conv2d", - "partial_flag": true, - "attr": [ - { - "name": "stride", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "pad", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "dilation", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "offset_a", - "param_type": "optional", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "FracZ" - ], - "name": "filter", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16" - ], - "format": [ - "DefaultFormat" - ], - "name": "bias", - "need_compile": false, - "param_type": "optional", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "int8" - ], - "format": [ - "DefaultFormat" - ], - "name": "offset_w", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(conv2d_op_info) def _conv2d_tbe(): """Conv2D TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/conv2d_backprop_filter.py b/mindspore/ops/_op_impl/tbe/conv2d_backprop_filter.py index 2c1397c0b1..e32e99d888 100644 --- a/mindspore/ops/_op_impl/tbe/conv2d_backprop_filter.py +++ b/mindspore/ops/_op_impl/tbe/conv2d_backprop_filter.py @@ -14,89 +14,27 @@ # ============================================================================ """Conv2DBackpropFilter op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +conv2d_backprop_filter_op_info = TBERegOp("Conv2DBackpropFilter") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("conv2d_backprop_filter_d.so") \ + .compute_cost(10) \ + .kernel_name("conv2d_backprop_filter_d") \ + .partial_flag(True) \ + .attr("filter_sizes", "required", "listInt", "all") \ + .attr("stride", "required", "listInt", "all") \ + .attr("pad_mode", "required", "str", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .input(0, "out_backprop", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F32_FracZ) \ + .get_op_info() -# map to tbe kernel name conv2d_backprop_filter_d -@op_info_register("""{ - "op_name": "Conv2DBackpropFilter", - "imply_type": "TBE", - "fusion_type": "CONVLUTION", - "async_flag": false, - "binfile_name": "conv2d_backprop_filter_d.so", - "compute_cost": 10, - "kernel_name": "conv2d_backprop_filter_d", - "partial_flag": true, - "attr": [ - { - "name": "filter_sizes", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "stride", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "pad_mode", - "param_type": "required", - "type": "str", - "value": "all" - }, - { - "name": "dilation", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "out_backprop", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32" - ], - "format": [ - "FracZ" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(conv2d_backprop_filter_op_info) def _conv2d_backprop_filter_tbe(): """Conv2DBackpropFilter TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/conv2d_backprop_input.py b/mindspore/ops/_op_impl/tbe/conv2d_backprop_input.py index d61989e472..2c1dd6aea2 100644 --- a/mindspore/ops/_op_impl/tbe/conv2d_backprop_input.py +++ b/mindspore/ops/_op_impl/tbe/conv2d_backprop_input.py @@ -14,88 +14,27 @@ # ============================================================================ """Conv2DBackpropInput op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +conv2d_backprop_input_op_info = TBERegOp("Conv2DBackpropInput") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("conv2d_backprop_input_d.so") \ + .compute_cost(10) \ + .kernel_name("conv2d_backprop_input_d") \ + .partial_flag(True) \ + .attr("input_sizes", "required", "listInt", "all") \ + .attr("stride", "required", "listInt", "all") \ + .attr("pad_mode", "required", "str", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .input(0, "out_backprop", False, "required", "all") \ + .input(1, "filter", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_FracZ, DataType.F16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Conv2DBackpropInput", - "imply_type": "TBE", - "fusion_type": "CONVLUTION", - "async_flag": false, - "binfile_name": "conv2d_backprop_input_d.so", - "compute_cost": 10, - "kernel_name": "conv2d_backprop_input_d", - "partial_flag": true, - "attr": [ - { - "name": "input_sizes", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "stride", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "pad_mode", - "param_type": "required", - "type": "str", - "value": "all" - }, - { - "name": "dilation", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "out_backprop", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "FracZ" - ], - "name": "filter", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(conv2d_backprop_input_op_info) def _conv2d_backprop_input_tbe(): """Conv2DBackpropInput TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/depthwise_conv2d.py b/mindspore/ops/_op_impl/tbe/depthwise_conv2d.py new file mode 100644 index 0000000000..fdafcd3fa4 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/depthwise_conv2d.py @@ -0,0 +1,44 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""DepthwiseConv2D op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +depthwise_conv2d_op_info = TBERegOp("DepthwiseConv2dNative") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("depthwise_conv2d.so") \ + .compute_cost(10) \ + .kernel_name("depthwise_conv2d") \ + .partial_flag(True) \ + .attr("stride", "required", "listInt", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .attr("pads", "required", "listInt", "all") \ + .attr("data_format", "required", "str", "all") \ + .attr("offset_a", "optional", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "filter", False, "required", "all") \ + .input(2, "bias", False, "optional", "all") \ + .input(3, "offset_w", False, "optional", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_C1HWNCoC0, DataType.F16_Default, DataType.F16_Default, + DataType.F16_5HD) \ + .get_op_info() + + +@op_info_register(depthwise_conv2d_op_info) +def _depthwise_conv2d_tbe(): + """DepthwiseConv2D TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_filter.py b/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_filter.py new file mode 100644 index 0000000000..c19a311009 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_filter.py @@ -0,0 +1,41 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""DepthwiseConv2DBackpropFilter op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +depthwise_conv2d_backprop_filter_op_info = TBERegOp("DepthwiseConv2dNativeBackpropFilter") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("depthwise_conv2d_backprop_filter_d.so") \ + .compute_cost(10) \ + .kernel_name("depthwise_conv2d_backprop_filter_d") \ + .partial_flag(True) \ + .attr("filter_size", "required", "listInt", "all") \ + .attr("stride", "required", "listInt", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .attr("pads", "required", "str", "all") \ + .attr("data_format", "required", "str", "all") \ + .input(0, "input", False, "required", "all") \ + .input(1, "out_backprop", False, "required", "all") \ + .output(0, "filter_grad", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F32_C1HWNCoC0) \ + .get_op_info() + + +@op_info_register(depthwise_conv2d_backprop_filter_op_info) +def _depthwise_conv2d_backprop_filter_tbe(): + """DepthwiseConv2DBackpropFilter TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_input.py b/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_input.py new file mode 100644 index 0000000000..9e671f18e2 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/depthwise_conv2d_backprop_input.py @@ -0,0 +1,41 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""DepthwiseConv2DBackpropInput op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +depthwise_conv2d_backprop_input_op_info = TBERegOp("DepthwiseConv2dNativeBackpropInput") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("depthwise_conv2d_backprop_input_d.so") \ + .compute_cost(10) \ + .kernel_name("depthwise_conv2d_backprop_input_d") \ + .partial_flag(True) \ + .attr("input_size", "required", "listInt", "all") \ + .attr("stride", "required", "listInt", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .attr("pads", "required", "str", "all") \ + .attr("data_format", "required", "str", "all") \ + .input(0, "filter", False, "required", "all") \ + .input(1, "out_backprop", False, "required", "all") \ + .output(0, "input_grad", False, "required", "all") \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_5HD, DataType.F16_5HD) \ + .get_op_info() + + +@op_info_register(depthwise_conv2d_backprop_input_op_info) +def _depthwise_conv2d_backprop_input_tbe(): + """DepthwiseConv2DBackpropInput TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/div.py b/mindspore/ops/_op_impl/tbe/div.py index c71d6f38c4..2a83745399 100644 --- a/mindspore/ops/_op_impl/tbe/div.py +++ b/mindspore/ops/_op_impl/tbe/div.py @@ -14,71 +14,32 @@ # ============================================================================ """Div op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +div_op_info = TBERegOp("Div") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("div.so") \ + .compute_cost(10) \ + .kernel_name("div") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Div", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "div.so", - "compute_cost": 10, - "kernel_name": "div", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(div_op_info) def _div_tbe(): """Div TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/dropout_do_mask.py b/mindspore/ops/_op_impl/tbe/dropout_do_mask.py index 5f4557a4f5..2bef489b96 100644 --- a/mindspore/ops/_op_impl/tbe/dropout_do_mask.py +++ b/mindspore/ops/_op_impl/tbe/dropout_do_mask.py @@ -14,76 +14,25 @@ # ============================================================================ """DropoutdoMask op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +drop_out_do_mask_op_info = TBERegOp("DropoutDoMask") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("drop_out_do_mask.so") \ + .compute_cost(10) \ + .kernel_name("drop_out_do_mask") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .input(1, "mask", False, "required", "all") \ + .input(2, "keep_prob", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.U8_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.U8_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "DropoutDoMask", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "drop_out_do_mask.so", - "compute_cost": 10, - "kernel_name": "drop_out_do_mask", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "uint8","uint8","uint8","uint8","uint8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "mask", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "keep_prob", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(drop_out_do_mask_op_info) def _dropout_do_mask_tbe(): """DropoutdoMask TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/equal.py b/mindspore/ops/_op_impl/tbe/equal.py index db2e152c27..594fb51cb5 100644 --- a/mindspore/ops/_op_impl/tbe/equal.py +++ b/mindspore/ops/_op_impl/tbe/equal.py @@ -14,66 +14,32 @@ # ============================================================================ """Equal op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +equal_op_info = TBERegOp("Equal") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("equal.so") \ + .compute_cost(10) \ + .kernel_name("equal") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Equal", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "equal.so", - "compute_cost": 10, - "kernel_name": "equal", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool","bool","bool","bool","bool","bool","bool","bool","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required" - } - ] -}""") +@op_info_register(equal_op_info) def _equal_tbe(): """Equal TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/exp.py b/mindspore/ops/_op_impl/tbe/exp.py index e5f34e67b0..545845a3b0 100644 --- a/mindspore/ops/_op_impl/tbe/exp.py +++ b/mindspore/ops/_op_impl/tbe/exp.py @@ -14,52 +14,25 @@ # ============================================================================ """Exp op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +exp_op_info = TBERegOp("Exp") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("exp.so") \ + .compute_cost(10) \ + .kernel_name("exp") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Exp", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "exp.so", - "compute_cost": 10, - "kernel_name": "exp", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(exp_op_info) def _exp_tbe(): """Exp TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/expand_dims.py b/mindspore/ops/_op_impl/tbe/expand_dims.py index 462a676e4f..8b0755a521 100644 --- a/mindspore/ops/_op_impl/tbe/expand_dims.py +++ b/mindspore/ops/_op_impl/tbe/expand_dims.py @@ -14,57 +14,25 @@ # ============================================================================ """ExpandDims op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +expand_dims_op_info = TBERegOp("ExpandDims") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("expand_dims.so") \ + .compute_cost(10) \ + .kernel_name("expand_dims") \ + .partial_flag(True) \ + .attr("axis", "required", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ExpandDims", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "expand_dims.so", - "compute_cost": 10, - "kernel_name": "expand_dims", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(expand_dims_op_info) def _expand_dims_tbe(): """ExpandDims TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/floor_div.py b/mindspore/ops/_op_impl/tbe/floor_div.py index fdc49e3805..74fd594901 100644 --- a/mindspore/ops/_op_impl/tbe/floor_div.py +++ b/mindspore/ops/_op_impl/tbe/floor_div.py @@ -14,64 +14,27 @@ # ============================================================================ """FloorDiv op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +floordiv_op_info = TBERegOp("FloorDiv") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("floordiv.so") \ + .compute_cost(10) \ + .kernel_name("floordiv") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "FloorDiv", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "floordiv.so", - "compute_cost": 10, - "kernel_name": "floordiv", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(floordiv_op_info) def _floor_div_tbe(): """FloorDiv TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/fused_mul_add.py b/mindspore/ops/_op_impl/tbe/fused_mul_add.py index 96e18a89c7..ad3c601e5d 100644 --- a/mindspore/ops/_op_impl/tbe/fused_mul_add.py +++ b/mindspore/ops/_op_impl/tbe/fused_mul_add.py @@ -14,93 +14,38 @@ # ============================================================================ """FusedMulAdd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +fused_mul_add_op_info = TBERegOp("FusedMulAdd") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("fused_mul_add.so") \ + .compute_cost(10) \ + .kernel_name("fused_mul_add") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "x3", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_FracZ, DataType.I32_FracZ, DataType.I32_FracZ, DataType.I32_FracZ) \ + .dtype_format(DataType.I32_FracNZ, DataType.I32_FracNZ, DataType.I32_FracNZ, DataType.I32_FracNZ) \ + .dtype_format(DataType.I32_C1HWNCoC0, DataType.I32_C1HWNCoC0, DataType.I32_C1HWNCoC0, DataType.I32_C1HWNCoC0) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() -@op_info_register("""{ - "op_name": "FusedMulAdd", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "fused_mul_add.so", - "compute_cost": 10, - "kernel_name": "fused_mul_add", - "partial_flag": true, - "attr": [ - - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x3", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(fused_mul_add_op_info) def _fused_mul_add_tbe(): """FusedMulAdd TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/fused_mul_add_n.py b/mindspore/ops/_op_impl/tbe/fused_mul_add_n.py index a4046a253b..9996466f70 100644 --- a/mindspore/ops/_op_impl/tbe/fused_mul_add_n.py +++ b/mindspore/ops/_op_impl/tbe/fused_mul_add_n.py @@ -14,86 +14,31 @@ # ============================================================================ """FusedMulAddN op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +fused_mul_add_n_op_info = TBERegOp("FusedMulAddN") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("fused_mul_add_n.so") \ + .compute_cost(10) \ + .kernel_name("fused_mul_add_n") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "x3", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_Default, DataType.F16_5HD) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_Default, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_Default, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_Default, DataType.F32_5HD) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_Default, DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_Default, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "FusedMulAddN", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "fused_mul_add_n.so", - "compute_cost": 10, - "kernel_name": "fused_mul_add_n", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x3", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(fused_mul_add_n_op_info) def _fused_mul_add_n_tbe(): """FusedMulAddN TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/fused_mul_apply_momentum.py b/mindspore/ops/_op_impl/tbe/fused_mul_apply_momentum.py index e303ee042f..a8f84427d6 100644 --- a/mindspore/ops/_op_impl/tbe/fused_mul_apply_momentum.py +++ b/mindspore/ops/_op_impl/tbe/fused_mul_apply_momentum.py @@ -14,137 +14,43 @@ # ============================================================================ """FusedMulApplyMomentum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +fused_mul_apply_momentum_op_info = TBERegOp("FusedMulApplyMomentum") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("fused_mul_apply_momentum.so") \ + .compute_cost(10) \ + .kernel_name("fused_mul_apply_momentum") \ + .partial_flag(True) \ + .attr("use_nesterov", "optional", "bool", "true,false", "false") \ + .input(0, "var", False, "required", "all") \ + .input(1, "accum", False, "required", "all") \ + .input(2, "lr", False, "required", "all") \ + .input(3, "x1", False, "required", "all") \ + .input(4, "momentum", False, "required", "all") \ + .input(5, "x2", False, "required", "all") \ + .output(0, "var", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_Default, DataType.F16_5HD, + DataType.F16_Default, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_Default, DataType.F16_C1HWNCoC0, + DataType.F16_Default, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_Default, DataType.F16_FracZ, + DataType.F16_Default, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_Default, DataType.F32_5HD, + DataType.F32_Default, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_Default, DataType.F32_C1HWNCoC0, + DataType.F32_Default, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_Default, DataType.F32_FracZ, + DataType.F32_Default, DataType.F32_FracZ, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "FusedMulApplyMomentum", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "fused_mul_apply_momentum.so", - "compute_cost": 10, - "kernel_name": "fused_mul_apply_momentum", - "partial_flag": true, - "attr": [ - { - "name": "use_nesterov", - "param_type": "optional", - "type": "bool", - "value": "true,false", - "default_value":"false" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "accum", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "lr", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "momentum", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 5, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16", - "float","float","float","float" - ], - "format": [ - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ", - "NC1HWC0","C1HWNCoC0","DefaultFormat","FracZ" - ], - "name": "var", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(fused_mul_apply_momentum_op_info) def _fused_mul_apply_momentum_tbe(): """FusedMulApplyMomentum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/gather_v2.py b/mindspore/ops/_op_impl/tbe/gather_v2.py index b0e14e99c0..72ba17d942 100644 --- a/mindspore/ops/_op_impl/tbe/gather_v2.py +++ b/mindspore/ops/_op_impl/tbe/gather_v2.py @@ -14,94 +14,53 @@ # ============================================================================ """AddN op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +gather_v2_op_info = TBERegOp("GatherV2") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("gather_v2_d.so") \ + .compute_cost(10) \ + .kernel_name("gather_v2_d") \ + .partial_flag(True) \ + .attr("axis", "optional", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "indices", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I32_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.I8_5HD, DataType.I64_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.I8_FracZ, DataType.I32_FracZ, DataType.I8_FracZ) \ + .dtype_format(DataType.I8_FracZ, DataType.I64_FracZ, DataType.I8_FracZ) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.I32_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.U8_5HD, DataType.I64_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.U8_FracZ, DataType.I32_FracZ, DataType.U8_FracZ) \ + .dtype_format(DataType.U8_FracZ, DataType.I64_FracZ, DataType.U8_FracZ) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_5HD, DataType.I64_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_FracZ, DataType.I32_FracZ, DataType.I32_FracZ) \ + .dtype_format(DataType.I32_FracZ, DataType.I64_FracZ, DataType.I32_FracZ) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.I32_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.I64_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.I32_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracZ, DataType.I64_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.I32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.I64_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.I32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracZ, DataType.I64_FracZ, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "GatherV2", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "gather_v2_d.so", - "compute_cost": 10, - "kernel_name": "gather_v2_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float16","float16", - "float","float","float","float","float","float", - "int32","int32","int32", "int32","int32","int32", - "uint8","uint8","uint8","uint8","uint8","uint8", - "int8","int8", "int8","int8","int8", "int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "int32","int32","int32","int64","int64","int64", - "int32","int32","int32","int64","int64","int64", - "int32","int32","int32","int64","int64","int64", - "int32","int32","int32","int64","int64","int64", - "int32","int32","int32","int64","int64","int64" - ], - "format": [ - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ" - ], - "name": "indices", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float16","float16","float16", - "float","float","float","float","float","float", - "int32","int32","int32", "int32","int32","int32", - "uint8","uint8","uint8","uint8","uint8","uint8", - "int8","int8", "int8","int8","int8", "int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ", - "DefaultFormat","NC1HWC0","FracZ","DefaultFormat","NC1HWC0","FracZ" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(gather_v2_op_info) def _gather_v2_tbe(): """GatherV2 TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/gelu.py b/mindspore/ops/_op_impl/tbe/gelu.py index 171d97c043..9d4b2ed7f3 100644 --- a/mindspore/ops/_op_impl/tbe/gelu.py +++ b/mindspore/ops/_op_impl/tbe/gelu.py @@ -14,51 +14,29 @@ # ============================================================================ """Gelu op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +gelu_op_info = TBERegOp("Gelu") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("gelu.so") \ + .compute_cost(10) \ + .kernel_name("gelu") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Gelu", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "gelu.so", - "compute_cost": 10, - "kernel_name": "gelu", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","float","float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "FRACTAL_NZ","FRACTAL_NZ","FracZ","FracZ","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","float","float16","float16","float16","float16","float","float","float","float" - ], - "format": [ - "FRACTAL_NZ","FRACTAL_NZ","FracZ","FracZ","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(gelu_op_info) def _gelu_tbe(): """Gelu TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/gelu_grad.py b/mindspore/ops/_op_impl/tbe/gelu_grad.py index 9b358262e0..ce62e55071 100644 --- a/mindspore/ops/_op_impl/tbe/gelu_grad.py +++ b/mindspore/ops/_op_impl/tbe/gelu_grad.py @@ -14,77 +14,29 @@ # ============================================================================ """GeluGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +gelu_grad_op_info = TBERegOp("GeluGrad") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("gelu_grad.so") \ + .compute_cost(10) \ + .kernel_name("gelu_grad") \ + .partial_flag(True) \ + .input(0, "dy", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "y", False, "required", "all") \ + .output(0, "z", True, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "GeluGrad", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "gelu_grad.so", - "compute_cost": 10, - "kernel_name": "gelu_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "z", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(gelu_grad_op_info) def _gelu_grad_tbe(): """GeluGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/greater.py b/mindspore/ops/_op_impl/tbe/greater.py index 09ee0e31af..90c680ab04 100644 --- a/mindspore/ops/_op_impl/tbe/greater.py +++ b/mindspore/ops/_op_impl/tbe/greater.py @@ -14,68 +14,32 @@ # ============================================================================ """Greater op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +greater_op_info = TBERegOp("Greater") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("greater.so") \ + .compute_cost(10) \ + .kernel_name("greater") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Greater", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "greater.so", - "compute_cost": 10, - "kernel_name": "greater", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool","bool","bool","bool","bool","bool","bool","bool","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(greater_op_info) def _greater_tbe(): """Greater TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/lamb_next_mv.py b/mindspore/ops/_op_impl/tbe/lamb_next_mv.py index b432b47c3d..2f2200a1f4 100644 --- a/mindspore/ops/_op_impl/tbe/lamb_next_mv.py +++ b/mindspore/ops/_op_impl/tbe/lamb_next_mv.py @@ -14,279 +14,46 @@ # ============================================================================ """LambNextMV op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +lamb_next_mv_op_info = TBERegOp("LambNextMV") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("lamb_next_m_v.so") \ + .compute_cost(10) \ + .kernel_name("lamb_next_m_v") \ + .partial_flag(True) \ + .input(0, "input1", False, "required", "all") \ + .input(1, "input2", False, "required", "all") \ + .input(2, "input3", False, "required", "all") \ + .input(3, "input4", False, "required", "all") \ + .input(4, "input5", False, "required", "all") \ + .input(5, "input6", False, "required", "all") \ + .input(6, "input7", False, "required", "all") \ + .input(7, "input8", False, "required", "all") \ + .input(8, "input9", False, "required", "all") \ + .input(9, "inputx0", False, "required", "all") \ + .input(10, "inputx1", False, "required", "all") \ + .input(11, "inputx2", False, "required", "all") \ + .input(12, "inputx3", False, "required", "all") \ + .output(0, "output1", False, "required", "all") \ + .output(1, "output2", False, "required", "all") \ + .output(2, "output3", False, "required", "all") \ + .output(3, "output4", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name":"LambNextMV", - "imply_type":"TBE", - "fusion_type":"ELEMWISE", - "async_flag":false, - "binfile_name":"lamb_next_m_v.so", - "compute_cost":10, - "kernel_name":"lamb_next_m_v", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input4", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":4, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input5", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":5, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input6", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":6, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input7", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":7, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input8", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":8, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input9", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":9, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx0", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":10, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":11, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":12, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx3", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output4", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(lamb_next_mv_op_info) def _lamb_next_mv_tbe(): """LambNextMV TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/lamb_next_mv_with_decay_v1.py b/mindspore/ops/_op_impl/tbe/lamb_next_mv_with_decay_v1.py index bf5b6cd0e7..aa135e5afe 100644 --- a/mindspore/ops/_op_impl/tbe/lamb_next_mv_with_decay_v1.py +++ b/mindspore/ops/_op_impl/tbe/lamb_next_mv_with_decay_v1.py @@ -14,279 +14,46 @@ # ============================================================================ """LambNextMVWithDecayV1 op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +lamb_next_m_v_with_decay_v1_op_info = TBERegOp("LambNextMVWithDecayV1") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("lamb_next_m_v_with_decay_v1.so") \ + .compute_cost(10) \ + .kernel_name("lamb_next_m_v_with_decay_v1") \ + .partial_flag(True) \ + .input(0, "input1", False, "required", "all") \ + .input(1, "input2", False, "required", "all") \ + .input(2, "input3", False, "required", "all") \ + .input(3, "input4", False, "required", "all") \ + .input(4, "input5", False, "required", "all") \ + .input(5, "input6", False, "required", "all") \ + .input(6, "input7", False, "required", "all") \ + .input(7, "input8", False, "required", "all") \ + .input(8, "input9", False, "required", "all") \ + .input(9, "inputx0", False, "required", "all") \ + .input(10, "inputx1", False, "required", "all") \ + .input(11, "inputx2", False, "required", "all") \ + .input(12, "inputx3", False, "required", "all") \ + .output(0, "output1", False, "required", "all") \ + .output(1, "output2", False, "required", "all") \ + .output(2, "output3", False, "required", "all") \ + .output(3, "output4", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name":"LambNextMVWithDecayV1", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"lamb_next_m_v_with_decay_v1.so", - "compute_cost":10, - "kernel_name":"lamb_next_m_v_with_decay_v1", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input4", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":4, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input5", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":5, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input6", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":6, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input7", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":7, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input8", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":8, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input9", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":9, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx0", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":10, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":11, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":12, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"inputx3", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output4", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(lamb_next_m_v_with_decay_v1_op_info) def _lamb_next_mv_with_decay_v1_tbe(): """LambNextMVWithDecayV1 TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/lamb_update_with_lr.py b/mindspore/ops/_op_impl/tbe/lamb_update_with_lr.py index a5062e74e2..b34ac57df2 100644 --- a/mindspore/ops/_op_impl/tbe/lamb_update_with_lr.py +++ b/mindspore/ops/_op_impl/tbe/lamb_update_with_lr.py @@ -14,174 +14,35 @@ # ============================================================================ """LambUpdateWithLr op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +lamb_update_with_lr_op_info = TBERegOp("LambUpdateWithLR") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("lamb_update_with_lr.so") \ + .compute_cost(10) \ + .kernel_name("lamb_update_with_lr") \ + .partial_flag(True) \ + .input(0, "input1", False, "required", "all") \ + .input(1, "input2", False, "required", "all") \ + .input(2, "input3", False, "required", "all") \ + .input(3, "input4", False, "required", "all") \ + .input(4, "input5", False, "required", "all") \ + .input(5, "input6", False, "required", "all") \ + .input(6, "input7", False, "required", "all") \ + .input(7, "input8", False, "required", "all") \ + .input(8, "input9", False, "required", "all") \ + .output(0, "output_y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name":"LambUpdateWithLR", - "imply_type":"TBE", - "fusion_type":"ELEMWISE", - "async_flag":false, - "binfile_name":"lamb_update_with_lr.so", - "compute_cost":10, - "kernel_name":"lamb_update_with_lr", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input4", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":4, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input5", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":5, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input6", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":6, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input7", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":7, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input8", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":8, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"input9", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"output_y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(lamb_update_with_lr_op_info) def _lamb_update_with_lr_tbe(): """LambUpdateWithLr TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/lamb_update_with_lr_v2.py b/mindspore/ops/_op_impl/tbe/lamb_update_with_lr_v2.py index 0900775b07..0902d68de9 100644 --- a/mindspore/ops/_op_impl/tbe/lamb_update_with_lr_v2.py +++ b/mindspore/ops/_op_impl/tbe/lamb_update_with_lr_v2.py @@ -14,144 +14,31 @@ # ============================================================================ """LambUpdateWithLrV2 op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +lamb_update_with_lr_v2_op_info = TBERegOp("LambUpdateWithLrV2") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("lamb_update_with_lr_v2.so") \ + .compute_cost(10) \ + .kernel_name("lamb_update_with_lr_v2") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "x3", False, "required", "all") \ + .input(3, "x4", False, "required", "all") \ + .input(4, "x5", False, "required", "all") \ + .input(5, "greater_y", False, "required", "all") \ + .input(6, "select_e", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name":"LambUpdateWithLrV2", - "imply_type":"TBE", - "fusion_type":"ELEMWISE", - "async_flag":false, - "binfile_name":"lamb_update_with_lr_v2.so", - "compute_cost":10, - "kernel_name":"lamb_update_with_lr_v2", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"x1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"x2", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"x3", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":3, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"x4", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":4, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"x5", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":5, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"greater_y", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":6, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"select_e", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float32" - ], - "format":[ - "DefaultFormat", - "DefaultFormat" - ], - "name":"y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(lamb_update_with_lr_v2_op_info) def _lamb_update_with_lr_v2_tbe(): """LambUpdateWithLrV2 TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/layer_norm.py b/mindspore/ops/_op_impl/tbe/layer_norm.py index 5fd4a6387b..bc71fa87d3 100644 --- a/mindspore/ops/_op_impl/tbe/layer_norm.py +++ b/mindspore/ops/_op_impl/tbe/layer_norm.py @@ -14,111 +14,39 @@ # ============================================================================ """LayerNorm op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +layer_norm_op_info = TBERegOp("LayerNorm") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("layer_norm.so") \ + .compute_cost(10) \ + .kernel_name("layer_norm") \ + .partial_flag(True) \ + .attr("begin_norm_axis", "required", "int", "all") \ + .attr("begin_params_axis", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "gamma", False, "required", "all") \ + .input(2, "beta", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .output(1, "mean", False, "required", "all") \ + .output(2, "variance", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_Default, DataType.F16_Default, DataType.F16_FracNZ, + DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_Default, DataType.F32_Default, DataType.F32_FracNZ, + DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LayerNorm", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "layer_norm.so", - "compute_cost": 10, - "kernel_name": "layer_norm", - "partial_flag": true, - "attr": [ - { - "name": "begin_norm_axis", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "begin_params_axis", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "gamma", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "beta", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "mean", - "param_type": "required" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - - ], - "name": "variance", - "param_type": "required" - } - ] -}""") +@op_info_register(layer_norm_op_info) def _layer_norm_tbe(): """LayerNorm TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/layer_norm_beta_gamma_backprop.py b/mindspore/ops/_op_impl/tbe/layer_norm_beta_gamma_backprop.py index cdf0dad744..ef254465bc 100644 --- a/mindspore/ops/_op_impl/tbe/layer_norm_beta_gamma_backprop.py +++ b/mindspore/ops/_op_impl/tbe/layer_norm_beta_gamma_backprop.py @@ -14,105 +14,38 @@ # ============================================================================ """LayerNormBetaGammaBackprop op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +layer_norm_beta_gamma_backprop_op_info = TBERegOp("LayerNormBetaGammaBackprop") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("layer_norm_beta_gamma_backprop.so") \ + .compute_cost(10) \ + .kernel_name("layer_norm_beta_gamma_backprop") \ + .partial_flag(True) \ + .attr("shape_gamma", "required", "listInt", "all") \ + .input(0, "dy", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "variance", False, "required", "all") \ + .input(3, "mean", False, "required", "all") \ + .output(0, "pd_gamma", False, "required", "all") \ + .output(1, "pd_beta", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_Default, DataType.F16_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LayerNormBetaGammaBackprop", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "layer_norm_beta_gamma_backprop.so", - "compute_cost": 10, - "kernel_name": "layer_norm_beta_gamma_backprop", - "partial_flag": true, - "attr": [ - { - "name": "shape_gamma", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "pd_gamma", - "param_type": "required" - }, - { - "index": 1, - "dtype": [ - "float","float","float","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "pd_beta", - "param_type": "required" - } - ] -}""") + +@op_info_register(layer_norm_beta_gamma_backprop_op_info) def _layer_norm_beta_gamma_backprop_tbe(): """LayerNormBetaGammaBackprop TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/layer_norm_grad.py b/mindspore/ops/_op_impl/tbe/layer_norm_grad.py index 6ba4656615..9540f2e265 100644 --- a/mindspore/ops/_op_impl/tbe/layer_norm_grad.py +++ b/mindspore/ops/_op_impl/tbe/layer_norm_grad.py @@ -14,124 +14,35 @@ # ============================================================================ """LayerNormGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +layer_norm_grad_op_info = TBERegOp("LayerNormGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("layer_norm_grad.so") \ + .compute_cost(10) \ + .kernel_name("layer_norm_grad") \ + .partial_flag(True) \ + .input(0, "dy", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "variance", False, "required", "all") \ + .input(3, "mean", False, "required", "all") \ + .input(4, "gamma", False, "required", "all") \ + .output(0, "pd_x", False, "required", "all") \ + .output(1, "pd_gamma", False, "required", "all") \ + .output(2, "pd_beta", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LayerNormGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "layer_norm_grad.so", - "compute_cost": 10, - "kernel_name": "layer_norm_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "gamma", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "pd_x", - "param_type": "required" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "pd_gamma", - "param_type": "required" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float","float" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "pd_beta", - "param_type": "required" - } - ] -}""") +@op_info_register(layer_norm_grad_op_info) def _layer_norm_grad_tbe(): """LayerNormGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/layer_norm_x_backprop.py b/mindspore/ops/_op_impl/tbe/layer_norm_x_backprop.py index 0557fdebc2..bbab66816d 100644 --- a/mindspore/ops/_op_impl/tbe/layer_norm_x_backprop.py +++ b/mindspore/ops/_op_impl/tbe/layer_norm_x_backprop.py @@ -14,102 +14,37 @@ # ============================================================================ """LayerNormXBackprop op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +layer_norm_x_backprop_op_info = TBERegOp("LayerNormXBackprop") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("layer_norm_x_backprop.so") \ + .compute_cost(10) \ + .kernel_name("layer_norm_x_backprop") \ + .partial_flag(True) \ + .input(0, "dy", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .input(2, "variance", False, "required", "all") \ + .input(3, "mean", False, "required", "all") \ + .input(4, "gamma", False, "required", "all") \ + .output(0, "pd_x", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LayerNormXBackprop", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "layer_norm_x_backprop.so", - "compute_cost": 10, - "kernel_name": "layer_norm_x_backprop", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "variance", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 3, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "mean", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 4, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "DefaultFormat","DefaultFormat","NC1HWC0","DefaultFormat","DefaultFormat","NC1HWC0" - ], - "name": "gamma", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float16","float","float","float" - ], - "format": [ - "FRACTAL_NZ","DefaultFormat","NC1HWC0","FRACTAL_NZ","DefaultFormat","NC1HWC0" - ], - "name": "pd_x", - "param_type": "required" - } - ] -}""") +@op_info_register(layer_norm_x_backprop_op_info) def _layer_norm_x_backprop_tbe(): """LayerNormXBackprop TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/less.py b/mindspore/ops/_op_impl/tbe/less.py index 6e48d60341..947c40b949 100644 --- a/mindspore/ops/_op_impl/tbe/less.py +++ b/mindspore/ops/_op_impl/tbe/less.py @@ -14,67 +14,32 @@ # ============================================================================ """Less op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +less_op_info = TBERegOp("Less") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("less.so") \ + .compute_cost(10) \ + .kernel_name("less") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Less", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "less.so", - "compute_cost": 10, - "kernel_name": "less", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool","bool","bool","bool","bool","bool","bool","bool","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(less_op_info) def _less_tbe(): """Less TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/less_equal.py b/mindspore/ops/_op_impl/tbe/less_equal.py index 556389fa0e..14cf7c8906 100644 --- a/mindspore/ops/_op_impl/tbe/less_equal.py +++ b/mindspore/ops/_op_impl/tbe/less_equal.py @@ -14,67 +14,34 @@ # ============================================================================ """LessEqual op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +less_equal_op_info = TBERegOp("LessEqual") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("less_equal.so") \ + .compute_cost(10) \ + .kernel_name("less_equal") \ + .partial_flag(True) \ + .attr("begin_norm_axis", "required", "int", "all") \ + .attr("begin_params_axis", "required", "int", "all") \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LessEqual", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "less_equal.so", - "compute_cost": 10, - "kernel_name": "less_equal", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool","bool","bool","bool","bool","bool","bool","bool","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat", - "NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(less_equal_op_info) def _less_equal_tbe(): """LessEqual TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/log.py b/mindspore/ops/_op_impl/tbe/log.py index 72a55757a2..b7da647248 100644 --- a/mindspore/ops/_op_impl/tbe/log.py +++ b/mindspore/ops/_op_impl/tbe/log.py @@ -14,52 +14,25 @@ # ============================================================================ """Log op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +log_op_info = TBERegOp("Log") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("log.so") \ + .compute_cost(10) \ + .kernel_name("log") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Log", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "log.so", - "compute_cost": 10, - "kernel_name": "log", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(log_op_info) def _log_tbe(): """Log TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/logical_and.py b/mindspore/ops/_op_impl/tbe/logical_and.py index da4862450f..925a4e82d8 100644 --- a/mindspore/ops/_op_impl/tbe/logical_and.py +++ b/mindspore/ops/_op_impl/tbe/logical_and.py @@ -14,65 +14,26 @@ # ============================================================================ """LogicalAnd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +logical_and_op_info = TBERegOp("LogicalAnd") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("logical_and.so") \ + .compute_cost(10) \ + .kernel_name("logical_and") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_FracZ, DataType.BOOL_FracZ, DataType.BOOL_FracZ) \ + .dtype_format(DataType.BOOL_C1HWNCoC0, DataType.BOOL_C1HWNCoC0, DataType.BOOL_C1HWNCoC0) \ + .dtype_format(DataType.BOOL_5HD, DataType.BOOL_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LogicalAnd", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "logical_and.so", - "compute_cost": 10, - "kernel_name": "logical_and", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(logical_and_op_info) def _logical_and_tbe(): """LogicalAnd TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/logical_not.py b/mindspore/ops/_op_impl/tbe/logical_not.py index 4fe8094ffb..3d40441156 100644 --- a/mindspore/ops/_op_impl/tbe/logical_not.py +++ b/mindspore/ops/_op_impl/tbe/logical_not.py @@ -14,52 +14,25 @@ # ============================================================================ """LogicalNot op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +logical_not_op_info = TBERegOp("LogicalNot") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("logical_not.so") \ + .compute_cost(10) \ + .kernel_name("logical_not") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_FracZ, DataType.BOOL_FracZ) \ + .dtype_format(DataType.BOOL_C1HWNCoC0, DataType.BOOL_C1HWNCoC0) \ + .dtype_format(DataType.BOOL_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LogicalNot", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "logical_not.so", - "compute_cost": 10, - "kernel_name": "logical_not", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(logical_not_op_info) def _logical_not_tbe(): """LogicalNot TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/logical_or.py b/mindspore/ops/_op_impl/tbe/logical_or.py index 0f21bb61b0..bf8d82c656 100644 --- a/mindspore/ops/_op_impl/tbe/logical_or.py +++ b/mindspore/ops/_op_impl/tbe/logical_or.py @@ -14,65 +14,26 @@ # ============================================================================ """LogicalOr op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +logical_or_op_info = TBERegOp("LogicalOr") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("logical_or.so") \ + .compute_cost(10) \ + .kernel_name("logical_or") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_FracZ, DataType.BOOL_FracZ, DataType.BOOL_FracZ) \ + .dtype_format(DataType.BOOL_C1HWNCoC0, DataType.BOOL_C1HWNCoC0, DataType.BOOL_C1HWNCoC0) \ + .dtype_format(DataType.BOOL_5HD, DataType.BOOL_5HD, DataType.BOOL_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LogicalOr", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "logical_or.so", - "compute_cost": 10, - "kernel_name": "logical_or", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(logical_or_op_info) def _logical_or_tbe(): """LogicalOr TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/logsoftmax.py b/mindspore/ops/_op_impl/tbe/logsoftmax.py index 03e8657919..9bf0baf3f2 100644 --- a/mindspore/ops/_op_impl/tbe/logsoftmax.py +++ b/mindspore/ops/_op_impl/tbe/logsoftmax.py @@ -14,57 +14,24 @@ # ============================================================================ """LogSoftmax op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +log_softmax_op_info = TBERegOp("LogSoftmax") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("log_softmax.so") \ + .compute_cost(10) \ + .kernel_name("log_softmax") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .input(0, "logits", False, "required", "all") \ + .output(0, "logsoftmax", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LogSoftmax", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "log_softmax.so", - "compute_cost": 10, - "kernel_name": "log_softmax", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "logits", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "logsoftmax", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(log_softmax_op_info) def _logsoftmax_tbe(): """LogSoftMaxGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/logsoftmax_grad.py b/mindspore/ops/_op_impl/tbe/logsoftmax_grad.py index f6858e9530..9223b821d5 100644 --- a/mindspore/ops/_op_impl/tbe/logsoftmax_grad.py +++ b/mindspore/ops/_op_impl/tbe/logsoftmax_grad.py @@ -14,70 +14,25 @@ # ============================================================================ """LogSoftmaxGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +log_softmax_grad_op_info = TBERegOp("LogSoftmaxGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("log_softmax_grad.so") \ + .compute_cost(10) \ + .kernel_name("log_softmax_grad") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "grad", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "LogSoftmaxGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "log_softmax_grad.so", - "compute_cost": 10, - "kernel_name": "log_softmax_grad", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(log_softmax_grad_op_info) def _logsoftmax_grad_tbe(): """LogSoftMaxGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/matmul.py b/mindspore/ops/_op_impl/tbe/matmul.py index d18d2cde48..c29378f721 100644 --- a/mindspore/ops/_op_impl/tbe/matmul.py +++ b/mindspore/ops/_op_impl/tbe/matmul.py @@ -14,89 +14,29 @@ # ============================================================================ """MatMul op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +matmul_op_info = TBERegOp("MatMul") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("matmul.so") \ + .compute_cost(10) \ + .kernel_name("matmul") \ + .partial_flag(True) \ + .attr("transpose_a", "required", "bool", "all") \ + .attr("transpose_b", "required", "bool", "all") \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "x3", False, "optional", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_Default, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F32_Default, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "MatMul", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "matmul.so", - "compute_cost": 10, - "kernel_name": "matmul", - "partial_flag": true, - "attr": [ - { - "name": "transpose_a", - "param_type": "required", - "type": "bool", - "value": "all" - }, - { - "name": "transpose_b", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","int32" - ], - "format": [ - "FRACTAL_NZ","FRACTAL_NZ","DefaultFormat","DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float16","float","int32" - ], - "format": [ - "FRACTAL_NZ","FRACTAL_NZ","DefaultFormat","DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float","float","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x3", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float","int32" - ], - "format": [ - "FRACTAL_NZ","FRACTAL_NZ","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(matmul_op_info) def _matmul_tbe(): """Mul TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/max_pool.py b/mindspore/ops/_op_impl/tbe/max_pool.py index 6b10bc8d9b..6c4c53cbce 100644 --- a/mindspore/ops/_op_impl/tbe/max_pool.py +++ b/mindspore/ops/_op_impl/tbe/max_pool.py @@ -14,74 +14,26 @@ # ============================================================================ """MaxPool op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +max_pool_op_info = TBERegOp("MaxPool") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("max_pool.so") \ + .compute_cost(10) \ + .kernel_name("max_pool") \ + .partial_flag(True) \ + .attr("ksize", "required", "listInt", "all") \ + .attr("strides", "required", "listInt", "all") \ + .attr("padding", "required", "str", "all") \ + .attr("data_format", "required", "str", "all") \ + .input(0, "input_data", False, "required", "all") \ + .output(0, "output_data", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "MaxPool", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "max_pool.so", - "compute_cost": 10, - "kernel_name": "max_pool", - "partial_flag": true, - "attr": [ - { - "name": "ksize", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "padding", - "param_type": "required", - "type": "str", - "value": "all" - }, - { - "name": "data_format", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "input_data", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "output_data", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(max_pool_op_info) def _max_pool_tbe(): """MaxPool TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/max_pool_grad.py b/mindspore/ops/_op_impl/tbe/max_pool_grad.py index 7c942d01e0..debe1a5a3a 100644 --- a/mindspore/ops/_op_impl/tbe/max_pool_grad.py +++ b/mindspore/ops/_op_impl/tbe/max_pool_grad.py @@ -14,93 +14,27 @@ # ============================================================================ """MaxPoolGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +max_pool_grad_op_info = TBERegOp("MaxPoolGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("max_pool_grad.so") \ + .compute_cost(10) \ + .kernel_name("max_pool_grad") \ + .partial_flag(True) \ + .attr("ksize", "required", "listInt", "all") \ + .attr("strides", "required", "listInt", "all") \ + .attr("padding", "required", "str", "all") \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .input(2, "grad", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "MaxPoolGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "max_pool_grad.so", - "compute_cost": 10, - "kernel_name": "max_pool_grad", - "partial_flag": true, - "attr": [ - { - "name": "ksize", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "padding", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "param_type": "required" - } - ] -}""") + +@op_info_register(max_pool_grad_op_info) def _max_pool_grad_tbe(): """MaxPoolGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/max_pool_grad_with_argmax.py b/mindspore/ops/_op_impl/tbe/max_pool_grad_with_argmax.py index 3730ee1b93..2d6556ffef 100644 --- a/mindspore/ops/_op_impl/tbe/max_pool_grad_with_argmax.py +++ b/mindspore/ops/_op_impl/tbe/max_pool_grad_with_argmax.py @@ -14,95 +14,28 @@ # ============================================================================ """MaxPoolGradWithArgmax op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +max_pool_grad_with_argmax_op_info = TBERegOp("MaxPoolGradWithArgmax") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("max_pool_grad_with_argmax.so") \ + .compute_cost(10) \ + .kernel_name("max_pool_grad_with_argmax") \ + .partial_flag(True) \ + .attr("ksize", "required", "listInt", "all") \ + .attr("strides", "required", "listInt", "all") \ + .attr("padding", "required", "str", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "grad", False, "required", "all") \ + .input(2, "argmax", False, "optional", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.U16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.I64_5HD, DataType.F16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "MaxPoolGradWithArgmax", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "max_pool_grad_with_argmax.so", - "compute_cost": 10, - "kernel_name": "max_pool_grad_with_argmax", - "partial_flag": true, - "attr": [ - { - "name": "ksize", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "padding", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "grad", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "uint16", "int64" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "argmax", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16" - ], - "format": [ - "NC1HWC0", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(max_pool_grad_with_argmax_op_info) def _max_pool_grad_with_argmax_tbe(): """MaxPoolGradWithArgmax TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/max_pool_with_argmax.py b/mindspore/ops/_op_impl/tbe/max_pool_with_argmax.py index 2e081c1082..24700d4b42 100644 --- a/mindspore/ops/_op_impl/tbe/max_pool_with_argmax.py +++ b/mindspore/ops/_op_impl/tbe/max_pool_with_argmax.py @@ -14,82 +14,26 @@ # ============================================================================ """MaxPoolWithArgmax op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +max_pool_with_argmax_op_info = TBERegOp("MaxPoolWithArgmax") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("max_pool_with_argmax.so") \ + .compute_cost(10) \ + .kernel_name("max_pool_with_argmax") \ + .partial_flag(True) \ + .attr("ksize", "required", "listInt", "all") \ + .attr("strides", "required", "listInt", "all") \ + .attr("padding", "required", "str", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .output(1, "argmax", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.U16_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "MaxPoolWithArgmax", - "imply_type": "TBE", - "fusion_type": "CONVLUTION", - "async_flag": false, - "binfile_name": "max_pool_with_argmax.so", - "compute_cost": 10, - "kernel_name": "max_pool_with_argmax", - "partial_flag": true, - "attr": [ - { - "name": "ksize", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "padding", - "param_type": "required", - "type": "str", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "uint16" - ], - "format": [ - "NC1HWC0" - ], - "name": "argmax", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(max_pool_with_argmax_op_info) def _max_pool_with_argmax_tbe(): """MaxPoolWithArgmax TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/maximum.py b/mindspore/ops/_op_impl/tbe/maximum.py index 2a4051f28d..6fb7d05e03 100644 --- a/mindspore/ops/_op_impl/tbe/maximum.py +++ b/mindspore/ops/_op_impl/tbe/maximum.py @@ -14,69 +14,28 @@ # ============================================================================ """Maximum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +maximum_op_info = TBERegOp("Maximum") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("maximum.so") \ + .compute_cost(10) \ + .kernel_name("maximum") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name":"Maximum", - "imply_type":"TBE", - "fusion_type":"ELEMWISE", - "async_flag":false, - "binfile_name":"maximum.so", - "compute_cost":10, - "kernel_name":"maximum", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x2", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(maximum_op_info) def _maximum_tbe(): """Maximum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/maximum_grad.py b/mindspore/ops/_op_impl/tbe/maximum_grad.py index f602616da9..b9bc9c09f8 100644 --- a/mindspore/ops/_op_impl/tbe/maximum_grad.py +++ b/mindspore/ops/_op_impl/tbe/maximum_grad.py @@ -14,112 +14,38 @@ # ============================================================================ """MaximumGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +maximum_grad_op_info = TBERegOp("MaximumGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("maximum_grad.so") \ + .compute_cost(10) \ + .kernel_name("maximum_grad") \ + .partial_flag(True) \ + .attr("grad_x", "optional", "bool", "all") \ + .attr("grad_y", "optional", "bool", "all") \ + .input(0, "grads", False, "required", "all") \ + .input(1, "x1", False, "required", "all") \ + .input(2, "x2", False, "required", "all") \ + .output(0, "y1", False, "required", "all") \ + .output(1, "y2", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, + DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, + DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name":"MaximumGrad", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"maximum_grad.so", - "compute_cost":10, - "kernel_name":"maximum_grad", - "partial_flag":true, - "attr":[ - { - "name":"grad_x", - "param_type":"optional", - "type":"bool", - "value":"all" - }, - { - "name":"grad_y", - "param_type":"optional", - "type":"bool", - "value":"all" - } - ], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"grads", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x2", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"y1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"y2", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(maximum_grad_op_info) def _maximum_grad_tbe(): """MaximumGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/minimum.py b/mindspore/ops/_op_impl/tbe/minimum.py index 2f7e5b80d7..1cebfd3dad 100644 --- a/mindspore/ops/_op_impl/tbe/minimum.py +++ b/mindspore/ops/_op_impl/tbe/minimum.py @@ -15,74 +15,28 @@ """Minimum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +minimum_op_info = TBERegOp("Minimum") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("minimum.so") \ + .compute_cost(10) \ + .kernel_name("minimum") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Minimum", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "minimum.so", - "compute_cost": 10, - "kernel_name": "minimum", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(minimum_op_info) def _minimum_tbe(): """Minimum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/minimum_grad.py b/mindspore/ops/_op_impl/tbe/minimum_grad.py index d49b2aa184..c3ea1c3a56 100644 --- a/mindspore/ops/_op_impl/tbe/minimum_grad.py +++ b/mindspore/ops/_op_impl/tbe/minimum_grad.py @@ -14,112 +14,38 @@ # ============================================================================ """MinimumGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +minimum_grad_op_info = TBERegOp("MinimumGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("minimum_grad.so") \ + .compute_cost(10) \ + .kernel_name("minimum_grad") \ + .partial_flag(True) \ + .attr("grad_x", "optional", "bool", "all") \ + .attr("grad_y", "optional", "bool", "all") \ + .input(0, "grads", False, "required", "all") \ + .input(1, "x1", False, "required", "all") \ + .input(2, "x2", False, "required", "all") \ + .output(0, "y1", False, "required", "all") \ + .output(1, "y2", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, + DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD, + DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, + DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, + DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, + DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, + DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name":"MinimumGrad", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"minimum_grad.so", - "compute_cost":10, - "kernel_name":"minimum_grad", - "partial_flag":true, - "attr":[ - { - "name":"grad_x", - "param_type":"optional", - "type":"bool", - "value":"all" - }, - { - "name":"grad_y", - "param_type":"optional", - "type":"bool", - "value":"all" - } - ], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"grads", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":2, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"x2", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"y1", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32" - ], - "format":[ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name":"y2", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(minimum_grad_op_info) def _minimum_grad_tbe(): """MinimumGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/mul.py b/mindspore/ops/_op_impl/tbe/mul.py index 912d5e372f..fa74c88de3 100644 --- a/mindspore/ops/_op_impl/tbe/mul.py +++ b/mindspore/ops/_op_impl/tbe/mul.py @@ -14,77 +14,37 @@ # ============================================================================ """Mul op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +mul_op_info = TBERegOp("Mul") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("mul.so") \ + .compute_cost(10) \ + .kernel_name("mul") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .input(1, "y", False, "required", "all") \ + .output(0, "output", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_FracZ, DataType.I32_FracZ, DataType.I32_FracZ) \ + .dtype_format(DataType.I32_FracNZ, DataType.I32_FracNZ, DataType.I32_FracNZ) \ + .dtype_format(DataType.I32_C1HWNCoC0, DataType.I32_C1HWNCoC0, DataType.I32_C1HWNCoC0) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Mul", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "mul.so", - "compute_cost": 10, - "kernel_name": "mul", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32", - "float16", "float16", "float16", "float16", "float16", - "float", "float", "float", "float","float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0", - "FRACTAL_NZ", "DefaultFormat", "FracZ", "C1HWNCoC0", "NC1HWC0" - ], - "name": "output", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(mul_op_info) def _mul_tbe(): """Mul TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/neg.py b/mindspore/ops/_op_impl/tbe/neg.py index bbfcd824ec..feb648f056 100644 --- a/mindspore/ops/_op_impl/tbe/neg.py +++ b/mindspore/ops/_op_impl/tbe/neg.py @@ -14,51 +14,29 @@ # ============================================================================ """Neg op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +neg_op_info = TBERegOp("Neg") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("neg.so") \ + .compute_cost(10) \ + .kernel_name("neg") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Neg", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "neg.so", - "compute_cost": 10, - "kernel_name": "neg", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float","float","float16","float16","int32","int32","int8","int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float","float","float16","float16","int32","int32","int8","int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(neg_op_info) def _neg_tbe(): """Neg TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/npu_alloc_float_status.py b/mindspore/ops/_op_impl/tbe/npu_alloc_float_status.py index 6f65b9064a..a395f38e76 100644 --- a/mindspore/ops/_op_impl/tbe/npu_alloc_float_status.py +++ b/mindspore/ops/_op_impl/tbe/npu_alloc_float_status.py @@ -14,39 +14,21 @@ # ============================================================================ """NPUAllocFloatStatus op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +npu_alloc_float_status_op_info = TBERegOp("NPUAllocFloatStatus") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("n_p_u_alloc_float_status.so") \ + .compute_cost(10) \ + .kernel_name("n_p_u_alloc_float_status") \ + .partial_flag(True) \ + .output(0, "data", False, "required", "all") \ + .dtype_format(DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "NPUAllocFloatStatus", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "n_p_u_alloc_float_status.so", - "compute_cost": 10, - "kernel_name": "n_p_u_alloc_float_status", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "DefaultFormat" - ], - "name": "data", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(npu_alloc_float_status_op_info) def _npu_alloc_float_status_tbe(): """NPUAllocFloatStatus TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/npu_clear_float_status.py b/mindspore/ops/_op_impl/tbe/npu_clear_float_status.py index d7e69673f2..b67bf5e62b 100644 --- a/mindspore/ops/_op_impl/tbe/npu_clear_float_status.py +++ b/mindspore/ops/_op_impl/tbe/npu_clear_float_status.py @@ -14,52 +14,22 @@ # ============================================================================ """NPUClearFloatStatus op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +npu_clear_float_status_op_info = TBERegOp("NPUClearFloatStatus") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("n_p_u_clear_float_status.so") \ + .compute_cost(10) \ + .kernel_name("n_p_u_clear_float_status") \ + .partial_flag(True) \ + .input(0, "addr", False, "required", "all") \ + .output(0, "data", False, "required", "all") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "NPUClearFloatStatus", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "n_p_u_clear_float_status.so", - "compute_cost": 10, - "kernel_name": "n_p_u_clear_float_status", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "DefaultFormat" - ], - "name": "addr", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "DefaultFormat" - ], - "name": "data", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(npu_clear_float_status_op_info) def _npu_clear_float_status_tbe(): """NPUClearFloatStatus TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/npu_get_float_status.py b/mindspore/ops/_op_impl/tbe/npu_get_float_status.py index 441fe3b271..ad3eb4be8c 100644 --- a/mindspore/ops/_op_impl/tbe/npu_get_float_status.py +++ b/mindspore/ops/_op_impl/tbe/npu_get_float_status.py @@ -14,52 +14,22 @@ # ============================================================================ """NPUGetFloatStatus op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +npu_get_float_status_op_info = TBERegOp("NPUGetFloatStatus") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("n_p_u_get_float_status.so") \ + .compute_cost(10) \ + .kernel_name("n_p_u_get_float_status") \ + .partial_flag(True) \ + .input(0, "addr", False, "required", "all") \ + .output(0, "data", False, "required", "all") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "NPUGetFloatStatus", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "n_p_u_get_float_status.so", - "compute_cost": 10, - "kernel_name": "n_p_u_get_float_status", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "DefaultFormat" - ], - "name": "addr", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "DefaultFormat" - ], - "name": "data", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(npu_get_float_status_op_info) def _npu_get_float_status_tbe(): """NPUGetFloatStatus TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/one_hot.py b/mindspore/ops/_op_impl/tbe/one_hot.py index 0af406dfc6..81a80bf759 100644 --- a/mindspore/ops/_op_impl/tbe/one_hot.py +++ b/mindspore/ops/_op_impl/tbe/one_hot.py @@ -14,96 +14,35 @@ # ============================================================================ """OneHot op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +one_hot_op_info = TBERegOp("OneHot") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("one_hot.so") \ + .compute_cost(10) \ + .kernel_name("one_hot") \ + .partial_flag(True) \ + .attr("depth", "required", "int", "all") \ + .attr("axis", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "on_value", False, "required", "all") \ + .input(2, "off_value", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.U8_Default, DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.U8_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.U8_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_Default, DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I32_Default, DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "OneHot", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "one_hot.so", - "compute_cost": 10, - "kernel_name": "one_hot", - "partial_flag": true, - "attr": [ - { - "name": "depth", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "axis", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32","int32","int32","int32","int32", - "uint8","uint8","uint8","uint8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float32","int32","int8","uint8", - "float16","float32","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "on_value", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16","float32","int32","int8","uint8", - "float16","float32","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "off_value", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float32","int32","int8","uint8", - "float16","float32","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(one_hot_op_info) def _one_hot_tbe(): """OneHot TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/pad_d.py b/mindspore/ops/_op_impl/tbe/pad_d.py index 25cb19816d..21d814d6b6 100644 --- a/mindspore/ops/_op_impl/tbe/pad_d.py +++ b/mindspore/ops/_op_impl/tbe/pad_d.py @@ -14,57 +14,27 @@ # ============================================================================ """Pad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +pad_d_op_info = TBERegOp("Pad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("pad_d.so") \ + .compute_cost(10) \ + .kernel_name("pad_d") \ + .partial_flag(True) \ + .attr("paddings", "optional", "listListInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Pad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "pad_d.so", - "compute_cost": 10, - "kernel_name": "pad_d", - "partial_flag": true, - "attr": [ - { - "name": "paddings", - "param_type": "optional", - "type": "listListInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int8","uint8","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int8","uint8","int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(pad_d_op_info) def _pad_d_tbe(): """Pad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/pow.py b/mindspore/ops/_op_impl/tbe/pow.py index aa67a8c942..223a139252 100644 --- a/mindspore/ops/_op_impl/tbe/pow.py +++ b/mindspore/ops/_op_impl/tbe/pow.py @@ -14,65 +14,27 @@ # ============================================================================ """Pow op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +pow_op_info = TBERegOp("Pow") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("pow.so") \ + .compute_cost(10) \ + .kernel_name("pow") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Pow", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "pow.so", - "compute_cost": 10, - "kernel_name": "pow", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "int8", "uint8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(pow_op_info) def _pow_tbe(): """Pow TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/real_div.py b/mindspore/ops/_op_impl/tbe/real_div.py index 01f870b7cb..b39948971d 100644 --- a/mindspore/ops/_op_impl/tbe/real_div.py +++ b/mindspore/ops/_op_impl/tbe/real_div.py @@ -14,64 +14,26 @@ # ============================================================================ """RealDiv op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +realdiv_op_info = TBERegOp("RealDiv") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("realdiv.so") \ + .compute_cost(10) \ + .kernel_name("realdiv") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .input(1, "y", False, "required", "all") \ + .output(0, "z", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "RealDiv", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "realdiv.so", - "compute_cost": 10, - "kernel_name": "realdiv", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "z", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(realdiv_op_info) def _real_div_tbe(): """RealDiv TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reciprocal.py b/mindspore/ops/_op_impl/tbe/reciprocal.py index ba039be4c5..dfa126384c 100644 --- a/mindspore/ops/_op_impl/tbe/reciprocal.py +++ b/mindspore/ops/_op_impl/tbe/reciprocal.py @@ -14,52 +14,27 @@ # ============================================================================ """Add op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reciprocal_op_info = TBERegOp("Reciprocal") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reciprocal.so") \ + .compute_cost(10) \ + .kernel_name("reciprocal") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_NHWC, DataType.F16_NHWC) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_NHWC, DataType.F32_NHWC) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Reciprocal", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reciprocal.so", - "compute_cost": 10, - "kernel_name": "reciprocal", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float32", "float32", "float32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float32", "float32", "float32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(reciprocal_op_info) def _reciprocal_tbe(): """Add TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reduce_max.py b/mindspore/ops/_op_impl/tbe/reduce_max.py index 9c4981babc..ab0e766f59 100644 --- a/mindspore/ops/_op_impl/tbe/reduce_max.py +++ b/mindspore/ops/_op_impl/tbe/reduce_max.py @@ -14,63 +14,29 @@ # ============================================================================ """ReduceMax op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reduce_max_d_op_info = TBERegOp("ReduceMax") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reduce_max_d.so") \ + .compute_cost(10) \ + .kernel_name("reduce_max_d") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReduceMax", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reduce_max_d.so", - "compute_cost": 10, - "kernel_name": "reduce_max_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "keep_dims", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "uint8", "bool", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "uint8", "bool", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reduce_max_d_op_info) def _reduce_max_tbe(): """ReduceMax TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reduce_mean.py b/mindspore/ops/_op_impl/tbe/reduce_mean.py index c8776fa8b1..47548e9036 100644 --- a/mindspore/ops/_op_impl/tbe/reduce_mean.py +++ b/mindspore/ops/_op_impl/tbe/reduce_mean.py @@ -14,63 +14,27 @@ # ============================================================================ """ReduceMean op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reduce_mean_op_info = TBERegOp("ReduceMean") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reduce_mean.so") \ + .compute_cost(10) \ + .kernel_name("reduce_mean") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReduceMean", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reduce_mean.so", - "compute_cost": 10, - "kernel_name": "reduce_mean", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "keep_dims", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","int8","uint8" - ], - "format": [ - "NC1HWC0","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","int8","uint8" - ], - "format": [ - "NC1HWC0","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reduce_mean_op_info) def _reduce_mean_tbe(): """ReduceMean TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reduce_mean_d.py b/mindspore/ops/_op_impl/tbe/reduce_mean_d.py index 59cfeb240b..e427b34869 100644 --- a/mindspore/ops/_op_impl/tbe/reduce_mean_d.py +++ b/mindspore/ops/_op_impl/tbe/reduce_mean_d.py @@ -14,63 +14,27 @@ # ============================================================================ """ReduceMeanD op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reduce_mean_d_op_info = TBERegOp("ReduceMeanD") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reduce_mean_d.so") \ + .compute_cost(10) \ + .kernel_name("reduce_mean_d") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReduceMeanD", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reduce_mean_d.so", - "compute_cost": 10, - "kernel_name": "reduce_mean_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "keep_dims", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float","float16","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float","float16","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reduce_mean_d_op_info) def _reduce_mean_d_tbe(): """Conv2D TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reduce_min.py b/mindspore/ops/_op_impl/tbe/reduce_min.py index f440b1fff6..f1601ebc94 100644 --- a/mindspore/ops/_op_impl/tbe/reduce_min.py +++ b/mindspore/ops/_op_impl/tbe/reduce_min.py @@ -14,63 +14,31 @@ # ============================================================================ """ReduceMin op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reduce_min_op_info = TBERegOp("ReduceMin") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reduce_min_d.so") \ + .compute_cost(10) \ + .kernel_name("reduce_min_d") \ + .partial_flag(True) \ + .attr("axis", "required", "listInt", "all") \ + .attr("keep_dims", "required", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_FracZ, DataType.I8_FracZ) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_FracZ, DataType.U8_FracZ) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReduceMin", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reduce_min_d.so", - "compute_cost": 10, - "kernel_name": "reduce_min_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "keep_dims", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "FracZ", "DefaultFormat", "FracZ", "DefaultFormat", "FracZ", "DefaultFormat", "FracZ" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "FracZ", "DefaultFormat", "FracZ", "DefaultFormat", "FracZ", "DefaultFormat", "FracZ" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reduce_min_op_info) def _reduce_min_tbe(): """ReduceMin TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reduce_sum.py b/mindspore/ops/_op_impl/tbe/reduce_sum.py index b15a4deccc..2f76f74562 100644 --- a/mindspore/ops/_op_impl/tbe/reduce_sum.py +++ b/mindspore/ops/_op_impl/tbe/reduce_sum.py @@ -14,63 +14,25 @@ # ============================================================================ """ReduceSum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reduce_sum_op_info = TBERegOp("ReduceSum") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reduce_sum_d.so") \ + .compute_cost(10) \ + .kernel_name("reduce_sum_d") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReduceSum", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reduce_sum_d.so", - "compute_cost": 10, - "kernel_name": "reduce_sum_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "keep_dims", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reduce_sum_op_info) def _reduce_sum_tbe(): """ReduceSum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/relu.py b/mindspore/ops/_op_impl/tbe/relu.py index 7350f2ae35..03cc381253 100644 --- a/mindspore/ops/_op_impl/tbe/relu.py +++ b/mindspore/ops/_op_impl/tbe/relu.py @@ -14,54 +14,29 @@ # ============================================================================ """ReLU op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +relu_op_info = TBERegOp("ReLU") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("relu.so") \ + .compute_cost(10) \ + .kernel_name("relu") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReLU", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "relu.so", - "compute_cost": 10, - "kernel_name": "relu", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float","int32", "int32", "int8", "int8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(relu_op_info) def _relu_tbe(): """Relu TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/relu6.py b/mindspore/ops/_op_impl/tbe/relu6.py new file mode 100644 index 0000000000..bbedfdeb0f --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/relu6.py @@ -0,0 +1,40 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""ReLU6 op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +relu6_op_info = TBERegOp("ReLU6") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("relu6.so") \ + .compute_cost(10) \ + .kernel_name("relu6") \ + .partial_flag(True) \ + .input(0, "features", False, "required", "all") \ + .output(0, "activations", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .get_op_info() + + +@op_info_register(relu6_op_info) +def _relu6_tbe(): + """Relu6 TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/relu6_grad.py b/mindspore/ops/_op_impl/tbe/relu6_grad.py new file mode 100644 index 0000000000..eaf3449fe7 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/relu6_grad.py @@ -0,0 +1,43 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""ReLU6Grad op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +relu6_grad_op_info = TBERegOp("ReLU6Grad") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("relu6_grad.so") \ + .compute_cost(10) \ + .kernel_name("relu6_grad") \ + .partial_flag(True) \ + .input(0, "gradients", False, "required", "all") \ + .input(1, "features", False, "required", "all") \ + .output(0, "backprops", False, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() + + +@op_info_register(relu6_grad_op_info) +def _relu6_grad_tbe(): + """Relu6Grad TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/relu_grad.py b/mindspore/ops/_op_impl/tbe/relu_grad.py index 28b4574e04..0f9e962cfd 100644 --- a/mindspore/ops/_op_impl/tbe/relu_grad.py +++ b/mindspore/ops/_op_impl/tbe/relu_grad.py @@ -14,68 +14,32 @@ # ============================================================================ """ReluGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +relugrad_op_info = TBERegOp("ReluGrad") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("relugrad.so") \ + .compute_cost(10) \ + .kernel_name("relugrad") \ + .partial_flag(True) \ + .input(0, "gradients", False, "required", "all") \ + .input(1, "features", False, "required", "all") \ + .output(0, "backprops", True, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ReluGrad", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "relugrad.so", - "compute_cost": 10, - "kernel_name": "relugrad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0","DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "gradients", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "features", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32", "int8", "int8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "backprops", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(relugrad_op_info) def _relu_grad_tbe(): """ReluGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/reshape.py b/mindspore/ops/_op_impl/tbe/reshape.py index 8386b7a6f0..d46fd966d8 100644 --- a/mindspore/ops/_op_impl/tbe/reshape.py +++ b/mindspore/ops/_op_impl/tbe/reshape.py @@ -14,57 +14,25 @@ # ============================================================================ """Reshape op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +reshape_op_info = TBERegOp("Reshape") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("reshape.so") \ + .compute_cost(10) \ + .kernel_name("reshape") \ + .partial_flag(True) \ + .attr("shape", "required", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Reshape", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "reshape.so", - "compute_cost": 10, - "kernel_name": "reshape", - "partial_flag": true, - "attr": [ - { - "name": "shape", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(reshape_op_info) def _reshape_tbe(): """Reshape TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor.py b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor.py index 63ecf0ede2..8a66f75dbb 100644 --- a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor.py +++ b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor.py @@ -14,67 +14,33 @@ # ============================================================================ """ResizeNearestNeighbor op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +resize_nearest_neighbor_op_info = TBERegOp("ResizeNearestNeighbor") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("resize_nearest_neighbor_d.so") \ + .compute_cost(10) \ + .kernel_name("resize_nearest_neighbor_d") \ + .partial_flag(True) \ + .attr("size", "required", "listInt", "all") \ + .attr("align_corners", "optional", "bool", "all") \ + .input(0, "images", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ResizeNearestNeighbor", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "resize_nearest_neighbor_d.so", - "compute_cost": 10, - "kernel_name": "resize_nearest_neighbor_d", - "partial_flag": true, - "attr": [ - { - "name": "size", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "align_corners", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8", - "float16","float","int32","int8","uint8" - ], - "format": [ - "NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "images", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8", - "float16","float","int32","int8","uint8" - ], - "format": [ - "NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0", - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(resize_nearest_neighbor_op_info) def _resize_nearest_neighbor_d_tbe(): """ResizeNearestNeighbor TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_d.py b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_d.py index 9595041401..4b54da991a 100644 --- a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_d.py +++ b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_d.py @@ -14,63 +14,28 @@ # ============================================================================ """ResizeNearestNeighbor op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +resize_nearest_neighbor_d_op_info = TBERegOp("ResizeNearestNeighbor") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("resize_nearest_neighbor_d.so") \ + .compute_cost(10) \ + .kernel_name("resize_nearest_neighbor_d") \ + .partial_flag(True) \ + .attr("size", "required", "listInt", "all") \ + .attr("align_corners", "optional", "bool", "all") \ + .input(0, "images", False, "required", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ResizeNearestNeighbor", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "resize_nearest_neighbor_d.so", - "compute_cost": 10, - "kernel_name": "resize_nearest_neighbor_d", - "partial_flag": true, - "attr": [ - { - "name": "size", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "align_corners", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0" - ], - "name": "images", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0","NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(resize_nearest_neighbor_d_op_info) def _resize_nearest_neighbor_d_tbe(): """ResizeNearestNeighbor TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_grad_d.py b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_grad_d.py index 51cfaf5176..6ee6c56146 100644 --- a/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_grad_d.py +++ b/mindspore/ops/_op_impl/tbe/resize_nearest_neighbor_grad_d.py @@ -14,63 +14,24 @@ # ============================================================================ """ResizeNearestNeighborgrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +resize_nearest_neighbor_grad_d_op_info = TBERegOp("ResizeNearestNeighborGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("resize_nearest_neighbor_grad_d.so") \ + .compute_cost(10) \ + .kernel_name("resize_nearest_neighbor_grad_d") \ + .partial_flag(True) \ + .attr("size", "required", "listInt", "all") \ + .attr("align_corners", "optional", "bool", "all") \ + .input(0, "grads", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ResizeNearestNeighborGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "resize_nearest_neighbor_grad_d.so", - "compute_cost": 10, - "kernel_name": "resize_nearest_neighbor_grad_d", - "partial_flag": true, - "attr": [ - { - "name": "size", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "align_corners", - "param_type": "optional", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "NC1HWC0" - ], - "name": "grads", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(resize_nearest_neighbor_grad_d_op_info) def _resize_nearest_neighbor_grad_d_tbe(): """ResizeNearestNeighborGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/round.py b/mindspore/ops/_op_impl/tbe/round.py index 1368100a8e..4559a3def0 100644 --- a/mindspore/ops/_op_impl/tbe/round.py +++ b/mindspore/ops/_op_impl/tbe/round.py @@ -14,52 +14,27 @@ # ============================================================================ """Round op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +round_op_info = TBERegOp("Round") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("round.so") \ + .compute_cost(10) \ + .kernel_name("round") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Round", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "round.so", - "compute_cost": 10, - "kernel_name": "round", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "FracZ", "DefaultFormat", "NC1HWC0", "FracZ" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "FracZ", "DefaultFormat", "NC1HWC0", "FracZ" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(round_op_info) def _round_tbe(): """Round TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/rsqrt.py b/mindspore/ops/_op_impl/tbe/rsqrt.py index e23d505397..b0830cf484 100644 --- a/mindspore/ops/_op_impl/tbe/rsqrt.py +++ b/mindspore/ops/_op_impl/tbe/rsqrt.py @@ -14,94 +14,29 @@ # ============================================================================ """Rsqrt op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +rsqrt_op_info = TBERegOp("Rsqrt") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("rsqrt.so") \ + .compute_cost(10) \ + .kernel_name("rsqrt") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() -@op_info_register("""{ - "op_name":"Rsqrt", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"rsqrt.so", - "compute_cost":10, - "kernel_name":"rsqrt", - "partial_flag":true, - "attr":[], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float16", - "float16", - "float16", - "float16", - "float16", - "float", - "float", - "float", - "float", - "float", - "float" - ], - "format":[ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "FracZ", - "C1HWNCoC0", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "FracZ", - "C1HWNCoC0" - ], - "name":"x", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float16", - "float16", - "float16", - "float16", - "float16", - "float", - "float", - "float", - "float", - "float", - "float" - ], - "format":[ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "FracZ", - "C1HWNCoC0", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "FracZ", - "C1HWNCoC0" - ], - "name":"y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(rsqrt_op_info) def _rsqrt_tbe(): """Rsqrt TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/scatter_nd.py b/mindspore/ops/_op_impl/tbe/scatter_nd.py index 947fc57920..6c9eae3ad4 100644 --- a/mindspore/ops/_op_impl/tbe/scatter_nd.py +++ b/mindspore/ops/_op_impl/tbe/scatter_nd.py @@ -14,71 +14,28 @@ # ============================================================================ """ScatterNd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +scatter_nd_op_info = TBERegOp("ScatterNd") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("scatter_nd_d.so") \ + .compute_cost(10) \ + .kernel_name("scatter_nd_d") \ + .partial_flag(True) \ + .attr("shape", "optional", "listInt", "all") \ + .input(0, "indices", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I32_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -# map to tbe kernel name scatter_nd_d -@op_info_register("""{ - "op_name": "ScatterNd", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "scatter_nd_d.so", - "compute_cost": 10, - "kernel_name": "scatter_nd_d", - "partial_flag": true, - "attr": [ - { - "name": "shape", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "indices", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(scatter_nd_op_info) def _scatter_nd_tbe(): """Conv2D TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/scatter_nd_d.py b/mindspore/ops/_op_impl/tbe/scatter_nd_d.py index ad776fde49..b069b7d8aa 100644 --- a/mindspore/ops/_op_impl/tbe/scatter_nd_d.py +++ b/mindspore/ops/_op_impl/tbe/scatter_nd_d.py @@ -14,70 +14,28 @@ # ============================================================================ """ScatterNdD op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +scatter_nd_d_op_info = TBERegOp("ScatterNdD") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("scatter_nd_d.so") \ + .compute_cost(10) \ + .kernel_name("scatter_nd_d") \ + .partial_flag(True) \ + .attr("shape", "optional", "listInt", "all") \ + .input(0, "indices", False, "required", "all") \ + .input(1, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I32_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ScatterNdD", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "scatter_nd_d.so", - "compute_cost": 10, - "kernel_name": "scatter_nd_d", - "partial_flag": true, - "attr": [ - { - "name": "shape", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "int32", "int32", "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "indices", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","int32","int8","uint8" - ], - "format": [ - "DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(scatter_nd_d_op_info) def _scatter_nd_d_tbe(): """ScatterNdD TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/select.py b/mindspore/ops/_op_impl/tbe/select.py index c205e0de1d..4af4325312 100644 --- a/mindspore/ops/_op_impl/tbe/select.py +++ b/mindspore/ops/_op_impl/tbe/select.py @@ -14,94 +14,33 @@ # ============================================================================ """Select op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +select_op_info = TBERegOp("Select") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("select.so") \ + .compute_cost(10) \ + .kernel_name("select") \ + .partial_flag(True) \ + .input(0, "condition", False, "required", "all") \ + .input(1, "x1", False, "required", "all") \ + .input(2, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.I8_Default, DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U8_Default, DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.BOOL_5HD, DataType.I8_5HD, DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.BOOL_5HD, DataType.U8_5HD, DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.BOOL_5HD, DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.BOOL_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.BOOL_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Select", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "select.so", - "compute_cost": 10, - "kernel_name": "select", - "partial_flag": true, - "attr":[ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool", - "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool", "bool" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "condition", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", - "int32", "int32", "int32", "int32", "int8", "int8", "int8", "int8", "uint8", - "uint8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32", "int8", "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32", "int8", "int8", "int8", "int8", "uint8", "uint8", "uint8", "uint8" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(select_op_info) def _select_tbe(): """Select TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sigmoid.py b/mindspore/ops/_op_impl/tbe/sigmoid.py index cba9561d27..38413c0432 100644 --- a/mindspore/ops/_op_impl/tbe/sigmoid.py +++ b/mindspore/ops/_op_impl/tbe/sigmoid.py @@ -14,67 +14,31 @@ # ============================================================================ """Sigmoid op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sigmoid_op_info = TBERegOp("Sigmoid") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("sigmoid.so") \ + .compute_cost(10) \ + .kernel_name("sigmoid") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Sigmoid", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "Sigmoid.so", - "compute_cost": 10, - "kernel_name": "sigmoid", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float", - "float16","float", - "float16","float", - "float16","float", - "float16","float" - ], - "format": [ - "FracZ","FracZ", - "FRACTAL_NZ","FRACTAL_NZ", - "C1HWNCoC0","C1HWNCoC0", - "NC1HWC0","NC1HWC0", - "DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float", - "float16","float", - "float16","float", - "float16","float", - "float16","float" - ], - "format": [ - "FracZ","FracZ", - "FRACTAL_NZ","FRACTAL_NZ", - "C1HWNCoC0","C1HWNCoC0", - "NC1HWC0","NC1HWC0", - "DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(sigmoid_op_info) def _sigmoid_tbe(): """Sigmoid TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits.py b/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits.py index b20438d5fe..61c81a8a99 100644 --- a/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits.py +++ b/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits.py @@ -14,64 +14,26 @@ # ============================================================================ """SigmoidCrossEntropyWithLogits op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sigmoid_cross_entropy_with_logits_op_info = TBERegOp("SigmoidCrossEntropyWithLogits") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("sigmoid_cross_entropy_with_logits.so") \ + .compute_cost(10) \ + .kernel_name("sigmoid_cross_entropy_with_logits") \ + .partial_flag(True) \ + .input(0, "predict", False, "required", "all") \ + .input(1, "target", False, "required", "all") \ + .output(0, "loss", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SigmoidCrossEntropyWithLogits", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "sigmoid_cross_entropy_with_logits.so", - "compute_cost": 10, - "kernel_name": "sigmoid_cross_entropy_with_logits", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "predict", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "target", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "loss", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(sigmoid_cross_entropy_with_logits_op_info) def _sigmoid_cross_entropy_with_logits_tbe(): """SigmoidCrossEntropyWithLogits TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits_grad.py b/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits_grad.py index 6e5df24cfe..cc2a29353d 100644 --- a/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits_grad.py +++ b/mindspore/ops/_op_impl/tbe/sigmoid_cross_entropy_with_logits_grad.py @@ -14,77 +14,27 @@ # ============================================================================ """SigmoidCrossEntropyWithLogitsGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sigmoid_cross_entropy_with_logits_grad_op_info = TBERegOp("SigmoidCrossEntropyWithLogitsGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("sigmoid_cross_entropy_with_logits_grad.so") \ + .compute_cost(10) \ + .kernel_name("sigmoid_cross_entropy_with_logits_grad") \ + .partial_flag(True) \ + .input(0, "predict", False, "required", "all") \ + .input(1, "target", False, "required", "all") \ + .input(2, "dout", False, "required", "all") \ + .output(0, "gradient", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SigmoidCrossEntropyWithLogitsGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "sigmoid_cross_entropy_with_logits_grad.so", - "compute_cost": 10, - "kernel_name": "sigmoid_cross_entropy_with_logits_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "predict", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "target", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "dout", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat" - ], - "name": "gradient", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(sigmoid_cross_entropy_with_logits_grad_op_info) def _sigmoid_cross_entropy_with_logits_grad_tbe(): """SigmoidCrossEntropyWithLogitsGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sigmoid_grad.py b/mindspore/ops/_op_impl/tbe/sigmoid_grad.py index f0833e8a80..bc2878ce96 100644 --- a/mindspore/ops/_op_impl/tbe/sigmoid_grad.py +++ b/mindspore/ops/_op_impl/tbe/sigmoid_grad.py @@ -14,64 +14,26 @@ # ============================================================================ """SigmoidGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sigmoid_cross_entropy_with_logits_op_info = TBERegOp("SigmoidGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("sigmoid_grad.so") \ + .compute_cost(10) \ + .kernel_name("sigmoid_grad") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .input(1, "y", False, "required", "all") \ + .output(0, "z", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SigmoidGrad", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "sigmoid_grad.so", - "compute_cost": 10, - "kernel_name": "sigmoid_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","float" - ], - "format": [ - "NC1HWC0","NC1HWC0","DefaultFormat","DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16","float","float16","float" - ], - "format": [ - "NC1HWC0","NC1HWC0","DefaultFormat","DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float","float16","float" - ], - "format": [ - "NC1HWC0","NC1HWC0","DefaultFormat","DefaultFormat" - ], - "name": "z", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(sigmoid_cross_entropy_with_logits_op_info) def _sigmoid_grad_tbe(): """SigmoidGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sign.py b/mindspore/ops/_op_impl/tbe/sign.py new file mode 100644 index 0000000000..823715aa9f --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/sign.py @@ -0,0 +1,41 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Sign op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +sign_op_info = TBERegOp("Sign") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("sign.so") \ + .compute_cost(10) \ + .kernel_name("sign") \ + .partial_flag(True) \ + .op_pattern("formatAgnostic") \ + .input(0, "x", None, "required", None) \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .get_op_info() + + +@op_info_register(sign_op_info) +def _sign_tbe(): + """Sign TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/slice.py b/mindspore/ops/_op_impl/tbe/slice.py index 779f19cbc5..402692ca32 100644 --- a/mindspore/ops/_op_impl/tbe/slice.py +++ b/mindspore/ops/_op_impl/tbe/slice.py @@ -14,99 +14,33 @@ # ============================================================================ """Slice op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +slice_op_info = TBERegOp("Slice") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("slice_d.so") \ + .compute_cost(10) \ + .kernel_name("slice_d") \ + .partial_flag(True) \ + .attr("begin", "required", "listInt", "all") \ + .attr("size", "required", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name":"Slice", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"slice_d.so", - "compute_cost":10, - "kernel_name":"slice_d", - "partial_flag":true, - "attr":[ - { - "name":"begin", - "param_type":"required", - "type":"listInt", - "value":"all" - }, - { - "name":"size", - "param_type":"required", - "type":"listInt", - "value":"all" - } - ], - "inputs":[ - { - "index":0, - "dtype":[ - "float", - "float16", - "int8", - "int16", - "int32", - "int64", - "uint8", - "uint16", - "uint32", - "uint64" - ], - "format":[ - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat" - ], - "name":"x", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float", - "float16", - "int8", - "int16", - "int32", - "int64", - "uint8", - "uint16", - "uint32", - "uint64" - ], - "format":[ - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat" - ], - "name":"y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(slice_op_info) def _slice_tbe(): """Slice TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/smooth_l1_loss.py b/mindspore/ops/_op_impl/tbe/smooth_l1_loss.py new file mode 100644 index 0000000000..3723b30c04 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/smooth_l1_loss.py @@ -0,0 +1,44 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""SmoothL1Loss op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +smooth_l1_loss_op_info = TBERegOp("SmoothL1Loss") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("smooth_l1_loss.so") \ + .compute_cost(10) \ + .kernel_name("smooth_l1_loss") \ + .partial_flag(True) \ + .attr("sigma", "required", "float", "all") \ + .input(0, "predict", False, "required", "all") \ + .input(1, "label", False, "required", "all") \ + .output(0, "loss", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() + + +@op_info_register(smooth_l1_loss_op_info) +def _smooth_l1_loss_tbe(): + """SmoothL1Loss TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/smooth_l1_loss_grad.py b/mindspore/ops/_op_impl/tbe/smooth_l1_loss_grad.py new file mode 100644 index 0000000000..fa1ae1ec34 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/smooth_l1_loss_grad.py @@ -0,0 +1,45 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""SmoothL1LossGrad op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +smooth_l1_loss_grad_op_info = TBERegOp("SmoothL1LossGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("smooth_l1_loss_grad.so") \ + .compute_cost(10) \ + .kernel_name("smooth_l1_loss_grad") \ + .partial_flag(True) \ + .attr("sigma", "required", "float", "all") \ + .input(0, "predict", False, "required", "all") \ + .input(1, "label", False, "required", "all") \ + .input(2, "dout", False, "required", "all") \ + .output(0, "loss", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0, DataType.F32_C1HWNCoC0) \ + .get_op_info() + + +@op_info_register(smooth_l1_loss_grad_op_info) +def _smooth_l1_loss_grad_tbe(): + """SmoothL1LossGrad TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/softmax.py b/mindspore/ops/_op_impl/tbe/softmax.py index 5a70d2605a..faefad87ec 100644 --- a/mindspore/ops/_op_impl/tbe/softmax.py +++ b/mindspore/ops/_op_impl/tbe/softmax.py @@ -14,57 +14,27 @@ # ============================================================================ """Softmax op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +softmax_op_info = TBERegOp("Softmax") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("softmax.so") \ + .compute_cost(10) \ + .kernel_name("softmax") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_FracNZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_FracNZ) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Softmax", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "softmax.so", - "compute_cost": 10, - "kernel_name": "softmax", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "NC1HWC0", "FRACTAL_NZ", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float" - ], - "format": [ - "FRACTAL_NZ", "DefaultFormat", "NC1HWC0", "FRACTAL_NZ", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(softmax_op_info) def _softmax_tbe(): """Softmax TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/softmax_cross_entropy_with_logits.py b/mindspore/ops/_op_impl/tbe/softmax_cross_entropy_with_logits.py index cc9f06948a..386562f9f2 100644 --- a/mindspore/ops/_op_impl/tbe/softmax_cross_entropy_with_logits.py +++ b/mindspore/ops/_op_impl/tbe/softmax_cross_entropy_with_logits.py @@ -14,78 +14,25 @@ # ============================================================================ """SoftmaxCrossEntropyWithLogits op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +softmax_cross_entropy_with_logits_op_info = TBERegOp("SoftmaxCrossEntropyWithLogits") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("softmax_cross_entropy_with_logits.so") \ + .compute_cost(10) \ + .kernel_name("softmax_cross_entropy_with_logits") \ + .partial_flag(True) \ + .input(0, "input_features", False, "required", "all") \ + .input(1, "input_labels", False, "required", "all") \ + .output(0, "output_loss", True, "required", "all") \ + .output(1, "output_backprop", True, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SoftmaxCrossEntropyWithLogits", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "softmax_cross_entropy_with_logits.so", - "compute_cost": 10, - "kernel_name": "softmax_cross_entropy_with_logits", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input_features", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input_labels", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output_loss", - "need_compile": true, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output_backprop", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(softmax_cross_entropy_with_logits_op_info) def _softmax_cross_entropy_with_logits_tbe(): """SoftmaxCrossEntropyWithLogits TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/split_d.py b/mindspore/ops/_op_impl/tbe/split_d.py index 41311ffb90..dcc8219fd4 100644 --- a/mindspore/ops/_op_impl/tbe/split_d.py +++ b/mindspore/ops/_op_impl/tbe/split_d.py @@ -14,71 +14,45 @@ # ============================================================================ """Add op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +split_d_op_info = TBERegOp("Split") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("split_d.so") \ + .compute_cost(10) \ + .kernel_name("split_d") \ + .partial_flag(True) \ + .attr("axis", "required", "int", "all") \ + .attr("output_num", "required", "int", "all") \ + .input(0, "value", False, "required", "all") \ + .output(0, "output", False, "dynamic", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_NHWC, DataType.BOOL_NHWC) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_NHWC, DataType.I8_NHWC) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_NHWC, DataType.U8_NHWC) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.I16_NHWC, DataType.I16_NHWC) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.U16_NHWC, DataType.U16_NHWC) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_NHWC, DataType.I32_NHWC) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U32_NHWC, DataType.U32_NHWC) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.I64_NHWC, DataType.I64_NHWC) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.U64_NHWC, DataType.U64_NHWC) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_NHWC, DataType.F16_NHWC) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_NHWC, DataType.F32_NHWC) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Split", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "split_d.so", - "compute_cost": 10, - "kernel_name": "split_d", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "output_num", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16","float32", "float32", "int32", "int32", "int8", "int8", - "int16", "int16", "int64", "int64", "uint8", "uint8", "uint16", "uint16", - "uint32", "uint32", "uint64", "uint64", "bool", "bool" - ], - "format": [ - "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - , "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - , "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - ], - "name": "value", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16","float32", "float32", "int32", "int32", "int8", "int8", - "int16", "int16", "int64", "int64", "uint8", "uint8", "uint16", "uint16", - "uint32", "uint32", "uint64", "uint64", "bool", "bool" - ], - "format": [ - "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - , "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - , "DefaultFormat", "NHWC", "DefaultFormat", "NHWC", "DefaultFormat", "NHWC" - ], - "name": "output", - "need_compile": false, - "param_type": "dynamic", - "shape": "all" - } - ] -}""") + +@op_info_register(split_d_op_info) def _split_d_tbe(): """Add TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sqrt.py b/mindspore/ops/_op_impl/tbe/sqrt.py index c73092886a..f9e339713b 100644 --- a/mindspore/ops/_op_impl/tbe/sqrt.py +++ b/mindspore/ops/_op_impl/tbe/sqrt.py @@ -14,52 +14,27 @@ # ============================================================================ """Sqrt op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sqrt_op_info = TBERegOp("Sqrt") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("sqrt.so") \ + .compute_cost(10) \ + .kernel_name("sqrt") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_NHWC, DataType.F16_NHWC) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_NHWC, DataType.F32_NHWC) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Sqrt", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "sqrt.so", - "compute_cost": 10, - "kernel_name": "sqrt", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(sqrt_op_info) def _sqrt_tbe(): """Sqrt TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/square.py b/mindspore/ops/_op_impl/tbe/square.py index 03a81236cc..c3eeb12780 100644 --- a/mindspore/ops/_op_impl/tbe/square.py +++ b/mindspore/ops/_op_impl/tbe/square.py @@ -14,56 +14,30 @@ # ============================================================================ """Square op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +square_op_info = TBERegOp("Square") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("square.so") \ + .compute_cost(10) \ + .kernel_name("square") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.I32_NHWC, DataType.I32_NHWC) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_NHWC, DataType.F16_NHWC) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .dtype_format(DataType.F32_NHWC, DataType.F32_NHWC) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Square", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "square.so", - "compute_cost": 10, - "kernel_name": "sqrt", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC", - "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float", "float", "float", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "NHWC", "DefaultFormat", "NC1HWC0", "NHWC", - "DefaultFormat", "NC1HWC0", "NHWC" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(square_op_info) def _square_tbe(): """Square TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/square_sum_v1.py b/mindspore/ops/_op_impl/tbe/square_sum_v1.py index 39b5400298..9d43fe4cc0 100644 --- a/mindspore/ops/_op_impl/tbe/square_sum_v1.py +++ b/mindspore/ops/_op_impl/tbe/square_sum_v1.py @@ -14,63 +14,25 @@ # ============================================================================ """SquareSumV1 op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +square_sum_v1_op_info = TBERegOp("SquareSumV1") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("square_sum_v1.so") \ + .compute_cost(10) \ + .kernel_name("square_sum_v1") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "input_x", False, "required", "all") \ + .output(0, "output1", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SquareSumV1", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "square_sum_v1.so", - "compute_cost": 10, - "kernel_name": "square_sum_v1", - "partial_flag": true, - "attr":[ - { - "name":"axis", - "param_type":"optional", - "type":"listInt", - "value":"all" - }, - { - "name":"keep_dims", - "param_type":"optional", - "type":"bool", - "value":"all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input_x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output1", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(square_sum_v1_op_info) def _square_sum_v1_tbe(): """SquareSumV1 TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/square_sum_v2.py b/mindspore/ops/_op_impl/tbe/square_sum_v2.py index 2f5ca49cc2..88bb1283d1 100644 --- a/mindspore/ops/_op_impl/tbe/square_sum_v2.py +++ b/mindspore/ops/_op_impl/tbe/square_sum_v2.py @@ -14,76 +14,26 @@ # ============================================================================ """SquareSumV2 op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +square_sum_v2_op_info = TBERegOp("SquareSumV2") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("square_sum_v2.so") \ + .compute_cost(10) \ + .kernel_name("square_sum_v2") \ + .partial_flag(True) \ + .attr("axis", "optional", "listInt", "all") \ + .attr("keep_dims", "optional", "bool", "all") \ + .input(0, "input_x", False, "required", "all") \ + .output(0, "output1", False, "required", "all") \ + .output(1, "output2", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "SquareSumV2", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "square_sum_v2.so", - "compute_cost": 10, - "kernel_name": "square_sum_v2", - "partial_flag": true, - "attr":[ - { - "name":"axis", - "param_type":"optional", - "type":"listInt", - "value":"all" - }, - { - "name":"keep_dims", - "param_type":"optional", - "type":"bool", - "value":"all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "input_x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "output2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(square_sum_v2_op_info) def _square_sum_v2_tbe(): """SquareSumV2 TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/squeeze.py b/mindspore/ops/_op_impl/tbe/squeeze.py index 765ffae2c1..9d585ccabe 100644 --- a/mindspore/ops/_op_impl/tbe/squeeze.py +++ b/mindspore/ops/_op_impl/tbe/squeeze.py @@ -14,57 +14,24 @@ # ============================================================================ """Squeeze op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +squeeze_op_info = TBERegOp("Squeeze") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("squeeze.so") \ + .compute_cost(10) \ + .kernel_name("squeeze") \ + .partial_flag(True) \ + .attr("axis", "required", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Squeeze", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "squeeze.so", - "compute_cost": 10, - "kernel_name": "squeeze", - "partial_flag": true, - "attr": [ - { - "name": "axis", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32" - ], - "format": [ - "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(squeeze_op_info) def _squeeze_tbe(): """Squeeze TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/strideslice_d.py b/mindspore/ops/_op_impl/tbe/strideslice_d.py index 8f398b4215..e008e6f3d7 100644 --- a/mindspore/ops/_op_impl/tbe/strideslice_d.py +++ b/mindspore/ops/_op_impl/tbe/strideslice_d.py @@ -14,99 +14,35 @@ # ============================================================================ """StridedSlice op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +strided_slice_d_op_info = TBERegOp("StridedSlice") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("strided_slice_d.so") \ + .compute_cost(10) \ + .kernel_name("strided_slice_d") \ + .partial_flag(True) \ + .attr("begin", "optional", "listInt", "all") \ + .attr("end", "optional", "listInt", "all") \ + .attr("strides", "optional", "listInt", "all") \ + .attr("begin_mask", "required", "int", "all") \ + .attr("end_mask", "required", "int", "all") \ + .attr("ellipsis_mask", "required", "int", "all") \ + .attr("new_axis_mask", "required", "int", "all") \ + .attr("shrink_axis_mask", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "StridedSlice", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "strided_slice_d.so", - "compute_cost": 10, - "kernel_name": "strided_slice_d", - "partial_flag": true, - "attr": [ - { - "name": "begin", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "end", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "begin_mask", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "end_mask", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "ellipsis_mask", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "new_axis_mask", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "shrink_axis_mask", - "param_type": "required", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "uint8", "bool", "int8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int32", "uint8", "bool", "int8" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(strided_slice_d_op_info) def _strided_slice_d_tbe(): """StridedSlice TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/strideslicegrad_d.py b/mindspore/ops/_op_impl/tbe/strideslicegrad_d.py index adeeab9a81..e7e1204385 100644 --- a/mindspore/ops/_op_impl/tbe/strideslicegrad_d.py +++ b/mindspore/ops/_op_impl/tbe/strideslicegrad_d.py @@ -14,107 +14,40 @@ # ============================================================================ """StridedSliceGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +strided_slice_grad_d_op_info = TBERegOp("StridedSliceGrad") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("strided_slice_grad_d.so") \ + .compute_cost(10) \ + .kernel_name("strided_slice_grad_d") \ + .partial_flag(True) \ + .attr("shapex", "optional", "listInt", "all") \ + .attr("begin", "optional", "listInt", "all") \ + .attr("end", "optional", "listInt", "all") \ + .attr("strides", "optional", "listInt", "all") \ + .attr("begin_mask", "optional", "int", "all") \ + .attr("end_mask", "optional", "int", "all") \ + .attr("ellipsis_mask", "optional", "int", "all") \ + .attr("new_axis_mask", "optional", "int", "all") \ + .attr("shrink_axis_mask", "optional", "int", "all") \ + .input(0, "dy", False, "required", "all") \ + .output(0, "output", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "StridedSliceGrad", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "strided_slice_grad_d.so", - "compute_cost": 10, - "kernel_name": "strided_slice_grad_d", - "partial_flag": true, - "attr": [ - { - "name": "shapex", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "begin", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "end", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "strides", - "param_type": "optional", - "type": "listInt", - "value": "all" - }, - { - "name": "begin_mask", - "param_type": "optional", - "type": "int", - "value": "all" - }, - { - "name": "end_mask", - "param_type": "optional", - "type": "int", - "value": "all" - }, - { - "name": "ellipsis_mask", - "param_type": "optional", - "type": "int", - "value": "all" - }, - { - "name": "new_axis_mask", - "param_type": "optional", - "type": "int", - "value": "all" - }, - { - "name": "shrink_axis_mask", - "param_type": "optional", - "type": "int", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","uint8","uint8","int8","int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0", - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","uint8","uint8","int8","int8" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0", - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "output", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(strided_slice_grad_d_op_info) def _strided_slice_grad_d_tbe(): """StridedSliceGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/sub.py b/mindspore/ops/_op_impl/tbe/sub.py index 8d6ea4aa0e..8e97681c6b 100644 --- a/mindspore/ops/_op_impl/tbe/sub.py +++ b/mindspore/ops/_op_impl/tbe/sub.py @@ -14,65 +14,28 @@ # ============================================================================ """Sub op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +sub_op_info = TBERegOp("Sub") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("sub.so") \ + .compute_cost(10) \ + .kernel_name("sub") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Sub", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "sub.so", - "compute_cost": 10, - "kernel_name": "sub", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(sub_op_info) def _sub_tbe(): """Add TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/tanh.py b/mindspore/ops/_op_impl/tbe/tanh.py index dd2737f2ce..3d0b2704a3 100644 --- a/mindspore/ops/_op_impl/tbe/tanh.py +++ b/mindspore/ops/_op_impl/tbe/tanh.py @@ -14,52 +14,25 @@ # ============================================================================ """Tanh op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +tanh_op_info = TBERegOp("Tanh") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("tanh.so") \ + .compute_cost(10) \ + .kernel_name("tanh") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Tanh", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "tanh.so", - "compute_cost": 10, - "kernel_name": "tanh", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(tanh_op_info) def _tanh_tbe(): """Tanh TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/tanh_grad.py b/mindspore/ops/_op_impl/tbe/tanh_grad.py index c50b5a3a5a..5796ed7aff 100644 --- a/mindspore/ops/_op_impl/tbe/tanh_grad.py +++ b/mindspore/ops/_op_impl/tbe/tanh_grad.py @@ -14,65 +14,26 @@ # ============================================================================ """TanhGrad op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +tanh_grad_op_info = TBERegOp("TanhGrad") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("tanh_grad.so") \ + .compute_cost(10) \ + .kernel_name("tanh_grad") \ + .partial_flag(True) \ + .input(0, "y", False, "required", "all") \ + .input(1, "dy", False, "required", "all") \ + .output(0, "z", True, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "TanhGrad", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "tanh_grad.so", - "compute_cost": 10, - "kernel_name": "tanh_grad", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "dy", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float", "float" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "NC1HWC0" - ], - "name": "z", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(tanh_grad_op_info) def _tanh_grad_tbe(): """TanhGrad TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/tensor_add.py b/mindspore/ops/_op_impl/tbe/tensor_add.py index 26a25c34b2..255c1b1278 100644 --- a/mindspore/ops/_op_impl/tbe/tensor_add.py +++ b/mindspore/ops/_op_impl/tbe/tensor_add.py @@ -14,70 +14,28 @@ # ============================================================================ """TensorAdd op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +tensor_add_op_info = TBERegOp("TensorAdd") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("add.so") \ + .compute_cost(10) \ + .kernel_name("add") \ + .partial_flag(True) \ + .input(0, "x1", False, "required", "all") \ + .input(1, "x2", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "TensorAdd", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "add.so", - "compute_cost": 10, - "kernel_name": "add", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", "int32", - "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "x2", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float16", "float16", "float16", "float", "float", "float", "float", "int32", - "int32", "int32", "int32" - ], - "format": [ - "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "NC1HWC0", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(tensor_add_op_info) def _tensor_add_tbe(): """Add TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/tile.py b/mindspore/ops/_op_impl/tbe/tile.py index 8299c500db..093e03f6ac 100644 --- a/mindspore/ops/_op_impl/tbe/tile.py +++ b/mindspore/ops/_op_impl/tbe/tile.py @@ -14,57 +14,25 @@ # ============================================================================ """Tile op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +tile_op_info = TBERegOp("Tile") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("tile_d.so") \ + .compute_cost(10) \ + .kernel_name("tile_d") \ + .partial_flag(True) \ + .attr("multiples", "optional", "listInt", "all")\ + .input(0, "x1", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Tile", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "tile_d.so", - "compute_cost": 10, - "kernel_name": "tile_d", - "partial_flag": true, - "attr": [ - { - "name": "multiples", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32", "float16", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x1", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float32", "int32", "float16", "int32" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(tile_op_info) def _tile_tbe(): """Tile TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/top_k.py b/mindspore/ops/_op_impl/tbe/top_k.py new file mode 100644 index 0000000000..92733bbf46 --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/top_k.py @@ -0,0 +1,39 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""TopK op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +top_k_op_info = TBERegOp("TopK") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("top_k.so") \ + .compute_cost(10) \ + .kernel_name("top_k") \ + .partial_flag(True) \ + .attr("k", "required", "int", "all")\ + .attr("sorted", "required", "bool", "all")\ + .input(0, "x", False, "required", "all") \ + .input(1, "input_indices", False, "optional", "all") \ + .output(0, "values", False, "required", "all") \ + .output(1, "indices", False, "required", "all") \ + .dtype_format(DataType.F16_Default, DataType.F16_Default, DataType.F16_Default, DataType.I32_Default) \ + .get_op_info() + + +@op_info_register(top_k_op_info) +def _top_k_tbe(): + """TopK TBE register""" + return diff --git a/mindspore/ops/_op_impl/tbe/topkv2.py b/mindspore/ops/_op_impl/tbe/topkv2.py deleted file mode 100644 index 916b246a38..0000000000 --- a/mindspore/ops/_op_impl/tbe/topkv2.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================ - -"""TopKV2 op""" -from mindspore.ops.op_info_register import op_info_register - - -@op_info_register("""{ - "op_name": "TopKV2", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "top_k_v2.so", - "compute_cost": 10, - "kernel_name": "top_k_v2", - "partial_flag": true, - "attr": [ - { - "name": "k", - "param_type": "required", - "type": "int", - "value": "all" - }, - { - "name": "sorted", - "param_type": "required", - "type": "bool", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "DefaultFormat" - ], - "name": "input_indices", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "DefaultFormat" - ], - "name": "values", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "int32" - ], - "format": [ - "DefaultFormat" - ], - "name": "indices", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") -def _topk_v2_tbe(): - """TopKV2 TBE register""" - return diff --git a/mindspore/ops/_op_impl/tbe/trans_data.py b/mindspore/ops/_op_impl/tbe/trans_data.py index 1b7c8fa25d..f961491b37 100644 --- a/mindspore/ops/_op_impl/tbe/trans_data.py +++ b/mindspore/ops/_op_impl/tbe/trans_data.py @@ -14,71 +14,54 @@ # ============================================================================ """TransData op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +trans_data_op_info = TBERegOp("TransData") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("trans_data.so") \ + .compute_cost(10) \ + .kernel_name("trans_data") \ + .partial_flag(True) \ + .attr("src_format", "required", "str", "DefaultFormat,NC1HWC0,FracZ,FRACTAL_NZ,HWCN,C1HWNCoC0")\ + .attr("dst_format", "required", "str", "DefaultFormat,NC1HWC0,FracZ,FRACTAL_NZ,HWCN,C1HWNCoC0")\ + .input(0, "src", False, "required", "all") \ + .output(0, "dst", False, "required", "all") \ + .dtype_format(DataType.U16_Default, DataType.U16_5HD) \ + .dtype_format(DataType.U16_Default, DataType.U16_FracZ) \ + .dtype_format(DataType.U16_Default, DataType.U16_FracNZ) \ + .dtype_format(DataType.U16_FracZ, DataType.U16_Default) \ + .dtype_format(DataType.U16_FracZ, DataType.U16_HWCN) \ + .dtype_format(DataType.U16_FracNZ, DataType.U16_Default) \ + .dtype_format(DataType.U16_5HD, DataType.U16_Default) \ + .dtype_format(DataType.U16_HWCN, DataType.U16_FracZ) \ + .dtype_format(DataType.U16_HWCN, DataType.U16_C1HWNCoC0) \ + .dtype_format(DataType.U16_C1HWNCoC0, DataType.U16_HWCN) \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_Default, DataType.F16_FracNZ) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_Default) \ + .dtype_format(DataType.F16_FracZ, DataType.F16_HWCN) \ + .dtype_format(DataType.F16_FracNZ, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_Default) \ + .dtype_format(DataType.F16_HWCN, DataType.F16_FracZ) \ + .dtype_format(DataType.F16_HWCN, DataType.F16_C1HWNCoC0) \ + .dtype_format(DataType.F16_C1HWNCoC0, DataType.F16_HWCN) \ + .dtype_format(DataType.F32_Default, DataType.F32_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_Default, DataType.F32_FracNZ) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_Default) \ + .dtype_format(DataType.F32_FracZ, DataType.F32_HWCN) \ + .dtype_format(DataType.F32_FracNZ, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_Default) \ + .dtype_format(DataType.F32_HWCN, DataType.F32_FracZ) \ + .dtype_format(DataType.F32_HWCN, DataType.F32_C1HWNCoC0) \ + .dtype_format(DataType.F32_C1HWNCoC0, DataType.F32_HWCN) \ + .get_op_info() -@op_info_register("""{ - "op_name": "TransData", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "trans_data.so", - "compute_cost": 10, - "kernel_name": "trans_data", - "partial_flag": true, - "attr": [ - { - "name": "src_format", - "param_type": "required", - "type": "str", - "value": "DefaultFormat,NC1HWC0,FracZ,FRACTAL_NZ,HWCN,C1HWNCoC0" - }, - { - "name": "dst_format", - "param_type": "required", - "type": "str", - "value": "DefaultFormat,NC1HWC0,FracZ,FRACTAL_NZ,HWCN,C1HWNCoC0" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "bool", - "float","float","float","float","float","float","float","float","float","float", - "float16","float16","float16","float16","float16","float16","float16","float16","float16","float16" - ], - "format": [ - "DefaultFormat", - "DefaultFormat","DefaultFormat","DefaultFormat","FracZ","FRACTAL_NZ","NC1HWC0","HWCN","HWCN","C1HWNCoC0","FracZ", - "DefaultFormat","DefaultFormat","DefaultFormat","FracZ","FRACTAL_NZ","NC1HWC0","HWCN","HWCN","C1HWNCoC0","FracZ" - ], - "name": "src", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "bool", - "float","float","float","float","float","float","float","float","float","float", - "float16","float16","float16","float16","float16","float16","float16","float16","float16","float16" - ], - "format": [ - "NC1HWC0", - "NC1HWC0","FRACTAL_NZ","FracZ","DefaultFormat","DefaultFormat","DefaultFormat","FracZ","C1HWNCoC0","HWCN","HWCN", - "NC1HWC0","FRACTAL_NZ","FracZ","DefaultFormat","DefaultFormat","DefaultFormat","FracZ","C1HWNCoC0","HWCN","HWCN" - ], - "name": "dst", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(trans_data_op_info) def _trans_data_tbe(): """TransData TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/transpose_d.py b/mindspore/ops/_op_impl/tbe/transpose_d.py index e79a16adeb..fffc95a38f 100644 --- a/mindspore/ops/_op_impl/tbe/transpose_d.py +++ b/mindspore/ops/_op_impl/tbe/transpose_d.py @@ -14,59 +14,32 @@ # ============================================================================ """TransposeD op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +transpose_d_op_info = TBERegOp("Transpose") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("transpose_d.so") \ + .compute_cost(10) \ + .kernel_name("transpose_d") \ + .partial_flag(True) \ + .attr("perm", "optional", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() -@op_info_register("""{ - "op_name": "Transpose", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "transpose_d.so", - "compute_cost": 10, - "kernel_name": "transpose_d", - "partial_flag": true, - "attr": [ - { - "name": "perm", - "param_type": "optional", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16", "float", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64" - ], - "format": [ - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat", - "DefaultFormat", "DefaultFormat", "DefaultFormat", "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +@op_info_register(transpose_d_op_info) def _transpose_d_tbe(): """TransposeD TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/unsorted_segment_sum.py b/mindspore/ops/_op_impl/tbe/unsorted_segment_sum.py index 2bc36b9e3d..5dc07dd59f 100644 --- a/mindspore/ops/_op_impl/tbe/unsorted_segment_sum.py +++ b/mindspore/ops/_op_impl/tbe/unsorted_segment_sum.py @@ -14,184 +14,33 @@ # ============================================================================ """UnsortedSegmentSum op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +unsorted_segment_sum_op_info = TBERegOp("UnsortedSegmentSum") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("unsorted_segment_sum_d.so") \ + .compute_cost(10) \ + .kernel_name("unsorted_segment_sum_d") \ + .partial_flag(True) \ + .attr("num_segments", "required", "int", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "segment_ids", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.I8_Default, DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I32_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.I32_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.I32_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.I32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name":"UnsortedSegmentSum", - "imply_type":"TBE", - "fusion_type":"OPAQUE", - "async_flag":false, - "binfile_name":"unsorted_segment_sum_d.so", - "compute_cost":10, - "kernel_name":"unsorted_segment_sum_d", - "partial_flag":true, - "attr":[ - { - "name":"num_segments", - "param_type":"required", - "type":"int", - "value":"all" - } - ], - "inputs":[ - { - "index":0, - "dtype":[ - "float16", - "float16", - "float16", - "float16", - "float", - "float", - "float", - "float", - "int8", - "int8", - "int8", - "int8", - "uint8", - "uint8", - "uint8", - "uint8", - "int32", - "int32", - "int32", - "int32" - ], - "format":[ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat" - ], - "name":"x", - "need_compile":false, - "param_type":"required", - "shape":"all" - }, - { - "index":1, - "dtype":[ - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32", - "int32" - ], - "format":[ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat" - ], - "name":"segment_ids", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ], - "outputs":[ - { - "index":0, - "dtype":[ - "float16", - "float16", - "float16", - "float16", - "float", - "float", - "float", - "float", - "int8", - "int8", - "int8", - "int8", - "uint8", - "uint8", - "uint8", - "uint8", - "int32", - "int32", - "int32", - "int32" - ], - "format":[ - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat", - "DefaultFormat", - "NC1HWC0", - "DefaultFormat", - "DefaultFormat" - ], - "name":"y", - "need_compile":false, - "param_type":"required", - "shape":"all" - } - ] -}""") + +@op_info_register(unsorted_segment_sum_op_info) def _unsorted_segment_sum_tbe(): """UnsortedSegmentSum TBE register""" return diff --git a/mindspore/ops/_op_impl/tbe/zeros_like.py b/mindspore/ops/_op_impl/tbe/zeros_like.py index 25f48b80a5..144b0c95cb 100644 --- a/mindspore/ops/_op_impl/tbe/zeros_like.py +++ b/mindspore/ops/_op_impl/tbe/zeros_like.py @@ -14,53 +14,33 @@ # ============================================================================ """ZerosLike op""" -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType +zeros_like_op_info = TBERegOp("ZerosLike") \ + .fusion_type("ELEMWISE") \ + .async_flag(False) \ + .binfile_name("zeros_like.so") \ + .compute_cost(10) \ + .kernel_name("zeros_like") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_5HD, DataType.BOOL_5HD) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_5HD, DataType.I8_5HD) \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_5HD, DataType.U8_5HD) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_5HD, DataType.I32_5HD) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_5HD, DataType.F32_5HD) \ + .get_op_info() -@op_info_register("""{ - "op_name": "ZerosLike", - "imply_type": "TBE", - "fusion_type": "ELEMWISE", - "async_flag": false, - "binfile_name": "zeros_like.so", - "compute_cost": 10, - "kernel_name": "zeros_like", - "partial_flag": true, - "attr": [ - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0", - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16","float16","float","float","int32","int32","int8","int8","uint8","uint8","bool","bool" - ], - "format": [ - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0", - "DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0","DefaultFormat","NC1HWC0" - ], - "name": "y", - "param_type": "required", - "shape": "all" - } - ] -}""") +@op_info_register(zeros_like_op_info) def _zeros_like_tbe(): """ZerosLike TBE register""" return diff --git a/mindspore/ops/_utils/__init__.py b/mindspore/ops/_utils/__init__.py index 00ce07453a..8fe1102968 100644 --- a/mindspore/ops/_utils/__init__.py +++ b/mindspore/ops/_utils/__init__.py @@ -14,6 +14,6 @@ # ============================================================================ """ops utils.""" -from .broadcast import _get_broadcast_shape +from .utils import _get_broadcast_shape, _get_concat_offset -__all__ = ['_get_broadcast_shape'] +__all__ = ['_get_broadcast_shape', '_get_concat_offset'] diff --git a/mindspore/ops/_utils/broadcast.py b/mindspore/ops/_utils/utils.py similarity index 62% rename from mindspore/ops/_utils/broadcast.py rename to mindspore/ops/_utils/utils.py index c71158de57..fbd81c4f0d 100644 --- a/mindspore/ops/_utils/broadcast.py +++ b/mindspore/ops/_utils/utils.py @@ -13,8 +13,11 @@ # limitations under the License. # ============================================================================ -"""broadcast""" +"""utils for operator""" +from ..._checkparam import ParamValidator as validator +from ..._checkparam import Rel +from ...common import dtype as mstype def _get_broadcast_shape(x_shape, y_shape, prim_name): """ @@ -57,3 +60,27 @@ def _get_broadcast_shape(x_shape, y_shape, prim_name): broadcast_shape_front = y_shape[0: y_len - length] if length == x_len else x_shape[0: x_len - length] broadcast_shape = broadcast_shape_front + broadcast_shape_back return broadcast_shape + + +def _get_concat_offset(x_shp, x_type, axis): + """for concat and concatoffset check args and compute offset""" + validator.check_type("shape", x_shp, [tuple]) + validator.check_integer("len of input_x shape", len(x_shp), 0, Rel.GT) + validator.check_subclass("shape0", x_type[0], mstype.tensor) + validator.check_integer("len of input_x0 shape", len(x_shp[0]), 0, Rel.GT) + rank_base = len(x_shp[0]) + validator.check_int_range('axis', axis, -rank_base - 1, rank_base, Rel.INC_BOTH) + if axis < 0: + axis = axis + rank_base + all_shp = x_shp[0][axis] + offset = [0,] + for i in range(1, len(x_shp)): + v = x_shp[i] + validator.check('len of x_shp[%d]' % i, len(v), 'len of base', len(x_shp[0])) + validator.check('x_type[%d]' % i, x_type[i], 'base', x_type[0]) + for j in range(rank_base): + if j != axis and v[j] != x_shp[0][j]: + raise ValueError("Concat evaluator element %d shape in input can not concat with first element" % i) + offset.append(all_shp) + all_shp += v[axis] + return offset, all_shp, axis diff --git a/mindspore/ops/composite/base.py b/mindspore/ops/composite/base.py index 8670f4aa7c..4b559d1605 100644 --- a/mindspore/ops/composite/base.py +++ b/mindspore/ops/composite/base.py @@ -307,3 +307,12 @@ def _mixed_precision_cast_helper_2(type_, x): if F.issubclass_(F.dtype(x), mstype.float_): return P.Cast()(x, type_) return x + +@_mp_cast_helper.register("TypeType", "Tuple") +@core +def _mixed_precision_cast_helper_3(type_, x): + """if x is a tuple""" + t = () + for item in x: + t = t + (_mp_cast_helper(type_, item),) + return t diff --git a/mindspore/ops/composite/multitype_ops/__init__.py b/mindspore/ops/composite/multitype_ops/__init__.py index db28b1b5f6..40bf71d49a 100644 --- a/mindspore/ops/composite/multitype_ops/__init__.py +++ b/mindspore/ops/composite/multitype_ops/__init__.py @@ -19,6 +19,9 @@ from .add_impl import add from .sub_impl import sub from .mul_impl import mul from .div_impl import div +from .pow_impl import pow_ +from .floordiv_impl import floordiv +from .mod_impl import mod from .getitem_impl import getitem from .zeros_like_impl import zeros_like from .ones_like_impl import ones_like @@ -38,6 +41,9 @@ __all__ = [ 'sub', 'mul', 'div', + 'pow_', + 'floordiv', + 'mod', 'uadd', 'zeros_like', 'ones_like', diff --git a/mindspore/ops/composite/multitype_ops/add_impl.py b/mindspore/ops/composite/multitype_ops/add_impl.py index 2b1f83679e..2ad81bfc93 100644 --- a/mindspore/ops/composite/multitype_ops/add_impl.py +++ b/mindspore/ops/composite/multitype_ops/add_impl.py @@ -69,6 +69,21 @@ def _scalar_add_scalar(x, y): return F.scalar_add(x, y) +@add.register("String", "String") +def _string_concat_string(x, y): + """ + Concatenate the string y to the string x. + + Args: + x (str): The first input string. + y (str): the second input string. + + Returns: + str, concatenate the y to the x. + """ + return F.string_concat(x, y) + + @add.register("Number", "Tensor") def _scalar_add_tensor(x, y): """ @@ -81,8 +96,7 @@ def _scalar_add_tensor(x, y): Returns: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(x, F.dtype(y)) - return F.tensor_add(z, y) + return F.tensor_add(x, y) @add.register("Tensor", "Number") @@ -97,8 +111,7 @@ def _tensor_add_scalar(x, y): Returns: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(y, F.dtype(x)) - return F.tensor_add(x, z) + return F.tensor_add(x, y) @add.register("Tensor", "Tensor") diff --git a/mindspore/ops/composite/multitype_ops/div_impl.py b/mindspore/ops/composite/multitype_ops/div_impl.py index 3edf3c8d9f..c37fcb9c36 100644 --- a/mindspore/ops/composite/multitype_ops/div_impl.py +++ b/mindspore/ops/composite/multitype_ops/div_impl.py @@ -68,8 +68,7 @@ def _scalar_div_tensor(x, y): Returns: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(x, F.dtype(y)) - return F.tensor_div(z, y) + return F.tensor_div(x, y) @div.register("Tensor", "Number") @@ -84,5 +83,4 @@ def _tensor_div_scalar(x, y): Returns: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(y, F.dtype(x)) - return F.tensor_div(x, z) + return F.tensor_div(x, y) diff --git a/mindspore/ops/composite/multitype_ops/equal_impl.py b/mindspore/ops/composite/multitype_ops/equal_impl.py index 428cdf4705..ff54c34fad 100644 --- a/mindspore/ops/composite/multitype_ops/equal_impl.py +++ b/mindspore/ops/composite/multitype_ops/equal_impl.py @@ -190,6 +190,7 @@ def _none_equal_tuple(x, y): """ return False + @equal.register("Tensor", "Number") @equal.register("Number", "Tensor") @equal.register("Tensor", "Tensor") @@ -235,3 +236,33 @@ def _none_equal_tensor(x, y): bool, return false. """ return False + + +@equal.register("List", "None") +def _list_equal_none(x, y): + """ + Determine if list equal none. + + Args: + x (list): The first input which is a list. + y (none): The second input which is none. + + Returns: + bool, return false. + """ + return False + + +@equal.register("None", "List") +def _none_equal_list(x, y): + """ + Determine if none equal list. + + Args: + x (none): The first input which is none. + y (list): The second input which is a list. + + Returns: + bool, return false. + """ + return False diff --git a/mindspore/ops/composite/multitype_ops/floordiv_impl.py b/mindspore/ops/composite/multitype_ops/floordiv_impl.py new file mode 100644 index 0000000000..c1a47f881f --- /dev/null +++ b/mindspore/ops/composite/multitype_ops/floordiv_impl.py @@ -0,0 +1,50 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Implementation for internal polymorphism `floordiv` operations.""" + +from ...composite import base +from ... import functional as F + + +floordiv = base.MultitypeFuncGraph("floordiv") +""" +`floordiv` is a metafuncgraph object which will compute the floordiv of two objects +using ".register" decorator. +""" + + +@floordiv.register("Number", "Number") +def _floordiv_scalar(x, y): + """Returns x // y where x and y are all scalars.""" + return F.scalar_floordiv(x, y) + + +@floordiv.register("Tensor", "Tensor") +def _floordiv_tensor(x, y): + """Returns x // y where x and y are all tensors and have save dtype.""" + return F.tensor_floordiv(x, y) + + +@floordiv.register("Tensor", "Number") +def _tensor_floordiv_scalar(x, y): + """Returns x // y where x is a tensor and y is a scalar. x and y should have same dtype.""" + return F.tensor_floordiv(x, y) + + +@floordiv.register("Number", "Tensor") +def _scalar_floordiv_tensor(x, y): + """Returns x // y where x is a scalar and y is a tensor. x and y should have same dtype.""" + return F.tensor_floordiv(x, y) diff --git a/mindspore/ops/composite/multitype_ops/mod_impl.py b/mindspore/ops/composite/multitype_ops/mod_impl.py new file mode 100644 index 0000000000..e9947677ac --- /dev/null +++ b/mindspore/ops/composite/multitype_ops/mod_impl.py @@ -0,0 +1,50 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Implementation for internal polymorphism `mod` operations.""" + +from ...composite import base +from ... import functional as F + + +mod = base.MultitypeFuncGraph("mod") +""" +`mod` is a metafuncgraph object which will compute the mod of two objects +using ".register" decorator. +""" + + +@mod.register("Number", "Number") +def _mod_scalar(x, y): + """Returns x % y where x and y are all scalars.""" + return F.scalar_mod(x, y) + + +@mod.register("Tensor", "Tensor") +def _mod_tensor(x, y): + """Returns x % y where x and y are all tensors and have save dtype.""" + return F.tensor_mod(x, y) + + +@mod.register("Tensor", "Number") +def _tensor_mod_scalar(x, y): + """Returns x % y where x is a tensor and y is a scalar. x and y should have same dtype.""" + return F.tensor_mod(x, y) + + +@mod.register("Number", "Tensor") +def _scalar_mod_tensor(x, y): + """Returns x % y where x is a scalar and y is a tensor. x and y should have same dtype.""" + return F.tensor_mod(x, y) diff --git a/mindspore/ops/composite/multitype_ops/mul_impl.py b/mindspore/ops/composite/multitype_ops/mul_impl.py index 1d4733a46b..ce9ec391af 100644 --- a/mindspore/ops/composite/multitype_ops/mul_impl.py +++ b/mindspore/ops/composite/multitype_ops/mul_impl.py @@ -56,8 +56,7 @@ def _scalar_mul_tensor(x, y): Outputs: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(x, F.dtype(y)) - return F.tensor_mul(z, y) + return F.tensor_mul(x, y) @mul.register("Tensor", "Number") @@ -68,5 +67,4 @@ def _tensor_mul_scalar(x, y): Outputs: Tensor, has the same dtype as x. """ - z = F.scalar_to_tensor(y, F.dtype(x)) - return F.tensor_mul(x, z) + return F.tensor_mul(x, y) diff --git a/mindspore/ops/composite/multitype_ops/pow_impl.py b/mindspore/ops/composite/multitype_ops/pow_impl.py new file mode 100644 index 0000000000..8d73335c98 --- /dev/null +++ b/mindspore/ops/composite/multitype_ops/pow_impl.py @@ -0,0 +1,50 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Implementation for internal polymorphism `pow` operations.""" + +from ...composite import base +from ... import functional as F + + +pow_ = base.MultitypeFuncGraph("pow") +""" +`pow` is a metafuncgraph object which will compute the pow of two objects +using ".register" decorator. +""" + + +@pow_.register("Number", "Number") +def _pow_scalar(x, y): + """Returns x ** y where x and y are all scalars.""" + return F.scalar_pow(x, y) + + +@pow_.register("Tensor", "Tensor") +def _pow_tensor(x, y): + """Returns x ** y where x and y are all tensors and have save dtype.""" + return F.tensor_pow(x, y) + + +@pow_.register("Tensor", "Number") +def _tensor_pow_scalar(x, y): + """Returns x ** y where x is a tensor and y is a scalar. x and y should have same dtype.""" + return F.tensor_pow(x, y) + + +@pow_.register("Number", "Tensor") +def _scalar_pow_tensor(x, y): + """Returns x ** y where x is a scalar and y is a tensor. x and y should have same dtype.""" + return F.tensor_pow(x, y) diff --git a/mindspore/ops/composite/multitype_ops/sub_impl.py b/mindspore/ops/composite/multitype_ops/sub_impl.py index 4a3224a859..431a58b991 100644 --- a/mindspore/ops/composite/multitype_ops/sub_impl.py +++ b/mindspore/ops/composite/multitype_ops/sub_impl.py @@ -41,12 +41,10 @@ def _sub_tensor(x, y): @sub.register("Number", "Tensor") def _scalar_sub_tensor(x, y): """Returns x - y where x is a scalar and y is a tensor. x and y should have same dtype.""" - z = F.scalar_to_tensor(x, F.dtype(y)) - return F.tensor_sub(z, y) + return F.tensor_sub(x, y) @sub.register("Tensor", "Number") def _tensor_sub_scalar(x, y): """Returns x - y where x is a tensor and y is a scalar. x and y should have same dtype.""" - z = F.scalar_to_tensor(y, F.dtype(x)) - return F.tensor_sub(x, z) + return F.tensor_sub(x, y) diff --git a/mindspore/ops/functional.py b/mindspore/ops/functional.py index 4da725145f..611c569553 100644 --- a/mindspore/ops/functional.py +++ b/mindspore/ops/functional.py @@ -48,6 +48,9 @@ tensor_ge = P.GreaterEqual() tensor_sub = P.Sub() tensor_mul = P.Mul() tensor_div = P.RealDiv() +tensor_floordiv = P.FloorDiv() +tensor_pow = P.Pow() +tensor_mod = P.FloorMod() strided_slice = P.StridedSlice() same_type_shape = P.SameTypeShape() equal = P.Equal() @@ -83,6 +86,7 @@ scalar_add = Primitive('scalar_add') scalar_mul = Primitive('scalar_mul') scalar_sub = Primitive('scalar_sub') scalar_div = Primitive('scalar_div') +scalar_floordiv = Primitive('scalar_floordiv') scalar_log = Primitive('scalar_log') scalar_pow = Primitive('scalar_pow') scalar_gt = Primitive('scalar_gt') @@ -95,6 +99,7 @@ scalar_uadd = Primitive('scalar_uadd') scalar_usub = Primitive('scalar_usub') scalar_mod = Primitive('scalar_mod') string_eq = Primitive('string_equal') +string_concat = Primitive('string_concat') bool_not = Primitive("bool_not") bool_or = Primitive("bool_or") bool_and = Primitive("bool_and") @@ -104,7 +109,8 @@ logical_not = P.LogicalNot() array_to_scalar = Primitive('array_to_scalar') is_ = Primitive("is_") is_not = Primitive("is_not") - +in_dict = Primitive("in_dict") +not_in_dict = Primitive("not_in_dict") broadcast_gradient_args = Primitive('BroadcastGradientArgs') dot = Primitive('dot') array_reduce = Primitive('array_reduce') diff --git a/mindspore/ops/op_info_register.py b/mindspore/ops/op_info_register.py index 0750094e18..e4b0bfdbfe 100644 --- a/mindspore/ops/op_info_register.py +++ b/mindspore/ops/op_info_register.py @@ -57,7 +57,7 @@ def op_info_register(op_info): return register_decorator -class RegOp(): +class RegOp: """ Base class for op info register. @@ -151,7 +151,7 @@ class RegOp(): fn_list[idx](element) out_dict[key_list[idx]] = element if kwargs: - out_dict = dict(out_dict, kwargs) + out_dict = dict(out_dict, **kwargs) return out_dict def fusion_type(self, fusion_type): @@ -177,7 +177,7 @@ class RegOp(): TypeError: If the type of args is not tuple. """ if len(self.inputs) + len(self.outputs) != len(args): - raise ValueError("input size add output size must be equal to detype format size") + raise ValueError("input size add output size must be equal to dtype format size") dtype_format = [] for arg in args: if not isinstance(arg, tuple) or len(arg) != 2: @@ -205,6 +205,64 @@ class RegOp(): return op_info +class AkgRegOp(RegOp): + """Class for Akg op info register""" + + def __init__(self, op_name): + super(AkgRegOp, self).__init__(op_name) + self.imply_type = "AutoDiff" + self.processor = "cuda" + + def input(self, index=None, name=None, **kwargs): + """ + Register Akg op input information. + + Args: + index (int): Order of the input. Default: None. + name (str): Name of the input. Default: None. + kwargs (dict): Other information for the input. + """ + param_list = [index, name] + key_list = ["index", "name"] + fn_list = [self._is_int, self._is_string] + input_dict = self._check_param(param_list, key_list, fn_list, kwargs) + self.inputs.append(input_dict) + return self + + def output(self, index=None, name=None, **kwargs): + """ + Register Akg op output information. + + Args: + index (int): Order of the output. Default: None. + name (str): Name of the output. Default: None. + kwargs (dict): Other information for the output. + """ + param_list = [index, name] + key_list = ["index", "name"] + fn_list = [self._is_int, self._is_string] + output_dict = self._check_param(param_list, key_list, fn_list, kwargs) + self.outputs.append(output_dict) + return self + + def attr(self, name=None, param_type=None, value_type=None, **kwargs): + """ + Register Akg op attribute information. + + Args: + name (str): Name of the attribute. Default: None. + param_type (str): Param type of the attribute. Default: None. + value_type (str): Value type of the attribute. Default: None. + kwargs (dict): Other information for the attribute. + """ + param_list = [name, param_type, value_type] + key_list = ["name", "param_type", "type"] + fn_list = [self._is_string] + attr_dict = self._check_param(param_list, key_list, fn_list, kwargs) + self.attr_.append(attr_dict) + return self + + class AiCPURegOp(RegOp): """Class for AiCPU op info register""" @@ -425,9 +483,9 @@ class TBERegOp(RegOp): return self -class DataType(): +class DataType: """ - Various combinations of dtype and formatself. + Various combinations of dtype and format. The current list below maybe not completed. If necessary, please add it. """ @@ -435,6 +493,9 @@ class DataType(): BOOL_None = ("bool", "") BOOL_Default = ("bool", "DefaultFormat") BOOL_5HD = ("bool", "NC1HWC0") + BOOL_FracZ = ("bool", "FracZ") + BOOL_FracNZ = ("bool", "FRACTAL_NZ") + BOOL_C1HWNCoC0 = ("bool", "C1HWNCoC0") BOOL_NCHW = ("bool", "NCHW") BOOL_NHWC = ("bool", "NHWC") BOOL_HWCN = ("bool", "HWCN") @@ -442,8 +503,9 @@ class DataType(): I8_None = ("int8", "") I8_Default = ("int8", "DefaultFormat") I8_5HD = ("int8", "NC1HWC0") - I8_FracZ = ("int8", "Fracz") + I8_FracZ = ("int8", "FracZ") I8_FracNZ = ("int8", "FRACTAL_NZ") + I8_C1HWNCoC0 = ("int8", "C1HWNCoC0") I8_NCHW = ("int8", "NCHW") I8_NHWC = ("int8", "NHWC") I8_HWCN = ("int8", "HWCN") @@ -451,8 +513,9 @@ class DataType(): U8_None = ("uint8", "") U8_Default = ("uint8", "DefaultFormat") U8_5HD = ("uint8", "NC1HWC0") - U8_FracZ = ("uint8", "Fracz") + U8_FracZ = ("uint8", "FracZ") U8_FracNZ = ("uint8", "FRACTAL_NZ") + U8_C1HWNCoC0 = ("uint8", "C1HWNCoC0") U8_NCHW = ("uint8", "NCHW") U8_NHWC = ("uint8", "NHWC") U8_HWCN = ("uint8", "HWCN") @@ -460,8 +523,9 @@ class DataType(): I16_None = ("int16", "") I16_Default = ("int16", "DefaultFormat") I16_5HD = ("int16", "NC1HWC0") - I16_FracZ = ("int16", "Fracz") + I16_FracZ = ("int16", "FracZ") I16_FracNZ = ("int16", "FRACTAL_NZ") + I16_C1HWNCoC0 = ("int16", "C1HWNCoC0") I16_NCHW = ("int16", "NCHW") I16_NHWC = ("int16", "NHWC") I16_HWCN = ("int16", "HWCN") @@ -469,8 +533,9 @@ class DataType(): U16_None = ("uint16", "") U16_Default = ("uint16", "DefaultFormat") U16_5HD = ("uint16", "NC1HWC0") - U16_FracZ = ("uint16", "Fracz") + U16_FracZ = ("uint16", "FracZ") U16_FracNZ = ("uint16", "FRACTAL_NZ") + U16_C1HWNCoC0 = ("uint16", "C1HWNCoC0") U16_NCHW = ("uint16", "NCHW") U16_NHWC = ("uint16", "NHWC") U16_HWCN = ("uint16", "HWCN") @@ -478,8 +543,9 @@ class DataType(): I32_None = ("int32", "") I32_Default = ("int32", "DefaultFormat") I32_5HD = ("int32", "NC1HWC0") - I32_FracZ = ("int32", "Fracz") + I32_FracZ = ("int32", "FracZ") I32_FracNZ = ("int32", "FRACTAL_NZ") + I32_C1HWNCoC0 = ("int32", "C1HWNCoC0") I32_NCHW = ("int32", "NCHW") I32_NHWC = ("int32", "NHWC") I32_HWCN = ("int32", "HWCN") @@ -487,8 +553,9 @@ class DataType(): U32_None = ("uint32", "") U32_Default = ("uint32", "DefaultFormat") U32_5HD = ("uint32", "NC1HWC0") - U32_FracZ = ("uint32", "Fracz") + U32_FracZ = ("uint32", "FracZ") U32_FracNZ = ("uint32", "FRACTAL_NZ") + U32_C1HWNCoC0 = ("uint32", "C1HWNCoC0") U32_NCHW = ("uint32", "NCHW") U32_NHWC = ("uint32", "NHWC") U32_HWCN = ("uint32", "HWCN") @@ -496,8 +563,9 @@ class DataType(): I64_None = ("int64", "") I64_Default = ("int64", "DefaultFormat") I64_5HD = ("int64", "NC1HWC0") - I64_FracZ = ("int64", "Fracz") + I64_FracZ = ("int64", "FracZ") I64_FracNZ = ("int64", "FRACTAL_NZ") + I64_C1HWNCoC0 = ("int64", "C1HWNCoC0") I64_NCHW = ("int64", "NCHW") I64_NHWC = ("int64", "NHWC") I64_HWCN = ("int64", "HWCN") @@ -505,8 +573,9 @@ class DataType(): U64_None = ("uint64", "") U64_Default = ("uint64", "DefaultFormat") U64_5HD = ("uint64", "NC1HWC0") - U64_FracZ = ("uint64", "Fracz") + U64_FracZ = ("uint64", "FracZ") U64_FracNZ = ("uint64", "FRACTAL_NZ") + U64_C1HWNCoC0 = ("uint64", "C1HWNCoC0") U64_NCHW = ("uint64", "NCHW") U64_NHWC = ("uint64", "NHWC") U64_HWCN = ("uint64", "HWCN") @@ -514,7 +583,7 @@ class DataType(): F16_None = ("float16", "") F16_Default = ("float16", "DefaultFormat") F16_5HD = ("float16", "NC1HWC0") - F16_FracZ = ("float16", "Fracz") + F16_FracZ = ("float16", "FracZ") F16_FracNZ = ("float16", "FRACTAL_NZ") F16_C1HWNCoC0 = ("float16", "C1HWNCoC0") F16_NCHW = ("float16", "NCHW") @@ -524,9 +593,10 @@ class DataType(): F32_None = ("float32", "") F32_Default = ("float32", "DefaultFormat") F32_5HD = ("float32", "NC1HWC0") - F32_FracZ = ("float32", "Fracz") + F32_FracZ = ("float32", "FracZ") F32_FracNZ = ("float32", "FRACTAL_NZ") F32_C1HWNCoC0 = ("float32", "C1HWNCoC0") F32_NCHW = ("float32", "NCHW") F32_NHWC = ("float32", "NHWC") F32_HWCN = ("float32", "HWCN") + \ No newline at end of file diff --git a/mindspore/ops/operations/__init__.py b/mindspore/ops/operations/__init__.py index c10aef1ac0..1f0ee8a04d 100644 --- a/mindspore/ops/operations/__init__.py +++ b/mindspore/ops/operations/__init__.py @@ -19,7 +19,7 @@ Primitive operator classes. A collection of operators to build nerual networks or computing functions. """ -from .array_ops import (Argmax, Argmin, Cast, ConcatOffset, Concat, Pack, Unpack, +from .array_ops import (Argmax, Argmin, Cast, Concat, Pack, Unpack, Diag, DiagPart, DType, ExpandDims, Eye, Fill, GatherNd, GatherV2, InvertPermutation, IsInstance, IsSubClass, ArgMaxWithValue, OnesLike, ZerosLike, @@ -34,7 +34,7 @@ from .comm_ops import (AllGather, AllReduce, _AlltoAll, ReduceScatter, Broadcast _MirrorOperator, ReduceOp, _VirtualDataset, _VirtualDiv, _GetTensorSlice) from .debug_ops import (ImageSummary, InsertGradientOf, ScalarSummary, - TensorSummary, Print) + TensorSummary, HistogramSummary, Print) from .control_ops import ControlDepend, GeSwitch, Merge from .inner_ops import ScalarCast from .math_ops import (Abs, ACos, AddN, AssignAdd, AssignSub, Atan2, BatchMatMul, @@ -57,18 +57,19 @@ from .nn_ops import (LSTM, SGD, Adam, ApplyMomentum, BatchNorm, Gelu, Elu, GetNext, L2Normalize, LayerNorm, LogSoftmax, - MaxPool, + MaxPool, ExtractImagePatches, AvgPool, Conv2DBackpropInput, - MaxPoolWithArgmax, OneHot, Pad, PReLU, ReLU, ReLU6, + MaxPoolWithArgmax, OneHot, Pad, MirrorPad, PReLU, ReLU, ReLU6, HSwish, HSigmoid, ResizeBilinear, Sigmoid, SigmoidCrossEntropyWithLogits, SmoothL1Loss, Softmax, SoftmaxCrossEntropyWithLogits, ROIAlign, SparseSoftmaxCrossEntropyWithLogits, Tanh, - TopK, BinaryCrossEntropy, SparseApplyAdagrad, LARSUpdate, ApplyFtrl, SparseApplyFtrlD, + TopK, BinaryCrossEntropy, SparseApplyAdagrad, LARSUpdate, ApplyFtrl, ApplyRMSProp, ApplyCenteredRMSProp) from .other_ops import Assign, IOU, BoundingBoxDecode, BoundingBoxEncode, CheckValid, MakeRefKey - +from . import _quant_ops +from ._quant_ops import * __all__ = [ 'TensorAdd', @@ -88,6 +89,7 @@ __all__ = [ 'Sqrt', 'Square', 'Conv2D', + 'ExtractImagePatches', 'Flatten', 'MaxPoolWithArgmax', 'FusedBatchNorm', @@ -138,12 +140,15 @@ __all__ = [ 'ReLU6', 'Elu', 'Sigmoid', + 'HSwish', + 'HSigmoid', 'Tanh', 'RandomChoiceWithMask', 'ResizeBilinear', 'ScalarSummary', 'ImageSummary', 'TensorSummary', + 'HistogramSummary', "Print", 'InsertGradientOf', 'InvertPermutation', @@ -177,6 +182,7 @@ __all__ = [ 'ScatterNd', 'ResizeNearestNeighbor', 'Pad', + 'MirrorPad', 'GatherNd', 'ScatterNdUpdate', 'Floor', @@ -195,7 +201,6 @@ __all__ = [ 'LogicalOr', 'Size', 'DepthwiseConv2dNative', - 'ConcatOffset', 'UnsortedSegmentSum', "AllGather", "AllReduce", @@ -227,7 +232,6 @@ __all__ = [ "Abs", "BinaryCrossEntropy", "SparseApplyAdagrad", - "SparseApplyFtrlD", "SpaceToDepth", "DepthToSpace", "Conv2DBackpropInput", @@ -242,4 +246,5 @@ __all__ = [ "ApplyCenteredRMSProp" ] +__all__.extend(_quant_ops.__all__) __all__.sort() diff --git a/mindspore/ops/operations/_grad_ops.py b/mindspore/ops/operations/_grad_ops.py index f38044ab6a..48d1a2a89c 100644 --- a/mindspore/ops/operations/_grad_ops.py +++ b/mindspore/ops/operations/_grad_ops.py @@ -20,6 +20,7 @@ from ..._c_expression import signature_kind as sig_kind from ..primitive import Primitive, PrimitiveWithInfer, prim_attr_register from ..._checkparam import ParamValidator as validator from ..._checkparam import Rel, check_int_positive, check_bool +from .._utils import _get_concat_offset from ...common import dtype as mstype @@ -107,6 +108,33 @@ class BinaryCrossEntropyGrad(PrimitiveWithInfer): validator.check_two_types_same('x_type', x_type, 'weight_type', weight_type) return x_type +class ConcatOffset(PrimitiveWithInfer): + """primitive for computing Concat's gradient.""" + + @prim_attr_register + def __init__(self, N=2, axis=0): + """init ConcatOffset""" + + def __infer__(self, input_x): + axis = self.axis + x_shp = input_x['shape'] + x_type = input_x['dtype'] + offset, _, axis = _get_concat_offset(x_shp, x_type, axis) + self.add_prim_attr('T', x_type[0].element_type()) + offset_values = [] + for i in range(len(x_shp)): + values = [] + for j in range(len(x_shp[0])): + value = 0 + if j == axis: + value = offset[i] + values.append(value) + offset_values.append(tuple(values)) + out = {'shape': None, + 'dtype': None, + 'value': tuple(offset_values)} + return out + class Conv2DBackpropFilter(PrimitiveWithInfer): """ @@ -119,8 +147,8 @@ class Conv2DBackpropFilter(PrimitiveWithInfer): pad (int): The pad value to fill. Default: 0. mode (int): 0 Math convolutiuon, 1 cross-correlation convolution , 2 deconvolution, 3 depthwise convolution. Default: 1. - stride (int): The stride to apply conv filter. Default: 1. - dilation (int): Specifies the dilation rate to use for dilated convolution. Default: 1. + stride (tuple): The stride to apply conv filter. Default: (1, 1). + dilation (tuple): Specifies the dilation rate to use for dilated convolution. Default: (1, 1, 1, 1). group (int): Splits input into groups. Default: 1. Returns: @@ -135,8 +163,8 @@ class Conv2DBackpropFilter(PrimitiveWithInfer): pad=0, pad_list=(0, 0, 0, 0), mode=1, - stride=1, - dilation=1, + stride=(1, 1), + dilation=(1, 1, 1, 1), group=1): """init Convolution""" self.init_prim_io_names(inputs=['out_backprop', 'input', 'filter_sizes'], outputs=['output']) @@ -146,7 +174,9 @@ class Conv2DBackpropFilter(PrimitiveWithInfer): pad_mode = pad_mode.upper() self.add_prim_attr('pad_mode', pad_mode) self.pad = pad - self.stride = stride + if isinstance(stride, tuple) and len(stride) == 4: + self.stride = (stride[2], stride[3]) + self.add_prim_attr('stride', self.stride) self.dilation = dilation self.group = group self.add_prim_attr('data_format', "NCHW") @@ -805,6 +835,38 @@ class SigmoidGrad(PrimitiveWithInfer): return out +class HSigmoidGrad(PrimitiveWithInfer): + """Gets the gradient of HSigmoid operation.""" + + @prim_attr_register + def __init__(self): + self.init_prim_io_names(inputs=['y_grad', 'x'], outputs=['output']) + + def infer_shape(self, y_grad_shape, x_shape): + return x_shape + + def infer_dtype(self, y_grad_dtype, x_dtype): + validator.check_typename("y_grad dtype", y_grad_dtype, (mstype.float16, mstype.float32)) + validator.check_typename("x dtype", x_dtype, (mstype.float16, mstype.float32)) + return x_dtype + + +class HSwishGrad(PrimitiveWithInfer): + """Gets the gradient of HSwish operation.""" + + @prim_attr_register + def __init__(self): + self.init_prim_io_names(inputs=['y_grad', 'x'], outputs=['output']) + + def infer_shape(self, y_grad_shape, x_shape): + return x_shape + + def infer_dtype(self, y_grad_dtype, x_dtype): + validator.check_typename("y_grad dtype", y_grad_dtype, (mstype.float16, mstype.float32)) + validator.check_typename("x_ dtype", x_dtype, (mstype.float16, mstype.float32)) + return x_dtype + + class SigmoidCrossEntropyWithLogitsGrad(PrimitiveWithInfer): """Computes the gradients of `SigmoidCrossEntropyWithLogits`.""" @@ -915,6 +977,24 @@ class TanhGrad(PrimitiveWithInfer): return out +class MirrorPadGrad(PrimitiveWithInfer): + """Gradients of MirrorPad operation.""" + + @prim_attr_register + def __init__(self, mode="REFLECT"): + """init MirrorPad""" + validator.check_string('mode', mode, ['REFLECT', 'SYMMETRIC']) + self.mode = mode + + def __infer__(self, dout, paddings, x): + validator.check_subclass("dout", dout['dtype'], mstype.tensor) + validator.check_subclass("paddings", paddings['dtype'], mstype.tensor) + validator.check_subclass("input_x", x['dtype'], mstype.tensor) + return {'shape': x['shape'], + 'dtype': dout['dtype'], + 'value': None} + + class RefToEmbed(Primitive): r""" Make a key from Ref. diff --git a/mindspore/ops/operations/_quant_ops.py b/mindspore/ops/operations/_quant_ops.py new file mode 100644 index 0000000000..14d1bc9234 --- /dev/null +++ b/mindspore/ops/operations/_quant_ops.py @@ -0,0 +1,525 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0(the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http: // www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""Operators for quantization.""" + +from ..._checkparam import ParamValidator as validator +from ..._checkparam import Rel, check_bool, check_int_positive, check_int +from ..primitive import PrimitiveWithInfer, prim_attr_register +from ...common import dtype as mstype + +__all__ = ["FakeQuantWithMinMax", + "FakeQuantWithMinMaxGrad", + "FakeQuantWithMinMaxPerChannel", + "FakeQuantWithMinMaxPerChannelGrad", + "BatchNormFold", + "BatchNormFoldGrad", + "CorrectionMul", + "CorrectionMulGrad", + "BatchNormFold2", + "BatchNormFold2Grad", + ] + + +class FakeQuantWithMinMax(PrimitiveWithInfer): + r""" + Simulate the quantize and dequantize operations in training time. + + Args: + num_bits (int) : Number bits for aware quantilization. Default: 8. + ema (bool): Use EMA algorithm update value min and max. Default: False. + ema_decay (int) : EMA algorithm decay parameter. Default: 0.999. + quant_delay (int): Quantilization delay parameter. Before delay step in training time not update + simulate aware quantize funcion. After delay step in training time begin simulate the aware + quantize funcion. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + training (bool): Training the network or not. Default: True. + + Inputs: + - **x** (Tensor) : float32 Tensor representing the shape of the output tensor. + - **min** (Tensor) : Value of the min range of the input data x. + - **max** (Tensor) : Value of the max range of the input data x. + + Outputs: + - Tensor: Simulate quantize tensor of x. + + Examples: + >>> input_tensor = Tensor(np.random.rand(3, 16, 5, 5), mstype.float32) + >>> min_tensor = Tensor(np.array([-6]), mstype.float32) + >>> max_tensor = Tensor(np.array([6]), mstype.float32) + >>> output_tensor = P.FakeQuantWithMinMax(num_bits=8)(input_tensor, min_tensor, max_tensor) + """ + support_quant_bit = [4, 7, 8] + + @prim_attr_register + def __init__(self, num_bits=8, ema=False, ema_decay=0.999, quant_delay=0, symmetric=False, narrow_range=False, + training=True): + """init FakeQuantWithMinMax OP""" + if num_bits not in self.support_quant_bit: + raise ValueError("Attr \'num_bits\' is not support.") + if ema and not ema_decay: + raise ValueError( + "Attr \'ema\' and \'ema_decay\' should set together.") + + self.ema = check_bool(ema) + self.symmetric = check_bool(symmetric) + self.narrow_range = check_bool(narrow_range) + self.training = check_bool(training) + self.ema_decay = validator.check_number_range( + 'ema_decay', ema_decay, 0, 1, Rel.INC_BOTH) + self.num_bits = check_int_positive(num_bits) + self.quant_delay = check_int(quant_delay) + self.init_prim_io_names(inputs=['x', 'min', 'max'], + outputs=['out']) + + def infer_shape(self, x_shape, min_shape, max_shape): + validator.check_integer("x shape", len(x_shape), 1, Rel.GT) + validator.check("min shape", min_shape, "max shape", max_shape) + validator.check_integer("min shape", len(min_shape), 1, Rel.EQ) + validator.check_integer("max shape", len(min_shape), 1, Rel.EQ) + return x_shape + + def infer_dtype(self, x_type, min_type, max_type): + validator.check_typename( + "x type", x_type, (mstype.float16, mstype.float32)) + validator.check_typename("min type", min_type, + (mstype.float16, mstype.float32)) + validator.check_typename("max type", max_type, + (mstype.float16, mstype.float32)) + return x_type + + +class FakeQuantWithMinMaxGrad(PrimitiveWithInfer): + """Performs grad of FakeQuantWithMinMax operation.""" + support_quant_bit = [4, 8] + + @prim_attr_register + def __init__(self, num_bits=8, quant_delay=0): + if num_bits not in self.support_quant_bit: + raise ValueError("Attr \'num_bits\' is not support.") + + self.quant_delay = check_int(quant_delay) + self.num_bits = check_int_positive(num_bits) + self.init_prim_io_names(inputs=['dout', 'x', 'min', 'max'], + outputs=['dx']) + + def infer_shape(self, dout_shape, x_shape, min_shape, max_shape): + validator.check("dout shape", dout_shape, "x shape", x_shape) + validator.check("min shape", min_shape, "max shape", max_shape) + validator.check_integer("min shape", len(min_shape), 1, Rel.EQ) + validator.check_integer("max shape", len(min_shape), 1, Rel.EQ) + return dout_shape + + def infer_dtype(self, dout_type, x_type, min_type, max_type): + validator.check_typename( + "dout type", dout_type, (mstype.float16, mstype.float32)) + validator.check_typename( + "x type", x_type, (mstype.float16, mstype.float32)) + validator.check_typename("min type", min_type, + (mstype.float16, mstype.float32)) + validator.check_typename("max type", max_type, + (mstype.float16, mstype.float32)) + return dout_type + + +class FakeQuantWithMinMaxPerChannel(PrimitiveWithInfer): + r""" + Simulate the quantize and dequantize operations in training time base on per channel. + + Args: + num_bits (int) : Number bits to quantilization. Default: 8. + ema (bool): Use EMA algorithm update tensor min and tensor max. Default: False. + ema_decay (int) : EMA algorithm decay parameter. Default: 0.999. + quant_delay (int): Quantilization delay parameter. Before delay step in training time not + update the weight data to simulate quantize operation. After delay step in training time + begin simulate the quantize operation. Default: 0. + symmetric (bool): Quantization algorithm use symmetric or not. Default: False. + narrow_range (bool): Quantization algorithm use narrow range or not. Default: False. + training (bool): Training the network or not. Default: True. + + Inputs: + - **x** (Tensor) : 4-D float32 Tensor representing the shape of the output tensor. + - **min** (int, float) : Value of the min range of the input data. + - **max** (int, float) : Value of the max range of the input data. + + Outputs: + - Tensor, has the same type as input. + + Examples: + >>> input_tensor = Tensor(np.random.rand(3,4,5,5), mstype.float32) + >>> min_tensor = Tensor(np.array([-6.0, -6.5, -4.0, -5.0]), mstype.float32) + >>> max_tensor = Tensor(np.array([6.0, 6.5, 4.0, 5.0]), mstype.float32) + >>> output_tensor = P.FakeQuantWithMinMax(num_bits=8)(input_tensor, min_tensor, max_tensor) + """ + support_quant_bit = [4, 8] + channel_idx = 0 + + @prim_attr_register + def __init__(self, num_bits=8, ema=False, ema_decay=0.999, quant_delay=0, symmetric=False, narrow_range=False, + training=True): + """init FakeQuantWithMinMaxPerChannel OP""" + if num_bits not in self.support_quant_bit: + raise ValueError("Attr \'num_bits\' is not support.") + if ema and not ema_decay: + raise ValueError( + "Attr \'ema\' and \'ema_decay\' should set together.") + + self.ema = check_bool(ema) + self.symmetric = check_bool(symmetric) + self.narrow_range = check_bool(narrow_range) + self.training = check_bool(training) + self.ema_decay = validator.check_number_range( + 'ema_decay', ema_decay, 0, 1, Rel.INC_BOTH) + self.num_bits = check_int_positive(num_bits) + self.quant_delay = check_int(quant_delay) + self.init_prim_io_names(inputs=['x', 'min', 'max'], + outputs=['out']) + + def infer_shape(self, x_shape, min_shape, max_shape): + validator.check_integer("x shape", len(x_shape), 1, Rel.GT) + validator.check_integer( + "min len", min_shape[0], x_shape[self.channel_idx], Rel.EQ) + validator.check_integer( + "max len", max_shape[0], x_shape[self.channel_idx], Rel.EQ) + return x_shape + + def infer_dtype(self, x_type, min_type, max_type): + validator.check_typename( + "x type", x_type, (mstype.float16, mstype.float32)) + validator.check_typename("min type", min_type, + (mstype.float16, mstype.float32)) + validator.check_typename("max type", max_type, + (mstype.float16, mstype.float32)) + return x_type + + +class FakeQuantWithMinMaxPerChannelGrad(PrimitiveWithInfer): + """Performs grad of FakeQuantWithMinMaxPerChannel operation.""" + support_quant_bit = [4, 8] + + @prim_attr_register + def __init__(self, num_bits=8, quant_delay=0): + """init FakeQuantWithMinMaxPerChannel Fill""" + if num_bits not in self.support_quant_bit: + raise ValueError("Attr \'num_bits\' is not support.") + + self.quant_delay = check_int(quant_delay) + self.num_bits = check_int_positive(num_bits) + self.init_prim_io_names(inputs=['dout', 'x', 'min', 'max'], + outputs=['dx']) + + def infer_shape(self, dout_shape, x_shape, min_shape, max_shape): + validator.check("dout shape", dout_shape, "x shape", x_shape) + validator.check("min shape", min_shape, "max shape", max_shape) + return dout_shape + + def infer_dtype(self, dout_type, x_type, min_type, max_type): + validator.check_typename( + "dout", dout_type, (mstype.float16, mstype.float32)) + validator.check_typename("x", x_type, (mstype.float16, mstype.float32)) + validator.check_typename( + "min", min_type, (mstype.float16, mstype.float32)) + validator.check_typename( + "max", max_type, (mstype.float16, mstype.float32)) + return dout_type + + +class BatchNormFold(PrimitiveWithInfer): + """ + Batch normalization folded. + + Args: + momentum (float): Momentum value should be [0, 1]. Default: 0.1. + epsilon (float): A small float number to avoid dividing by 0. 1e-12 if dtype in + float32 else 1e-3. Default: 1e-12. + is_training (bool): In training mode set True, else set False. Default: True. + freeze_bn (int): Delay in steps at which computation switches from regular batch + norm to frozen mean and std. Default: 0. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C)`. + - **mean** (Tensor) - Tensor of shape :math:`(C,)`. + - **variance** (Tensor) - Tensor of shape :math:`(C,)`. + - **global_step** (Tensor) - Tensor to record current global step. + + Outputs: + Tuple of 4 Tensor, the normalized input and the updated parameters. + + - **batch_mean** (Tensor) - Tensor of shape :math:`(C,)`. + - **batch_std** (Tensor) - Tensor of shape :math:`(C,)`. + - **running_mean** (Tensor) - Tensor of shape :math:`(C,)`. + - **running_std** (Tensor) - Tensor of shape :math:`(C,)`. + + """ + channel = 1 + + @prim_attr_register + def __init__(self, momentum=0.1, epsilon=1e-12, is_training=True, freeze_bn=0): + """init batch norm fold layer""" + self.momentum = validator.check_number_range( + 'momentum', momentum, 0, 1, Rel.INC_BOTH) + self.epsilon = validator.check_float_positive('epsilon', epsilon) + self.is_training = check_bool(is_training) + self.freeze_bn = check_int(freeze_bn) + + self.init_prim_io_names(inputs=['x', 'mean', 'variance', 'global_step'], + outputs=['batch_mean', 'batch_std', 'running_mean', 'running_std']) + + def infer_shape(self, x_shape, mean_shape, variance_shape, global_step_shape): + validator.check("mean shape", mean_shape, + "gamma_shape", variance_shape) + validator.check("mean_shape size", + mean_shape[0], "input channel", x_shape[self.channel]) + validator.check_integer("global_step shape", + len(global_step_shape), 1, Rel.EQ) + return mean_shape, mean_shape, mean_shape, mean_shape + + def infer_dtype(self, x_type, mean_type, variance_type, global_step_type): + validator.check("input type", x_type, "mean type", mean_type) + validator.check("input type", x_type, "variance type", variance_type) + validator.check_typename("input type", x_type, + (mstype.float16, mstype.float32)) + validator.check_typename( + "global_step type", global_step_type, (mstype.int32,)) + return x_type, x_type, x_type, x_type + + +class BatchNormFoldGrad(PrimitiveWithInfer): + """Performs grad of BatchNormFold operation.""" + channel = 1 + + @prim_attr_register + def __init__(self, epsilon=1e-12, is_training=True, freeze_bn=0): + """init BatchNormGrad layer""" + self.is_training = check_bool(is_training) + self.freeze_bn = check_int(freeze_bn) + self.epsilon = validator.check_float_positive('epsilon', epsilon) + self.init_prim_io_names(inputs=['d_batch_mean', 'd_batch_std', 'x', 'batch_mean', 'batch_std', 'global_step'], + outputs=['dx']) + + def infer_shape(self, d_batch_mean_shape, d_batch_std_shape, x_shape, batch_mean_shape, batch_std_shape, + global_step_shape): + validator.check("d_batch_mean shape", d_batch_mean_shape, + "d_batch_std shape", d_batch_std_shape) + validator.check("d_batch_mean shape", d_batch_mean_shape, + "batch_mean shape", batch_mean_shape) + validator.check("d_batch_mean shape", d_batch_mean_shape, + "batch_std shape", batch_std_shape) + validator.check( + "x_shape shape", d_batch_mean_shape[0], "input channel", x_shape[self.channel]) + validator.check_integer("global_step shape", + len(global_step_shape), 1, Rel.EQ) + return x_shape + + def infer_dtype(self, d_batch_mean_type, d_batch_std_type, x_type, batch_mean_type, batch_std_type, + global_step_type): + validator.check("input type", x_type, + "d_batch_mean type", d_batch_mean_type) + validator.check("input type", x_type, + "d_batch_std type", d_batch_std_type) + validator.check("input type", x_type, + "batch_mean type", batch_mean_type) + validator.check("input type", x_type, "batch_std type", batch_std_type) + validator.check_typename("input type", x_type, + (mstype.float16, mstype.float32)) + validator.check_typename( + "global_step type", global_step_type, (mstype.int32,)) + return x_type + + +class CorrectionMul(PrimitiveWithInfer): + """ + Scale the weights with a correction factor to the long term statistics + prior to quantization. This ensures that there is no jitter in the quantized weights + due to batch to batch variation. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C)`. + - **batch_std** (Tensor) - Tensor of shape :math:`(C,)`. + - **running_std** (Tensor) - Tensor of shape :math:`(C,)`. + + Outputs: + - **out** (Tensor) - Tensor has the same shape as x. + + """ + channel = 0 + + @prim_attr_register + def __init__(self): + """init correction mul layer""" + self.init_prim_io_names(inputs=['x', 'batch_std', 'running_std'], + outputs=['out']) + + def infer_shape(self, x_shape, batch_std_shape, running_std_shape): + validator.check("batch_std shape", batch_std_shape, + "running_std shape", running_std_shape) + validator.check( + "batch_std size", batch_std_shape[0], "x_shape channel size", x_shape[self.channel]) + return x_shape + + def infer_dtype(self, x_type, batch_std_type, running_std_type): + validator.check("batch_std type", batch_std_type, + "running_std type", running_std_type) + validator.check("batch_std_type", batch_std_type, "x_type", x_type) + validator.check_typename( + "batch_std type", batch_std_type, (mstype.float16, mstype.float32)) + return x_type + + +class CorrectionMulGrad(PrimitiveWithInfer): + """Performs grad of CorrectionMul operation.""" + channel = 0 + + @prim_attr_register + def __init__(self): + """init correction mul layer""" + self.init_prim_io_names(inputs=['dout', 'x', 'gamma', 'running_std'], + outputs=['dx', 'd_gamma']) + + def infer_shape(self, dout_shape, x_shape, gamma_shape, running_std_shape): + validator.check("dout shape", dout_shape, "x_shape x", x_shape) + validator.check( + "gamma size", gamma_shape[0], "dout channel size", dout_shape[self.channel]) + validator.check( + "running_std size", running_std_shape[0], "dout channel size", dout_shape[self.channel]) + return x_shape, gamma_shape + + def infer_dtype(self, dout_type, x_type, gamma_type, running_std_type): + validator.check("x type", x_type, "dout type", dout_type) + validator.check("gamma type", gamma_type, "dout type", dout_type) + validator.check("running_std type", running_std_type, + "dout type", dout_type) + validator.check_typename( + "dout type", dout_type, (mstype.float16, mstype.float32)) + return x_type, x_type + + +class BatchNormFold2(PrimitiveWithInfer): + """ + Scale the bias with a correction factor to the long term statistics + prior to quantization. This ensures that there is no jitter in the quantized bias + due to batch to batch variation. + + Inputs: + - **x** (Tensor) - Tensor of shape :math:`(N, C)`. + - **beta** (Tensor) - Tensor of shape :math:`(C,)`. + - **gamma** (Tensor) - Tensor of shape :math:`(C,)`. + - **batch_std** (Tensor) - Tensor of shape :math:`(C,)`. + - **batch_mean** (Tensor) - Tensor of shape :math:`(C,)`. + - **running_std** (Tensor) - Tensor of shape :math:`(C,)`. + - **running_mean** (Tensor) - Tensor of shape :math:`(C,)`. + - **global_step** (Tensor) - Tensor to record current global step. + + Outputs: + - **y** (Tensor) - Tensor has the same shape as x. + + """ + channel = 1 + + @prim_attr_register + def __init__(self, freeze_bn=0): + """init conv2d fold layer""" + self.freeze_bn = check_int(freeze_bn) + self.init_prim_io_names(inputs=['x', 'beta', 'gamma', 'batch_std', 'batch_mean', + 'running_std', 'running_mean', 'global_step'], + outputs=['y']) + + def infer_shape(self, x_shape, beta_shape, gamma_shape, batch_std_shape, running_std_shape, batch_mean_shape, + running_mean_shape, global_step_shape): + validator.check("batch_std shape", batch_std_shape, + "running_std shape", running_std_shape) + validator.check("batch_std shape", batch_std_shape, + "batch_mean shape", batch_mean_shape) + validator.check("batch_std shape", batch_std_shape, + "beta shape", beta_shape) + validator.check("batch_std shape", batch_std_shape, + "running_mean shape", running_mean_shape) + validator.check("batch_std shape", batch_std_shape, + "batch_mean shape", gamma_shape) + validator.check( + "batch_std size", batch_std_shape[0], "x_shape channel size", x_shape[self.channel]) + validator.check_integer("global_step shape", + len(global_step_shape), 1, Rel.EQ) + return x_shape + + def infer_dtype(self, x_type, beta_type, gamma_type, batch_std_type, running_std_type, batch_mean_type, + running_mean_type, global_step_type): + validator.check("batch_std type", batch_std_type, + "running_std type", running_std_type) + validator.check("batch_std type", batch_std_type, + "batch_mean type", batch_mean_type) + validator.check("batch_std type", batch_std_type, + "beta type", beta_type) + validator.check("batch_std type", batch_std_type, + "running_mean type", running_mean_type) + validator.check("batch_std type", batch_std_type, + "gamma type", gamma_type) + validator.check("x_type", x_type, "batch_std type", batch_std_type) + validator.check_typename( + "batch_std type", batch_std_type, (mstype.float16, mstype.float32)) + validator.check_typename( + "global_step type", global_step_type, (mstype.int32,)) + return x_type + + +class BatchNormFold2Grad(PrimitiveWithInfer): + """Performs grad of CorrectionAddGrad operation.""" + channel = 1 + + @prim_attr_register + def __init__(self, freeze_bn=0): + """init MulFold layer""" + self.freeze_bn = freeze_bn + self.init_prim_io_names(inputs=['dout', 'x', 'gamma', + 'batch_std', 'batch_mean', + 'running_std', 'running_mean', 'global_step'], + outputs=['d_batch_std', 'd_batch_mean', 'd_beta', 'd_gamma', 'dx']) + + def infer_shape(self, dout_shape, x_shape, gamma_shape, + batch_std_shape, batch_mean_shape, + running_std_shape, running_mean_shape, global_step_shape): + validator.check("batch_std shape", batch_std_shape, + "batch_mean shape", batch_mean_shape) + validator.check("batch_std shape", batch_std_shape, + "running_std shape", running_std_shape) + validator.check("batch_std shape", batch_std_shape, + "running_mean shape", running_mean_shape) + validator.check("batch_std shape", batch_std_shape, + "gamma shape", gamma_shape) + validator.check( + "batch_std size", batch_std_shape[0], "dout channel size", dout_shape[self.channel]) + validator.check_integer("global_step shape", + len(global_step_shape), 1, Rel.EQ) + return gamma_shape, gamma_shape, gamma_shape, gamma_shape, x_shape + + def infer_dtype(self, dout_type, x_type, gamma_type, + batch_std_type, batch_mean_type, + running_std_type, running_mean_type, global_step_type): + validator.check("batch_std type", batch_std_type, + "batch_mean type", batch_mean_type) + validator.check("batch_std type", batch_std_type, + "gamma type", gamma_type) + validator.check("batch_std type", batch_std_type, + "running_std type", running_std_type) + validator.check("batch_std type", batch_std_type, + "running_mean type", running_mean_type) + validator.check("batch_std_type", batch_std_type, + "dout type", dout_type) + validator.check_typename( + "batch_std type", batch_std_type, (mstype.float16, mstype.float32)) + validator.check_typename( + "global_step type", global_step_type, (mstype.int32,)) + return gamma_type, gamma_type, gamma_type, gamma_type, gamma_type diff --git a/mindspore/ops/operations/array_ops.py b/mindspore/ops/operations/array_ops.py index ac7f8ed699..2219e3bb50 100644 --- a/mindspore/ops/operations/array_ops.py +++ b/mindspore/ops/operations/array_ops.py @@ -29,6 +29,7 @@ from ..._checkparam import Rel from ...common import dtype as mstype from ...common.tensor import Tensor from ..operations.math_ops import _infer_shape_reduce +from .._utils import _get_concat_offset from ..primitive import Primitive, PrimitiveWithInfer, prim_attr_register def _check_infer_attr_reduce(axis, keep_dims): @@ -174,10 +175,9 @@ class Cast(PrimitiveWithInfer): Examples: >>> input_np = np.random.randn(2, 3, 4, 5).astype(np.float32) >>> input_x = Tensor(input_np) - >>> type_dst = mindspore.int32 + >>> type_dst = mindspore.float16 >>> cast = P.Cast() >>> result = cast(input_x, type_dst) - >>> expect = input_np.astype(type_dst) """ @prim_attr_register @@ -795,7 +795,7 @@ class ZerosLike(PrimitiveWithInfer): Examples: >>> zeroslike = P.ZerosLike() - >>> x = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) + >>> x = Tensor(np.array([[0, 1], [2, 1]]).astype(np.float32)) >>> output = zeroslike(x) """ @@ -983,8 +983,7 @@ class Argmax(PrimitiveWithInfer): Examples: >>> input_x = Tensor(np.array([2.0, 3.1, 1.2])) - >>> index = P.Argmax()(input_x) - >>> assert index == Tensor(1, mindspore.int64) + >>> index = P.Argmax(output_type=mindspore.int32)(input_x) """ @prim_attr_register @@ -1008,6 +1007,7 @@ class Argmax(PrimitiveWithInfer): def infer_dtype(self, x_dtype): validator.check_subclass("input_x", x_dtype, mstype.tensor) + validator.check_typename('input_x', x_dtype, [mstype.float32, mstype.float16]) return mstype.tensor_type(self.output_type) @@ -1097,7 +1097,7 @@ class ArgMaxWithValue(PrimitiveWithInfer): axis = self.axis x_rank = len(x_shape) validator.check_int_range("axis", axis, -x_rank, x_rank, Rel.INC_LEFT) - ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.prim_name()) + ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.name) return ouput_shape, ouput_shape def infer_dtype(self, x_dtype): @@ -1143,7 +1143,7 @@ class ArgMinWithValue(PrimitiveWithInfer): axis = self.axis x_rank = len(x_shape) validator.check_int_range("axis", axis, -x_rank, x_rank, Rel.INC_LEFT) - ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.prim_name()) + ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.name) return ouput_shape, ouput_shape def infer_dtype(self, x_dtype): @@ -1238,7 +1238,8 @@ class UnsortedSegmentSum(PrimitiveWithInfer): >>> input_x = [1, 2, 3, 4] >>> segment_ids = [0, 0, 1, 2] >>> num_segments = 4 - >>> type = P.UnsortedSegmentSum()(input_x, segment_ids, num_segments) + >>> P.UnsortedSegmentSum()(input_x, segment_ids, num_segments) + [3, 3, 4, 0] """ @prim_attr_register @@ -1274,30 +1275,6 @@ class UnsortedSegmentSum(PrimitiveWithInfer): return out -def _get_concat_offset(x_shp, x_type, axis): - """for concat and concatoffset check args and compute offset""" - validator.check_type("shape", x_shp, [tuple]) - validator.check_integer("len of input_x shape", len(x_shp), 0, Rel.GT) - validator.check_subclass("shape0", x_type[0], mstype.tensor) - validator.check_integer("len of input_x0 shape", len(x_shp[0]), 0, Rel.GT) - rank_base = len(x_shp[0]) - validator.check_int_range('axis', axis, -rank_base - 1, rank_base, Rel.INC_BOTH) - if axis < 0: - axis = axis + rank_base - all_shp = x_shp[0][axis] - offset = [0,] - for i in range(1, len(x_shp)): - v = x_shp[i] - validator.check('len of x_shp[%d]' % i, len(v), 'len of base', len(x_shp[0])) - validator.check('x_type[%d]' % i, x_type[i], 'base', x_type[0]) - for j in range(rank_base): - if j != axis and v[j] != x_shp[0][j]: - raise ValueError("Concat evaluator element %d shape in input can not concat with first element" % i) - offset.append(all_shp) - all_shp += v[axis] - return offset, all_shp, axis - - class Concat(PrimitiveWithInfer): r""" Concat tensor in specified axis. @@ -1499,7 +1476,9 @@ class Slice(PrimitiveWithInfer): Tensor. Examples: - >>> data = Tensor(np.array([3,2,3]).astype(np.int32)) + >>> data = Tensor(np.array([[[1, 1, 1], [2, 2, 2]], + >>> [[3, 3, 3], [4, 4, 4]], + >>> [[5, 5, 5], [6, 6, 6]]]).astype(np.int32)) >>> type = P.Slice()(data, (1, 0, 0), (1, 1, 3)) """ @@ -1530,34 +1509,6 @@ class Slice(PrimitiveWithInfer): 'value': None} -class ConcatOffset(PrimitiveWithInfer): - """primitive for computing Concat's gradient.""" - - @prim_attr_register - def __init__(self, N=2, axis=0): - """init ConcatOffset""" - - def __infer__(self, input_x): - axis = self.axis - x_shp = input_x['shape'] - x_type = input_x['dtype'] - offset, _, axis = _get_concat_offset(x_shp, x_type, axis) - self.add_prim_attr('T', x_type[0].element_type()) - offset_values = [] - for i in range(len(x_shp)): - values = [] - for j in range(len(x_shp[0])): - value = 0 - if j == axis: - value = offset[i] - values.append(value) - offset_values.append(tuple(values)) - out = {'shape': None, - 'dtype': None, - 'value': tuple(offset_values)} - return out - - class Select(PrimitiveWithInfer): r""" diff --git a/mindspore/ops/operations/comm_ops.py b/mindspore/ops/operations/comm_ops.py index 1644c5800a..a5a4c9f236 100644 --- a/mindspore/ops/operations/comm_ops.py +++ b/mindspore/ops/operations/comm_ops.py @@ -65,7 +65,7 @@ class AllReduce(PrimitiveWithInfer): The contents depend on the specified operation. Examples: - >>> from mindspore.communication.management import init + >>> from mindspore.communication import init >>> import mindspore.ops.operations as P >>> init('nccl') >>> class Net(nn.Cell): @@ -130,7 +130,7 @@ class AllGather(PrimitiveWithInfer): then the shape of output is :math:`(N, x_1, x_2, ..., x_R)`. Examples: - >>> from mindspore.communication.management import init + >>> from mindspore.communication import init >>> import mindspore.ops.operations as P >>> init('nccl') >>> class Net(nn.Cell): @@ -162,6 +162,8 @@ class AllGather(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): + if x_dtype == mstype.bool_: + raise TypeError("AllGather does not support 'Bool' as the dtype of input!") return x_dtype def __call__(self, tensor): @@ -185,7 +187,7 @@ class ReduceScatter(PrimitiveWithInfer): ValueError: If the first dimension of input can not be divided by rank size. Examples: - >>> from mindspore.communication.management import init + >>> from mindspore.communication import init >>> import mindspore.ops.operations as P >>> init('nccl') >>> class Net(nn.Cell): @@ -219,6 +221,8 @@ class ReduceScatter(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): + if x_dtype == mstype.bool_: + raise TypeError("ReduceScatter does not support 'Bool' as the dtype of input!") return x_dtype def __call__(self, tensor): @@ -248,7 +252,7 @@ class Broadcast(PrimitiveWithInfer): TypeError: If root_rank is not a integer or group is not a string. Examples: - >>> from mindspore.communication.management import init + >>> from mindspore.communication import init >>> import mindspore.ops.operations as P >>> init('nccl') >>> class Net(nn.Cell): @@ -276,6 +280,8 @@ class Broadcast(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): + if x_dtype == mstype.bool_: + raise TypeError("Broadcast does not support 'Bool' as the dtype of input!") return x_dtype @@ -318,6 +324,8 @@ class _AlltoAll(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): + if x_dtype == mstype.bool_: + raise TypeError("AlltoAll does not support 'Bool' as the dtype of input!") return x_dtype def __call__(self, tensor): diff --git a/mindspore/ops/operations/control_ops.py b/mindspore/ops/operations/control_ops.py index 167739b89a..ca161cfad0 100644 --- a/mindspore/ops/operations/control_ops.py +++ b/mindspore/ops/operations/control_ops.py @@ -50,17 +50,19 @@ class ControlDepend(Primitive): >>> # step should be increased, so the add operation should depend on the data calculation operation. >>> class Net(nn.Cell): >>> def __init__(self): - >>> super(Net, self).__init__() - >>> self.global_step = Parameter(initializer(0, [1]), name="global_step") - >>> self.rate = 0.2 - >>> self.control_depend = ControlDepend() + >>> super(Net, self).__init__() + >>> self.control_depend = P.ControlDepend() + >>> self.softmax = P.Softmax() >>> - >>> def construct(self, x): - >>> data = self.rate * self.global_step + x - >>> added_global_step = self.global_step + 1 - >>> self.global_step = added_global_step - >>> self.control_depend(data, added_global_step) - >>> return data + >>> def construct(self, x, y): + >>> mul = x * y + >>> softmax = self.softmax(x) + >>> ret = self.control_depend(mul, softmax) + >>> return ret + >>> x = Tensor(np.ones([4, 5]), dtype=mindspore.float32) + >>> y = Tensor(np.ones([4, 5]), dtype=mindspore.float32) + >>> net = Net() + >>> output = net(x, y) """ @prim_attr_register @@ -89,10 +91,10 @@ class GeSwitch(PrimitiveWithInfer): Examples: >>> class Net(nn.Cell): >>> def __init__(self): - >>> super(Net, self).__init__() + >>> super(Net, self).__init__() >>> self.square = P.Square() >>> self.add = P.TensorAdd() - >>> self.value = Tensor(np.full((1), 3, dtype=np.float32)) + >>> self.value = Tensor(np.full((1), 3), mindspore.float32) >>> self.switch = P.GeSwitch() >>> self.merge = P.Merge() >>> self.less = P.Less() diff --git a/mindspore/ops/operations/debug_ops.py b/mindspore/ops/operations/debug_ops.py index a69dcc2df1..1d8fdedc26 100644 --- a/mindspore/ops/operations/debug_ops.py +++ b/mindspore/ops/operations/debug_ops.py @@ -98,6 +98,33 @@ class TensorSummary(Primitive): """init""" +class HistogramSummary(Primitive): + """ + Output tensor to protocol buffer through histogram summary operator. + + Inputs: + - **name** (str) - The name of the input variable. + - **value** (Tensor) - The value of tensor, and the rank of tensor should be greater than 0. + + Examples: + >>> class SummaryDemo(nn.Cell): + >>> def __init__(self,): + >>> super(SummaryDemo, self).__init__() + >>> self.summary = P.HistogramSummary() + >>> self.add = P.TensorAdd() + >>> + >>> def construct(self, x, y): + >>> x = self.add(x, y) + >>> name = "x" + >>> self.summary(name, x) + >>> return x + """ + + @prim_attr_register + def __init__(self): + """init""" + + class InsertGradientOf(PrimitiveWithInfer): """ Attach callback to graph node that will be invoked on the node's gradient. @@ -123,6 +150,7 @@ class InsertGradientOf(PrimitiveWithInfer): >>> return ret >>> >>> clip = P.InsertGradientOf(clip_gradient) + >>> grad_all = C.GradOperation('get_all', get_all=True) >>> def InsertGradientOfClipDemo(): >>> def clip_test(x, y): >>> x = clip(x) @@ -135,7 +163,7 @@ class InsertGradientOf(PrimitiveWithInfer): >>> return clip_test(x, y) >>> >>> def fd(x, y): - >>> return C.grad_all(clip_test)(x, y) + >>> return grad_all(clip_test)(x, y) >>> >>> print("forward: ", f(1.1, 0.1)) >>> print("clip_gradient:", fd(1.1, 0.1)) @@ -160,6 +188,9 @@ class Print(PrimitiveWithInfer): """ Output tensor or string to stdout. + Note: + The print operation cannot support float64 and bool types currently. + Inputs: - **input_x** (Union[Tensor, str]) - The graph node to attach to. The input supports multiple strings and tensors which are separated by ','. diff --git a/mindspore/ops/operations/math_ops.py b/mindspore/ops/operations/math_ops.py index 106886c45c..98665dd27a 100644 --- a/mindspore/ops/operations/math_ops.py +++ b/mindspore/ops/operations/math_ops.py @@ -74,7 +74,7 @@ class _BinaryOp(PrimitiveWithInfer): self.init_prim_io_names(inputs=['x', 'y'], outputs=['output']) def infer_shape(self, x_shape, y_shape): - return _get_broadcast_shape(x_shape, y_shape, self.prim_name()) + return _get_broadcast_shape(x_shape, y_shape, self.name) class _MathBinaryOp(_BinaryOp): @@ -89,7 +89,7 @@ class _MathBinaryOp(_BinaryOp): return x_dtype def infer_dtype(self, x_dtype, y_dtype): - return _MathBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type, self.prim_name()) + return _MathBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type, self.name) class TensorAdd(_MathBinaryOp): @@ -133,7 +133,7 @@ class AssignAdd(PrimitiveWithInfer): >>> def __init__(self): >>> super(Net, self).__init__() >>> self.AssignAdd = P.AssignAdd() - >>> self.variable = Parameter(initializer(1, [1], mindspore.int64), name="global_step") + >>> self.variable = mindspore.Parameter(initializer(1, [1], mindspore.int64), name="global_step") >>> >>> def construct(self, x): >>> self.AssignAdd(self.variable, x) @@ -158,7 +158,7 @@ class AssignAdd(PrimitiveWithInfer): def infer_dtype(self, variable, value): args = {"value": value} - validator.check_scalar_or_tensor_type_same(args, mstype.number_type, self.prim_name()) + validator.check_scalar_or_tensor_type_same(args, mstype.number_type, self.name) return value @@ -176,7 +176,7 @@ class AssignSub(PrimitiveWithInfer): >>> def __init__(self): >>> super(Net, self).__init__() >>> self.AssignSub = P.AssignSub() - >>> self.variable = Parameter(initializer(1, [1], mindspore.int64), name="global_step") + >>> self.variable = mindspore.Parameter(initializer(1, [1], mindspore.int64), name="global_step") >>> >>> def construct(self, x): >>> self.AssignSub(self.variable, x) @@ -201,7 +201,7 @@ class AssignSub(PrimitiveWithInfer): def infer_dtype(self, variable, value): args = {"value": value} - validator.check_scalar_or_tensor_type_same(args, mstype.number_type, self.prim_name()) + validator.check_scalar_or_tensor_type_same(args, mstype.number_type, self.name) return value @@ -222,16 +222,16 @@ class _Reduce(PrimitiveWithInfer): @prim_attr_register def __init__(self, keep_dims=False): """init Reduce""" - validator.check_value_type('keep_dims', keep_dims, [bool], self.prim_name()) + validator.check_value_type('keep_dims', keep_dims, [bool], self.name) self.init_prim_io_names(inputs=['input_x', 'axis'], outputs=['y']) def do_infer(self, input_x, axis, valid_dtype=mstype.number_type): axis_v = axis['value'] input_shp = input_x['shape'] args = {'input_x': input_x['dtype']} - validator.check_tensor_type_same(args, valid_dtype, self.prim_name()) + validator.check_tensor_type_same(args, valid_dtype, self.name) - input_shp = _infer_shape_reduce(input_shp, axis_v, self.keep_dims, self.prim_name()) + input_shp = _infer_shape_reduce(input_shp, axis_v, self.keep_dims, self.name) return {'shape': input_shp, 'dtype': input_x['dtype'], 'value': None} @@ -466,7 +466,7 @@ class CumProd(PrimitiveWithInfer): """ @prim_attr_register def __init__(self, exclusive=False, reverse=False): - cls_name = self.prim_name() + cls_name = self.name self.exclusive = validator.check_value_type("exclusive", exclusive, [bool], cls_name) self.reverse = validator.check_value_type("reverse", reverse, [bool], cls_name) @@ -474,7 +474,7 @@ class CumProd(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type, axis_type): - cls_name = self.prim_name() + cls_name = self.name validator.check_tensor_type_same({'x': x_type}, mstype.number_type, cls_name) validator.check_subclass("axis", axis_type, mstype.int_, cls_name) return x_type @@ -510,7 +510,7 @@ class MatMul(PrimitiveWithInfer): def __init__(self, transpose_a=False, transpose_b=False): self.init_prim_io_names(inputs=['x1', 'x2'], outputs=['output']) self.__setattr_flag__ = True - cls_name = self.prim_name() + cls_name = self.name validator.check_value_type("transpose_a", transpose_a, [bool], cls_name) validator.check_value_type("transpose_b", transpose_b, [bool], cls_name) @@ -521,7 +521,7 @@ class MatMul(PrimitiveWithInfer): def infer_shape(self, x, y): self.check_shape_size(x, y) - cls_name = self.prim_name() + cls_name = self.name # expected dimension of x, y, x:[...,a,b] y:[..., c,d], the dim size should be the same except the last two for i in range(len(x) - 2): if x[i] != y[i]: @@ -546,7 +546,7 @@ class MatMul(PrimitiveWithInfer): def infer_dtype(self, x, y): args = {"x": x, "y": y} - validator.check_tensor_type_same(args, mstype.float_type + mstype.int_type, self.prim_name()) + validator.check_tensor_type_same(args, mstype.float_type + mstype.int_type, self.name) return x @@ -590,7 +590,7 @@ class BatchMatMul(MatMul): def __init__(self, transpose_a=False, transpose_b=False): self.init_prim_io_names(inputs=['x1', 'x2'], outputs=['output']) self.__setattr_flag__ = True - cls_name = self.prim_name() + cls_name = self.name validator.check_value_type("transpose_a", transpose_a, [bool], cls_name) validator.check_value_type("transpose_b", transpose_b, [bool], cls_name) @@ -628,13 +628,13 @@ class CumSum(PrimitiveWithInfer): @prim_attr_register def __init__(self, exclusive=False, reverse=False): """init cumsum""" - cls_name = self.prim_name() + cls_name = self.name validator.check_value_type('exclusive', exclusive, [bool], cls_name) validator.check_value_type('reverse', reverse, [bool], cls_name) self.init_prim_io_names(inputs=['x', 'axis'], outputs=['y']) def __infer__(self, x, axis): - cls_name = self.prim_name() + cls_name = self.name x_shp = x['shape'] validator.check_value_type('axis', axis['value'], [int], cls_name) valid_types = [mstype.uint8, mstype.int8, mstype.int32, mstype.float16, mstype.float32] @@ -667,8 +667,8 @@ class AddN(PrimitiveWithInfer): >>> return self.addN(z) >>> >>> net = NetAddN() - >>> input_x = Tensor(np.array([1, 2, 3]), mindspore.int32) - >>> input_y = Tensor(np.array([4, 5, 6]), mindspore.int32) + >>> input_x = Tensor(np.array([1, 2, 3]), mindspore.float32) + >>> input_y = Tensor(np.array([4, 5, 6]), mindspore.float32) >>> net(input_x, input_y, input_x, input_y) Tensor([10, 14, 18], shape=(3,), dtype=mindspore.int32) """ @@ -679,7 +679,7 @@ class AddN(PrimitiveWithInfer): self.init_prim_io_names(inputs=["inputs"], outputs=["sum"]) def infer_shape(self, inputs): - cls_name = self.prim_name() + cls_name = self.name validator.check_integer("inputs", len(inputs), 1, Rel.GE, cls_name) self.add_prim_attr('n', len(inputs)) shp0 = inputs[0] @@ -688,7 +688,7 @@ class AddN(PrimitiveWithInfer): return shp0 def infer_dtype(self, inputs): - cls_name = self.prim_name() + cls_name = self.name validator.check_value_type("inputs", inputs, [tuple, list], cls_name) validator.check_integer("inputs", len(inputs), 1, Rel.GE, cls_name) args = {} @@ -718,7 +718,7 @@ class Neg(PrimitiveWithInfer): return input_x def infer_dtype(self, input_x): - validator.check_tensor_type_same({"input_x": input_x}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({"input_x": input_x}, mstype.number_type, self.name) return input_x @@ -809,7 +809,7 @@ class Square(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.name) return x_type @@ -838,7 +838,7 @@ class Rsqrt(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.name) return x_type @@ -867,7 +867,7 @@ class Sqrt(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({"x": x_type}, mstype.number_type, self.name) return x_type @@ -897,14 +897,29 @@ class Reciprocal(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_subclass("x", x, mstype.tensor, self.prim_name()) + validator.check_subclass("x", x, mstype.tensor, self.name) return x -class Pow(PrimitiveWithInfer): +class Pow(_MathBinaryOp): """ Computes a tensor to the power of the second input. + The first input must be a tensor, and the second input should be a tensor or a number. + When the inputs are two tensors, the shapes of them could be broadcast, + and the data types of them should be the same. + When the inputs are one tensor and one scalar, the scalar could not be a parameter, + only could be a constant, and the type of the scalar is the same as the data type of the tensor. + + Inputs: + - **input_x** (Union[Tensor]) - The first input is a tensor whose data type is number. + - **input_y** (Union[Tensor, Number]) - The second input is a tensor whose data type is same as 'input_x' or + a number. + + Outputs: + Tensor, the shape is same as the shape after broadcasting, and the data type is same as 'input_x'. + + Inputs: - **input_x** (Tensor) - The input tensor. - **input_y** (Union[Tensor, Number]) - The exponent part. If exponent is a tensor, its shape must be able to @@ -927,17 +942,6 @@ class Pow(PrimitiveWithInfer): [1.0, 16.0, 64.0] """ - @prim_attr_register - def __init__(self): - """init Multiply""" - - def infer_shape(self, x, power): - return x - - def infer_dtype(self, x, power): - validator.check_tensor_type_same({"x": x}, mstype.number_type, self.prim_name()) - return x - class Exp(PrimitiveWithInfer): """ @@ -965,7 +969,7 @@ class Exp(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_subclass("x", x_type, mstype.tensor, self.prim_name()) + validator.check_subclass("x", x_type, mstype.tensor, self.name) return x_type @@ -994,7 +998,7 @@ class Log(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_subclass("x", x, mstype.tensor, self.prim_name()) + validator.check_subclass("x", x, mstype.tensor, self.name) return x @@ -1176,7 +1180,7 @@ class Floor(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): - validator.check_tensor_type_same({"x": x_dtype}, mstype.float_type, self.prim_name()) + validator.check_tensor_type_same({"x": x_dtype}, mstype.float_type, self.name) return x_dtype @@ -1231,7 +1235,7 @@ class Acosh(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_tensor_type_same({'x': x}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x}, mstype.number_type, self.name) return x @@ -1247,7 +1251,7 @@ class _LogicBinaryOp(_BinaryOp): return mstype.tensor_type(mstype.bool_) def infer_dtype(self, x_dtype, y_dtype): - return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, prim_name=self.prim_name()) + return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, prim_name=self.name) class Equal(_LogicBinaryOp): @@ -1283,7 +1287,7 @@ class Equal(_LogicBinaryOp): """ def infer_dtype(self, x_dtype, y_dtype): - return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type + (mstype.bool_,), self.prim_name()) + return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type + (mstype.bool_,), self.name) class EqualCount(PrimitiveWithInfer): @@ -1318,7 +1322,7 @@ class EqualCount(PrimitiveWithInfer): def infer_dtype(self, x_dtype, y_dtype): args = {'x': x_dtype, 'y': y_dtype} - validator.check_tensor_type_same(args, mstype.number_type + (mstype.bool_,), self.prim_name()) + validator.check_tensor_type_same(args, mstype.number_type + (mstype.bool_,), self.name) return x_dtype @@ -1355,7 +1359,7 @@ class NotEqual(_LogicBinaryOp): """ def infer_dtype(self, x_dtype, y_dtype): - return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type + (mstype.bool_,), self.prim_name()) + return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, mstype.number_type + (mstype.bool_,), self.name) class Greater(_LogicBinaryOp): @@ -1471,7 +1475,7 @@ class LogicalNot(PrimitiveWithInfer): Computes the "logical NOT" of a tensor element-wise. Inputs: - - **input_x** (Tensor) - The input tensor whose dtype is bool + - **input_x** (Tensor) - The input tensor whose dtype is bool. Outputs: Tensor, the shape is same as the `input_x`, and the dtype is bool. @@ -1491,7 +1495,7 @@ class LogicalNot(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): - validator.check_tensor_type_same({"x": x_dtype}, [mstype.bool_], self.prim_name()) + validator.check_tensor_type_same({"x": x_dtype}, [mstype.bool_], self.name) return mstype.tensor_type(mstype.bool_) @@ -1521,7 +1525,7 @@ class LogicalAnd(_LogicBinaryOp): """ def infer_dtype(self, x_dtype, y_dtype): - return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, (mstype.bool_,), self.prim_name()) + return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, (mstype.bool_,), self.name) class LogicalOr(_LogicBinaryOp): @@ -1550,7 +1554,7 @@ class LogicalOr(_LogicBinaryOp): """ def infer_dtype(self, x_dtype, y_dtype): - return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, (mstype.bool_,), self.prim_name()) + return _LogicBinaryOp.do_infer_dtype(x_dtype, y_dtype, (mstype.bool_,), self.name) class IsNan(PrimitiveWithInfer): """ @@ -1699,13 +1703,13 @@ class NPUGetFloatStatus(PrimitiveWithInfer): self.add_prim_attr("_side_effect_flag", True) def infer_shape(self, x_shape): - cls_name = self.prim_name() + cls_name = self.name validator.check_integer("len(x_shape)", len(x_shape), 1, Rel.EQ, cls_name) validator.check_integer("x_shape[0]", x_shape[0], 8, Rel.EQ, cls_name) return [8] def infer_dtype(self, x_dtype): - validator.check_tensor_type_same({'x': x_dtype}, [mstype.float32], self.prim_name()) + validator.check_tensor_type_same({'x': x_dtype}, [mstype.float32], self.name) return mstype.float32 @@ -1741,13 +1745,13 @@ class NPUClearFloatStatus(PrimitiveWithInfer): self.add_prim_attr("_side_effect_flag", True) def infer_shape(self, x_shape): - cls_name = self.prim_name() + cls_name = self.name validator.check_integer("len(x_shape)", len(x_shape), 1, Rel.EQ, cls_name) validator.check_integer("x_shape[0]", x_shape[0], 8, Rel.EQ, cls_name) return [8] def infer_dtype(self, x_dtype): - validator.check_tensor_type_same({'x': x_dtype}, [mstype.float32], self.prim_name()) + validator.check_tensor_type_same({'x': x_dtype}, [mstype.float32], self.name) return mstype.float32 @@ -1775,7 +1779,7 @@ class Cos(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_tensor_type_same({'x': x}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x}, mstype.number_type, self.name) return x @@ -1803,7 +1807,7 @@ class ACos(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_tensor_type_same({'x': x}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x}, mstype.number_type, self.name) return x @@ -1831,7 +1835,7 @@ class Sin(PrimitiveWithInfer): return x def infer_dtype(self, x): - validator.check_tensor_type_same({'x': x}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x}, mstype.number_type, self.name) return x @@ -1868,7 +1872,7 @@ class NMSWithMask(PrimitiveWithInfer): >>> bbox = np.random.rand(128, 5) >>> bbox[:, 2] += bbox[:, 0] >>> bbox[:, 3] += bbox[:, 1] - >>> inputs = Tensor(bbox) + >>> inputs = Tensor(bbox, mindspore.float32) >>> nms = P.NMSWithMask(0.5) >>> output_boxes, indices, mask = nms(inputs) """ @@ -1876,11 +1880,11 @@ class NMSWithMask(PrimitiveWithInfer): @prim_attr_register def __init__(self, iou_threshold=0.5): """Init NMSWithMask""" - validator.check_value_type("iou_threshold", iou_threshold, [float], self.prim_name()) + validator.check_value_type("iou_threshold", iou_threshold, [float], self.name) self.init_prim_io_names(inputs=['bboxes'], outputs=['selected_boxes', 'selected_idx', 'selected_mask']) def infer_shape(self, bboxes_shape): - cls_name = self.prim_name() + cls_name = self.name validator.check_integer("bboxes rank", len(bboxes_shape), 2, Rel.EQ, cls_name) validator.check_integer("bboxes.shape()[0]", bboxes_shape[0], 0, Rel.GT, cls_name) validator.check_integer("bboxes.shape()[1]", bboxes_shape[1], 5, Rel.EQ, cls_name) @@ -1888,7 +1892,7 @@ class NMSWithMask(PrimitiveWithInfer): return (bboxes_shape, (num,), (num,)) def infer_dtype(self, bboxes_dtype): - validator.check_tensor_type_same({"bboxes": bboxes_dtype}, [mstype.float16, mstype.float32], self.prim_name()) + validator.check_tensor_type_same({"bboxes": bboxes_dtype}, [mstype.float16, mstype.float32], self.name) return (bboxes_dtype, mstype.int32, mstype.bool_) @@ -1917,7 +1921,7 @@ class Abs(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_tensor_type_same({'x': x_type}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x_type}, mstype.number_type, self.name) return x_type def infer_value(self, x): @@ -1959,7 +1963,7 @@ class Sign(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_dtype): - validator.check_tensor_type_same({'x': x_dtype}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x_dtype}, mstype.number_type, self.name) return x_dtype @@ -1988,7 +1992,7 @@ class Round(PrimitiveWithInfer): return x_shape def infer_dtype(self, x_type): - validator.check_tensor_type_same({'x': x_type}, mstype.number_type, self.prim_name()) + validator.check_tensor_type_same({'x': x_type}, mstype.number_type, self.name) return x_type diff --git a/mindspore/ops/operations/nn_ops.py b/mindspore/ops/operations/nn_ops.py index 3cc6718484..9827975fd0 100644 --- a/mindspore/ops/operations/nn_ops.py +++ b/mindspore/ops/operations/nn_ops.py @@ -22,6 +22,8 @@ from functools import reduce import numpy as np from ... import context +from ..._c_expression import signature_rw as sig_rw +from ..._c_expression import signature_kind as sig_kind from ..._checkparam import ParamValidator as validator from ..._checkparam import Rel, check_bool, check_int_positive from ...common import dtype as mstype @@ -154,7 +156,7 @@ class ReLU(PrimitiveWithInfer): Tensor, with the same type and shape as the `input_x`. Examples: - >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]], np.float32)) + >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32) >>> relu = P.ReLU() >>> result = relu(input_x) [[0, 4.0, 0.0], [2.0, 0.0, 9.0]] @@ -187,7 +189,7 @@ class ReLU6(PrimitiveWithInfer): Tensor, with the same type and shape as the `input_x`. Examples: - >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]], np.float32)) + >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32) >>> relu6 = P.ReLU6() >>> result = relu6(input_x) """ @@ -207,7 +209,7 @@ class ReLU6(PrimitiveWithInfer): class Elu(PrimitiveWithInfer): - """ + r""" Computes exponential linear: `alpha * (exp(x) - 1)` if x < 0, `x` otherwise. The data type of input tensor should be float. @@ -221,7 +223,7 @@ class Elu(PrimitiveWithInfer): Tensor, has the same shape and data type as `input_x`. Examples: - >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]], np.float32)) + >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32) >>> elu = P.Elu() >>> result = elu(input_x) Tensor([[-0.632 4.0 -0.999] @@ -242,6 +244,40 @@ class Elu(PrimitiveWithInfer): return input_x +class HSwish(PrimitiveWithInfer): + r""" + Hard swish activation function. + + Applies hswish-type activation element-wise. The input is a Tensor with any valid shape. + + Hard swish is defined as: + + .. math:: + \text{hswish}(x_{i}) = x_{i} * \frac{ReLU6(x_{i} + 3)}{6}, + + where :math:`x_{i}` is the :math:`i`-th slice along the given dim of the input Tensor. + + Inputs: + - **input_data** (Tensor) - The input of Hswish. + + Outputs: + Tensor, with the same type and shape as the `input_data`. + + """ + @prim_attr_register + def __init__(self): + self.init_prim_io_names(inputs=['x'], outputs=['output']) + + def infer_shape(self, xshape): + return xshape + + def infer_dtype(self, x_dtype): + validator.check_subclass("x_dtype", x_dtype, mstype.tensor) + validator.check_typename("x_dtype", x_dtype, (mstype.float16, mstype.float32)) + return x_dtype + + + class Sigmoid(PrimitiveWithInfer): r""" Sigmoid activation function. @@ -258,6 +294,7 @@ class Sigmoid(PrimitiveWithInfer): Outputs: Tensor, with the same type and shape as the input_x. + """ @prim_attr_register @@ -273,6 +310,40 @@ class Sigmoid(PrimitiveWithInfer): return input_x +class HSigmoid(PrimitiveWithInfer): + r""" + Hard sigmoid activation function. + + Applies hard sigmoid activation element-wise. The input is a Tensor with any valid shape. + + Hard sigmoid is defined as: + + .. math:: + \text{hsigmoid}(x_{i}) = max(0, min(1, \frac{2 * x_{i} + 5}{10})), + + where :math:`x_{i}` is the :math:`i`-th slice along the given dim of the input Tensor. + + Inputs: + - **input_data** (Tensor) - The input of HSigmoid. + + Outputs: + Tensor, with the same type and shape as the `input_data`. + + """ + + @prim_attr_register + def __init__(self): + self.init_prim_io_names(inputs=['x'], outputs=['output']) + + def infer_shape(self, x_shape): + return x_shape + + def infer_dtype(self, x_dtype): + validator.check_subclass("x_dtype", x_dtype, mstype.tensor) + validator.check_typename("x_dtype", x_dtype, (mstype.float16, mstype.float32)) + return x_dtype + + class Tanh(PrimitiveWithInfer): r""" Tanh activation function. @@ -460,8 +531,8 @@ class Conv2D(PrimitiveWithInfer): 2 deconvolution, 3 depthwise convolution. Default: 1. pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". pad (int): The pad value to fill. Default: 0. - stride (int): The stride to apply conv filter. Default: 1. - dilation (int): Specify the space to use between kernel elements. Default: 1. + stride (Union(int, tuple[int])): The stride to apply conv filter. Default: 1. + dilation (Union(int, tuple[int])): Specify the space to use between kernel elements. Default: 1. group (int): Split input into groups. Default: 1. Returns: @@ -488,11 +559,35 @@ class Conv2D(PrimitiveWithInfer): group=1): """init Conv2D""" self.init_prim_io_names(inputs=['x', 'w'], outputs=['output']) - self.kernel_size = kernel_size self.kernel_size = validator.check_type('kernel_size', kernel_size, (int, tuple)) - if isinstance(self.kernel_size, int): - self.kernel_size = (self.kernel_size, self.kernel_size) - validator.check_integer('length of kernel_size', len(self.kernel_size), 2, Rel.GE) + if isinstance(kernel_size, int): + self.kernel_size = (kernel_size, kernel_size) + if len(self.kernel_size) != 2 or (not isinstance(self.kernel_size[0], int)) or \ + (not isinstance(self.kernel_size[1], int)) or \ + self.kernel_size[0] < 1 or self.kernel_size[1] < 1: + raise ValueError(f"The \'kernel_size\' of \'Conv2D\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {kernel_size}") + self.stride = validator.check_type('stride', stride, (int, tuple)) + if isinstance(stride, int): + self.stride = (stride, stride) + if len(self.stride) != 2 or (not isinstance(self.stride[0], int)) or \ + (not isinstance(self.stride[1], int)) or \ + self.stride[0] < 1 or self.stride[1] < 1: + raise ValueError(f"The \'stride\' of \'Conv2D\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {stride}") + self.add_prim_attr('stride', (1, 1, self.stride[0], self.stride[1])) + self.dilation = validator.check_type('dilation', dilation, (tuple, int)) + if isinstance(dilation, int): + self.dilation = (1, 1, dilation, dilation) + elif len(dilation) == 2: + self.dilation = (1, 1, dilation[0], dilation[1]) + if len(self.dilation) != 4 or (not isinstance(self.dilation[0], int) or self.dilation[0] < 1) or \ + (not isinstance(self.dilation[1], int) or self.dilation[1] < 1) or \ + (not isinstance(self.dilation[2], int) or self.dilation[2] < 1) or \ + (not isinstance(self.dilation[3], int) or self.dilation[3] < 1): + raise ValueError(f"The \'dilation\' of \'Conv2D\' should be an positive int number or " + f"a tuple of two or four positive int numbers, but got {dilation}") + self.add_prim_attr('dilation', self.dilation) validator.equal('type of pad', type(pad), 'not bool', not isinstance(pad, bool)) validator.equal('type of pad', type(pad), 'int', isinstance(pad, int)) self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad']) @@ -504,18 +599,6 @@ class Conv2D(PrimitiveWithInfer): self.add_prim_attr('data_format', "NCHW") self.out_channel = validator.check_integer('out_channel', out_channel, 0, Rel.GT) self.group = validator.check_integer('group', group, 0, Rel.GT) - self.dilation = validator.check_integer('dilation', dilation, 1, Rel.GE) - validator.check_type('kernel_size', kernel_size, [int, tuple]) - if isinstance(kernel_size, int) and kernel_size < 1: - raise ValueError('Attr \'kernel_size\' of \'Conv2D\' Op passed ' - + str(self.kernel_size) + ', should be a int or tuple and equal to or greater than 1.') - if isinstance(kernel_size, tuple) and (len(kernel_size) != 2 or - (not isinstance(kernel_size[0], int)) or - (not isinstance(kernel_size[1], int)) or - kernel_size[0] < 1 or kernel_size[1] < 1): - raise ValueError('Attr \'kernel_size\' of \'Conv2D\' Op passed ' - + str(self.kernel_size) + ', should be a int or tuple and equal to or greater than 1.') - self.stride = validator.check_integer('stride', stride, 1, Rel.GE) def infer_shape(self, x_shape, w_shape): validator.check_integer("weight_shape", len(w_shape), 4, Rel.EQ) @@ -526,29 +609,33 @@ class Conv2D(PrimitiveWithInfer): kernel_size_h = w_shape[2] kernel_size_w = w_shape[3] + stride_h = self.stride[2] + stride_w = self.stride[3] + dilation_h = self.dilation[2] + dilation_w = self.dilation[3] if self.pad_mode == "valid": - h_out = math.ceil((x_shape[2] - self.dilation * (kernel_size_h - 1)) / self.stride) - w_out = math.ceil((x_shape[3] - self.dilation * (kernel_size_w - 1)) / self.stride) + h_out = math.ceil((x_shape[2] - dilation_h * (kernel_size_h - 1)) / stride_h) + w_out = math.ceil((x_shape[3] - dilation_w * (kernel_size_w - 1)) / stride_w) pad_top, pad_bottom, pad_left, pad_right = 0, 0, 0, 0 elif self.pad_mode == "same": - h_out = math.ceil(x_shape[2] / self.stride) - w_out = math.ceil(x_shape[3] / self.stride) + h_out = math.ceil(x_shape[2] / stride_h) + w_out = math.ceil(x_shape[3] / stride_w) - pad_needed_h = max(0, (h_out - 1) * self.stride + self.dilation * (kernel_size_h - 1) + 1 - x_shape[2]) + pad_needed_h = max(0, (h_out - 1) * stride_h + dilation_h * (kernel_size_h - 1) + 1 - x_shape[2]) pad_top = math.floor(pad_needed_h / 2) pad_bottom = pad_needed_h - pad_top - pad_needed_w = max(0, (w_out - 1) * self.stride + self.dilation * (kernel_size_w - 1) + 1 - x_shape[3]) + pad_needed_w = max(0, (w_out - 1) * stride_w + dilation_w * (kernel_size_w - 1) + 1 - x_shape[3]) pad_left = math.floor(pad_needed_w / 2) pad_right = pad_needed_w - pad_left elif self.pad_mode == 'pad': pad_top, pad_bottom, pad_left, pad_right = self.pad, self.pad, self.pad, self.pad - h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (self.dilation - 1)) \ - / self.stride - w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (self.dilation - 1)) \ - / self.stride + h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ + / stride_h + w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ + / stride_w h_out = math.floor(h_out) w_out = math.floor(w_out) @@ -580,19 +667,19 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): Args: channel_multiplier (int): The multipiler for the original output conv. - kernel_size (int or tuple): The size of the conv kernel. + kernel_size (Union[int, tuple[int]]): The size of the conv kernel. mode (int): 0 Math convolution, 1 cross-correlation convolution , 2 deconvolution, 3 depthwise convolution. Default: 3. pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". pad (int): The pad value to fill. Default: 0. - stride (int): The stride to apply conv filter. Default: 1. - dilation (int): Specifies the dilation rate to use for dilated convolution. Default: 1. + stride (Union[int, tuple[int]]): The stride to apply conv filter. Default: 1. + dilation (Union[int, tuple[int]]): Specifies the dilation rate to use for dilated convolution. Default: 1. group (int): Splits input into groups. Default: 1. Inputs: - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. - **weight** (Tensor) - Set size of kernel is :math:`(K_1, K_2)`, then the shape is - :math:`(C_{out}, C_{in}, K_1, K_2)`. + :math:`(\text{channel_multiplier}, C_{in}, K_1, K_2)`. Outputs: Tensor of shape :math:`(N, C_{in} * \text{channel_multiplier}, H_{out}, W_{out})`. @@ -609,16 +696,35 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): dilation=1, group=1): """init DepthwiseConv2dNative""" + self.init_prim_io_names(inputs=['x', 'w'], outputs=['output']) validator.check_pad_value_by_mode(self.__class__.__name__, pad_mode, pad) - validator.check_type("kernel_size", kernel_size, (int, tuple)) + self.kernel_size = validator.check_type('kernel_size', kernel_size, (int, tuple)) if isinstance(kernel_size, int): - kernel_size = (kernel_size, kernel_size) - if isinstance(kernel_size, tuple) and (len(kernel_size) != 2 or - (not isinstance(kernel_size[0], int)) or - (not isinstance(kernel_size[1], int)) or - kernel_size[0] < 1 or kernel_size[1] < 1): - raise ValueError(f"Attr kernel_size of DepthwiseConv2dNative Op not passed " - f"{kernel_size}, should be a int or tuple and equal to or greater than 1.") + self.kernel_size = (kernel_size, kernel_size) + if len(self.kernel_size) != 2 or (not isinstance(self.kernel_size[0], int)) or \ + (not isinstance(self.kernel_size[1], int)) or \ + self.kernel_size[0] < 1 or self.kernel_size[1] < 1: + raise ValueError(f"The \'kernel_size\' of \'DepthwiseConv2dNative\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {kernel_size}") + self.stride = validator.check_type('stride', stride, (int, tuple)) + if isinstance(stride, int): + self.stride = (stride, stride) + if len(self.stride) != 2 or (not isinstance(self.stride[0], int)) or \ + (not isinstance(self.stride[1], int)) or \ + self.stride[0] < 1 or self.stride[1] < 1: + raise ValueError(f"The \'stride\' of \'DepthwiseConv2dNative\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {stride}") + self.add_prim_attr('stride', (1, 1, self.stride[0], self.stride[1])) + self.dilation = validator.check_type('dilation', dilation, (tuple, int)) + if isinstance(dilation, int): + self.dilation = (dilation, dilation) + if len(self.dilation) != 2 or (not isinstance(self.dilation[0], int)) or \ + (not isinstance(self.dilation[1], int)) or \ + self.dilation[0] < 1 or self.dilation[1] < 1: + raise ValueError(f"The \'dilation\' of \'DepthwiseConv2dNative\' should be an positive int number or " + f"a tuple of two or four positive int numbers, but got {dilation}") + self.add_prim_attr('dilation', (1, 1, self.dilation[0], self.dilation[1])) + validator.equal('type of pad', type(pad), 'not bool', not isinstance(pad, bool)) if pad_mode not in ("same", "valid", "pad"): raise ValueError(f"Attr pad_mode of DepthwiseConv2dNative Op not passed" f"{pad_mode} not in valid, same, pad.") @@ -627,9 +733,6 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): self.add_prim_attr('data_format', "NCHW") self.channel_multiplier = validator.check_integer("channel_multiplier", channel_multiplier, 0, Rel.GT) self.group = validator.check_integer("group", group, 0, Rel.GT) - self.dilation = validator.check_integer("dilation", dilation, 1, Rel.GE) - self.kernel_size = validator.check_value_on_integer("kernel_size", kernel_size, 1, Rel.GE) - self.stride = validator.check_integer("stride", stride, 1, Rel.GE) self.pad = pad def infer_shape(self, x_shape, w_shape): @@ -640,29 +743,33 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): kernel_size_h = w_shape[2] kernel_size_w = w_shape[3] + stride_h = self.stride[2] + stride_w = self.stride[3] + dilation_h = self.dilation[2] + dilation_w = self.dilation[3] if self.pad_mode == "valid": - h_out = math.ceil((x_shape[2] - self.dilation * (kernel_size_h - 1)) / self.stride) - w_out = math.ceil((x_shape[3] - self.dilation * (kernel_size_w - 1)) / self.stride) + h_out = math.ceil((x_shape[2] - dilation_h * (kernel_size_h - 1)) / stride_h) + w_out = math.ceil((x_shape[3] - dilation_w * (kernel_size_w - 1)) / stride_w) pad_top, pad_bottom, pad_left, pad_right = 0, 0, 0, 0 elif self.pad_mode == "same": - h_out = math.ceil(x_shape[2] / self.stride) - w_out = math.ceil(x_shape[3] / self.stride) + h_out = math.ceil(x_shape[2] / stride_h) + w_out = math.ceil(x_shape[3] / stride_w) - pad_needed_h = max(0, (h_out - 1) * self.stride + self.dilation * (kernel_size_h - 1) + 1 - x_shape[2]) + pad_needed_h = max(0, (h_out - 1) * stride_h+ dilation_h * (kernel_size_h - 1) + 1 - x_shape[2]) pad_top = math.floor(pad_needed_h / 2) pad_bottom = pad_needed_h - pad_top - pad_needed_w = max(0, (w_out - 1) * self.stride + self.dilation * (kernel_size_w - 1) + 1 - x_shape[3]) + pad_needed_w = max(0, (w_out - 1) * stride_w + dilation_w * (kernel_size_w - 1) + 1 - x_shape[3]) pad_left = math.floor(pad_needed_w / 2) pad_right = pad_needed_w - pad_left elif self.pad_mode == 'pad': pad_top, pad_bottom, pad_left, pad_right = self.pad, self.pad, self.pad, self.pad - h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (self.dilation - 1)) \ - / self.stride - w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (self.dilation - 1)) \ - / self.stride + h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ + / stride_h + w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ + / stride_w h_out = math.floor(h_out) w_out = math.floor(w_out) else: @@ -715,7 +822,7 @@ class _Pool(PrimitiveWithInfer): (not isinstance(ksize[1], int)) or ksize[0] <= 0 or ksize[1] <= 0): - raise ValueError(f"The 'ksize' passed to operator {self.name} should be an positive int number or" + raise ValueError(f"The 'ksize' passed to operator {self.name} should be an positive int number or " f"a tuple of two positive int numbers, but got {ksize}") self.ksize = (1, 1, ksize[0], ksize[1]) if self.is_maxpoolwithargmax: @@ -731,7 +838,7 @@ class _Pool(PrimitiveWithInfer): (not isinstance(strides[1], int)) or strides[0] <= 0 or strides[1] <= 0): - raise ValueError(f"The 'strides' passed to operator {self.name} should be an positive int number or" + raise ValueError(f"The 'strides' passed to operator {self.name} should be an positive int number or " f"a tuple of two positive int numbers, but got {strides}") self.strides = (1, 1, strides[0], strides[1]) if self.is_maxpoolwithargmax: @@ -853,7 +960,6 @@ class MaxPoolWithArgmax(_Pool): - **output** (Tensor) - Maxpooling result, with shape :math:`(N, C_{out}, H_{out}, W_{out})`. - **mask** (Tensor) - Max values' index represented by the mask. """ - def __init__(self, ksize=1, strides=1, padding="valid"): super(MaxPoolWithArgmax, self).__init__(ksize, strides, padding) self.is_tbe = context.get_context("device_target") == "Ascend" @@ -944,8 +1050,8 @@ class Conv2DBackpropInput(PrimitiveWithInfer): pad (int): The pad value to fill. Default: 0. mode (int): 0 Math convolutiuon, 1 cross-correlation convolution , 2 deconvolution, 3 depthwise convolution. Default: 1. - stride (int): The stride to apply conv filter. Default: 1. - dilation (int): Specifies the dilation rate to use for dilated convolution. Default: 1. + stride (Union[int. tuple[int]]): The stride to apply conv filter. Default: 1. + dilation (Union[int. tuple[int]]): Specifies the dilation rate to use for dilated convolution. Default: 1. group (int): Splits input into groups. Default: 1. Returns: @@ -967,25 +1073,41 @@ class Conv2DBackpropInput(PrimitiveWithInfer): self.init_prim_io_names(inputs=['out_backprop', 'filter', 'input_sizes'], outputs=['output']) self.out_channel = validator.check_integer('out_channel', out_channel, 0, Rel.GT) self.kernel_size = validator.check_type('kernel_size', kernel_size, (int, tuple)) - if isinstance(self.kernel_size, int): - if kernel_size < 1: - raise ValueError('Attr \'kernel_size\' of \'Conv2DBackpropInput\' Op passed ' - + str(self.kernel_size) + ', should be a int or tuple and equal to or greater than 1.') - self.kernel_size = (self.kernel_size, self.kernel_size) - elif isinstance(kernel_size, tuple) and (len(kernel_size) != 2 or - (not isinstance(kernel_size[0], int)) or - (not isinstance(kernel_size[1], int)) or - kernel_size[0] < 1 or kernel_size[1] < 1): - raise ValueError('Attr \'kernel_size\' of \'Conv2DBackpropInput\' Op passed ' - + str(self.kernel_size) + ', should be a int or tuple and equal to or greater than 1.') + if isinstance(kernel_size, int): + self.kernel_size = (kernel_size, kernel_size) + if len(self.kernel_size) != 2 or (not isinstance(self.kernel_size[0], int)) or \ + (not isinstance(self.kernel_size[1], int)) or \ + self.kernel_size[0] < 1 or self.kernel_size[1] < 1: + raise ValueError(f"The \'kernel_size\' of \'Conv2DBackpropInput\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {kernel_size}") + self.stride = validator.check_type('stride', stride, (int, tuple)) + if isinstance(stride, int): + self.stride = (stride, stride) + elif isinstance(stride, tuple) and len(stride) == 4: + self.stride = (stride[2], stride[3]) + if len(self.stride) != 2 or (not isinstance(self.stride[0], int)) or (not isinstance(self.stride[1], int)) or \ + self.stride[0] < 1 or self.stride[1] < 1: + raise ValueError(f"The \'stride\' of \'Conv2DBackpropInput\' should be an positive int number or " + f"a tuple of two or four positive int numbers, but got {stride}") + self.add_prim_attr('stride', self.stride) + self.dilation = validator.check_type('dilation', dilation, (tuple, int)) + if isinstance(dilation, int): + self.dilation = (1, 1, dilation, dilation) + elif len(dilation) == 2: + self.dilation = (1, 1, dilation[0], dilation[1]) + if len(self.dilation) != 4 or (not isinstance(self.dilation[0], int) or self.dilation[0] < 1) or \ + (not isinstance(self.dilation[1], int) or self.dilation[1] < 1) or \ + (not isinstance(self.dilation[2], int) or self.dilation[2] < 1) or \ + (not isinstance(self.dilation[3], int) or self.dilation[3] < 1): + raise ValueError(f"The \'dilation\' of \'Conv2DBackpropInput\' should be an positive int number or " + f"a tuple of two or four positive int numbers, but got {dilation}") + self.add_prim_attr('dilation', self.dilation) validator.equal('type of pad', type(pad), 'not bool', not isinstance(pad, bool)) validator.equal('type of pad', type(pad), 'int', isinstance(pad, int)) self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad']) self.pad = validator.check_pad_value_by_mode(self.__class__.__name__, pad_mode, pad) self.mode = validator.check_integer('mode', mode, 1, Rel.EQ) self.group = validator.check_integer('group', group, 0, Rel.GT) - self.dilation = validator.check_integer('dilation', dilation, 1, Rel.GE) - self.stride = validator.check_integer('stride', stride, 1, Rel.GE) pad_mode = pad_mode.upper() self.add_prim_attr('pad_mode', pad_mode) self.add_prim_attr('data_format', "NCHW") @@ -1004,16 +1126,18 @@ class Conv2DBackpropInput(PrimitiveWithInfer): dout_shape = doutput['shape'] kernel_h = self.kernel_size[0] kernel_w = self.kernel_size[1] + stride_h = self.stride[0] + stride_w = self.stride[1] # default pad mode is valid pad_list = (0, 0, 0, 0) if self.pad_list: pad_list = tuple(self.pad_list) elif self.pad_mode == "SAME": - pad_needed_h = max(0, (dout_shape[2] - 1) * self.stride + kernel_h - x_size_v[2]) + pad_needed_h = max(0, (dout_shape[2] - 1) * stride_h + kernel_h - x_size_v[2]) pad_top = math.floor(pad_needed_h / 2) pad_bottom = pad_needed_h - pad_top - pad_needed_w = max(0, (dout_shape[3] - 1) * self.stride + kernel_w - x_size_v[3]) + pad_needed_w = max(0, (dout_shape[3] - 1) * stride_w + kernel_w - x_size_v[3]) pad_left = math.floor(pad_needed_w / 2) pad_right = pad_needed_w - pad_left pad_list = (pad_top, pad_bottom, pad_left, pad_right) @@ -1222,35 +1346,33 @@ class ApplyMomentum(PrimitiveWithInfer): Tensor, parameters to be updated. Examples: - >>> net = ResNet50() - >>> loss = nn.SoftmaxCrossEntropyWithLogits() - >>> opt = P.ApplyMomentum(Tensor(np.array([0.001])), Tensor(np.array([0.9])), - filter(lambda x: x.requires_grad, net.get_parameters())) - >>> model = Model(net, loss, opt) + Please refer to the usage in nn.ApplyMomentum. """ - + __mindspore_signature__ = ( + ('variable', sig_rw.RW_WRITE, sig_kind.KIND_POSITIONAL_KEYWORD), + ('accumulation', sig_rw.RW_WRITE, sig_kind.KIND_POSITIONAL_KEYWORD), + ('learning_rate', sig_rw.RW_READ, sig_kind.KIND_POSITIONAL_KEYWORD), + ('gradient', sig_rw.RW_READ, sig_kind.KIND_POSITIONAL_KEYWORD), + ('momentum', sig_rw.RW_READ, sig_kind.KIND_POSITIONAL_KEYWORD) + ) @prim_attr_register def __init__(self, use_nesterov=False, use_locking=False, gradient_scale=1.0): self.init_prim_io_names(inputs=['variable', 'accumulation', 'learning_rate', 'gradient', 'momentum'], outputs=['output']) def infer_shape(self, v_shape, a_shape, l_shape, g_shape, m_shape): - validator.check(f'variable shape {v_shape}', len(v_shape), '', 0, Rel.GT) - validator.check(f'accumulation shape {a_shape}', len(a_shape), '', 0, Rel.GT) - validator.check(f'learning rate shape {l_shape}', len(l_shape), '', 0, Rel.GE) - validator.check(f'gradient shape {g_shape}', len(g_shape), '', 0, Rel.GE) - validator.check(f'momentum shape {m_shape}', len(m_shape), '', 0, Rel.GE) return v_shape def infer_dtype(self, v_dtype, a_dtype, l_dtype, g_dtype, m_dtype): - validator.check_subclass("v_dtype", v_dtype, mstype.tensor) - validator.check_subclass("a_dtype", a_dtype, mstype.tensor) - v_type = validator.check_typename("v_dtype", v_dtype, [mstype.float16, mstype.float32, mstype.float64]) - validator.check_typename("a_dtype", a_dtype, [mstype.float16, mstype.float32, mstype.float64]) + if v_dtype != mstype.type_refkey and a_dtype != mstype.type_refkey: + validator.check_subclass("v_dtype", v_dtype, mstype.tensor) + validator.check_subclass("a_dtype", a_dtype, mstype.tensor) + validator.check_typename("v_dtype", v_dtype, [mstype.float16, mstype.float32, mstype.float64]) + validator.check_typename("a_dtype", a_dtype, [mstype.float16, mstype.float32, mstype.float64]) validator.check_typename("l_dtype", l_dtype, [mstype.float16, mstype.float32, mstype.float64]) validator.check_typename("g_dtype", g_dtype, [mstype.float16, mstype.float32, mstype.float64]) validator.check_typename("m_dtype", m_dtype, [mstype.float16, mstype.float32, mstype.float64]) - return v_type + return g_dtype class SmoothL1Loss(PrimitiveWithInfer): @@ -1311,9 +1433,9 @@ class SGD(PrimitiveWithInfer): nesterov (bool): Enable Nesterov momentum. Default: False. Inputs: - - **parameters** (Tensor) - Parameters to be updated. + - **parameters** (Tensor) - Parameters to be updated. Their data type can be list or tuple. - **gradient** (Tensor) - Gradients. - - **learning_rate** (Tensor) - Learning rate. e.g. Tensor(0.1, mindspore.float32). + - **learning_rate** (Tensor) - Learning rate. Must be float value. e.g. Tensor(0.1, mindspore.float32). - **accum** (Tensor) - Accum(velocity) to be updated. - **momentum** (Tensor) - Momentum. e.g. Tensor(0.1, mindspore.float32). - **stat** (Tensor) - States to be updated with the same shape as gradient. @@ -1324,6 +1446,7 @@ class SGD(PrimitiveWithInfer): @prim_attr_register def __init__(self, dampening=0.0, weight_decay=0.0, nesterov=False): + validator.check_type("nesterov", nesterov, [bool]) self.init_prim_io_names(inputs=['parameters', 'gradient', 'learning_rate', 'accum', 'momentum', 'stat'], outputs=['output']) @@ -1824,7 +1947,7 @@ class GetNext(PrimitiveWithInfer): and the type is described is `types`. Examples: - >>> get_next = P.GetNext([mindspore.float32, mindspore.int32], [[32, 1, 28, 28], [10]], 'shared_name') + >>> get_next = P.GetNext([mindspore.float32, mindspore.int32], [[32, 1, 28, 28], [10]], 2, 'shared_name') >>> feature, label = get_next() """ @@ -2023,6 +2146,7 @@ class Pad(PrimitiveWithInfer): for item in paddings: if len(item) != 2: raise ValueError('The shape of paddings must be (n, 2).') + self.paddings = paddings def infer_shape(self, x): paddings = np.array(self.paddings) @@ -2035,9 +2159,78 @@ class Pad(PrimitiveWithInfer): return y_shape def infer_dtype(self, x): + validator.check_subclass("input_x", x, mstype.tensor) return x +class MirrorPad(PrimitiveWithInfer): + """ + Pads the input tensor according to the paddings and mode. + + Args: + mode (string): Specifies padding mode. The optional values are "REFLECT", "SYMMETRIC". + Default: "REFLECT". + + Inputs: + - **input_x** (Tensor) - The input tensor. + - **paddings** (Tensor) - The paddings tensor. The value of `paddings` is a matrix(list), + and its shape is (N, 2). N is the rank of input data. All elements of paddings + are int type. For `D` th dimension of input, paddings[D, 0] indicates how many sizes to be + extended ahead of the `D` th dimension of the input tensor, and paddings[D, 1] indicates + how many sizes to be extended behind of the `D` th dimension of the input tensor. + + Outputs: + Tensor, the tensor after padding. + + - If 'mode` is "REFLECT", it uses a way of symmetrical copying throught the axis of symmetry to fill in, + symmetry. If the `input_x` is [[1,2,3],[4,5,6],[7,8,9]] and `paddings` is [[1,1],[2,2]], then the + Outputs is [[6,5,4,5,6,5,4],[3,2,1,2,3,2,1],[6,5,4,5,6,5,4],[9,8,7,8,9,8,7],[6,5,4,5,6,5,4]]. + - If 'mode' is "SYMMETRIC", the filling method is similar to the "REFLECT". It is also copied + according to the symmetry axis, except that it includes the symmetry axis. If the `input_x` + is [[1,2,3],[4,5,6],[7,8,9]] and `paddings` is [[1,1],[2,2]], then the Outputs is + [[2,1,1,2,3,3,2],[2,1,1,2,3,3,2],[5,4,4,5,6,6,5],[8,7,7,8,9,9,8],[8,7,7,8,9,9,8]]. + + Examples: + >>> from mindspore import Tensor + >>> from mindspore.ops import operations as P + >>> import mindspore.nn as nn + >>> import numpy as np + >>> class Net(nn.Cell): + >>> def __init__(self): + >>> super(Net, self).__init__() + >>> self.pad = P.MirrorPad(mode="REFLECT") + >>> def construct(self, x, paddings): + >>> return self.pad(x, paddings) + >>> x = np.random.random(size=(2, 3)).astype(np.float32) + >>> paddings = Tensor([[1,1],[2,2]]) + >>> pad = Net() + >>> ms_output = pad(Tensor(x), paddings) + """ + + @prim_attr_register + def __init__(self, mode='REFLECT'): + """Init Pad""" + validator.check_string('mode', mode, ['REFLECT', 'SYMMETRIC']) + self.mode = mode + + def __infer__(self, input_x, paddings): + validator.check_subclass("input_x", input_x['dtype'], mstype.tensor) + validator.check_subclass("paddings", paddings['dtype'], mstype.tensor) + x_shape = list(input_x['shape']) + paddings_value = paddings['value'].asnumpy() + paddings_size = paddings_value.size + validator.check_integer('paddings.shape', paddings_size, len(x_shape) * 2, Rel.EQ) + if not np.all(paddings_size >= 0): + raise ValueError('All elements of paddings must be >= 0.') + y_shape = () + for i in range(0, int(paddings_size / 2)): + y_shape += ((x_shape[i] + paddings_value[i, 0] + paddings_value[i, 1]),) + + return {'shape': y_shape, + 'dtype': input_x['dtype'], + 'value': None} + + class ROIAlign(PrimitiveWithInfer): """ Computes Region of Interest (RoI) Align operator. @@ -2136,7 +2329,11 @@ class Adam(PrimitiveWithInfer): - **gradient** (Tensor) - Gradients. Outputs: - Tensor, has the same shape and data type as `var`. + Tuple of 3 Tensor, the updated parameters. + + - **var** (Tensor) - The same shape and data type as `var`. + - **m** (Tensor) - The same shape and data type as `m`. + - **v** (Tensor) - The same shape and data type as `v`. """ @prim_attr_register @@ -2149,7 +2346,7 @@ class Adam(PrimitiveWithInfer): validator.check_param_equal("var_shape", var_shape, "m_shape", m_shape) validator.check_param_equal("var_shape", var_shape, "v_shape", v_shape) validator.check_param_equal("var_shape", var_shape, "grad_shape", grad_shape) - return var_shape + return var_shape, m_shape, v_shape def infer_dtype(self, var_dtype, m_dtype, v_dtype, beta1_power_dtype, beta2_power_dtype, lr_dtype, beta1_dtype, beta2_dtype, epsilon_dtype, grad_dtype): @@ -2159,7 +2356,7 @@ class Adam(PrimitiveWithInfer): args = {"beta1_power_dtype": beta1_power_dtype, "beta2_power_dtype": beta2_power_dtype, 'lr_dtype': lr_dtype, "beta1_dtype": beta1_dtype, "beta2_dtype": beta2_dtype, "epsilon_dtype": epsilon_dtype} validator.check_type_same(args, [mstype.float16, mstype.float32]) - return var_dtype + return var_dtype, m_dtype, v_dtype class BinaryCrossEntropy(PrimitiveWithInfer): @@ -2272,79 +2469,6 @@ class SparseApplyAdagrad(PrimitiveWithInfer): return var_type -class SparseApplyFtrlD(PrimitiveWithInfer): - r""" - Conduct experiment on updating on parameters related to FTRL optimization algorithm. - - .. math :: - \text{accum} = \text{grad} * \text{grad} - - .. math :: - \text{linear} += \text{grad} + (\text{accum} ^ {\text{-lr_power}} - - \frac{\text{accum} ^ \text{-lr_power}}{\text{lr}} * \text{var}) - - .. math :: - \text{quadratic} = {\text{1.0}/({\text{accum}^\text{lr_power} * \text{lr}}) + 2*\text{l2} - - .. math :: - \text{var} = {\text{sign}({linear}) * \text{l1} - \text{linear}})/{ quadratic } - if \vert linear \vert > l1 \ else \ 0.0 - - Args: - lr (float): Learning rate. - l1 (float): temp value NO.1. - l2 (float): temp value No.2. - lr_power (float): temp value used as power number. - use_locking (bool): If true, updating the var and accum tensors will be protected. Default: False. - - Inputs: - - **var** (Tensor) - Variable to be update. The type must be float32. - - **accum** (Tensor) - Accum to be update. The shape must be the same as `var`'s shape, - the type must be float32. - - **linear** (Tensor) - Linear to be update. The shape must be the same as `var`'s shape, - the type must be float32. - - **grad** (Tensor) - Gradient. The shape must be the same as `var`'s shape, - the type must be float32. - - **indices** (Tensor) - A vector of indices into the first dimension of 'var' and 'accum', - the shape of `indices` must be the same as `grad` in first dimension, the type must be int32. - - Output: - Tensors, has the same shape and type as `var`. - - """ - - @prim_attr_register - def __init__(self, lr, l1, l2, lr_power, use_locking=False): - """init SparseApplyFtrlD""" - self.lr = validator.check_type("lr", lr, [float]) - self.l1 = validator.check_type("l1", l1, [float]) - self.l2 = validator.check_type("l2", l2, [float]) - self.lr_power = validator.check_type("lr_power", lr_power, [float]) - self.use_locking = validator.check_type("use_locking", use_locking, [bool]) - - def infer_shape(self, var_shape, accum_shape, linear_shape, grad_shape, indices_shape): - validator.check_param_equal('var shape', var_shape, 'accum shape', accum_shape) - validator.check_param_equal('len of var shape', len(var_shape), 'len of grad shape', len(grad_shape)) - validator.check_param_equal('len of var shape', len(var_shape), 'len of linear shape', len(linear_shape)) - if len(var_shape) > 1: - validator.check_param_equal('var_shape', var_shape[1:], 'grad_shape', grad_shape[1:]) - validator.check_param_equal('var_shape', var_shape[1:], 'linear_shape', linear_shape[1:]) - validator.check_integer("len of indices shape", len(indices_shape), 1, Rel.EQ) - validator.check('the first dimension of grad', grad_shape[0], - 'the shape of indices', indices_shape[0], Rel.EQ) - - return var_shape - - def infer_dtype(self, var_type, accum_type, linear_type, grad_type, indices_type): - validator.check_subclass("var_type", var_type, mstype.tensor) - validator.check_subclass("accum_type", accum_type, mstype.tensor) - validator.check_subclass("linear_type", linear_type, mstype.tensor) - validator.check_subclass("grad_type", grad_type, mstype.tensor) - validator.check_subclass("indices_type", indices_type, mstype.tensor) - - return var_type - - class LARSUpdate(PrimitiveWithInfer): """ Conduct lars (layer-wise adaptive rate scaling) update on the square sum of gradient. @@ -2424,6 +2548,7 @@ class ApplyFtrl(PrimitiveWithInfer): Outputs: Tensor, representing the updated var. """ + @prim_attr_register def __init__(self, use_locking=False): self.init_prim_io_names(inputs=['var', 'accum', 'linear', 'grad', 'lr', 'l1', 'l2', 'lr_power'], @@ -2444,8 +2569,99 @@ class ApplyFtrl(PrimitiveWithInfer): args = {'var_type': var_type, 'accum_type': accum_type, 'linear_type': linear_type, 'grad_type': grad_type} validator.check_type_same(args, (mstype.float32, mstype.float16)) - validator.check_typename("lr", lr_type,[mstype.float16, mstype.float32]) - validator.check_typename("l1", l1_type,[mstype.float16, mstype.float32]) - validator.check_typename("l2", l2_type,[mstype.float16, mstype.float32]) - validator.check_typename("lr_power", lr_power_type,[mstype.float16, mstype.float32]) + validator.check_typename("lr", lr_type, [mstype.float16, mstype.float32]) + validator.check_typename("l1", l1_type, [mstype.float16, mstype.float32]) + validator.check_typename("l2", l2_type, [mstype.float16, mstype.float32]) + validator.check_typename("lr_power", lr_power_type, [mstype.float16, mstype.float32]) return var_type + + +class ExtractImagePatches(PrimitiveWithInfer): + """ + Extract patches from images. + The input tensor must be a 4-D tensor and the data format is NHWC. + + Args: + ksizes (Union[tuple[int], list[int]]): The size of sliding window, should be a tuple or list of int, + and the format is [1, ksize_row, ksize_col, 1]. + strides (Union[tuple[int], list[int]]): Distance between the centers of the two consecutive patches, + should be a tuple or list of int, and the format is [1, stride_row, stride_col, 1]. + rates (Union[tuple[int], list[int]]): In each extracted patch, the gap between the corresponding dim + pixel positions, should be a tuple or list of int, and the format is [1, rate_row, rate_col, 1]. + padding (str): The type of padding algorithm, is a string whose value is "same" or "valid", + not case sensitive. Default: "valid". + + - same: Means that the patch can take the part beyond the original image, and this part is filled with 0. + + - valid: Means that the patch area taken must be completely contained in the original image. + + Inputs: + - **input_x** (Tensor) - A 4-D tensor whose shape is [in_batch, in_row, in_col, in_depth] and + data type is int8, float16, uint8. + + Outputs: + Tensor, a 4-D tensor whose data type is same as 'input_x', + and the shape is [out_batch, out_row, out_col, out_depth], the out_batch is same as the in_batch. + """ + + @prim_attr_register + def __init__(self, ksizes, strides, rates, padding="valid"): + """init""" + validator.check_type("ksizes", ksizes, [tuple, list]) + validator.check_type("strides", strides, [tuple, list]) + validator.check_type("rates", rates, [tuple, list]) + self.padding = validator.check_string('padding', padding.upper(), ['VALID', 'SAME']) + self.add_prim_attr("padding", self.padding) + + if len(ksizes) != 4 or ksizes[0] != 1 or ksizes[3] != 1: + raise ValueError("The format of ksizes should be [1, ksize_row, ksize_col, 1], " + f"but got {ksizes}.") + if not isinstance(ksizes[1], int) or not isinstance(ksizes[2], int) or \ + ksizes[1] < 1 or ksizes[2] < 1: + raise ValueError("The ksize_row and ksize_col in ksizes should be an positive integer number, " + f"but got ksize_row is {ksizes[1]}, ksize_col is {ksizes[2]}") + + if len(strides) != 4 or strides[0] != 1 or strides[3] != 1: + raise ValueError("The format of strides should be [1, stride_row, stride_col, 1], " + f"but got {strides}.") + if not isinstance(strides[1], int) or not isinstance(strides[2], int) or \ + strides[1] < 1 or strides[2] < 1: + raise ValueError("The stride_row and stride_col in strides should be an positive integer number, " + f"but got stride_row is {strides[1]}, stride_col is {strides[2]}") + + if len(rates) != 4 or rates[0] != 1 or rates[3] != 1: + raise ValueError("The format of rates should be [1, rate_row, rate_col, 1], " + f"but got {rates}.") + if not isinstance(rates[1], int) or not isinstance(rates[2], int) or \ + rates[1] < 1 or rates[2] < 1: + raise ValueError("The rate_row and rate_col in rates should be an positive integer number, " + f"but got rate_row is {rates[1]}, rate_col is {rates[2]}") + + def infer_shape(self, input_x): + in_batch, in_row, in_col, in_depth = input_x + _, ksize_row, ksize_col, _ = self.ksizes + _, stride_row, stride_col, _ = self.strides + _, rate_row, rate_col, _ = self.rates + if len(input_x) != 4: + raise ValueError("The `input_x` should be a 4-D tensor, " + f"but got a {len(input_x)}-D tensor whose shape is {input_x}") + + out_batch = in_batch + out_depth = ksize_row * ksize_col * in_depth + + if self.padding == "VALID": + out_row = \ + (in_row - (ksize_row + (ksize_row - 1) * (rate_row - 1))) // stride_row + 1 + out_col = \ + (in_col - (ksize_col + (ksize_col - 1) * (rate_col - 1))) // stride_col + 1 + else: + out_row = (in_row - 1) // stride_row + 1 + out_col = (in_col - 1) // stride_col + 1 + + out_shape = [out_batch, out_row, out_col, out_depth] + return out_shape + + def infer_dtype(self, input_x): + validator.check_subclass("input_x", input_x, mstype.tensor) + validator.check_typename("input_x_dtype", input_x, (mstype.int8, mstype.float16, mstype.float32)) + return input_x diff --git a/mindspore/ops/operations/other_ops.py b/mindspore/ops/operations/other_ops.py index e4d526ad01..2ece6b7088 100644 --- a/mindspore/ops/operations/other_ops.py +++ b/mindspore/ops/operations/other_ops.py @@ -39,7 +39,7 @@ class Assign(PrimitiveWithInfer): >>> self.y = mindspore.Parameter(Tensor([1.0], mindspore.float32), name="y") >>> >>> def construct(self, x): - >>> Assign()(self.y, x) + >>> P.Assign()(self.y, x) >>> return x >>> x = Tensor([2.0], mindspore.float32) >>> net = Net() @@ -76,7 +76,7 @@ class BoundingBoxEncode(PrimitiveWithInfer): Tensor, encoded bounding boxes. Examples: - >>> boundingbox_encode = BoundingBoxEncode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0)) + >>> boundingbox_encode = P.BoundingBoxEncode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0)) >>> delta_box = boundingbox_encode(anchor_box, groundtruth_box) """ @@ -119,8 +119,8 @@ class BoundingBoxDecode(PrimitiveWithInfer): Tensor, decoded boxes. Examples: - >>> boundingbox_decode = BoundingBoxDecode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0), - max_shape=(768, 1280), wh_ratio_clip=0.016) + >>> boundingbox_decode = P.BoundingBoxDecode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0), + >>> max_shape=(768, 1280), wh_ratio_clip=0.016) >>> bbox = boundingbox_decode(anchor_box, deltas) """ @@ -208,7 +208,7 @@ class IOU(PrimitiveWithInfer): KeyError: When `mode` is not 'iou' or 'iof'. Examples: - >>> iou = IOU() + >>> iou = P.IOU() >>> anchor_boxes = Tensor(np.random.randint(1,5, [10, 4])) >>> gt_boxes = Tensor(np.random.randint(1,5, [3, 4])) >>> iou(anchor_boxes, gt_boxes) @@ -255,15 +255,15 @@ class MakeRefKey(Primitive): >>> class Net(nn.Cell): >>> def __init__(self): >>> super(Net, self).__init__() - >>> self.y = Parameter(Tensor(np.ones([6, 8, 10], np.int32)), name="y") - >>> self.make_ref_key = MakeRefKey("y") + >>> self.y = mindspore.Parameter(Tensor(np.ones([6, 8, 10]), mindspore.int32), name="y") + >>> self.make_ref_key = P.MakeRefKey("y") >>> >>> def construct(self, x): >>> key = self.make_ref_key() >>> ref = F.make_ref(key, x, self.y) >>> return ref * x >>> - >>> x = Tensor(np.ones([3, 4, 5], np.int32)) + >>> x = Tensor(np.ones([3, 4, 5]), mindspore.int32) >>> net = Net() >>> net(x) """ @@ -271,3 +271,6 @@ class MakeRefKey(Primitive): @prim_attr_register def __init__(self, tag): validator.check_type('tag', tag, (str,)) + + def __call__(self): + pass diff --git a/mindspore/ops/operations/random_ops.py b/mindspore/ops/operations/random_ops.py index 95692a622e..18c2212b3d 100644 --- a/mindspore/ops/operations/random_ops.py +++ b/mindspore/ops/operations/random_ops.py @@ -44,8 +44,8 @@ class RandomChoiceWithMask(PrimitiveWithInfer): - **mask** (Tensor) - The output has shape 1-D. Examples: - >>> rnd_choice_mask = RandomChoiceWithMask() - >>> input_x = Tensor(np.ones(shape=[240000, 4]), mindspore.bool_) + >>> rnd_choice_mask = P.RandomChoiceWithMask() + >>> input_x = Tensor(np.ones(shape=[240000, 4]).astype(np.bool)) >>> output_y, output_mask = rnd_choice_mask(input_x) """ diff --git a/mindspore/ops/primitive.py b/mindspore/ops/primitive.py index 96e754f5f7..d281b4f76c 100644 --- a/mindspore/ops/primitive.py +++ b/mindspore/ops/primitive.py @@ -194,9 +194,6 @@ class PrimitiveWithInfer(Primitive): Primitive.__init__(self, name) self.set_prim_type(prim_type.py_infer_shape) - def prim_name(self): - return self.__class__.__name__ - def _clone(self): """ Deeply clones the primitive object. diff --git a/mindspore/parallel/algo_parameter_config.py b/mindspore/parallel/algo_parameter_config.py index aafc02367f..d1e4aa87a9 100644 --- a/mindspore/parallel/algo_parameter_config.py +++ b/mindspore/parallel/algo_parameter_config.py @@ -53,13 +53,13 @@ class _AlgoParameterConfig(): self.check_config_handle() return self._config_handle.get_simplify_cal() - def set_not_fully_use_devices(self, not_fully): + def set_fully_use_devices(self, not_fully): self.check_config_handle() - self._config_handle.set_not_fully_use_devices(not_fully) + self._config_handle.set_fully_use_devices(not_fully) - def get_not_fully_use_devices(self): + def get_fully_use_devices(self): self.check_config_handle() - return self._config_handle.get_not_fully_use_devices() + return self._config_handle.get_fully_use_devices() def set_elementwise_op_strategy_follow(self, element_strategy_follow): self.check_config_handle() @@ -119,7 +119,7 @@ def _algo_parameter_config(): set_algo_parameters_config_func_map = { "simplify_cal": _algo_parameter_config().set_simplify_cal, - "not_fully_use_devices": _algo_parameter_config().set_not_fully_use_devices, + "fully_use_devices": _algo_parameter_config().set_fully_use_devices, "elementwise_op_strategy_follow": _algo_parameter_config().set_elementwise_op_strategy_follow, "tensor_slice_align_enable": _algo_parameter_config().set_tensor_slice_align_enable, "tensor_slice_align_size": _algo_parameter_config().set_tensor_slice_align_size} @@ -127,14 +127,14 @@ set_algo_parameters_config_func_map = { get_algo_parameters_config_func_map = { "simplify_cal": _algo_parameter_config().get_simplify_cal, - "not_fully_use_devices": _algo_parameter_config().get_not_fully_use_devices, + "fully_use_devices": _algo_parameter_config().get_fully_use_devices, "elementwise_op_strategy_follow": _algo_parameter_config().get_elementwise_op_strategy_follow, "tensor_slice_align_enable": _algo_parameter_config().get_tensor_slice_align_enable, "tensor_slice_align_size": _algo_parameter_config().get_tensor_slice_align_size} @args_type_check(simplify_cal=bool, tensor_slice_align_enable=bool, tensor_slice_align_size=int, - not_fully_use_devices=bool, elementwise_op_strategy_follow=bool) + fully_use_devices=bool, elementwise_op_strategy_follow=bool) def set_algo_parameters(**kwargs): """ Set algo parameter config. @@ -146,7 +146,7 @@ def set_algo_parameters(**kwargs): simplify_cal (bool): Whether simplifying calculations in strategy-searching algorithm. Default: True tensor_slice_align_enable (bool): Whether checking tensor slice shape. Default: False tensor_slice_align_size (int): The minimum tensor slice shape, the value must be in [1, 1024]. Default: 16 - not_fully_use_devices (bool): Whether generating strategies that not fully use devices. Default: False + fully_use_devices (bool): Whether generating strategies that fully use all available devices. Default: True elementwise_op_strategy_follow (bool): Whether the elementwise operator have the same strategies as its subsequent operators. Default: False diff --git a/mindspore/train/amp.py b/mindspore/train/amp.py index e909b44e40..c4c115ef27 100644 --- a/mindspore/train/amp.py +++ b/mindspore/train/amp.py @@ -82,6 +82,29 @@ def _check_kwargs(key_words): if loss_scale_manager: validator.check_isinstance('loss_scale_manager', loss_scale_manager, LossScaleManager) + +def _add_loss_network(network, loss_fn, cast_model_type): + class WithLossCell(nn.Cell): + "Wrap loss for amp. Cast network output back to float32" + + def __init__(self, backbone, loss_fn): + super(WithLossCell, self).__init__(auto_prefix=False) + self._backbone = backbone + self._loss_fn = loss_fn + + def construct(self, data, label): + out = self._backbone(data) + label = _mp_cast_helper(mstype.float32, label) + return self._loss_fn(F.cast(out, mstype.float32), label) + + validator.check_isinstance('loss_fn', loss_fn, nn.Cell) + if cast_model_type == mstype.float16: + network = WithLossCell(network, loss_fn) + else: + network = nn.WithLossCell(network, loss_fn) + return network + + def build_train_network(network, optimizer, loss_fn=None, level='O0', **kwargs): """ Build the mixed precision training cell automatically. @@ -117,24 +140,7 @@ def build_train_network(network, optimizer, loss_fn=None, level='O0', **kwargs): _do_keep_batchnorm_fp32(network) if loss_fn: - class WithLossCell(nn.Cell): - "Wrap loss for amp. Cast network output back to float32" - - def __init__(self, backbone, loss_fn): - super(WithLossCell, self).__init__(auto_prefix=False) - self._backbone = backbone - self._loss_fn = loss_fn - - def construct(self, data, label): - out = self._backbone(data) - label = _mp_cast_helper(mstype.float32, label) - return self._loss_fn(F.cast(out, mstype.float32), label) - - validator.check_isinstance('loss_fn', loss_fn, nn.Cell) - if config.cast_model_type == mstype.float16: - network = WithLossCell(network, loss_fn) - else: - network = nn.WithLossCell(network, loss_fn) + network = _add_loss_network(network, loss_fn, config.cast_model_type) if _get_parallel_mode() in (ParallelMode.SEMI_AUTO_PARALLEL, ParallelMode.AUTO_PARALLEL): network = _VirtualDatasetCell(network) diff --git a/mindspore/train/callback.py b/mindspore/train/callback.py index dcf630342c..b9635acc62 100644 --- a/mindspore/train/callback.py +++ b/mindspore/train/callback.py @@ -686,9 +686,6 @@ class TimeMonitor(Callback): def __init__(self, data_size): super(TimeMonitor, self).__init__() self.data_size = data_size - self.step_time_cost = [] - self.epoch_time_cost = [] - self.per_step_time = [] def epoch_begin(self, run_context): self.epoch_time = time.time() @@ -696,8 +693,6 @@ class TimeMonitor(Callback): def epoch_end(self, run_context): epoch_mseconds = (time.time() - self.epoch_time) * 1000 per_step_mseconds = epoch_mseconds / self.data_size - self.epoch_time_cost.append(epoch_mseconds) - self.per_step_time.append(per_step_mseconds) print("epoch time: {0}, per step time: {1}".format(epoch_mseconds, per_step_mseconds), flush=True) def step_begin(self, run_context): @@ -705,6 +700,5 @@ class TimeMonitor(Callback): def step_end(self, run_context): step_mseconds = (time.time() - self.step_time) * 1000 - self.step_time_cost.append(step_mseconds) print('step time', step_mseconds, flush=True) diff --git a/mindspore/train/model.py b/mindspore/train/model.py index 41b372f85a..be3939d450 100755 --- a/mindspore/train/model.py +++ b/mindspore/train/model.py @@ -24,8 +24,7 @@ from .. import context from ..parallel._utils import _get_parallel_mode, _get_device_num, _get_global_rank, \ _get_parameter_broadcast, _device_number_check, _parameter_broadcast_check, _callback_wrapper from ..nn.metrics import Loss -from ..nn.wrap import WithLossCell, WithEvalCell, \ - DataWrapper +from .. import nn from ..nn.wrap.cell_wrapper import _VirtualDatasetCell from .parallel_utils import ParallelMode from ..common import dtype as mstype @@ -72,7 +71,7 @@ class Model: >>> self.bn = nn.BatchNorm2d(64) >>> self.relu = nn.ReLU() >>> self.flatten = nn.Flatten() - >>> self.fc = nn.Dense(64*222*222, 3) # padding=0 + >>> self.fc = nn.Dense(64*224*224, 12) # padding=0 >>> >>> def construct(self, x): >>> x = self.conv(x) @@ -131,7 +130,7 @@ class Model: self._loss_fn, level=self._amp_level) elif self._loss_fn: - network = WithLossCell(network, self._loss_fn) + network = nn.WithLossCell(network, self._loss_fn) # If need to check if loss_fn is not None, but optimizer is None return network @@ -151,7 +150,7 @@ class Model: else: if self._loss_fn is None: raise ValueError("loss_fn can not be None.") - self._eval_network = WithEvalCell(self._network, self._loss_fn) + self._eval_network = nn.WithEvalCell(self._network, self._loss_fn) self._eval_indexes = [0, 1, 2] def _clear_metrics(self): @@ -206,6 +205,8 @@ class Model: function respectively. callbacks (list): List of callback object. Callbacks which should be executed while training. Default: None. dataset_sink_mode (bool): Determines whether to pass the data through dataset channel. Default: True. + Configure pynative mode, the training process will be performed with + dataset not sink. """ epoch = check_int_positive(epoch) self._train_network.set_train() @@ -227,8 +228,13 @@ class Model: cb_params.train_dataset = train_dataset cb_params.list_callback = list_callback - if dataset_sink_mode and context.get_context("mode") == context.GRAPH_MODE: - self._train_dataset_sink_process(epoch, train_dataset, list_callback, cb_params) + if dataset_sink_mode: + if context.get_context("mode") == context.PYNATIVE_MODE: + logger.warning("The pynative mode cannot support dataset sink mode currently." + "So the training process will be performed with dataset not sink.") + self._train_process(epoch, train_dataset, list_callback, cb_params) + else: + self._train_dataset_sink_process(epoch, train_dataset, list_callback, cb_params) else: self._train_process(epoch, train_dataset, list_callback, cb_params) @@ -248,13 +254,14 @@ class Model: """ # remove later to deal with loop sink need_wrap = False - if not hasattr(train_dataset, '__ME_INITED__') and context.get_context("enable_loop_sink"): + if not hasattr(train_dataset, '__ME_INITED__') and context.get_context("enable_loop_sink") \ + and not context.get_context("enable_ge"): need_wrap = True dataset_helper = DatasetHelper(train_dataset) # remove later to deal with loop sink if need_wrap: - self._train_network = DataWrapper(self._train_network, *(dataset_helper.types_shapes()), + self._train_network = nn.DataWrapper(self._train_network, *(dataset_helper.types_shapes()), train_dataset.__ME_INITED__) cb_params.train_network = self._train_network self._train_network.set_train() @@ -349,10 +356,15 @@ class Model: """ Training API where the iteration is controlled by python front-end. - Configure to pynative mode, the training will be performed with dataset non-sink mode. + When setting pynative mode, the training process will be performed with dataset not sink. Note: CPU is not supported when dataset_sink_mode is true. + If dataset_sink_mode is True, epoch of training should be equal to the count of repeat + operation in dataset processing. Otherwise, errors could occur since the amount of data + is not the amount training requires. + If dataset_sink_mode is True, data will be sent to device. If device is Ascend, features + of data will be transferred one by one. The limitation of data transmission per time is 256M. Args: epoch (int): Total number of iterations on the data. @@ -363,6 +375,8 @@ class Model: function respectively. callbacks (list): List of callback object. Callbacks which should be excuted while training. Default: None. dataset_sink_mode (bool): Determines whether to pass the data through dataset channel. Default: True. + Configure pynative mode, the training process will be performed with + dataset not sink. Examples: @@ -407,7 +421,8 @@ class Model: # remove later to deal with loop sink need_wrap = False - if not hasattr(valid_dataset, '__ME_INITED__') and context.get_context("enable_loop_sink"): + if not hasattr(valid_dataset, '__ME_INITED__') and context.get_context("enable_loop_sink") \ + and not context.get_context("enable_ge"): need_wrap = True valid_dataset.__loop_size__ = 1 @@ -415,7 +430,7 @@ class Model: # remove later to deal with loop sink if need_wrap: - self._eval_network = DataWrapper(self._eval_network, *(dataset_helper.types_shapes()), + self._eval_network = nn.DataWrapper(self._eval_network, *(dataset_helper.types_shapes()), valid_dataset.__ME_INITED__) self._eval_network.set_train(mode=False) self._eval_network.phase = 'eval' @@ -474,6 +489,8 @@ class Model: Note: CPU is not supported when dataset_sink_mode is true. + If dataset_sink_mode is True, data will be sent to device. If device is Ascend, features + of data will be transferred one by one. The limitation of data transmission per time is 256M. Args: valid_dataset (Dataset): Dataset to evaluate the model. @@ -508,7 +525,7 @@ class Model: self._clear_metrics() - if dataset_sink_mode and context.get_context("mode") == context.GRAPH_MODE: + if dataset_sink_mode: return self._eval_dataset_sink_process(valid_dataset, list_callback, cb_params) return self._eval_process(valid_dataset, list_callback, cb_params) diff --git a/mindspore/train/serialization.py b/mindspore/train/serialization.py index 90d8816094..ae17bf8116 100644 --- a/mindspore/train/serialization.py +++ b/mindspore/train/serialization.py @@ -224,42 +224,60 @@ def load_param_into_net(net, parameter_dict): msg = ("Argument parameter_dict should be a dict, but got {}.".format(type(parameter_dict))) raise TypeError(msg) - logger.info("Execute parameter into net process.") - param_name_net_not_have = [] + logger.info("Execute load parameter into net process.") for name in parameter_dict: - b_par_dict_have_par_of_net = False for _, param in net.parameters_and_names(): - if name == param.name: - b_par_dict_have_par_of_net = True + if name == param.name and param.layerwise_parallel: # layerwise parallel parameter data loaded from checkpoint file, # was a complete(merged) data, need to be splited - if param.layerwise_parallel: - new_param = parameter_dict[param.name] - _load_tensor_for_layerwise(new_param, param) + new_param = parameter_dict[param.name] + _load_tensor_for_layerwise(new_param, param) break - if not b_par_dict_have_par_of_net: - param_name_net_not_have.append(name) - param_name_param_dict_not_have = [] + param_not_load = [] for _, param in net.parameters_and_names(): if param.name in parameter_dict: new_param = parameter_dict[param.name] - if not isinstance(new_param, Parameter): logger.error("Failed to combine the net and the parameters.") msg = ("Argument parameter_dict element should be a Parameter, but got {}.".format(type(new_param))) raise TypeError(msg) _update_param(param, new_param) else: - param_name_param_dict_not_have.append(param.name) + param_not_load.append(param.name) + + if param_not_load: + _load_dismatch_prefix_params(net, parameter_dict, param_not_load) logger.debug("Params not matched(in net but not in parameter_dict):") - for paramname in param_name_param_dict_not_have: - logger.debug("%s", paramname) - logger.debug("Params not matched(in parameter_dict but not in net):") - for paramname in param_name_net_not_have: - logger.debug("%s", paramname) - logger.info("Load parameter into net process finish.") + for param_name in param_not_load: + logger.debug("%s", param_name) + + logger.info("Load parameter into net finish, {} parameters has not been loaded.".format(len(param_not_load))) + + +def _load_dismatch_prefix_params(net, parameter_dict, param_not_load): + """When some net parameter did not load, try to continue load.""" + prefix_name = "" + longest_name = param_not_load[0] + while prefix_name != longest_name and param_not_load: + logger.debug("Count: {} parameters has not been loaded, try to load continue.".format(len(param_not_load))) + longest_name = sorted(param_not_load, key=len, reverse=True)[0] + prefix_name = longest_name + for net_param_name in param_not_load: + for dict_name in parameter_dict: + if dict_name.endswith(net_param_name): + tmp_name = dict_name[:-len(net_param_name)] + prefix_name = prefix_name if len(prefix_name) < len(tmp_name) else tmp_name + + if prefix_name != longest_name: + logger.info("Remove parameter prefix name: {}, continue to load.".format(prefix_name)) + for _, param in net.parameters_and_names(): + new_param_name = prefix_name + param.name + if param.name in param_not_load and new_param_name in parameter_dict: + new_param = parameter_dict[new_param_name] + _update_param(param, new_param) + param_not_load.remove(param.name) def _save_graph(network, file_name): @@ -408,7 +426,7 @@ def export(net, *inputs, file_name, file_format='GEIR'): - GEIR: Graph Engine Intermidiate Representation. An intermidiate representation format of Ascend model. - ONNX: Open Neural Network eXchange. An open format built to represent machine learning models. - - LITE: Huawei model format for mobile. + - LITE: Huawei model format for mobile. A lite model only for the MindSpore Lite """ logger.info("exporting model file:%s format:%s.", file_name, file_format) check_input_data(*inputs, data_class=Tensor) diff --git a/mindspore/train/summary/_summary_adapter.py b/mindspore/train/summary/_summary_adapter.py index 29a5774271..7db80de693 100644 --- a/mindspore/train/summary/_summary_adapter.py +++ b/mindspore/train/summary/_summary_adapter.py @@ -71,12 +71,14 @@ class SummaryType(Enum): TENSOR (Number): Summary TENSOR enum. IMAGE (Number): Summary image enum. GRAPH (Number): Summary graph enum. + HISTOGRAM (Number): Summary histogram enum. INVALID (Number): Unknow type. """ SCALAR = 1 # Scalar summary TENSOR = 2 # Tensor summary IMAGE = 3 # Image summary GRAPH = 4 # graph + HISTOGRAM = 5 # Histogram Summary INVALID = 0xFF # unknow type @@ -148,7 +150,7 @@ def package_summary_event(data_id, step): """ data_list = get_summary_data(data_id) if data_list is None: - logger.error("The step(%r) does not have record data.", self.step) + logger.error("The step(%r) does not have record data.", step) del_summary_data(data_id) # create the event of summary summary_event = Event() @@ -177,6 +179,12 @@ def package_summary_event(data_id, step): summary_value.tag = tag summary_image = summary_value.image _get_image_summary(tag, data, summary_image, MS_IMAGE_TENSOR_FORMAT) + elif summary_type is SummaryType.HISTOGRAM: + logger.debug("Now process Histogram summary, tag = %r", tag) + summary_value = summary.value.add() + summary_value.tag = tag + summary_histogram = summary_value.histogram + _fill_histogram_summary(tag, data, summary_histogram) else: # The data is invalid ,jump the data logger.error("Summary type is error, tag = %r", tag) @@ -284,6 +292,74 @@ def _get_tensor_summary(tag: str, np_value, summary_tensor): return summary_tensor +def _fill_histogram_summary(tag: str, np_value: np.array, summary_histogram) -> None: + """ + Package the histogram summary. + + Args: + tag (str): Summary tag describe. + np_value (np.array): Summary data. + summary_histogram (summary_pb2.Summary.Histogram): Summary histogram data. + """ + logger.debug("Set(%r) the histogram summary value", tag) + # Default bucket for tensor with no valid data. + default_bucket_left = -0.5 + default_bucket_width = 1.0 + + if np_value.size == 0: + bucket = summary_histogram.buckets.add() + bucket.left = default_bucket_left + bucket.width = default_bucket_width + bucket.count = 0 + + summary_histogram.nan_count = 0 + summary_histogram.pos_inf_count = 0 + summary_histogram.neg_inf_count = 0 + + summary_histogram.max = 0 + summary_histogram.min = 0 + summary_histogram.sum = 0 + + summary_histogram.count = 0 + + return + + summary_histogram.nan_count = np.count_nonzero(np.isnan(np_value)) + summary_histogram.pos_inf_count = np.count_nonzero(np.isposinf(np_value)) + summary_histogram.neg_inf_count = np.count_nonzero(np.isneginf(np_value)) + summary_histogram.count = np_value.size + + masked_value = np.ma.masked_invalid(np_value) + tensor_max = masked_value.max() + tensor_min = masked_value.min() + tensor_sum = masked_value.sum() + + # No valid value in tensor. + if tensor_max is np.ma.masked: + bucket = summary_histogram.buckets.add() + bucket.left = default_bucket_left + bucket.width = default_bucket_width + bucket.count = 0 + + summary_histogram.max = np.nan + summary_histogram.min = np.nan + summary_histogram.sum = 0 + + return + + counts, edges = np.histogram(np_value, bins='auto', range=(tensor_min, tensor_max)) + + for ind, count in enumerate(counts): + bucket = summary_histogram.buckets.add() + bucket.left = edges[ind] + bucket.width = edges[ind + 1] - edges[ind] + bucket.count = count + + summary_histogram.max = tensor_max + summary_histogram.min = tensor_min + summary_histogram.sum = tensor_sum + + def _get_image_summary(tag: str, np_value, summary_image, input_format='NCHW'): """ Package the image summary. diff --git a/mindspore/train/summary/_summary_scheduler.py b/mindspore/train/summary/_summary_scheduler.py index fa5a228e6a..3327b02fa7 100644 --- a/mindspore/train/summary/_summary_scheduler.py +++ b/mindspore/train/summary/_summary_scheduler.py @@ -23,6 +23,7 @@ from ._summary_adapter import SummaryType, package_summary_event, save_summary_d FORMAT_SCALAR_STR = "Scalar" FORMAT_TENSOR_STR = "Tensor" FORMAT_IMAGE_STR = "Image" +FORMAT_HISTOGRAM_STR = "Histogram" FORMAT_BEGIN_SLICE = "[:" FORMAT_END_SLICE = "]" @@ -95,6 +96,8 @@ def _parse_tag_format(tag: str): summary_type = SummaryType.TENSOR elif type_str == FORMAT_IMAGE_STR: summary_type = SummaryType.IMAGE + elif type_str == FORMAT_HISTOGRAM_STR: + summary_type = SummaryType.HISTOGRAM else: logger.error("The tag(%s) type is invalid.", tag) summary_type = SummaryType.INVALID diff --git a/package.sh b/package.sh deleted file mode 100755 index 0c75a1bbfd..0000000000 --- a/package.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/bash -# Copyright 2019 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================ - -set -e - -BASEPATH=$(cd "$(dirname $0)"; pwd) -echo "${BASEPATH}" -cd "${BASEPATH}" -BUILD_PATH="${BASEPATH}/build" -PACKAGE_PATH="${BUILD_PATH}/package" -OUTPUT_PATH="${BASEPATH}/output" - -mk_new_dir() { - local create_dir="$1" # the target to make - - if [[ -d "${create_dir}" ]];then - rm -rf "${create_dir}" - fi - - mkdir -pv "${create_dir}" -} - -to_lower () { - echo "$1" | tr '[:upper:]' '[:lower:]' -} - -COMMIT_ID=$(git log --format='[sha1]:%h,[branch]:%d' -1 | sed 's/ //g') -export COMMIT_ID - -PYTHON=$(which python3) -PYTHON_VERSION=$("${PYTHON}" -V 2>&1 | awk '{print $2}' | cut -d. -f-2) -if [[ $(uname) == "Linux" ]]; then - if [[ "${PYTHON_VERSION}" == "3.7" ]]; then - PY_TAGS="cp37-cp37m" - elif [[ "${PYTHON_VERSION}" == "3.6" ]]; then - PY_TAGS="cp36-cp36m" - else - echo "Could not find 'Python 3.6' or 'Python 3.7'" - exit 1 - fi - PLATFORM_TAG=$(to_lower "$(uname)_$(uname -m)") -elif [[ $(uname) == "Darwin" ]]; then - if [[ "${PYTHON_VERSION}" == "3.7" || "${PYTHON_VERSION}" == "3.6" ]]; then - PY_TAGS="py3-none" - else - echo "Could not find 'Python 3.6' or 'Python 3.7'" - exit 1 - fi - PLATFORM_TAG="any" -fi -echo "=========${BASEPATH}===================" -mk_new_dir "${OUTPUT_PATH}" - -#copy necessary file to pack_path -cp ${BASEPATH}/mindspore/*.py "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/nn" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/_extends" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/parallel" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/mindrecord" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/train" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/model_zoo" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/common" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/ops" "${PACKAGE_PATH}/mindspore" -cp -rf "${BUILD_PATH}/../mindspore/communication" "${PACKAGE_PATH}/mindspore" - -if [[ "X$2" = "Xgpu" ]]; then - echo "package akg when gpu enable." - cp -rf "${BASEPATH}/mindspore/akg" "${PACKAGE_PATH}" - if [[ -d "${BUILD_PATH}/mindspore/incubator-tvm" ]]; then - cp -rf "${BUILD_PATH}/mindspore/incubator-tvm/topi/python/topi" "${PACKAGE_PATH}/akg" - cp -rf "${BUILD_PATH}/mindspore/incubator-tvm/python/tvm" "${PACKAGE_PATH}/akg" - fi -fi - -# move dataset -if [[ -d "${BASEPATH}/mindspore/dataset" ]]; then - cp -rf "${BASEPATH}/mindspore/dataset" "${PACKAGE_PATH}/mindspore" -fi - -cd "${PACKAGE_PATH}" -if [ -n "$1" ];then - export BACKEND_POLICY=$1 -else - export BACKEND_POLICY="ms" -fi - -# package name -if [[ "X$1" = "Xge" ]]; then - export MS_PACKAGE_NAME="mindspore" -elif [[ "X$1" = "Xms" && "X$2" = "Xgpu" ]]; then - export MS_PACKAGE_NAME="mindspore-gpu" -elif [[ "X$1" = "Xms" && "X$2" = "Xascend" ]]; then - export MS_PACKAGE_NAME="mindspore-ascend" -elif [[ "X$1" = "Xms" && "X$2" = "Xcpu" ]]; then - export MS_PACKAGE_NAME="mindspore" -else - export MS_PACKAGE_NAME="mindspore" -fi - -${PYTHON} "${BASEPATH}/setup.py" bdist_wheel - -chmod -R 700 ${PACKAGE_PATH}/mindspore/ -chmod -R 700 ${PACKAGE_PATH}/${MS_PACKAGE_NAME//-/_}.egg-info/ - -# rename package -PACKAGE_FULL_NAME=$(find "${PACKAGE_PATH}" -iname "*.whl") -PACKAGE_BASE_NAME=$(echo ${PACKAGE_FULL_NAME} | awk -F / '{print $NF}' | awk -F - '{print $1"-"$2}') -PACKAGE_BASE_NAME=${PACKAGE_BASE_NAME//_*-/-} - -PACKAGE_NEW_NAME="${PACKAGE_BASE_NAME}-${PY_TAGS}-${PLATFORM_TAG}.whl" -cp -rf "${PACKAGE_PATH}/dist"/*.whl "${PACKAGE_PATH}/${PACKAGE_NEW_NAME}" -cp -f "${PACKAGE_PATH}/${PACKAGE_NEW_NAME}" "${OUTPUT_PATH}" - -cd "${BASEPATH}" - -echo "------Successfully created mindspore package------" diff --git a/requirements.txt b/requirements.txt index e4b61f2b6f..e182cd7a3b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ protobuf >= 3.8.0 asttokens >= 1.1.13 pillow >= 6.2.0 scipy >= 1.3.3 -dataclasses >= 0.6 easydict >= 1.9 sympy >= 1.4 cffi >= 1.13.2 diff --git a/dbg_dump_parser.sh b/scripts/dbg_dump_parser.sh similarity index 98% rename from dbg_dump_parser.sh rename to scripts/dbg_dump_parser.sh index 1d1ec28248..cae3409419 100755 --- a/dbg_dump_parser.sh +++ b/scripts/dbg_dump_parser.sh @@ -81,6 +81,8 @@ function checkopts() # check options checkopts "$@" +CUR_PATH=$(pwd) +cd "`dirname $0`/.." cd build/mindspore/ make -j8 @@ -118,3 +120,5 @@ if [[ "${mode}" == "${MODE_DBG}" || "${mode}" == "${MODE_ALL}" ]]; then echo "MS_IR_FILE=$(pwd)/anf_ir_file.dbg MS_IR_PATH=$(pwd)/pkl_objs.dbg/ pytest -s ${UT_NAME}" MS_IR_FILE=$(pwd)/anf_ir_file.dbg MS_IR_PATH=$(pwd)/pkl_objs.dbg/ pytest -s "${UT_NAME}" fi + +cd $CUR_PATH diff --git a/setup.py b/setup.py index e009a9b312..82e6d70fcc 100644 --- a/setup.py +++ b/setup.py @@ -17,6 +17,7 @@ """setup package.""" import os import stat +import platform from setuptools import setup, find_packages from setuptools.command.egg_info import egg_info @@ -97,6 +98,8 @@ required_package = [ package_data = { '': [ '*.so*', + '*.pyd', + '*.dll', 'lib/*.so*', 'lib/*.a', '.commit_id', @@ -111,6 +114,9 @@ def update_permissions(path): Args: path (str): Target directory path. """ + if platform.system() == "Windows": + return + for dirpath, dirnames, filenames in os.walk(path): for dirname in dirnames: dir_fullpath = os.path.join(dirpath, dirname) @@ -137,7 +143,7 @@ class BuildPy(build_py): super().run() mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', 'mindspore') update_permissions(mindspore_dir) - mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', 'akg') + mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', '_akg') update_permissions(mindspore_dir) diff --git a/tests/mindspore_test_framework/utils/block_util.py b/tests/mindspore_test_framework/utils/block_util.py index b4a926c15d..75946c3559 100644 --- a/tests/mindspore_test_framework/utils/block_util.py +++ b/tests/mindspore_test_framework/utils/block_util.py @@ -65,32 +65,11 @@ class IthOutputCell(nn.Cell): self.output_index = output_index def construct(self, *inputs): - raise NotImplementedError - - def construct1(self, x1): - predict = self.network(x1)[self.output_index] - return predict - - def construct2(self, x1, x2): - predict = self.network(x1, x2)[self.output_index] - return predict - - def construct3(self, x1, x2, x3): - predict = self.network(x1, x2, x3)[self.output_index] - return predict - - def construct4(self, x1, x2, x3, x4): - predict = self.network(x1, x2, x3, x4)[self.output_index] - return predict - - def construct5(self, x1, x2, x3, x4, x5): - predict = self.network(x1, x2, x3, x4, x5)[self.output_index] + predict = self.network(*inputs)[self.output_index] return predict def get_output_cell(network, num_input, output_index, training=True): net = IthOutputCell(network, output_index) - f = getattr(net, 'construct%d' % num_input) - setattr(net, "construct", f) set_block_training(net, training) return net diff --git a/tests/st/nccl/test_nccl_all.py b/tests/st/nccl/test_nccl_all.py new file mode 100644 index 0000000000..99494bb741 --- /dev/null +++ b/tests/st/nccl/test_nccl_all.py @@ -0,0 +1,44 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +import os +import pytest + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_single +def test_nccl_lenet(): + return_code = os.system("mpirun -n 8 pytest -s test_nccl_lenet.py") + assert(return_code == 0) + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_single +def test_nccl_all_reduce_op(): + return_code = os.system("mpirun -n 8 pytest -s test_nccl_all_reduce_op.py") + assert(return_code == 0) + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_single +def test_nccl_all_gather_op(): + return_code = os.system("mpirun -n 8 pytest -s test_nccl_all_gather_op.py") + assert(return_code == 0) + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_single +def test_nccl_reduce_scatter_op(): + return_code = os.system("mpirun -n 8 pytest -s test_nccl_reduce_scatter_op.py") + assert(return_code == 0) diff --git a/tests/st/nccl/test_nccl_all_reduce_op.py b/tests/st/nccl/test_nccl_all_reduce_op.py index 3ba8b219e4..7c2e579463 100644 --- a/tests/st/nccl/test_nccl_all_reduce_op.py +++ b/tests/st/nccl/test_nccl_all_reduce_op.py @@ -20,7 +20,7 @@ import mindspore.context as context from mindspore.common.initializer import initializer from mindspore.common.parameter import Parameter from mindspore.communication.management import init, NCCL_WORLD_COMM_GROUP, get_rank, get_group_size -context.set_context(mode=context.GRAPH_MODE, device_target='GPU') +context.set_context(mode=context.GRAPH_MODE, device_target='GPU', enable_dynamic_memory=False) init('nccl') rank = get_rank() diff --git a/tests/st/nccl/test_nccl_lenet.py b/tests/st/nccl/test_nccl_lenet.py index 5642603d42..2aebc5da50 100644 --- a/tests/st/nccl/test_nccl_lenet.py +++ b/tests/st/nccl/test_nccl_lenet.py @@ -27,7 +27,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target="GPU") init('nccl') epoch = 2 -total = 50000 +total = 5000 batch_size = 32 mini_batch = total // batch_size @@ -94,3 +94,4 @@ def test_lenet_nccl(): with open("ms_loss.txt", "w") as fo2: fo2.write("loss:") fo2.write(str(losses[-5:])) + assert(losses[-1] < 0.01) diff --git a/tests/st/nccl/test_nccl_reduce_scatter_op.py b/tests/st/nccl/test_nccl_reduce_scatter_op.py index af22c7690f..32c1f31788 100644 --- a/tests/st/nccl/test_nccl_reduce_scatter_op.py +++ b/tests/st/nccl/test_nccl_reduce_scatter_op.py @@ -62,8 +62,6 @@ def test_ReduceScatter(): expect1 = np.ones([1, 1, 3, 3]).astype(np.float32) * 0.01 * size diff1 = output[1].asnumpy() - expect1 error1 = np.ones(shape=expect1.shape) * 1.0e-5 - print(expect1) - print(output[1]) assert np.all(diff1 < error1) assert (output[1].shape() == expect1.shape) diff --git a/tests/st/networks/test_cpu_lenet.py b/tests/st/networks/test_cpu_lenet.py index bdcbc32382..9fd50f5d9b 100644 --- a/tests/st/networks/test_cpu_lenet.py +++ b/tests/st/networks/test_cpu_lenet.py @@ -78,4 +78,4 @@ def test_lenet(): data = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32) * 0.01) label = Tensor(np.ones([32]).astype(np.int32)) net = LeNet() - train(net, data, label) \ No newline at end of file + train(net, data, label) diff --git a/tests/st/networks/test_gpu_lstm.py b/tests/st/networks/test_gpu_lstm.py index 4387179812..e5208ff669 100644 --- a/tests/st/networks/test_gpu_lstm.py +++ b/tests/st/networks/test_gpu_lstm.py @@ -135,4 +135,5 @@ def test_LSTM(): for epoch in range(num_epochs): loss = train_network(train_features, train_labels) losses.append(loss) + print("loss:", loss.asnumpy()) assert(losses[-1].asnumpy() < 0.01) diff --git a/tests/st/ops/cpu/test_conv2d_backprop_filter_op.py b/tests/st/ops/cpu/test_conv2d_backprop_filter_op.py index 75ca915499..c2f8422e30 100644 --- a/tests/st/ops/cpu/test_conv2d_backprop_filter_op.py +++ b/tests/st/ops/cpu/test_conv2d_backprop_filter_op.py @@ -35,8 +35,8 @@ class Net4(nn.Cell): pad_mode="valid", pad=0, mode=1, - stride=1, - dilation=1, + stride=(1, 1), + dilation=(1, 1, 1, 1), group=1) self.w = Parameter(initializer(Tensor(np.array([[[[1, 0, -1], [1, 0, -1], [1, 0, -1]]]]).astype(np.float32)), [1, 1, 3, 3]), name='w') self.x = Parameter(initializer(Tensor(np.array([[[ diff --git a/tests/st/ops/cpu/test_one_hot_op.py b/tests/st/ops/cpu/test_one_hot_op.py new file mode 100644 index 0000000000..3f2c54b3cb --- /dev/null +++ b/tests/st/ops/cpu/test_one_hot_op.py @@ -0,0 +1,82 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import numpy as np +import mindspore.context as context + +context.set_context(device_target='CPU') + + +class NetOneHot(nn.Cell): + def __init__(self): + super(NetOneHot, self).__init__() + self.on_value = 2.0 + self.off_value = 3.0 + + self.depth_1 = 6 + self.one_hot_1 = nn.OneHot(-1, self.depth_1, self.on_value, self.off_value) + + self.depth_2 = 4 + self.one_hot_2 = nn.OneHot(0, self.depth_1, self.on_value, self.off_value) + self.one_hot_3 = nn.OneHot(0, self.depth_2, self.on_value, self.off_value) + self.one_hot_4 = nn.OneHot(1, self.depth_1, self.on_value, self.off_value) + + @ms_function + def construct(self, indices1, indices2, indices3, indices4): + return (self.one_hot_1(indices1), self.one_hot_2(indices2), + self.one_hot_3(indices3), self.one_hot_4(indices4)) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_one_hot(): + one_hot = NetOneHot() + indices1 = Tensor(np.array([[0, 1], [4, 5], [2, 6]]).astype(np.int32)) + indices2 = Tensor(np.array([1, 2, 3]).astype(np.int32)) + indices3 = Tensor(np.array([[0, 1], [1, 0]]).astype(np.int32)) + indices4 = Tensor(np.array([[0, 1], [4, 5], [2, 6]]).astype(np.int32)) + output = one_hot(indices1, indices2, indices3, indices4) + expect_0 = np.array([ + [[2., 3., 3., 3., 3., 3.], [3., 2., 3., 3., 3., 3.]], + [[3., 3., 3., 3., 2., 3.], [3., 3., 3., 3., 3., 2.]], + [[3., 3., 2., 3., 3., 3.], [3., 3., 3., 3., 3., 3.]] + ]).astype(np.float32) + expect_1 = np.array([ + [3., 3., 3.], + [2., 3., 3.], + [3., 2., 3.], + [3., 3., 2.], + [3., 3., 3.], + [3., 3., 3.] + ]).astype(np.float32) + expect_2 = np.array([ + [[2., 3.], [3., 2.]], [[3., 2.], [2., 3.]], [[3., 3.], [3., 3.]], + [[3., 3.], [3., 3.]] + ]).astype(np.float32) + expect_3 = np.array([ + [[2., 3.], [3., 2.], [3., 3.], [3., 3.], [3., 3.], [3., 3.]], + [[3., 3.], [3., 3.], [3., 3.], [3., 3.], [2., 3.], [3., 2.]], + [[3., 3.], [3., 3.], [2., 3.], [3., 3.], [3., 3.], [3., 3.]] + ]).astype(np.float32) + assert (output[0].asnumpy() == expect_0).all() + assert (output[1].asnumpy() == expect_1).all() + assert (output[2].asnumpy() == expect_2).all() + assert (output[3].asnumpy() == expect_3).all() diff --git a/tests/st/ops/custom_ops_tbe/cus_conv2d_impl.py b/tests/st/ops/custom_ops_tbe/cus_conv2d_impl.py index 54f6954a18..04ac7c2ff7 100644 --- a/tests/st/ops/custom_ops_tbe/cus_conv2d_impl.py +++ b/tests/st/ops/custom_ops_tbe/cus_conv2d_impl.py @@ -13,95 +13,28 @@ # limitations under the License. # ============================================================================ from tests.st.ops.custom_ops_tbe.conv2d import conv2d -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType -@op_info_register("""{ - "op_name": "Cus_Conv2D", - "imply_type": "TBE", - "fusion_type": "CONVLUTION", - "async_flag": false, - "binfile_name": "conv2d.so", - "compute_cost": 10, - "kernel_name": "Cus_Conv2D", - "partial_flag": true, - "attr": [ - { - "name": "stride", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "pad_list", - "param_type": "required", - "type": "listInt", - "value": "all" - }, - { - "name": "dilation", - "param_type": "required", - "type": "listInt", - "value": "all" - } - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 1, - "dtype": [ - "float16" - ], - "format": [ - "FracZ" - ], - "name": "filter", - "need_compile": false, - "param_type": "required", - "shape": "all" - }, - { - "index": 2, - "dtype": [ - "float16" - ], - "format": [ - "DefaultFormat" - ], - "name": "bias", - "need_compile": false, - "param_type": "optional", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float16" - ], - "format": [ - "NC1HWC0" - ], - "name": "y", - "need_compile": true, - "param_type": "required", - "shape": "all" - } - ] -}""") +cus_conv2D_op_info = TBERegOp("Cus_Conv2D") \ + .fusion_type("CONVLUTION") \ + .async_flag(False) \ + .binfile_name("conv2d.so") \ + .compute_cost(10) \ + .kernel_name("Cus_Conv2D") \ + .partial_flag(True) \ + .attr("stride", "required", "listInt", "all") \ + .attr("pad_list", "required", "listInt", "all") \ + .attr("dilation", "required", "listInt", "all") \ + .input(0, "x", False, "required", "all") \ + .input(1, "filter", False, "required", "all") \ + .input(2, "bias", False, "optional", "all") \ + .output(0, "y", True, "required", "all") \ + .dtype_format(DataType.F16_5HD, DataType.F16_FracZ, DataType.F32_Default, DataType.F16_5HD) \ + .get_op_info() + + +@op_info_register(cus_conv2D_op_info) def Cus_Conv2D(inputs, weights, bias, outputs, strides, pads, dilations, kernel_name="conv2d"): conv2d(inputs, weights, bias, outputs, strides, pads, dilations, - kernel_name) \ No newline at end of file + kernel_name) diff --git a/tests/st/ops/custom_ops_tbe/cus_square.py b/tests/st/ops/custom_ops_tbe/cus_square.py index 6a9e769f51..d006f75b4c 100644 --- a/tests/st/ops/custom_ops_tbe/cus_square.py +++ b/tests/st/ops/custom_ops_tbe/cus_square.py @@ -24,7 +24,7 @@ class CusSquare(PrimitiveWithInfer): def __init__(self): """init CusSquare""" self.init_prim_io_names(inputs=['x'], outputs=['y']) - from .square_impl import CusSquare + from square_impl import CusSquare def vm_impl(self, x): x = x.asnumpy() diff --git a/tests/st/ops/custom_ops_tbe/square_impl.py b/tests/st/ops/custom_ops_tbe/square_impl.py index e5992eff1c..f3a1e0751d 100644 --- a/tests/st/ops/custom_ops_tbe/square_impl.py +++ b/tests/st/ops/custom_ops_tbe/square_impl.py @@ -18,11 +18,12 @@ from topi import generic import te.lang.cce from topi.cce import util from te.platform.fusion_manager import fusion_manager -from mindspore.ops.op_info_register import op_info_register +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType # shape size limit for aicore is 2**31 SHAPE_SIZE_LIMIT = 200000000 + @fusion_manager.register("square") def square_compute(input_x, output_y, kernel_name="square"): """ @@ -46,49 +47,21 @@ def square_compute(input_x, output_y, kernel_name="square"): res = te.lang.cce.vmul(input_x, input_x) return res -@op_info_register("""{ - "op_name": "CusSquare", - "imply_type": "TBE", - "fusion_type": "OPAQUE", - "async_flag": false, - "binfile_name": "square.so", - "compute_cost": 10, - "kernel_name": "CusSquare", - "partial_flag": true, - "attr": [ - - ], - "inputs": [ - { - "index": 0, - "dtype": [ - "float32" - ], - "format": [ - "DefaultFormat" - ], - "name": "x", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ], - "outputs": [ - { - "index": 0, - "dtype": [ - "float32" - ], - "format": [ - "DefaultFormat" - ], - "name": "y", - "need_compile": false, - "param_type": "required", - "shape": "all" - } - ] -}""") + +cus_conv2D_op_info = TBERegOp("CusSquare") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("square.so") \ + .compute_cost(10) \ + .kernel_name("CusSquare") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .get_op_info() + + +@op_info_register(cus_conv2D_op_info) def CusSquare(input_x, output_y, kernel_name="square"): """ algorithm: square diff --git a/tests/st/ops/custom_ops_tbe/test_square.py b/tests/st/ops/custom_ops_tbe/test_square.py index c67edae307..d8439000f8 100644 --- a/tests/st/ops/custom_ops_tbe/test_square.py +++ b/tests/st/ops/custom_ops_tbe/test_square.py @@ -16,7 +16,7 @@ import numpy as np import mindspore.nn as nn import mindspore.context as context from mindspore import Tensor -from .cus_square import CusSquare +from cus_square import CusSquare import pytest context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") @@ -32,6 +32,7 @@ class Net(nn.Cell): @pytest.mark.level0 @pytest.mark.platform_x86_ascend_training +@pytest.mark.platform_arm_ascend_training @pytest.mark.env_onecard def test_net(): x = np.array([1.0, 4.0, 9.0]).astype(np.float32) diff --git a/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss.py b/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss.py new file mode 100644 index 0000000000..cc0c0e0fc2 --- /dev/null +++ b/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss.py @@ -0,0 +1,42 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import mindspore.nn as nn +import mindspore.context as context +from mindspore import Tensor +from mindspore.ops import operations as P +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, sigma=1.0): + super(Net, self).__init__() + self.SmoothL1Loss = P.SmoothL1Loss(sigma) + + def construct(self, pred, gt): + return self.SmoothL1Loss(pred, gt) + + +def test_net(): + pred = np.random.randn(2, 4).astype(np.float32) + gt = np.random.randn(2, 4).astype(np.float32) + smooth_l1_loss = Net() + loss = smooth_l1_loss(Tensor(pred), Tensor(gt)) + print("------------- input ---------------") + print("predict:\n", pred) + print("grount truth:\n", gt) + print("------------- output ---------------") + print("loss:\n", loss.asnumpy()) diff --git a/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss_grad.py b/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss_grad.py new file mode 100644 index 0000000000..1ab9d998a1 --- /dev/null +++ b/tests/st/ops/davinci/test_tbe_ops/test_smooth_l1_loss_grad.py @@ -0,0 +1,55 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import mindspore.nn as nn +import mindspore.context as context +from mindspore.ops.composite import GradOperation +from mindspore import Tensor +from mindspore.ops import operations as P + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, sigma=1.0): + super(Net, self).__init__() + self.SmoothL1Loss = P.SmoothL1Loss(sigma) + + def construct(self, pred, gt): + return self.SmoothL1Loss(pred, gt) + +class Grad(nn.Cell): + def __init__(self, network): + super(Grad, self).__init__() + self.grad = GradOperation(name="get_all", get_all=True, sens_param=True) + self.network = network + + def construct(self, pred, gt, dout): + return self.grad(self.network)(pred, gt, dout) + + +def test_net(): + pred = np.random.randn(2, 4).astype(np.float32) + gt = np.random.randn(2, 4).astype(np.float32) + dout = np.random.randn(2, 4).astype(np.float32) + smooth_l1_loss_grad = Grad(Net()) + output = smooth_l1_loss_grad(Tensor(pred), Tensor(gt), Tensor(dout)) + print("------------- input ---------------") + print("predict:\n", pred) + print("grount truth:\n", gt) + print("dout:\n", dout) + print("------------- output ---------------") + print("predict grad:\n", output[0].asnumpy()) diff --git a/tests/st/ops/davinci/test_tbe_ops/test_topkv2.py b/tests/st/ops/davinci/test_tbe_ops/test_topk.py similarity index 97% rename from tests/st/ops/davinci/test_tbe_ops/test_topkv2.py rename to tests/st/ops/davinci/test_tbe_ops/test_topk.py index a505865637..275ef50038 100644 --- a/tests/st/ops/davinci/test_tbe_ops/test_topkv2.py +++ b/tests/st/ops/davinci/test_tbe_ops/test_topk.py @@ -24,7 +24,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") class Net(nn.Cell): def __init__(self, k): super(Net, self).__init__() - self.topk = P.TopK() + self.topk = P.TopK(True) self.k = k def construct(self, x): diff --git a/tests/st/ops/gpu/test_assign_op.py b/tests/st/ops/gpu/test_assign_op.py new file mode 100644 index 0000000000..4cf730d763 --- /dev/null +++ b/tests/st/ops/gpu/test_assign_op.py @@ -0,0 +1,50 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +import numpy as np +import mindspore.context as context + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.assign = P.Assign() + + def construct(self, var, value): + return self.assign(var, value) + +x = np.array([[1.2, 1], [1, 0]]).astype(np.float32) +value = np.array([[1, 2], [3, 4.0]]).astype(np.float32) + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_assign(): + context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + assign = Net() + var = Tensor(x) + output = assign(var, Tensor(value)) + + error = np.ones(shape=[2, 2]) * 1.0e-6 + diff1 = output.asnumpy() - value + diff2 = var.asnumpy() - value + assert np.all(diff1 < error) + assert np.all(-diff1 < error) + assert np.all(diff2 < error) + assert np.all(-diff2 < error) diff --git a/tests/st/ops/gpu/test_batchnorm_fold2_op.py b/tests/st/ops/gpu/test_batchnorm_fold2_op.py new file mode 100644 index 0000000000..0440e92a8d --- /dev/null +++ b/tests/st/ops/gpu/test_batchnorm_fold2_op.py @@ -0,0 +1,89 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import mindspore.context as context + +context.set_context(device_target='GPU') + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.op = P.BatchNormFold2(100000) + + @ms_function + def construct(self, x, beta, gamma, batch_std, batch_mean, running_std, running_mean, current_step): + return self.op(x, beta, gamma, batch_std, batch_mean, running_std, running_mean, current_step) + + +class Net_gnd(nn.Cell): + def __init__(self): + super(Net_gnd, self).__init__() + self.conv_mul = P.ConvMul(freeze_bn=100000) + self.correct_add = P.CorrectionAdd(freeze_bn=100000) + self.add_fold = P.AddFold() + + @ms_function + def construct(self, x, beta, gamma, batch_std, batch_mean, running_std, running_mean, current_step): + out = self.conv_mul(x, batch_std, running_std, current_step) + out = self.correct_add(out, gamma, batch_std, batch_mean, + running_std, running_mean, current_step) + out = self.add_fold(out, beta, gamma, batch_std, batch_mean) + return out + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnrom_fold2(): + net = Net() + c = 64 + freeze_bn = 100000 + x = np.random.uniform(-1, 1, size=[3, c, 32, 32]).astype('float32') + beta = np.random.uniform(1, 2, size=[c]).astype('float32') + gamma = np.random.uniform(1, 2, size=[c]).astype('float32') + batch_std = np.random.uniform(1, 2, size=[c]).astype('float32') + batch_mean = np.random.uniform(1, 2, size=[c]).astype('float32') + running_std = np.random.uniform(1, 2, size=[c]).astype('float32') + running_mean = np.random.uniform(1, 2, size=[c]).astype('float32') + current_step = np.array([0]).astype('int32') + output = net(Tensor(x), Tensor(beta), Tensor(gamma), Tensor(batch_std), Tensor(batch_mean), + Tensor(running_std), Tensor(running_mean), Tensor(current_step)) + expect = (x + beta.reshape(-1, 1, 1) - (gamma * running_mean / running_std).reshape(-1, 1, + 1) if current_step >= freeze_bn else + x * (running_std / batch_std).reshape(-1, 1, 1) + (beta - gamma * batch_mean / batch_std).reshape(-1, 1, + 1)) + error = np.ones(shape=expect.shape) * 1.0e-6 + diff = output.asnumpy() - expect + assert np.all(diff < error) + assert np.all(diff > error * -1) + + current_step = np.array([100000]).astype('int32') + output = net(Tensor(x), Tensor(beta), Tensor(gamma), Tensor(batch_std), Tensor(batch_mean), Tensor(running_std), + Tensor(running_mean), Tensor(current_step)) + expect = (x + beta.reshape(-1, 1, 1) - (gamma * running_mean / running_std).reshape(-1, 1, + 1) if current_step >= freeze_bn else + x * (batch_std / running_std).reshape(-1, 1, 1) + (beta - gamma * batch_mean / batch_std).reshape(-1, 1, + 1)) + error = np.ones(shape=expect.shape) * 1.0e-6 + diff = output.asnumpy() - expect + assert np.all(diff < error) + assert np.all(diff > error * -1) diff --git a/tests/st/ops/gpu/test_batchnorm_fold_grad_op.py b/tests/st/ops/gpu/test_batchnorm_fold_grad_op.py new file mode 100644 index 0000000000..8e55f6a473 --- /dev/null +++ b/tests/st/ops/gpu/test_batchnorm_fold_grad_op.py @@ -0,0 +1,96 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import mindspore.context as context + +context.set_context(device_target='GPU') + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.op = P.BatchNormFoldGrad(freeze_bn=10) + + @ms_function + def construct(self, d_batch_mean, d_batch_std, x, batch_mean, batch_std, current_step): + dx = self.op(d_batch_mean, d_batch_std, x, batch_mean, batch_std, current_step) + return dx + + +def np_result(d_batch_mean, d_batch_std, x, batch_mean, batch_std): + n = x.shape[0] * x.shape[2] * x.shape[3] + dx = d_batch_mean.reshape(1, -1, 1, 1) / n + d_batch_std.reshape(1, -1, 1, 1) * ( + x - batch_mean.reshape(1, -1, 1, 1)) / batch_std.reshape(1, -1, 1, 1) / n + return dx + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold_grad1(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[3, c, 32, 32]).astype('float32') + d_batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + d_batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([0]).astype('int32') + dx = net(Tensor(d_batch_mean), Tensor(d_batch_std), Tensor(x), Tensor(batch_mean), Tensor(batch_std), + Tensor(current_step)) + expect = np_result(d_batch_mean, d_batch_std, x, batch_mean, batch_std) + assert np.allclose(dx.asnumpy(), expect, rtol=1.e-7, atol=1.e-7) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold_grad2(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[1, c, 256, 256]).astype('float32') + d_batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + d_batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([0]).astype('int32') + dx = net(Tensor(d_batch_mean), Tensor(d_batch_std), Tensor(x), Tensor(batch_mean), Tensor(batch_std), + Tensor(current_step)) + expect = np_result(d_batch_mean, d_batch_std, x, batch_mean, batch_std) + assert np.allclose(dx.asnumpy(), expect, rtol=1.e-7, atol=1.e-7) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold_grad_freeze(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[3, c, 32, 32]).astype('float32') + d_batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + d_batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_mean = np.random.uniform(1, 10, size=[c]).astype('float32') + batch_std = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([10]).astype('int32') + dx = net(Tensor(d_batch_mean), Tensor(d_batch_std), Tensor(x), Tensor(batch_mean), Tensor(batch_std), + Tensor(current_step)) + expect = np.zeros_like(x) + assert np.allclose(dx.asnumpy(), expect, rtol=1.e-7, atol=1.e-7) diff --git a/tests/st/ops/gpu/test_batchnorm_fold_op.py b/tests/st/ops/gpu/test_batchnorm_fold_op.py new file mode 100644 index 0000000000..c4abf152a6 --- /dev/null +++ b/tests/st/ops/gpu/test_batchnorm_fold_op.py @@ -0,0 +1,116 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import mindspore.context as context + +context.set_context(device_target='GPU') + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.op = P.BatchNormFold(freeze_bn=10) + + @ms_function + def construct(self, x, mean, variance, current_step): + a, b, c, d = self.op(x, mean, variance, current_step) + return a, b, c, d + + +def np_result(x, mean, var, momentum, epsilon): + np_mean = x.mean(axis=(0, 2, 3)) + np_var = x.var(axis=(0, 2, 3)) + n = x.shape[0] * x.shape[2] * x.shape[3] + mean_update = momentum * np_mean + (1 - momentum) * mean + var_update = momentum * np_var * n / (n - 1) + (1 - momentum) * var + np_var = np.sqrt(np_var + epsilon) + delay_mean = mean.copy() + delay_std = np.sqrt(var + epsilon) + return np_mean, np_var, mean_update, var_update, delay_mean, delay_std + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[3, c, 32, 32]).astype('float32') + mean = np.random.uniform(1, 10, size=[c]).astype('float32') + variance = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([0]).astype('int32') + ms_mean = Tensor(mean) + ms_var = Tensor(variance) + batch_mean, batch_var, delay_mean, delay_std = net(Tensor(x), ms_mean, ms_var, + Tensor(current_step)) + + expect1, expect2, expect3, expect4, expect5, expect6 = np_result(x, mean, variance, 0.9, 1e-12) + assert np.allclose(batch_mean.asnumpy(), expect1, rtol=1.e-7, atol=1.e-5) + assert np.allclose(batch_var.asnumpy(), expect2, rtol=1.e-7, atol=1.e-5) + assert np.allclose(ms_mean.asnumpy(), expect3, rtol=1.e-7, atol=1.e-5) + assert np.allclose(ms_var.asnumpy(), expect4, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_mean.asnumpy(), expect5, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_std.asnumpy(), expect6, rtol=1.e-7, atol=1.e-5) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold2(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[3, c, 512, 512]).astype('float32') + mean = np.random.uniform(1, 10, size=[c]).astype('float32') + variance = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([0]).astype('int32') + ms_mean = Tensor(mean) + ms_var = Tensor(variance) + batch_mean, batch_var, delay_mean, delay_std = net(Tensor(x), ms_mean, ms_var, + Tensor(current_step)) + expect1, expect2, expect3, expect4, expect5, expect6 = np_result(x, mean, variance, 0.9, 1e-12) + assert np.allclose(batch_mean.asnumpy(), expect1, rtol=1.e-7, atol=1.e-5) + assert np.allclose(batch_var.asnumpy(), expect2, rtol=1.e-7, atol=1.e-5) + assert np.allclose(ms_mean.asnumpy(), expect3, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_mean.asnumpy(), expect5, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_std.asnumpy(), expect6, rtol=1.e-7, atol=1.e-5) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_batchnorm_fold_freeze(): + net = Net() + c = 64 + x = np.random.uniform(1, 10, size=[3, c, 32, 32]).astype('float32') + mean = np.random.uniform(1, 10, size=[c]).astype('float32') + variance = np.random.uniform(1, 10, size=[c]).astype('float32') + current_step = np.array([10]).astype('int32') + ms_mean = Tensor(mean) + ms_var = Tensor(variance) + batch_mean, batch_var, delay_mean, delay_std = net(Tensor(x), ms_mean, ms_var, + Tensor(current_step)) + expect1, expect2, expect3, expect4, expect5, expect6 = np_result(x, mean, variance, 0.9, 1e-12) + assert np.allclose(batch_mean.asnumpy(), np.zeros_like(mean), rtol=1.e-7, atol=1.e-5) + assert np.allclose(batch_var.asnumpy(), np.ones_like(mean), rtol=1.e-7, atol=1.e-5) + assert np.allclose(ms_mean.asnumpy(), mean, rtol=1.e-7, atol=1.e-5) + assert np.allclose(ms_var.asnumpy(), variance, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_mean.asnumpy(), expect5, rtol=1.e-7, atol=1.e-5) + assert np.allclose(delay_std.asnumpy(), expect6, rtol=1.e-7, atol=1.e-5) diff --git a/tests/st/ops/gpu/test_conv2d_backprop_filter_op.py b/tests/st/ops/gpu/test_conv2d_backprop_filter_op.py index 6e2e76cd47..0f66f2fac5 100644 --- a/tests/st/ops/gpu/test_conv2d_backprop_filter_op.py +++ b/tests/st/ops/gpu/test_conv2d_backprop_filter_op.py @@ -35,8 +35,8 @@ class Conv2dFilter(nn.Cell): pad_mode="valid", pad=0, mode=1, - stride=1, - dilation=1, + stride=(1, 1), + dilation=(1, 1, 1, 1), group=1) self.get_shape = P.Shape() diff --git a/tests/st/ops/gpu/test_conv2d_op.py b/tests/st/ops/gpu/test_conv2d_op.py index d724f6f6c8..1bac156c37 100644 --- a/tests/st/ops/gpu/test_conv2d_op.py +++ b/tests/st/ops/gpu/test_conv2d_op.py @@ -14,10 +14,10 @@ # ============================================================================ import pytest +import numpy as np from mindspore import Tensor from mindspore.ops import operations as P import mindspore.nn as nn -import numpy as np import mindspore.context as context diff --git a/tests/st/ops/gpu/test_correction_mul_grad_op.py b/tests/st/ops/gpu/test_correction_mul_grad_op.py new file mode 100644 index 0000000000..88b391a77a --- /dev/null +++ b/tests/st/ops/gpu/test_correction_mul_grad_op.py @@ -0,0 +1,55 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import pytest +import os +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import mindspore.context as context + + +context.set_context(device_target='GPU') + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.op_w = P.CorrectionMulGrad() + + @ms_function + def construct(self, dy, x, batch_std, running_std): + dx, d_batch_std = self.op_w(dy, x, batch_std, running_std) + return dx, d_batch_std + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_correction_mul_grad(): + net = Net() + co, ci, h, w = 64, 1, 32, 32 + dout = np.random.uniform(-0.1, 0.1, size=[co, ci, h, w]).astype('float32') + x = np.random.uniform(1, 1, size=[co, ci, h, w]).astype('float32') + batch_std = np.random.uniform(1, 10, size=[co]).astype('float32') + running_std = np.random.uniform(1, 10, size=[co]).astype('float32') + output = net(Tensor(dout), Tensor(x), Tensor(batch_std), Tensor(running_std)) + expect = [0, 0] + expect[0] = (dout * np.reshape(batch_std / running_std, (co, 1, 1, 1))) + expect[1] = (np.sum(dout * x, (1, 2, 3)) / running_std) + for i, v in enumerate(output): + assert (np.allclose(output[i].asnumpy(), expect[i], rtol=1.e-5, atol=1.e-5)) diff --git a/tests/st/ops/gpu/test_correction_mul_op.py b/tests/st/ops/gpu/test_correction_mul_op.py new file mode 100644 index 0000000000..01389e148c --- /dev/null +++ b/tests/st/ops/gpu/test_correction_mul_op.py @@ -0,0 +1,52 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import numpy as np +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.common.api import ms_function +import mindspore.context as context + +context.set_context(device_target='GPU') + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.op = P.CorrectionMul() + + @ms_function + def construct(self, x, batch_var, moving_var): + return self.op(x, batch_var, moving_var) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_correction_mul(): + net = Net() + co = 64 + x = np.random.uniform(-1, 1, size=[co, 64, 32, 32]).astype('float32') + bv = np.random.uniform(1, 2, size=[co]).astype('float32') + mv = np.random.uniform(1, 2, size=[co]).astype('float32') + output = net(Tensor(x), Tensor(bv), Tensor(mv)) + expect = x * np.reshape(bv, (co, 1, 1, 1)) / np.reshape(mv, (co, 1, 1, 1)) + error = np.ones(shape=expect.shape) * 1.0e-5 + diff = output.asnumpy() - expect + assert np.all(diff < error) + assert np.all(diff > error * -1) + assert (output.shape() == expect.shape) diff --git a/tests/st/ops/gpu/test_select_op.py b/tests/st/ops/gpu/test_select_op.py new file mode 100644 index 0000000000..5cac6a6ad3 --- /dev/null +++ b/tests/st/ops/gpu/test_select_op.py @@ -0,0 +1,47 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +import pytest +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +import numpy as np +import mindspore.context as context + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.select = P.Select() + + def construct(self, cond, x, y): + return self.select(cond, x, y) + +cond = np.array([[True, False], [True, False]]).astype(np.bool) +x = np.array([[1.2, 1], [1, 0]]).astype(np.float32) +y = np.array([[1, 2], [3, 4.0]]).astype(np.float32) + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_select(): + context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + select = Net() + output = select(Tensor(cond), Tensor(x), Tensor(y)) + expect = [[1.2, 2], [1, 4.0]] + error = np.ones(shape=[2, 2]) * 1.0e-6 + diff = output.asnumpy() - expect + assert np.all(diff < error) + assert np.all(-diff < error) diff --git a/tests/st/pynative/test_ascend_lenet.py b/tests/st/pynative/test_ascend_lenet.py index c03b2eee85..4009844791 100644 --- a/tests/st/pynative/test_ascend_lenet.py +++ b/tests/st/pynative/test_ascend_lenet.py @@ -122,8 +122,9 @@ class GradWrap(nn.Cell): @pytest.mark.level0 +@pytest.mark.platform_arm_ascend_training @pytest.mark.platform_x86_ascend_training -@pytest.mark.env_single +@pytest.mark.env_onecard def test_ascend_pynative_lenet(): context.set_context(mode=context.PYNATIVE_MODE, device_target="Ascend") @@ -150,7 +151,7 @@ def test_ascend_pynative_lenet(): end_time = time.time() cost_time = end_time - start_time total_time = total_time + cost_time - print("======epoch: ", epoch, " loss: ", loss_output.asnumpy(), " cost time: ", cost_time) - assert(total_time < 20.0) - assert(loss_output.asnumpy() < 0.01) + print("======epoch: ", epoch, " loss: ", loss_output.asnumpy(), " cost time: ", cost_time) + assert(loss_output.asnumpy() < 0.1) + \ No newline at end of file diff --git a/tests/st/summary/test_gpu_summary.py b/tests/st/summary/test_gpu_summary.py index ef645fcb2e..c97c08c4e1 100644 --- a/tests/st/summary/test_gpu_summary.py +++ b/tests/st/summary/test_gpu_summary.py @@ -24,17 +24,6 @@ from mindspore.common.tensor import Tensor from mindspore.ops import operations as P from mindspore.train.summary.summary_record import SummaryRecord -''' - This testcase is used for save summary data only. You need install MindData first and uncomment the commented - packages to analyse summary data. - Using "minddata start --datalog='./test_me_summary_event_file/' --host=0.0.0.0" to make data visible. -''' -# from minddata.datavisual.data_transform.data_manager import DataManager -# from minddata.datavisual.visual.train_visual.train_task_manager import TrainTaskManager -# from minddata.datavisual.visual.train_visual.scalars_processor import ScalarsProcessor -# from minddata.datavisual.common.enums import PluginNameEnum -# from minddata.datavisual.common.enums import DataManagerStatus - context.set_context(mode=context.GRAPH_MODE, device_target="GPU") @@ -43,6 +32,7 @@ CUR_DIR = os.getcwd() SUMMARY_DIR_ME = CUR_DIR + "/test_me_summary_event_file/" SUMMARY_DIR_ME_TEMP = CUR_DIR + "/test_me_temp_summary_event_file/" + def clean_environment_file(srcDir): if os.path.exists(srcDir): ls = os.listdir(srcDir) @@ -50,6 +40,8 @@ def clean_environment_file(srcDir): filePath = os.path.join(srcDir, line) os.remove(filePath) os.removedirs(srcDir) + + def save_summary_events_file(srcDir, desDir): if not os.path.exists(desDir): print("-- create desDir") @@ -64,12 +56,14 @@ def save_summary_events_file(srcDir, desDir): os.remove(filePath) os.removedirs(srcDir) + class SummaryNet(nn.Cell): def __init__(self, tag_tuple=None, scalar=1): super(SummaryNet, self).__init__() self.summary_s = P.ScalarSummary() self.summary_i = P.ImageSummary() self.summary_t = P.TensorSummary() + self.histogram_summary = P.HistogramSummary() self.add = P.TensorAdd() self.tag_tuple = tag_tuple self.scalar = scalar @@ -79,8 +73,10 @@ class SummaryNet(nn.Cell): self.summary_s("x1", x) z = self.add(x, y) self.summary_t("z1", z) + self.histogram_summary("histogram", z) return z + def train_summary_record_scalar_for_1(test_writer, steps, fwd_x, fwd_y): net = SummaryNet() out_me_dict = {} @@ -93,6 +89,7 @@ def train_summary_record_scalar_for_1(test_writer, steps, fwd_x, fwd_y): out_me_dict[i] = out_put.asnumpy() return out_me_dict + def me_scalar_summary(steps, tag=None, value=None): test_writer = SummaryRecord(SUMMARY_DIR_ME_TEMP) @@ -104,44 +101,6 @@ def me_scalar_summary(steps, tag=None, value=None): test_writer.close() return out_me_dict -def print_scalar_data(): - print("============start print_scalar_data\n") - data_manager = DataManager() - data_manager.start_load_data(path=SUMMARY_DIR_ME) - while data_manager.get_status() != DataManagerStatus.DONE: - time.sleep(0.1) - task_manager = TrainTaskManager(data_manager) - train_jobs = task_manager.get_all_train_tasks(PluginNameEnum.scalar) - print(train_jobs) - """ - train_jobs - ['train_jobs': { - 'id': '12-123', - 'name': 'train_job_name', - 'tags': ['x1', 'y1'] - }] - """ - scalar_processor = ScalarsProcessor(data_manager) - metadata = scalar_processor.get_metadata_list(train_job_ids=train_jobs['train_jobs'][0]['id'], tag=train_jobs['train_jobs'][0]['tags'][0]) - print(metadata) - ''' - metadata - { - 'scalars' : [ - { - 'train_job_id' : '12-12', - 'metadatas' : [ - { - 'wall_time' : 0.1, - 'step' : 1, - 'value' : 0.1 - } - ] - } - ] - } - ''' - print("============end print_scalar_data\n") @pytest.mark.level0 @pytest.mark.platform_x86_gpu_training diff --git a/tests/train_step_wrap.py b/tests/train_step_wrap.py index 7289c01004..d48e25b837 100644 --- a/tests/train_step_wrap.py +++ b/tests/train_step_wrap.py @@ -21,47 +21,6 @@ from mindspore.ops import composite as C from mindspore.ops import operations as P from mindspore import Parameter, ParameterTuple - -run_opt = C.MultitypeFuncGraph("run_opt") - -# pylint: disable=unused-argument -@run_opt.register("Function", "Int", "Number", "Number", - "Tensor", "Tensor", "Tensor") -def tensor_run_opt(opt, iterator, learning_rate, momentum, - gradient, variable, moment): - success = True - new_weight = opt(gradient, moment, variable, learning_rate, momentum) - success = F.depend(success, P.Assign()(variable, new_weight)) - return success - - -class OptimizerByMomentum(nn.Cell): - """ - OptimizerByMomentum definition - """ - # list of tensor - def __init__(self, weights): - super(OptimizerByMomentum, self).__init__() - self.learning_rate = Parameter(0.1, name="learning_rate") - self.momentum = Parameter(0.05, name="momentum") - self.iter = Parameter(0, name="iter") - - self.weights = weights - self.moments = weights.clone(prefix="moments", init='zeros') - - self.hyper_map = C.HyperMap() - self.opt = P.ApplyMomentum() - - def construct(self, grads): - success = True - weights = self.weights - moments = self.moments - success = self.hyper_map( - F.partial(run_opt, self.opt, self.iter, - self.learning_rate, self.momentum), grads, weights, moments) - # self.learning_rate = updata_lr(self.learning_rate, self.momentum) - return success - class TrainStepWrap(nn.Cell): """ TrainStepWrap definition @@ -71,7 +30,7 @@ class TrainStepWrap(nn.Cell): self.network = network self.network.set_train() self.weights = ParameterTuple(network.trainable_params()) - self.optimizer = OptimizerByMomentum(self.weights) + self.optimizer = nn.Momentum(self.weights, 0.1, 0.9) self.hyper_map = C.HyperMap() self.grad = C.GradOperation('grad', get_by_list=True) @@ -107,7 +66,7 @@ class TrainStepWrap2(nn.Cell): self.network = network self.network.set_train() self.weights = ParameterTuple(network.get_parameters()) - self.optimizer = OptimizerByMomentum(self.weights) + self.optimizer = nn.Momentum(self.weights, 0.1, 0.9) self.hyper_map = C.HyperMap() self.grad = C.GradOperation('grad', get_by_list=True, sens_param=True) self.sens = sens diff --git a/tests/ut/cpp/dataset/CMakeLists.txt b/tests/ut/cpp/dataset/CMakeLists.txt index 086a67c7d7..ae9c46e62c 100644 --- a/tests/ut/cpp/dataset/CMakeLists.txt +++ b/tests/ut/cpp/dataset/CMakeLists.txt @@ -41,6 +41,7 @@ SET(DE_UT_SRCS random_vertical_flip_op_test.cc rename_op_test.cc repeat_op_test.cc + skip_op_test.cc rescale_op_test.cc resize_bilinear_op_test.cc resize_op_test.cc @@ -63,6 +64,7 @@ SET(DE_UT_SRCS voc_op_test.cc cifar_op_test.cc celeba_op_test.cc + take_op_test.cc ) add_executable(de_ut_tests ${DE_UT_SRCS}) diff --git a/tests/ut/cpp/dataset/repeat_op_test.cc b/tests/ut/cpp/dataset/repeat_op_test.cc index 99e91afe81..e32e98cbd7 100644 --- a/tests/ut/cpp/dataset/repeat_op_test.cc +++ b/tests/ut/cpp/dataset/repeat_op_test.cc @@ -33,18 +33,29 @@ TEST_F(MindDataTestrepeat_op, Testrepeat_opFuntions) { auto my_tree = std::make_shared(); std::shared_ptr parent_op = std::make_shared(32); - - std::shared_ptr leaf_op = std::make_shared(16); + std::string dataset_path; + dataset_path = datasets_root_path_ + "/testTFTestAllTypes/test.data"; +// TFReaderOp + std::shared_ptr my_tfreader_op; + TFReaderOp::Builder builder; + builder.SetDatasetFilesList({dataset_path}) + .SetRowsPerBuffer(16) + .SetWorkerConnectorSize(16) + .SetNumWorkers(16); + Status rc= builder.Build(&my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + rc = my_tree->AssociateNode(my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); my_tree->AssociateNode(parent_op); - my_tree->AssociateNode(leaf_op); ASSERT_NE(parent_op, nullptr); - ASSERT_NE(leaf_op, nullptr); - parent_op->AddChild(std::move(leaf_op)); - parent_op->Print(std::cout, false); - parent_op->PrepareNodeAction(); + ASSERT_NE(my_tfreader_op, nullptr); + parent_op->AddChild(std::move(my_tfreader_op)); + MS_LOG(INFO) << parent_op; + my_tree->Prepare(); + RepeatOp RepeatOpOp(); std::shared_ptr repeat_op; - Status rc = RepeatOp::Builder(3).Build(&repeat_op); + rc = RepeatOp::Builder(3).Build(&repeat_op); ASSERT_NE(repeat_op, nullptr); } diff --git a/tests/ut/cpp/dataset/skip_op_test.cc b/tests/ut/cpp/dataset/skip_op_test.cc new file mode 100644 index 0000000000..c2168b24d4 --- /dev/null +++ b/tests/ut/cpp/dataset/skip_op_test.cc @@ -0,0 +1,91 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dataset/util/circular_pool.h" +#include "dataset/core/client.h" +#include "common/common.h" +#include "gtest/gtest.h" +#include "utils/log_adapter.h" + +using namespace mindspore::dataset; +using mindspore::MsLogLevel::INFO; +using mindspore::ExceptionType::NoExceptionType; +using mindspore::LogStream; + +class MindDataTestSkipOp : public UT::DatasetOpTesting {}; + +TEST_F(MindDataTestSkipOp, TestSkipOpFuntions) { + // Start with an empty execution tree + auto my_tree = std::make_shared(); + + std::string dataset_path; + dataset_path = datasets_root_path_ + "/testTFTestAllTypes/test.data"; + + std::shared_ptr my_tfreader_op; + TFReaderOp::Builder builder; + builder.SetDatasetFilesList({dataset_path}) + .SetRowsPerBuffer(16) + .SetWorkerConnectorSize(16) + .SetNumWorkers(16); + std::unique_ptr schema = std::make_unique(); + schema->LoadSchemaFile(datasets_root_path_ + "/testTFTestAllTypes/datasetSchema.json", {}); + builder.SetDataSchema(std::move(schema)); + Status rc = builder.Build(&my_tfreader_op); ASSERT_TRUE(rc.IsOk()); + rc = my_tree->AssociateNode(my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + + // SkipOp + std::shared_ptr skip_op = std::make_shared(5); + rc = my_tree->AssociateNode(skip_op); + ASSERT_TRUE(rc.IsOk()); + + // Set children/root layout. + rc = skip_op->AddChild(my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + rc = my_tree->AssignRoot(skip_op); + ASSERT_TRUE(rc.IsOk()); + + MS_LOG(INFO) << "Launching tree and begin iteration."; + rc = my_tree->Prepare(); + + ASSERT_TRUE(rc.IsOk()); + + rc = my_tree->Launch(); + ASSERT_TRUE(rc.IsOk()); + + // Start the loop of reading tensors from our pipeline + DatasetIterator di(my_tree); + TensorRow tensor_list; + rc = di.FetchNextTensorRow(&tensor_list); + ASSERT_TRUE(rc.IsOk()); + + int row_count = 0; + while (!tensor_list.empty()) { + MS_LOG(INFO) << "Row display for row #: " << row_count << "."; + + // Display the tensor by calling the printer on it + for (int i = 0; i < tensor_list.size(); i++) { + std::ostringstream ss; + ss << "(" << tensor_list[i] << "): " << *tensor_list[i] << std::endl; + MS_LOG(INFO) << "Tensor print: " << ss.str() << "."; + } + + rc = di.FetchNextTensorRow(&tensor_list); + ASSERT_TRUE(rc.IsOk()); + row_count++; + } + + ASSERT_EQ(row_count, 7); +} \ No newline at end of file diff --git a/tests/ut/cpp/dataset/stand_alone_samplers_test.cc b/tests/ut/cpp/dataset/stand_alone_samplers_test.cc index 48cc811615..ea0ae78aef 100644 --- a/tests/ut/cpp/dataset/stand_alone_samplers_test.cc +++ b/tests/ut/cpp/dataset/stand_alone_samplers_test.cc @@ -75,7 +75,7 @@ TEST_F(MindDataTestStandAloneSampler, TestDistributedSampler) { std::shared_ptr tensor; for (int i = 0; i < 6; i++) { std::unique_ptr sampler = std::make_unique(3, i % 3, (i < 3 ? false : true)); - sampler->Init(&mock); + sampler->HandshakeRandomAccessOp(&mock); sampler->GetNextBuffer(&db); db->GetTensor(&tensor, 0, 0); MS_LOG(DEBUG) << (*tensor); @@ -95,7 +95,7 @@ TEST_F(MindDataTestStandAloneSampler, TestStandAoneSequentialSampler) { std::shared_ptr sampler = std::make_shared(3); std::unique_ptr db; std::shared_ptr tensor; - sampler->Init(&mock); + sampler->HandshakeRandomAccessOp(&mock); sampler->GetNextBuffer(&db); db->GetTensor(&tensor, 0, 0); EXPECT_TRUE((*tensor) == (*label1)); diff --git a/tests/ut/cpp/dataset/subset_random_sampler_test.cc b/tests/ut/cpp/dataset/subset_random_sampler_test.cc index 5142a6d399..bb8b3439d5 100644 --- a/tests/ut/cpp/dataset/subset_random_sampler_test.cc +++ b/tests/ut/cpp/dataset/subset_random_sampler_test.cc @@ -52,8 +52,8 @@ TEST_F(MindDataTestSubsetRandomSampler, TestAllAtOnce) { std::unordered_set in_set(in.begin(), in.end()); SubsetRandomSampler sampler(in); - DummyRandomAccessOp dummy_random_access_op(5); - sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(5); + sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -80,8 +80,8 @@ TEST_F(MindDataTestSubsetRandomSampler, TestGetNextBuffer) { std::vector input(total_samples, 1); SubsetRandomSampler sampler(input, samples_per_buffer); - DummyRandomAccessOp dummy_random_access_op(total_samples); - sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -111,8 +111,8 @@ TEST_F(MindDataTestSubsetRandomSampler, TestReset) { std::unordered_set in_set(in.begin(), in.end()); SubsetRandomSampler sampler(in); - DummyRandomAccessOp dummy_random_access_op(5); - sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(5); + sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; diff --git a/tests/ut/cpp/dataset/take_op_test.cc b/tests/ut/cpp/dataset/take_op_test.cc new file mode 100644 index 0000000000..7f8508de20 --- /dev/null +++ b/tests/ut/cpp/dataset/take_op_test.cc @@ -0,0 +1,103 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "common/common.h" +#include "common/utils.h" +#include "dataset/core/client.h" +#include "gtest/gtest.h" +#include "utils/log_adapter.h" + +namespace common = mindspore::common; + +using namespace mindspore::dataset; +using mindspore::MsLogLevel::INFO; +using mindspore::ExceptionType::NoExceptionType; +using mindspore::LogStream; + +class MindDataTestTakeOp : public UT::DatasetOpTesting {}; + +TEST_F(MindDataTestTakeOp, TestTakeProject) { + // Start with an empty execution tree + auto my_tree = std::make_shared(); + + std::string dataset_path; + dataset_path = datasets_root_path_ + "/testTFTestAllTypes/test.data"; + + // TFReaderOp + std::shared_ptr my_tfreader_op; + TFReaderOp::Builder builder; + builder.SetDatasetFilesList({dataset_path}) + .SetRowsPerBuffer(16) + .SetWorkerConnectorSize(16) + .SetNumWorkers(16); + std::unique_ptr schema = std::make_unique(); + schema->LoadSchemaFile(datasets_root_path_ + "/testTFTestAllTypes/datasetSchema.json", {}); + builder.SetDataSchema(std::move(schema)); + Status rc = builder.Build(&my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + + // TakeOp + std::shared_ptr my_take_op; + TakeOp::Builder builder_take(5); + rc = builder_take.Build(&my_take_op); + ASSERT_TRUE(rc.IsOk()); + + rc = my_tree->AssociateNode(my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + rc = my_tree->AssociateNode(my_take_op); + ASSERT_TRUE(rc.IsOk()); + + // Set children/root layout. + rc = my_take_op->AddChild(my_tfreader_op); + ASSERT_TRUE(rc.IsOk()); + rc = my_tree->AssignRoot(my_take_op); + ASSERT_TRUE(rc.IsOk()); + + MS_LOG(INFO) << "Launching tree and begin iteration."; + rc = my_tree->Prepare(); + + ASSERT_TRUE(rc.IsOk()); + + rc = my_tree->Launch(); + ASSERT_TRUE(rc.IsOk()); + + // Start the loop of reading tensors from our pipeline + DatasetIterator di(my_tree); + TensorRow tensor_list; + rc = di.FetchNextTensorRow(&tensor_list); + ASSERT_TRUE(rc.IsOk()); + + int row_count = 0; + while (!tensor_list.empty()) { + MS_LOG(INFO) << "Row display for row #: " << row_count << "."; + + // Display the tensor by calling the printer on it + for (int i = 0; i < tensor_list.size(); i++) { + std::ostringstream ss; + ss << "(" << tensor_list[i] << "): " << *tensor_list[i] << std::endl; + MS_LOG(INFO) << "Tensor print: " << ss.str() << "."; + } + + rc = di.FetchNextTensorRow(&tensor_list); + ASSERT_TRUE(rc.IsOk()); + row_count++; + } + + ASSERT_EQ(row_count, 5); +} diff --git a/tests/ut/cpp/dataset/weighted_random_sampler_test.cc b/tests/ut/cpp/dataset/weighted_random_sampler_test.cc index 1c5d73613f..51a4bc3cb3 100644 --- a/tests/ut/cpp/dataset/weighted_random_sampler_test.cc +++ b/tests/ut/cpp/dataset/weighted_random_sampler_test.cc @@ -60,8 +60,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestOneshotReplacement) { // create sampler with replacement = true WeightedRandomSampler m_sampler(weights, num_samples, true); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -90,8 +90,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestOneshotNoReplacement) { // create sampler with replacement = replacement WeightedRandomSampler m_sampler(weights, num_samples, false); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -126,8 +126,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestGetNextBufferReplacement) { // create sampler with replacement = replacement WeightedRandomSampler m_sampler(weights, num_samples, true, samples_per_buffer); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -162,8 +162,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestGetNextBufferNoReplacement) { // create sampler with replacement = replacement WeightedRandomSampler m_sampler(weights, num_samples, false, samples_per_buffer); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -203,8 +203,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestResetReplacement) { // create sampler with replacement = true WeightedRandomSampler m_sampler(weights, num_samples, true); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; @@ -248,8 +248,8 @@ TEST_F(MindDataTestWeightedRandomSampler, TestResetNoReplacement) { // create sampler with replacement = true WeightedRandomSampler m_sampler(weights, num_samples, false); - DummyRandomAccessOp dummy_random_access_op(total_samples); - m_sampler.Init(&dummy_random_access_op); + DummyRandomAccessOp dummyRandomAccessOp(total_samples); + m_sampler.HandshakeRandomAccessOp(&dummyRandomAccessOp); std::unique_ptr db; TensorRow row; diff --git a/tests/ut/cpp/mindrecord/ut_shard_index_generator_test.cc b/tests/ut/cpp/mindrecord/ut_shard_index_generator_test.cc index a5e343a5b3..0c33d33ffd 100644 --- a/tests/ut/cpp/mindrecord/ut_shard_index_generator_test.cc +++ b/tests/ut/cpp/mindrecord/ut_shard_index_generator_test.cc @@ -53,6 +53,7 @@ class TestShardIndexGenerator : public UT::Common { TestShardIndexGenerator() {} }; +/* TEST_F(TestShardIndexGenerator, GetField) { MS_LOG(INFO) << FormatInfo("Test ShardIndex: get field"); @@ -82,6 +83,8 @@ TEST_F(TestShardIndexGenerator, GetField) { } } } +*/ + TEST_F(TestShardIndexGenerator, TakeFieldType) { MS_LOG(INFO) << FormatInfo("Test ShardSchema: take field Type"); diff --git a/tests/ut/cpp/mindrecord/ut_shard_operator_test.cc b/tests/ut/cpp/mindrecord/ut_shard_operator_test.cc index 46ea1712b2..549e2140f4 100644 --- a/tests/ut/cpp/mindrecord/ut_shard_operator_test.cc +++ b/tests/ut/cpp/mindrecord/ut_shard_operator_test.cc @@ -30,9 +30,9 @@ #include "mindrecord/include/shard_shuffle.h" #include "ut_common.h" -using mindspore::MsLogLevel::INFO; -using mindspore::ExceptionType::NoExceptionType; using mindspore::LogStream; +using mindspore::ExceptionType::NoExceptionType; +using mindspore::MsLogLevel::INFO; namespace mindspore { namespace mindrecord { @@ -117,7 +117,6 @@ TEST_F(TestShardOperator, TestShardSampleRatio) { ASSERT_TRUE(i <= 10); } - TEST_F(TestShardOperator, TestShardSamplePartition) { MS_LOG(INFO) << common::SafeCStr(FormatInfo("Test read imageNet")); std::string file_name = "./imagenet.shard01"; @@ -170,8 +169,8 @@ TEST_F(TestShardOperator, TestShardCategory) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; ASSERT_TRUE((std::get<1>(x[0]))["label"] == categories[category_no].second); @@ -199,8 +198,8 @@ TEST_F(TestShardOperator, TestShardShuffle) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; } dataset.Finish(); @@ -224,8 +223,8 @@ TEST_F(TestShardOperator, TestShardSampleShuffle) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; } dataset.Finish(); @@ -251,8 +250,8 @@ TEST_F(TestShardOperator, TestShardShuffleSample) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; } dataset.Finish(); @@ -278,8 +277,8 @@ TEST_F(TestShardOperator, TestShardSampleShuffleSample) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; } dataset.Finish(); @@ -307,8 +306,8 @@ TEST_F(TestShardOperator, TestShardShuffleCompare) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; auto y = compare_dataset.GetNext(); @@ -342,8 +341,8 @@ TEST_F(TestShardOperator, TestShardCategoryShuffle1) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; ASSERT_TRUE((std::get<1>(x[0]))["label"] == categories[category_no].second); @@ -376,8 +375,8 @@ TEST_F(TestShardOperator, TestShardCategoryShuffle2) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; ASSERT_TRUE((std::get<1>(x[0]))["label"] == categories[category_no].second); category_no++; @@ -410,8 +409,8 @@ TEST_F(TestShardOperator, TestShardCategorySample) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; ASSERT_TRUE((std::get<1>(x[0]))["label"] == categories[category_no].second); @@ -448,8 +447,8 @@ TEST_F(TestShardOperator, TestShardCategorySampleShuffle) { while (true) { auto x = dataset.GetNext(); if (x.empty()) break; - MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) << - ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); + MS_LOG(INFO) << "index: " << i << ", filename: " << common::SafeCStr((std::get<1>(x[0]))["file_name"]) + << ", label: " << common::SafeCStr((std::get<1>(x[0]))["label"].dump()); i++; ASSERT_TRUE((std::get<1>(x[0]))["label"] == categories[category_no].second); diff --git a/tests/ut/cpp/parallel/auto_parallel/dp_algo_test.cc b/tests/ut/cpp/parallel/auto_parallel/dp_algo_test.cc index d0243d5327..0462993672 100644 --- a/tests/ut/cpp/parallel/auto_parallel/dp_algo_test.cc +++ b/tests/ut/cpp/parallel/auto_parallel/dp_algo_test.cc @@ -178,6 +178,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_0 = {{4096, 1024}}; matmul0 = std::make_shared("matmul_info", inputs_shape_0, outputs_shape_0, attr_0); matmul0->set_name("MatMul0"); + matmul0->set_outputs_type({kFloat32}); // matmul1 ValuePtr transpose_a_1 = MakeValue(false); @@ -187,6 +188,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_1 = {{128, 4096}}; matmul1 = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); matmul1->set_name("MatMul1"); + matmul1->set_outputs_type({kFloat32}); // matmul2 ValuePtr transpose_a_2 = MakeValue(false); @@ -196,6 +198,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_2 = {{128, 1024}}; matmul2 = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); matmul2->set_name("MatMul2"); + matmul2->set_outputs_type({kFloat32}); // matmul3 ValuePtr transpose_a_3 = MakeValue(false); @@ -205,6 +208,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_3 = {{1024, 4096}}; matmul3 = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); matmul3->set_name("MatMul3"); + matmul3->set_outputs_type({kFloat32}); // matmul4 ValuePtr transpose_a_4 = MakeValue(false); @@ -214,6 +218,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_4 = {{128, 4096}}; matmul4 = std::make_shared("matmul_info", inputs_shape_4, outputs_shape_4, attr_4); matmul4->set_name("MatMul4"); + matmul4->set_outputs_type({kFloat32}); // matmul5 ValuePtr transpose_a_5 = MakeValue(false); @@ -223,6 +228,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_5 = {{128, 4096}}; matmul5 = std::make_shared("matmul_info", inputs_shape_5, outputs_shape_5, attr_5); matmul5->set_name("MatMul5"); + matmul5->set_outputs_type({kFloat32}); // matmul6 ValuePtr transpose_a_6 = MakeValue(false); @@ -232,6 +238,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_6 = {{4096, 1024}}; matmul6 = std::make_shared("matmul_info", inputs_shape_6, outputs_shape_6, attr_6); matmul6->set_name("MatMul6"); + matmul6->set_outputs_type({kFloat32}); // matmul7 ValuePtr transpose_a_7 = MakeValue(false); @@ -241,6 +248,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_7 = {{64, 4096}}; matmul7 = std::make_shared("matmul_info", inputs_shape_7, outputs_shape_7, attr_7); matmul7->set_name("MatMul7"); + matmul7->set_outputs_type({kFloat32}); // matmul8 ValuePtr transpose_a_8 = MakeValue(false); @@ -250,6 +258,7 @@ void TestDPAlgo::SetUp() { Shapes outputs_shape_8 = {{64, 40960}}; matmul8 = std::make_shared("matmul_info", inputs_shape_8, outputs_shape_8, attr_8); matmul8->set_name("MatMul8"); + matmul8->set_outputs_type({kFloat32}); } void TestDPAlgo::ConstructTwoLargeMatMul() { @@ -278,12 +287,15 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes outputs_shape = {{64, 64}}; tmp_identity_ptr1 = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr1->set_name("identity_info1"); + tmp_identity_ptr1->set_outputs_type({kFloat32}); tmp_identity_ptr2 = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr2->set_name("identity_info2"); + tmp_identity_ptr2->set_outputs_type({kFloat32}); tmp_identity_ptr = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr->set_name("identity_info"); + tmp_identity_ptr->set_outputs_type({kFloat32}); // mm1_ptr ValuePtr transpose_a_1 = MakeValue(false); @@ -292,6 +304,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_1 = {{64, 64}, {64, 64}}; Shapes outputs_shape_1 = {{64, 64}}; mm1_ptr = std::make_shared("matmul_info1", inputs_shape_1, outputs_shape_1, attr_1); + mm1_ptr->set_outputs_type({kFloat32}); // mm2_ptr ValuePtr transpose_a_2 = MakeValue(false); @@ -300,6 +313,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_2 = {{64, 64}, {64, 64}}; Shapes outputs_shape_2 = {{64, 64}}; mm2_ptr = std::make_shared("matmul_info2", inputs_shape_2, outputs_shape_2, attr_2); + mm2_ptr->set_outputs_type({kFloat32}); // mm3_ptr ValuePtr transpose_a_3 = MakeValue(false); @@ -308,6 +322,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_3 = {{64, 64}, {64, 64}}; Shapes outputs_shape_3 = {{64, 64}}; mm3_ptr = std::make_shared("matmul_info3", inputs_shape_3, outputs_shape_3, attr_3); + mm3_ptr->set_outputs_type({kFloat32}); // mm4_ptr ValuePtr transpose_a_4 = MakeValue(false); @@ -316,6 +331,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_4 = {{64, 64}, {64, 64}}; Shapes outputs_shape_4 = {{64, 64}}; mm4_ptr = std::make_shared("matmul_info4", inputs_shape_4, outputs_shape_4, attr_4); + mm4_ptr->set_outputs_type({kFloat32}); // mm5_ptr ValuePtr transpose_a_5 = MakeValue(false); @@ -324,6 +340,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_5 = {{64, 64}, {64, 64}}; Shapes outputs_shape_5 = {{64, 64}}; mm5_ptr = std::make_shared("matmul_info5", inputs_shape_5, outputs_shape_5, attr_5); + mm5_ptr->set_outputs_type({kFloat32}); // mm6_ptr ValuePtr transpose_a_6 = MakeValue(false); @@ -332,6 +349,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_6 = {{64, 64}, {64, 64}}; Shapes outputs_shape_6 = {{64, 64}}; mm6_ptr = std::make_shared("matmul_info6", inputs_shape_6, outputs_shape_6, attr_6); + mm6_ptr->set_outputs_type({kFloat32}); // mm7_ptr ValuePtr transpose_a_7 = MakeValue(false); @@ -340,6 +358,7 @@ void TestDPAlgo::ConstructBatmanGraph() { Shapes inputs_shape_7 = {{64, 64}, {64, 64}}; Shapes outputs_shape_7 = {{64, 64}}; mm7_ptr = std::make_shared("matmul_info7", inputs_shape_7, outputs_shape_7, attr_7); + mm7_ptr->set_outputs_type({kFloat32}); // create edges edge_i0_m3 = std::make_shared(edge_iden_matmul_name, tmp_identity_ptr, mm3_ptr, 0, 0, false, true); @@ -451,6 +470,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes outputs_shape = {{64, 64}}; tmp_identity_ptr1 = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr1->set_name("identity_info1"); + tmp_identity_ptr1->set_outputs_type({kFloat32}); // mm6_ptr ValuePtr transpose_a_6 = MakeValue(false); @@ -459,9 +479,11 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_6 = {{64, 64}, {64, 64}}; Shapes outputs_shape_6 = {{64, 64}}; mm6_ptr = std::make_shared("matmul_info", inputs_shape_6, outputs_shape_6, attr_6); + mm6_ptr->set_outputs_type({kFloat32}); tmp_identity_ptr2 = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr2->set_name("identity_info2"); + tmp_identity_ptr2->set_outputs_type({kFloat32}); // mm1_ptr ValuePtr transpose_a_1 = MakeValue(false); @@ -470,6 +492,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_1 = {{64, 64}, {64, 64}}; Shapes outputs_shape_1 = {{64, 64}}; mm1_ptr = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + mm1_ptr->set_outputs_type({kFloat32}); // mm2_ptr ValuePtr transpose_a_2 = MakeValue(false); @@ -478,6 +501,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_2 = {{64, 64}, {64, 64}}; Shapes outputs_shape_2 = {{64, 64}}; mm2_ptr = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + mm2_ptr->set_outputs_type({kFloat32}); // mm3_ptr ValuePtr transpose_a_3 = MakeValue(false); @@ -486,6 +510,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_3 = {{64, 64}, {64, 64}}; Shapes outputs_shape_3 = {{64, 64}}; mm3_ptr = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + mm3_ptr->set_outputs_type({kFloat32}); // mm4_ptr ValuePtr transpose_a_4 = MakeValue(false); @@ -494,6 +519,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_4 = {{64, 64}, {64, 64}}; Shapes outputs_shape_4 = {{64, 64}}; mm4_ptr = std::make_shared("matmul_info", inputs_shape_4, outputs_shape_4, attr_4); + mm4_ptr->set_outputs_type({kFloat32}); // mm5_ptr ValuePtr transpose_a_5 = MakeValue(false); @@ -502,6 +528,7 @@ void TestDPAlgo::ConstructTriangleGraph() { Shapes inputs_shape_5 = {{64, 64}, {64, 64}}; Shapes outputs_shape_5 = {{64, 64}}; mm5_ptr = std::make_shared("matmul_info", inputs_shape_5, outputs_shape_5, attr_5); + mm5_ptr->set_outputs_type({kFloat32}); // create edges std::string edge_matmul_matmul_name = "MatMul-MatMul"; @@ -584,6 +611,7 @@ void TestDPAlgo::ConstructTriangleGraph2() { Shapes outputs_shape = {{64, 64}}; tmp_identity_ptr1 = std::make_shared(inputs_shape, outputs_shape, attr); tmp_identity_ptr1->set_name("identity_info1"); + tmp_identity_ptr1->set_outputs_type({kFloat32}); // mm1_ptr ValuePtr transpose_a_1 = MakeValue(false); @@ -592,6 +620,7 @@ void TestDPAlgo::ConstructTriangleGraph2() { Shapes inputs_shape_1 = {{64, 64}, {64, 64}}; Shapes outputs_shape_1 = {{64, 64}}; mm1_ptr = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + mm1_ptr->set_outputs_type({kFloat32}); // mm2_ptr ValuePtr transpose_a_2 = MakeValue(false); @@ -600,6 +629,7 @@ void TestDPAlgo::ConstructTriangleGraph2() { Shapes inputs_shape_2 = {{64, 64}, {64, 64}}; Shapes outputs_shape_2 = {{64, 64}}; mm2_ptr = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + mm2_ptr->set_outputs_type({kFloat32}); // mm3_ptr ValuePtr transpose_a_3 = MakeValue(false); @@ -608,6 +638,7 @@ void TestDPAlgo::ConstructTriangleGraph2() { Shapes inputs_shape_3 = {{64, 64}, {64, 64}}; Shapes outputs_shape_3 = {{64, 64}}; mm3_ptr = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + mm3_ptr->set_outputs_type({kFloat32}); // create edges std::string edge_matmul_matmul_name = "MatMul-MatMul"; @@ -953,6 +984,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_1 = {{32, 16}, {16, 32}}; Shapes outputs_shape_1 = {{32, 32}}; mm1_ptr = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + mm1_ptr->set_outputs_type({kFloat32}); // mm2_ptr ValuePtr transpose_a_2 = MakeValue(false); @@ -961,6 +993,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_2 = {{8, 32}, {32, 32}}; Shapes outputs_shape_2 = {{8, 32}}; mm2_ptr = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + mm2_ptr->set_outputs_type({kFloat32}); // mm3_ptr ValuePtr transpose_a_3 = MakeValue(false); @@ -969,6 +1002,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_3 = {{32, 32}, {32, 64}}; Shapes outputs_shape_3 = {{32, 64}}; mm3_ptr = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + mm3_ptr->set_outputs_type({kFloat32}); // mm4_ptr ValuePtr transpose_a_4 = MakeValue(false); @@ -977,6 +1011,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_4 = {{64, 32}, {32, 32}}; Shapes outputs_shape_4 = {{64, 32}}; mm4_ptr = std::make_shared("matmul_info", inputs_shape_4, outputs_shape_4, attr_4); + mm4_ptr->set_outputs_type({kFloat32}); // mm5_ptr ValuePtr transpose_a_5 = MakeValue(false); @@ -985,6 +1020,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_5 = {{8, 32}, {32, 64}}; Shapes outputs_shape_5 = {{8, 64}}; mm5_ptr = std::make_shared("matmul_info", inputs_shape_5, outputs_shape_5, attr_5); + mm5_ptr->set_outputs_type({kFloat32}); // mm5_ptr ValuePtr transpose_a_6 = MakeValue(false); @@ -993,6 +1029,7 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes inputs_shape_6 = {{8, 64}, {64, 32}}; Shapes outputs_shape_6 = {{8, 32}}; mm6_ptr = std::make_shared("matmul_info", inputs_shape_6, outputs_shape_6, attr_6); + mm6_ptr->set_outputs_type({kFloat32}); ValuePtr relu = MakeValue(std::string("relu")); std::unordered_map relu_attr = {{"activation_type", relu}}; @@ -1001,26 +1038,31 @@ void TestDPAlgo::ConstructMMRGraph() { Shapes relu1_inputs_shape = {{8, 32}}; Shapes relu1_outputs_shape = {{8, 32}}; relu1_ptr = std::make_shared("relu_info", relu1_inputs_shape, relu1_outputs_shape, relu_attr); + relu1_ptr->set_outputs_type({kFloat32}); // relu2_ptr Shapes relu2_inputs_shape = {{32, 64}}; Shapes relu2_outputs_shape = {{32, 64}}; relu2_ptr = std::make_shared("relu_info", relu2_inputs_shape, relu2_outputs_shape, relu_attr); + relu2_ptr->set_outputs_type({kFloat32}); // relu3_ptr Shapes relu3_inputs_shape = {{64, 32}}; Shapes relu3_outputs_shape = {{64, 32}}; relu3_ptr = std::make_shared("relu_info", relu3_inputs_shape, relu3_outputs_shape, relu_attr); + relu3_ptr->set_outputs_type({kFloat32}); // relu4_ptr Shapes relu4_inputs_shape = {{8, 64}}; Shapes relu4_outputs_shape = {{8, 64}}; relu4_ptr = std::make_shared("relu_info", relu4_inputs_shape, relu4_outputs_shape, relu_attr); + relu4_ptr->set_outputs_type({kFloat32}); // relu5_ptr Shapes relu5_inputs_shape = {{8, 32}}; Shapes relu5_outputs_shape = {{8, 32}}; relu5_ptr = std::make_shared("relu_info", relu5_inputs_shape, relu5_outputs_shape, relu_attr); + relu5_ptr->set_outputs_type({kFloat32}); std::string edge_matmul_matmul_name = "MatMul-MatMul"; std::string edge_matmul_relu_name = "MatMul-ReLU"; @@ -1134,6 +1176,7 @@ void TestDPAlgo::ConstructIdentityDiamondGraph() { Shapes inputs_shape = {{32, 64}}; Shapes outputs_shape = {{32, 64}}; tmp_identity_ptr = std::make_shared(inputs_shape, outputs_shape, attr); + tmp_identity_ptr->set_outputs_type({kFloat32}); // mm1_ptr ValuePtr transpose_a_1 = MakeValue(false); @@ -1142,6 +1185,7 @@ void TestDPAlgo::ConstructIdentityDiamondGraph() { Shapes inputs_shape_1 = {{32, 64}, {64, 128}}; Shapes outputs_shape_1 = {{32, 128}}; mm1_ptr = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + mm1_ptr->set_outputs_type({kFloat32}); // mm2_ptr ValuePtr transpose_a_2 = MakeValue(false); @@ -1150,6 +1194,7 @@ void TestDPAlgo::ConstructIdentityDiamondGraph() { Shapes inputs_shape_2 = {{128, 32}, {32, 64}}; Shapes outputs_shape_2 = {{128, 64}}; mm2_ptr = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + mm2_ptr->set_outputs_type({kFloat32}); // mm3_ptr ValuePtr transpose_a_3 = MakeValue(false); @@ -1158,6 +1203,7 @@ void TestDPAlgo::ConstructIdentityDiamondGraph() { Shapes inputs_shape_3 = {{32, 128}, {128, 64}}; Shapes outputs_shape_3 = {{32, 64}}; mm3_ptr = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + mm3_ptr->set_outputs_type({kFloat32}); // create edges std::string edge_matmul_matmul_name = "MatMul-MatMul"; diff --git a/tests/ut/cpp/parallel/auto_parallel/edge_costmodel_test.cc b/tests/ut/cpp/parallel/auto_parallel/edge_costmodel_test.cc index 467f4976e8..423a258a28 100644 --- a/tests/ut/cpp/parallel/auto_parallel/edge_costmodel_test.cc +++ b/tests/ut/cpp/parallel/auto_parallel/edge_costmodel_test.cc @@ -65,6 +65,7 @@ void TestEdgeCostModel::SetUp() { Shapes inputs_shape_1 = {{8, 16}, {16, 32}}; Shapes outputs_shape_1 = {{8, 32}}; matmul1 = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + matmul1->set_outputs_type({kFloat32}); // matmul2 ValuePtr transpose_a_2 = MakeValue(false); @@ -73,6 +74,7 @@ void TestEdgeCostModel::SetUp() { Shapes inputs_shape_2 = {{8, 32}, {32, 16}}; Shapes outputs_shape_2 = {{8, 16}}; matmul2 = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + matmul2->set_outputs_type({kFloat32}); // matmul3 ValuePtr transpose_a_3 = MakeValue(false); @@ -81,6 +83,7 @@ void TestEdgeCostModel::SetUp() { Shapes inputs_shape_3 = {{16, 8}, {8, 32}}; Shapes outputs_shape_3 = {{16, 32}}; matmul3 = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + matmul3->set_outputs_type({kFloat32}); // matmul4 ValuePtr transpose_a_4 = MakeValue(false); @@ -89,6 +92,7 @@ void TestEdgeCostModel::SetUp() { Shapes inputs_shape_4 = {{8, 16}, {16, 32}}; Shapes outputs_shape_4 = {{8, 32}}; matmul4 = std::make_shared("matmul_info", inputs_shape_4, outputs_shape_4, attr_4); + matmul4->set_outputs_type({kFloat32}); // matmul5 ValuePtr transpose_a_5 = MakeValue(false); @@ -97,6 +101,7 @@ void TestEdgeCostModel::SetUp() { Shapes inputs_shape_5 = {{8, 32}, {8, 32}}; Shapes outputs_shape_5 = {{8, 8}}; matmul5 = std::make_shared("matmul_info", inputs_shape_5, outputs_shape_5, attr_5); + matmul5->set_outputs_type({kFloat32}); } TEST_F(TestEdgeCostModel, test_InitEdgeCost) { diff --git a/tests/ut/cpp/parallel/auto_parallel/graph_costmodel_test.cc b/tests/ut/cpp/parallel/auto_parallel/graph_costmodel_test.cc index 415a1fdd55..81b017a28d 100644 --- a/tests/ut/cpp/parallel/auto_parallel/graph_costmodel_test.cc +++ b/tests/ut/cpp/parallel/auto_parallel/graph_costmodel_test.cc @@ -76,6 +76,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_0 = {{32, 16}, {16, 16}}; Shapes outputs_shape_0 = {{32, 16}}; matmul0 = std::make_shared("matmul_info", inputs_shape_0, outputs_shape_0, attr_0); + matmul0->set_outputs_type({kFloat32}); // matmul1 ValuePtr transpose_a_1 = MakeValue(false); @@ -84,6 +85,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_1 = {{8, 16}, {16, 32}}; Shapes outputs_shape_1 = {{8, 32}}; matmul1 = std::make_shared("matmul_info", inputs_shape_1, outputs_shape_1, attr_1); + matmul1->set_outputs_type({kFloat32}); // matmul2 ValuePtr transpose_a_2 = MakeValue(false); @@ -92,6 +94,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_2 = {{8, 32}, {32, 16}}; Shapes outputs_shape_2 = {{8, 16}}; matmul2 = std::make_shared("matmul_info", inputs_shape_2, outputs_shape_2, attr_2); + matmul2->set_outputs_type({kFloat32}); // matmul3 ValuePtr transpose_a_3 = MakeValue(false); @@ -100,6 +103,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_3 = {{16, 8}, {8, 32}}; Shapes outputs_shape_3 = {{16, 32}}; matmul3 = std::make_shared("matmul_info", inputs_shape_3, outputs_shape_3, attr_3); + matmul3->set_outputs_type({kFloat32}); // matmul4 ValuePtr transpose_a_4 = MakeValue(false); @@ -108,6 +112,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_4 = {{8, 16}, {16, 32}}; Shapes outputs_shape_4 = {{8, 32}}; matmul4 = std::make_shared("matmul_info", inputs_shape_4, outputs_shape_4, attr_4); + matmul4->set_outputs_type({kFloat32}); // matmul5 ValuePtr transpose_a_5 = MakeValue(false); @@ -116,6 +121,7 @@ void TestCostGraph::SetUp() { Shapes inputs_shape_5 = {{8, 32}, {8, 32}}; Shapes outputs_shape_5 = {{8, 8}}; matmul5 = std::make_shared("matmul_info", inputs_shape_5, outputs_shape_5, attr_5); + matmul5->set_outputs_type({kFloat32}); } void TestCostGraph::ConstructStarGraph2() { diff --git a/tests/ut/cpp/parallel/ops_info/activation_test.cc b/tests/ut/cpp/parallel/ops_info/activation_test.cc index a8f8425ae9..9af7203799 100644 --- a/tests/ut/cpp/parallel/ops_info/activation_test.cc +++ b/tests/ut/cpp/parallel/ops_info/activation_test.cc @@ -84,9 +84,9 @@ TEST_F(TestActivation, test_activation_strategies) { act_ptr_->InitForCostModel(sp); std::vector inputs_info = act_ptr_->inputs_tensor_info(); std::vector outputs_info = act_ptr_->outputs_tensor_info(); - ASSERT_DOUBLE_EQ(act_ptr_->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(act_ptr_->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), cost.computation_cost_); - ASSERT_DOUBLE_EQ(act_ptr_->cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(act_ptr_->operator_cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), cost.communication_cost_); } } @@ -109,9 +109,9 @@ TEST_F(TestActivation, test_softmax_strategies) { soft_ptr_->InitForCostModel(sp); std::vector inputs_info = soft_ptr_->inputs_tensor_info(); std::vector outputs_info = soft_ptr_->outputs_tensor_info(); - ASSERT_DOUBLE_EQ(soft_ptr_->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(soft_ptr_->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), cost.computation_cost_); - ASSERT_DOUBLE_EQ(soft_ptr_->cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(soft_ptr_->operator_cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), cost.communication_cost_); } } diff --git a/tests/ut/cpp/parallel/ops_info/dropout_do_mask_info_test.cc b/tests/ut/cpp/parallel/ops_info/dropout_do_mask_info_test.cc deleted file mode 100644 index 2f17fb4450..0000000000 --- a/tests/ut/cpp/parallel/ops_info/dropout_do_mask_info_test.cc +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Copyright 2019 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "common/common_test.h" -#include "parallel/strategy.h" -#include "parallel/ops_info/dropout_do_mask_info.h" -#include "parallel/device_manager.h" -#include "parallel/step_parallel.h" - -namespace mindspore { -namespace parallel { - -class DropoutDoMaskInfo; -using DropoutDoMaskInfoPtr = std::shared_ptr; -DropoutDoMaskInfoPtr do_mask; - -class TestDropoutDoMaskInfo : public UT::Common { - public: - TestDropoutDoMaskInfo() {} - void SetUp(); - void TearDown() {} -}; - -void TestDropoutDoMaskInfo::SetUp() { - std::vector dev_list; - - for (int32_t i = 0; i < 34; i++) { - dev_list.push_back(i); - } - - std::vector stage_map; - stage_map.push_back(32); - stage_map.push_back(2); - - int32_t local_dev = 0; - - // create a new g_device_manager - g_device_manager = std::make_shared(); - g_device_manager->Init(dev_list, local_dev, stage_map, "hccl"); - - std::unordered_map attr; - - Shapes inputs_shape = {{32, 128}, {64}, {}}; - Shapes outputs_shape = {{32, 128}}; - do_mask = std::make_shared("do_mask_info", inputs_shape, outputs_shape, attr); -} - -TEST_F(TestDropoutDoMaskInfo, InferDevMatrixShape) { - std::vector stra = {{4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - do_mask->Init(strategy); - std::vector dev_matrix_shape = do_mask->dev_matrix_shape(); - - std::vector expect = {4, 8}; - ASSERT_EQ(dev_matrix_shape, expect); -} - -TEST_F(TestDropoutDoMaskInfo, InferSliceShape) { - std::vector stra = {{4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - do_mask->Init(strategy); - std::vector inputs = do_mask->inputs_tensor_info(); - std::vector outputs = do_mask->outputs_tensor_info(); - - Shape input_a_slice_shape_expect = {8, 16}; - Shape input_b_slice_shape_expect = {64}; - Shape output_slice_shape_expect = {8, 16}; - - TensorInfo input_a_tensor_info = inputs.at(0); - TensorInfo input_b_tensor_info = inputs.at(1); - TensorInfo output_tensor_info = outputs.at(0); - Shape input_a_slice_shape = input_a_tensor_info.slice_shape(); - Shape input_b_slice_shape = input_b_tensor_info.slice_shape(); - Shape output_slice_shape = output_tensor_info.slice_shape(); - - ASSERT_EQ(input_a_slice_shape, input_a_slice_shape_expect); - ASSERT_EQ(input_b_slice_shape, input_b_slice_shape_expect); - ASSERT_EQ(output_slice_shape, output_slice_shape_expect); -} - -TEST_F(TestDropoutDoMaskInfo, GetTensorLayout) { - std::vector stra = {{4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - do_mask->Init(strategy); - std::vector inputs = do_mask->inputs_tensor_info(); - std::vector outputs = do_mask->outputs_tensor_info(); - - TensorMap input_a_map_expect = {1, 0}; - TensorMap input_b_map_expect = {-1}; - TensorMap output_map_expect = {1, 0}; - - TensorInfo input_a_tensor_info = inputs.at(0); - TensorInfo input_b_tensor_info = inputs.at(1); - TensorInfo output_tensor_info = outputs.at(0); - Map input_a_tensor_map = input_a_tensor_info.tensor_layout().origin_tensor_map(); - Map input_b_tensor_map = input_b_tensor_info.tensor_layout().origin_tensor_map(); - Map output_tensor_map = output_tensor_info.tensor_layout().origin_tensor_map(); - - ASSERT_EQ(input_a_tensor_map.array(), input_a_map_expect); - ASSERT_EQ(input_b_tensor_map.array(), input_b_map_expect); - ASSERT_EQ(output_tensor_map.array(), output_map_expect); -} - -TEST_F(TestDropoutDoMaskInfo, GetForwardOp) { - std::vector stra = {{4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - do_mask->Init(strategy); - OperatorVector forward_op = do_mask->forward_op(); - size_t size = forward_op.size(); - - ASSERT_EQ(size, 0); -} - -TEST_F(TestDropoutDoMaskInfo, CheckStrategy1) { - std::vector stra = {{4, 8, 2}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = do_mask->Init(strategy); - ASSERT_EQ(ret, FAILED); -} - -TEST_F(TestDropoutDoMaskInfo, CheckStrategy2) { - std::vector stra = {{8, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = do_mask->Init(strategy); - ASSERT_EQ(ret, FAILED); -} - -TEST_F(TestDropoutDoMaskInfo, CheckStrategy3) { - std::vector stra = {{4, 8}, {4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = do_mask->Init(strategy); - ASSERT_EQ(ret, FAILED); -} - -TEST_F(TestDropoutDoMaskInfo, CheckStrategy4) { - std::vector stra = {{4, 8}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = do_mask->Init(strategy); - ASSERT_EQ(ret, SUCCESS); -} -} // namespace parallel -} // namespace mindspore diff --git a/tests/ut/cpp/parallel/ops_info/generator_info_test.cc b/tests/ut/cpp/parallel/ops_info/generator_info_test.cc deleted file mode 100644 index eb463066a6..0000000000 --- a/tests/ut/cpp/parallel/ops_info/generator_info_test.cc +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright 2019 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "common/common_test.h" -#include "parallel/strategy.h" -#include "parallel/ops_info/generator_info.h" -#include "parallel/device_manager.h" -#include "parallel/step_parallel.h" - -namespace mindspore { -namespace parallel { - -class DropoutGenMaskInfo; -using DropoutGenMaskInfoPtr = std::shared_ptr; -DropoutGenMaskInfoPtr gen_mask; - -class TestDropoutGenMaskInfo : public UT::Common { - public: - TestDropoutGenMaskInfo() {} - void SetUp(); - void TearDown() {} -}; - -void TestDropoutGenMaskInfo::SetUp() { - std::vector dev_list; - - for (int32_t i = 0; i < 10; i++) { - dev_list.push_back(i); - } - - std::vector stage_map; - stage_map.push_back(8); - stage_map.push_back(2); - - int32_t local_dev = 0; - - // create a new g_device_manager - g_device_manager = std::make_shared(); - g_device_manager->Init(dev_list, local_dev, stage_map, "hccl"); - - std::unordered_map attr; - - Shapes inputs_shape; - Shapes outputs_shape = {{128}}; - std::vector shape = {32, 128}; - ValuePtr val0 = MakeValue(shape); - ValuePtr val1; - std::vector val = {val0, val1}; - gen_mask = std::make_shared("gen_mask_info", inputs_shape, outputs_shape, attr); - gen_mask->set_input_value(val); -} - -TEST_F(TestDropoutGenMaskInfo, InferDevMatrixShape) { - std::vector stra = {{8, 1}}; - StrategyPtr strategy = NewStrategy(0, stra); - - gen_mask->Init(strategy); - std::vector dev_matrix_shape = gen_mask->dev_matrix_shape(); - - std::vector expect = {8, 1}; - ASSERT_EQ(dev_matrix_shape, expect); -} - -TEST_F(TestDropoutGenMaskInfo, InferSliceShape) { - std::vector stra = {{8, 1}}; - StrategyPtr strategy = NewStrategy(0, stra); - - gen_mask->Init(strategy); - std::vector outputs = gen_mask->outputs_tensor_info(); - - Shape output_slice_shape_expect = {128}; - - TensorInfo output_tensor_info = outputs.at(0); - Shape output_slice_shape = output_tensor_info.slice_shape(); - - ASSERT_EQ(output_slice_shape, output_slice_shape_expect); -} - -TEST_F(TestDropoutGenMaskInfo, GetTensorLayout) { - std::vector stra = {{8, 1}}; - StrategyPtr strategy = NewStrategy(0, stra); - - gen_mask->Init(strategy); - std::vector outputs = gen_mask->outputs_tensor_info(); - - TensorMap output_map_expect = {-1}; - - TensorInfo output_tensor_info = outputs.at(0); - Map output_tensor_map = output_tensor_info.tensor_layout().origin_tensor_map(); - - ASSERT_EQ(output_tensor_map.array(), output_map_expect); -} - -TEST_F(TestDropoutGenMaskInfo, GetForwardOp) { - std::vector stra = {{8, 1}}; - StrategyPtr strategy = NewStrategy(0, stra); - - gen_mask->Init(strategy); - OperatorVector forward_op = gen_mask->forward_op(); - size_t size = forward_op.size(); - - ASSERT_EQ(size, 0); -} - -TEST_F(TestDropoutGenMaskInfo, CheckStrategy1) { - std::vector stra = {{4, 8, 2}, {2, 3}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = gen_mask->Init(strategy); - ASSERT_EQ(ret, FAILED); -} - -TEST_F(TestDropoutGenMaskInfo, CheckStrategy2) { - std::vector stra = {{8, 1}}; - StrategyPtr strategy = NewStrategy(0, stra); - - Status ret = gen_mask->Init(strategy); - ASSERT_EQ(ret, SUCCESS); -} -} // namespace parallel -} // namespace mindspore diff --git a/tests/ut/cpp/parallel/ops_info/matmul_info_test.cc b/tests/ut/cpp/parallel/ops_info/matmul_info_test.cc index 2fece098e8..f710f51265 100644 --- a/tests/ut/cpp/parallel/ops_info/matmul_info_test.cc +++ b/tests/ut/cpp/parallel/ops_info/matmul_info_test.cc @@ -569,7 +569,7 @@ TEST_F(TestMatmulInfo, test_GenerateStrategies1) { matmul1->InitForCostModel(sp); std::vector inputs_info = matmul1->inputs_tensor_info(); std::vector outputs_info = matmul1->outputs_tensor_info(); - ASSERT_DOUBLE_EQ(matmul1->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(matmul1->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), cost.computation_cost_); break; } @@ -599,7 +599,7 @@ TEST_F(TestMatmulInfo, test_GenerateStrategies2) { TensorInfo replica_input1_info(tly, input1_shape, input1_slice_shape); replica_inputs_info.push_back(replica_input1_info); - ASSERT_DOUBLE_EQ(matmul3->cost()->GetComputationCost(replica_inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(matmul3->operator_cost()->GetComputationCost(replica_inputs_info, outputs_info, sp->GetInputStage()), cost.computation_cost_); break; } diff --git a/tests/ut/cpp/parallel/ops_info/pow_info_test.cc b/tests/ut/cpp/parallel/ops_info/pow_info_test.cc index f6ea2c3d3c..7b37a90fd8 100644 --- a/tests/ut/cpp/parallel/ops_info/pow_info_test.cc +++ b/tests/ut/cpp/parallel/ops_info/pow_info_test.cc @@ -19,7 +19,7 @@ #include #include "common/common_test.h" #include "parallel/strategy.h" -#include "parallel/ops_info/elementary_function_info.h" +#include "parallel/ops_info/arithmetic_info.h" #include "parallel/device_manager.h" #include "parallel/step_parallel.h" @@ -56,14 +56,14 @@ void TestPowInfo::SetUp() { std::unordered_map attr; - Shapes inputs_shape = {{32, 64, 128}}; + Shapes inputs_shape = {{32, 64, 128}, {32, 64, 128}}; Shapes outputs_shape = {{32, 64, 128}}; pow = std::make_shared("pow_info", inputs_shape, outputs_shape, attr); } TEST_F(TestPowInfo, InferDevMatrixShape1) { - std::vector inputs = {{2, 4, 8}}; + std::vector inputs = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, inputs); pow->Init(strategy); @@ -74,7 +74,7 @@ TEST_F(TestPowInfo, InferDevMatrixShape1) { } TEST_F(TestPowInfo, InferSliceShape1) { - std::vector str = {{2, 4, 8}}; + std::vector str = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, str); pow->Init(strategy); @@ -95,7 +95,7 @@ TEST_F(TestPowInfo, InferSliceShape1) { } TEST_F(TestPowInfo, GetTensorLayout1) { - std::vector str = {{2, 4, 8}}; + std::vector str = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, str); pow->Init(strategy); @@ -116,7 +116,7 @@ TEST_F(TestPowInfo, GetTensorLayout1) { } TEST_F(TestPowInfo, GetForwardOp1) { - std::vector inputs = {{2, 4, 8}}; + std::vector inputs = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, inputs); pow->Init(strategy); @@ -127,7 +127,7 @@ TEST_F(TestPowInfo, GetForwardOp1) { } TEST_F(TestPowInfo, GetMirrorOPs1) { - std::vector inputs = {{2, 4, 8}}; + std::vector inputs = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, inputs); pow->Init(strategy); @@ -147,7 +147,7 @@ TEST_F(TestPowInfo, CheckStrategy1) { } TEST_F(TestPowInfo, CheckStrategy2) { - std::vector inputs = {{2, 4, 8, 16}}; + std::vector inputs = {{2, 4, 8, 16}, {2, 4, 8, 16}}; StrategyPtr strategy = NewStrategy(0, inputs); Status ret = pow->Init(strategy); @@ -155,7 +155,7 @@ TEST_F(TestPowInfo, CheckStrategy2) { } TEST_F(TestPowInfo, CheckStrategy3) { - std::vector inputs = {{2, 4, 8}}; + std::vector inputs = {{2, 4, 8}, {2, 4, 8}}; StrategyPtr strategy = NewStrategy(0, inputs); Status ret = pow->Init(strategy); diff --git a/tests/ut/cpp/parallel/ops_info/tensor_add_info_test.cc b/tests/ut/cpp/parallel/ops_info/tensor_add_info_test.cc index 8c956328a7..42d292c605 100644 --- a/tests/ut/cpp/parallel/ops_info/tensor_add_info_test.cc +++ b/tests/ut/cpp/parallel/ops_info/tensor_add_info_test.cc @@ -188,11 +188,11 @@ TEST_F(TestTensorAddInfo, GenerateStrategies) { tensor_add->InitForCostModel(sp); std::vector inputs_info = tensor_add->inputs_tensor_info(); std::vector outputs_info = tensor_add->outputs_tensor_info(); - double memory_cost0 = tensor_add->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()); + double memory_cost0 = tensor_add->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()); double memory_cost1 = cost.computation_cost_; bool memory = memory_cost0 - memory_cost1 <= 1.0; - double comm_cost0 = tensor_add->cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()); + double comm_cost0 = tensor_add->operator_cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()); double comm_cost1 = cost.communication_cost_; bool comm = comm_cost0 - comm_cost1 <= 1.0; @@ -210,11 +210,11 @@ TEST_F(TestTensorAddInfo, GenerateStrategies1) { tensor_add1->InitForCostModel(sp); std::vector inputs_info = tensor_add1->inputs_tensor_info(); std::vector outputs_info = tensor_add1->outputs_tensor_info(); - double memory_cost0 = tensor_add1->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()); + double memory_cost0 = tensor_add1->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()); double memory_cost1 = cost.computation_cost_; bool memory = memory_cost0 - memory_cost1 <= 1.0; - double comm_cost0 = tensor_add1->cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()); + double comm_cost0 = tensor_add1->operator_cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()); double comm_cost1 = cost.communication_cost_; bool comm = comm_cost0 - comm_cost1 <= 1.0; diff --git a/tests/ut/cpp/parallel/ops_info/tmpidentity_test.cc b/tests/ut/cpp/parallel/ops_info/tmpidentity_test.cc index 3971a2b471..eabac51e17 100644 --- a/tests/ut/cpp/parallel/ops_info/tmpidentity_test.cc +++ b/tests/ut/cpp/parallel/ops_info/tmpidentity_test.cc @@ -145,9 +145,9 @@ TEST_F(TestTmpIdentityInfo, test_generate_strategies) { identity_ptr->Init(sp); std::vector inputs_info = identity_ptr->inputs_tensor_info(); std::vector outputs_info = identity_ptr->outputs_tensor_info(); - ASSERT_DOUBLE_EQ(identity_ptr->cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(identity_ptr->operator_cost()->GetComputationCost(inputs_info, outputs_info, sp->GetInputStage()), cost.computation_cost_); - ASSERT_DOUBLE_EQ(identity_ptr->cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), + ASSERT_DOUBLE_EQ(identity_ptr->operator_cost()->GetCommCost(inputs_info, outputs_info, sp->GetInputStage()), cost.communication_cost_); } } diff --git a/tests/ut/cpp/parallel/tensor_layout/redistribution_layout_transfer_test.cc b/tests/ut/cpp/parallel/tensor_layout/redistribution_layout_transfer_test.cc index 4e34847582..5291e2f48d 100644 --- a/tests/ut/cpp/parallel/tensor_layout/redistribution_layout_transfer_test.cc +++ b/tests/ut/cpp/parallel/tensor_layout/redistribution_layout_transfer_test.cc @@ -245,8 +245,8 @@ void ValidRedistributionLayoutCheck(const DeviceArrangement& in_device_arrangeme unified_out_tensor_map, unified_tensor_shape); } -void ValidRedistributionLayoutCheckAll(const int32_t& device_pow_size, const int32_t& tensor_pow_size, - const int32_t& max_device_dim, const int32_t& max_shape_dim) { +void ValidRedistributionLayoutCheckAll(int32_t device_pow_size, int32_t tensor_pow_size, + int32_t max_device_dim, int32_t max_shape_dim) { std::vector> layout_list; GenerateValidLayoutByDeviceSizeAndTensorSize(device_pow_size, tensor_pow_size, max_device_dim, max_shape_dim, &layout_list); diff --git a/tests/ut/cpp/parallel/tensor_layout/reshape_layout_transfer_test.cc b/tests/ut/cpp/parallel/tensor_layout/reshape_layout_transfer_test.cc index 36b89684f6..9d6152721e 100644 --- a/tests/ut/cpp/parallel/tensor_layout/reshape_layout_transfer_test.cc +++ b/tests/ut/cpp/parallel/tensor_layout/reshape_layout_transfer_test.cc @@ -260,8 +260,8 @@ TEST_F(TestReshapeLayoutTransfer, ValidInferUnifiedLayoutCheck11) { ValidUnifiedLayoutCheck(device_arrangement, in_tensor_map, in_tensor_shape, out_tensor_map, out_tensor_shape); } -void ValidInferUnifiedLayoutCheckAll(const int32_t& device_pow_size, const int32_t& tensor_pow_size, - const int32_t& max_device_dim, const int32_t& max_shape_dim) { +void ValidInferUnifiedLayoutCheckAll(int32_t device_pow_size, int32_t tensor_pow_size, + int32_t max_device_dim, int32_t max_shape_dim) { std::vector> layout_list; GenerateValidLayoutByDeviceSizeAndTensorSize(device_pow_size, tensor_pow_size, max_device_dim, max_shape_dim, &layout_list); diff --git a/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.cc b/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.cc index 07d270c95c..93147c486b 100644 --- a/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.cc +++ b/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.cc @@ -51,7 +51,7 @@ std::vector> combine(const std::vector& in, int32_ return output; } -void GenerateValidShapeBySizeAndDim(const int32_t& pow_size, const int32_t& dim, +void GenerateValidShapeBySizeAndDim(int32_t pow_size, int32_t dim, std::vector>* out) { out->clear(); std::vector in; @@ -78,7 +78,7 @@ void GenerateValidShapeBySizeAndDim(const int32_t& pow_size, const int32_t& dim, return; } -void GenerateValidShapeBySize(const int32_t& pow_size, std::vector>* out) { +void GenerateValidShapeBySize(int32_t pow_size, std::vector>* out) { out->clear(); for (int32_t dim = 1; dim <= pow_size; dim++) { std::vector> combine_result; @@ -148,8 +148,8 @@ void GenerateValidTensorMap(const std::vector& device_arrangement, cons } void GenerateValidLayoutByDeviceSizeAndTensorSize( - const int32_t& device_pow_size, const int32_t& tensor_pow_size, const int32_t& max_device_dim, - const int32_t& max_shape_dim, + int32_t device_pow_size, int32_t tensor_pow_size, int32_t max_device_dim, + int32_t max_shape_dim, std::vector, std::vector, std::vector>>* layout_list) { layout_list->clear(); std::vector> device_arrangement_list; diff --git a/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.h b/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.h index e14556378f..a359cadbea 100644 --- a/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.h +++ b/tests/ut/cpp/parallel/tensor_layout/util_layout_gen_test.h @@ -27,10 +27,10 @@ namespace parallel { std::vector> combine(const std::vector& in, int32_t target); -void GenerateValidShapeBySizeAndDim(const int32_t& pow_size, const int32_t& dim, +void GenerateValidShapeBySizeAndDim(int32_t pow_size, int32_t dim, std::vector>* out); -void GenerateValidShapeBySize(const int32_t& pow_size, std::vector>* out); +void GenerateValidShapeBySize(int32_t pow_size, std::vector>* out); std::vector GenerateTensorMap(const uint32_t& map_size, const std::vector& pos_index, const std::vector& pos_value); @@ -39,8 +39,8 @@ void GenerateValidTensorMap(const std::vector& device_arrangement, cons std::vector>* tensor_map_list); void GenerateValidLayoutByDeviceSizeAndTensorSize( - const int32_t& device_pow_size, const int32_t& tensor_pow_size, const int32_t& max_device_dim, - const int32_t& max_shape_dim, + int32_t device_pow_size, int32_t tensor_pow_size, int32_t max_device_dim, + int32_t max_shape_dim, std::vector, std::vector, std::vector>>* layout_list); uint32_t ComputeNoneNumber(const std::vector& tensor_map); diff --git a/tests/ut/cpp/pipeline/parse/parser_class_test.cc b/tests/ut/cpp/pipeline/parse/parser_class_test.cc index 599994aab2..dcedc32b1b 100644 --- a/tests/ut/cpp/pipeline/parse/parser_class_test.cc +++ b/tests/ut/cpp/pipeline/parse/parser_class_test.cc @@ -84,6 +84,7 @@ TEST_F(TestParserClass, TestParseDataClassApi) { } } +/* # skip ut test cases temporarily // Test case 2: test parse object, transfore the CELL instance to api. TEST_F(TestParserClass, TestParseMethod) { py::object obj_ = python_adapter::CallPyFn("gtest_input.pipeline.parse.parse_class", "test_parse_object_instance"); @@ -114,6 +115,7 @@ TEST_F(TestParserClass, TestParseCompileAPI) { python_adapter::CallPyFn("gtest_input.pipeline.parse.parse_compile", "test_build"); MS_LOG(DEBUG) << "Test end"; } +*/ } // namespace parse } // namespace mindspore diff --git a/tests/ut/cpp/pipeline/parse/parser_integrate_test.cc b/tests/ut/cpp/pipeline/parse/parser_integrate_test.cc index 3ec260c6c0..fd8438503f 100644 --- a/tests/ut/cpp/pipeline/parse/parser_integrate_test.cc +++ b/tests/ut/cpp/pipeline/parse/parser_integrate_test.cc @@ -86,10 +86,12 @@ TEST_F(TestParserIntegrate, TestParseGraphResolveGetAttr) { ASSERT_TRUE(func_graph != nullptr); } +/* skip ut test case temporarily TEST_F(TestParserIntegrate, TestParseGraphResolveUnknown) { EXPECT_THROW({ python_adapter::CallPyFn("gtest_input.pipeline.parse.parser_integrate", "test_undefined_symbol"); }, std::runtime_error); } +*/ /* #not supported yet TEST_F(TestParserIntegrate, TestParseGraphTestModelInside) { diff --git a/tests/ut/cpp/pipeline/parse/parser_primitive_test.cc b/tests/ut/cpp/pipeline/parse/parser_primitive_test.cc index e4cfd5132f..adc09cca32 100644 --- a/tests/ut/cpp/pipeline/parse/parser_primitive_test.cc +++ b/tests/ut/cpp/pipeline/parse/parser_primitive_test.cc @@ -109,6 +109,7 @@ TEST_F(TestParserPrimitive, TestParsePrimitive) { #endif } +/* skip ut test case temporarily TEST_F(TestParserPrimitive, TestParsePrimitiveParmeter) { py::object obj_ = python_adapter::CallPyFn("gtest_input.pipeline.parse.parse_primitive", "test_primitive_obj_parameter"); @@ -157,6 +158,7 @@ TEST_F(TestParserPrimitive, TestParsePrimitiveParmeter2) { i++; } } +*/ } // namespace parse } // namespace mindspore diff --git a/tests/ut/cpp/pipeline/static_analysis/evaluator_test.cc b/tests/ut/cpp/pipeline/static_analysis/evaluator_test.cc index d3983552e8..80acbe6ad5 100644 --- a/tests/ut/cpp/pipeline/static_analysis/evaluator_test.cc +++ b/tests/ut/cpp/pipeline/static_analysis/evaluator_test.cc @@ -63,6 +63,7 @@ TEST_F(TestEvaluatorCacheMap, test_evaluator_cache_map) { ASSERT_TRUE(iter == cache.end()); } +/* skip ut test cases temporarily class TestStandardEvaluator : public UT::Common { public: TestStandardEvaluator() : getPyFun("gtest_input.pipeline.infer.infer_test", true), engine_(nullptr) {} @@ -240,5 +241,7 @@ TEST_F(TestPartialEvaluator, test_infer_construct_sub_unresolved) { ASSERT_TRUE(*(abs_base_got->GetTypeTrack()) == *(abstract_x->GetTypeTrack())); ASSERT_TRUE(abs_base_got->GetTypeTrack()->type_id() == kNumberTypeFloat64); } +*/ + } // namespace abstract } // namespace mindspore diff --git a/tests/ut/cpp/pipeline/static_analysis/prim_test.cc b/tests/ut/cpp/pipeline/static_analysis/prim_test.cc index 629f410601..f54961af94 100644 --- a/tests/ut/cpp/pipeline/static_analysis/prim_test.cc +++ b/tests/ut/cpp/pipeline/static_analysis/prim_test.cc @@ -83,12 +83,13 @@ const std::shared_ptr UTPrimUtils::kI16 = std::make_shared(16); const std::shared_ptr UTPrimUtils::kI64 = std::make_shared(64); const std::shared_ptr UTPrimUtils::kU64 = std::make_shared(64); namespace { +/* skip ut test cases temporarily AbstractBasePtr ArrayOfTensor(const TypePtr &t, std::initializer_list shp) { auto shape = std::vector(shp); auto tensor = std::make_shared(t->type_id(), shape); return ToAbstract(tensor); } - +*/ } // namespace class TestPrim : public UT::Common { @@ -496,6 +497,7 @@ TEST_F(TestPrim, test_relu) { ASSERT_TRUE(*res == *expected); } +/* TEST_F(TestPrim, test_relu2) { FuncGraphPtr func_graph = getPyFun("get_relu"); ASSERT_TRUE(func_graph != nullptr); @@ -1151,6 +1153,7 @@ TEST_F(TestPrim, test_DictGetItem2) { ASSERT_TRUE(*tensor_ret == *expect); } +*/ } // namespace abstract } // namespace mindspore diff --git a/tests/ut/cpp/pipeline/static_analysis/static_analysis_test.cc b/tests/ut/cpp/pipeline/static_analysis/static_analysis_test.cc index 2da631d744..ac857dfac9 100644 --- a/tests/ut/cpp/pipeline/static_analysis/static_analysis_test.cc +++ b/tests/ut/cpp/pipeline/static_analysis/static_analysis_test.cc @@ -442,6 +442,7 @@ void TestGraphInfer::TearDown() { parse::data_converter::ClearObjectCache(); } +/* skip ut test cases temporarily TEST_F(TestGraphInfer, test_graph_infer_defaults) { FuncGraphPtr graph = getPyFun.CallAndParseRet("test_graph_infer_defaults"); AbstractBasePtrList args_spec_list = {}; @@ -497,5 +498,7 @@ TEST_F(TestGraphInfer, test_graph_infer_vararg_kwonlyargs_kwarg_defaults) { AbstractBasePtr expect = FromValue(MakeValue(57), false); ASSERT_EQ(*res, *expect); } +*/ + } // namespace abstract } // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc b/tests/ut/cpp/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc new file mode 100644 index 0000000000..93885a4b3a --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/enhancer/getnext_memcpy_elimination.cc @@ -0,0 +1,98 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#include "session/anf_runtime_algorithm.h" +#include "operator/ops.h" +#include "ir/meta_tensor.h" +#include "debug/anf_ir_dump.h" +#include "utils/utils.h" +#include "kernel/kernel_build_info.h" +#include "pre_activate/common/optimizer.h" +#include "mindspore/ccsrc/pre_activate/ascend/enhancer/getnext_memcpy_elimination.h" + +namespace mindspore { +namespace opt { +class TestGetNextMemcpyElimination : public BackendCommon { + public: + TestGetNextMemcpyElimination() : get_py_fun_("gtest_input.pre_activate.getnext_memcpy_elimination_test", true) {} + + public: + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestGetNextMemcpyElimination, test_getnext_memcpy_elimination) { + FuncGraphPtr g_before = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination", "before"); + ASSERT_TRUE(g_before != nullptr); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto pass = std::make_shared(); + pm->AddPass(pass); + optimizer->AddPassManager(pm); + auto new_graph = optimizer->Optimize(g_before); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestGetNextMemcpyElimination, test_getnext_memcpy_elimination_no_attr) { + FuncGraphPtr g_before = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_no_attr", "before"); + ASSERT_TRUE(g_before != nullptr); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto pass = std::make_shared(); + pm->AddPass(pass); + optimizer->AddPassManager(pm); + auto new_graph = optimizer->Optimize(g_before); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_no_attr", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestGetNextMemcpyElimination, test_getnext_memcpy_elimination_memcpy_multi_users) { + FuncGraphPtr g_before = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_memcpy_multi_users", "before"); + ASSERT_TRUE(g_before != nullptr); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto pass = std::make_shared(); + pm->AddPass(pass); + optimizer->AddPassManager(pm); + auto new_graph = optimizer->Optimize(g_before); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_memcpy_multi_users", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestGetNextMemcpyElimination, test_getnext_memcpy_elimination_next_multi_inputs) { + FuncGraphPtr g_before = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_next_multi_inputs", "before"); + ASSERT_TRUE(g_before != nullptr); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto pass = std::make_shared(); + pm->AddPass(pass); + optimizer->AddPassManager(pm); + auto new_graph = optimizer->Optimize(g_before); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_getnext_memcpy_elimination_next_multi_inputs", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc b/tests/ut/cpp/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc new file mode 100644 index 0000000000..2616354e4c --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.cc @@ -0,0 +1,67 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#include "session/ascend_session.h" +#include "pipeline/resource.h" +#include "operator/ops.h" +#include "ir/manager.h" +#include "debug/anf_ir_dump.h" +#include "utils/utils.h" +#include "kernel/kernel_build_info.h" +#include "pre_activate/common/optimizer.h" +#include "pre_activate/ascend/enhancer/insert_memcpy_async_for_getnext.h" + +namespace mindspore { +namespace opt { +using KernelBuildInfoBuilder = kernel::KernelBuildInfo::KernelBuildInfoBuilder; + +class TestHWInsertMemcpyAsyncForGetNext : public BackendCommon { + public: + TestHWInsertMemcpyAsyncForGetNext() : get_py_fun_("gtest_input.pre_activate.insert_memcpy_async_for_getnext", true) {} + ~TestHWInsertMemcpyAsyncForGetNext() override = default; + + public: + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestHWInsertMemcpyAsyncForGetNext, test_insert_memcpy_async_for_getnext_multi_output) { + FuncGraphPtr g_before = get_py_fun_.CallAndParseRet("test_insert_memcpy_async_for_getnext", "getnext_multi_output_before"); + + AbstractBasePtrList args_spec_list{}; + auto kernel_graph = GetKernelGraph(g_before, args_spec_list); + + KernelBuildInfoBuilder builder; + builder.SetOutputsFormat({kOpFormat_DEFAULT, kOpFormat_DEFAULT}); + builder.SetOutputsDeviceType({kFloat32->type_id(), kInt32->type_id()}); + auto ret = kernel_graph->get_return(); + EXPECT_NE(ret->input(1), nullptr); + EXPECT_NE(ret->input(1)->cast()->input(1), nullptr); + auto get_next = ret->input(1)->cast()->input(1); + get_next->set_kernel_info(std::make_shared()); + AnfAlgo::SetSelectKernelBuildInfo(builder.Build(), get_next.get()); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + auto new_graph = optimizer->Optimize(kernel_graph); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_insert_memcpy_async_for_getnext", "getnext_multi_output_after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} +} // namespace opt +} // namespace mindspore \ No newline at end of file diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fission/addn_fission_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fission/addn_fission_test.cc new file mode 100644 index 0000000000..90174636b1 --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/ir_fission/addn_fission_test.cc @@ -0,0 +1,160 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#define private public +#define protected public +#include "pre_activate/ascend/ir_fission/addn_fission.h" +#undef private +#undef protected + +namespace mindspore { +namespace opt { +class TestHWAddnFission : public BackendCommon { + public: + TestHWAddnFission() : get_py_fun_("gtest_input.pre_activate.addn_fission_test", true) {} + ~TestHWAddnFission() override = default; + + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestHWAddnFission, test_addn_fission_divided_by_2) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_addn_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 9; ++i) { + args_spec_list.push_back(x_abstract); + } + auto kg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto addn_fission = std::make_shared(); + addn_fission->inputs_divisor_ = 2; + pm->AddPass(addn_fission); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(kg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_addn_fission", "after_divided_by_2"); + EXPECT_NE(g_after, nullptr); + auto kg_after = GetKernelGraph(g_after, args_spec_list); + EXPECT_TRUE(CheckEqualGraph(kg_after, new_graph)); +} + +TEST_F(TestHWAddnFission, test_addn_fission_divided_by_3) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_addn_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 9; ++i) { + args_spec_list.push_back(x_abstract); + } + auto kg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto addn_fission = std::make_shared(); + addn_fission->inputs_divisor_ = 3; + pm->AddPass(addn_fission); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(kg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_addn_fission", "after_divided_by_3"); + EXPECT_NE(g_after, nullptr); + auto kg_after = GetKernelGraph(g_after, args_spec_list); + EXPECT_TRUE(CheckEqualGraph(kg_after, new_graph)); +} + +TEST_F(TestHWAddnFission, test_addn_fission_divided_by_4) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_addn_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 9; ++i) { + args_spec_list.push_back(x_abstract); + } + auto kg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto addn_fission = std::make_shared(); + addn_fission->inputs_divisor_ = 4; + pm->AddPass(addn_fission); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(kg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_addn_fission", "after_divided_by_4"); + EXPECT_NE(g_after, nullptr); + auto kg_after = GetKernelGraph(g_after, args_spec_list); + EXPECT_TRUE(CheckEqualGraph(kg_after, new_graph)); +} + +TEST_F(TestHWAddnFission, test_addn_fission_divided_by_8) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_addn_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 9; ++i) { + args_spec_list.push_back(x_abstract); + } + auto kg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto addn_fission = std::make_shared(); + addn_fission->inputs_divisor_ = 8; + pm->AddPass(addn_fission); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(kg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_addn_fission", "after_divided_by_8"); + EXPECT_NE(g_after, nullptr); + auto kg_after = GetKernelGraph(g_after, args_spec_list); + EXPECT_TRUE(CheckEqualGraph(kg_after, new_graph)); +} + +TEST_F(TestHWAddnFission, test_addn_fission_divided_by_9) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_addn_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 9; ++i) { + args_spec_list.push_back(x_abstract); + } + auto kg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + auto addn_fission = std::make_shared(); + addn_fission->inputs_divisor_ = 9; + pm->AddPass(addn_fission); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(kg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_addn_fission", "after_divided_by_9"); + EXPECT_NE(g_after, nullptr); + auto kg_after = GetKernelGraph(g_after, args_spec_list); + EXPECT_TRUE(CheckEqualGraph(kg_after, new_graph)); +} +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fusion/adam_apply_one_fusion_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fusion/adam_apply_one_fusion_test.cc index f4e418bed1..c2ee7b6519 100644 --- a/tests/ut/cpp/pre_activate/ascend/ir_fusion/adam_apply_one_fusion_test.cc +++ b/tests/ut/cpp/pre_activate/ascend/ir_fusion/adam_apply_one_fusion_test.cc @@ -66,5 +66,156 @@ TEST_F(TestHWAdamApplyOneFusion, test_adam_apply_one_fusion) { EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); } +TEST_F(TestHWAdamApplyOneFusion, test_adam_apply_one_cond1_fusion) { + /* + * def before_cond1(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + * square0 = Square(input0) + * mul1 = Mul(mul1_x, input0) + * mul0 = Mul(mul0_x, input2) + * mul2 = Mul(mul2_x, input1) + * mul3 = Mul(mul3_x, square0) + * add0 = Add(mul0, mul1) + * add1 = Add(mul2, mul3) + * sqrt0 = Sqrt(add1) + * add2 = Add(add2_y, sqrt0) + * true_div0 = RealDiv(add0, add2) + * mul4 = Mul(input4, true_div0) + * sub0 = Sub(input3, mul4) + * outputs = make_tuple(add1, add0, sub0) + * output = tuple_getitem(outputs, 0) + * return output + */ + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "before_cond1"); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 10; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestHWAdamApplyOneFusion, test_adam_apply_one_cond2_fusion) { + /* + * def before_cond2(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + * square0 = Square(input0) + * mul1 = Mul(mul1_x, input0) + * mul0 = Mul(mul0_x, input2) + * mul2 = Mul(mul2_x, input1) + * mul3 = Mul(square0, mul3_x) + * add0 = Add(mul0, mul1) + * add1 = Add(mul2, mul3) + * sqrt0 = Sqrt(add1) + * add2 = Add(sqrt0, add2_y) + * true_div0 = RealDiv(add0, add2) + * mul4 = Mul(true_div0, input4) + * sub0 = Sub(input3, mul4) + * outputs = make_tuple(add1, add0, sub0) + * output = tuple_getitem(outputs, 0) + * return output + */ + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "before_cond2"); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 10; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestHWAdamApplyOneFusion, test_adam_apply_one_cond3_fusion) { + /* + * def before_cond3(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + * square0 = Square(input0) + * mul1 = Mul(mul1_x, input0) + * mul0 = Mul(mul0_x, input2) + * mul2 = Mul(mul2_x, input1) + * mul3 = Mul(mul3_x, square0) + * add0 = Add(mul0, mul1) + * add1 = Add(mul2, mul3) + * sqrt0 = Sqrt(add1) + * add2 = Add(sqrt0, add2_y) + * true_div0 = RealDiv(add0, add2) + * mul4 = Mul(true_div0, input4) + * sub0 = Sub(input3, mul4) + * outputs = make_tuple(add1, add0, sub0) + * output = tuple_getitem(outputs, 0) + * return output + */ + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "before_cond3"); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 10; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +TEST_F(TestHWAdamApplyOneFusion, test_adam_apply_one_cond4_fusion) { + /* + * def before_cond4(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + * square0 = Square(input0) + * mul1 = Mul(mul1_x, input0) + * mul0 = Mul(mul0_x, input2) + * mul2 = Mul(mul2_x, input1) + * mul3 = Mul(mul3_x, square0) + * add0 = Add(mul0, mul1) + * add1 = Add(mul2, mul3) + * sqrt0 = Sqrt(add1) + * add2 = Add(add2_y, sqrt0) + * true_div0 = RealDiv(add0, add2) + * mul4 = Mul(true_div0, input4) + * sub0 = Sub(input3, mul4) + * outputs = make_tuple(add1, add0, sub0) + * output = tuple_getitem(outputs, 0) + * return output + */ + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "before_cond4"); + std::vector shp{2, 32, 224, 224}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 10; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_adam_apply_one_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} } // namespace opt } // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion_test.cc new file mode 100644 index 0000000000..e3bf09d2cb --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion_test.cc @@ -0,0 +1,54 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#include "pre_activate/common/optimizer.h" +#include "pre_activate/ascend/ir_fusion/confusion_mul_grad_fusion.h" +#include "debug/anf_ir_dump.h" + +namespace mindspore { +namespace opt { +class TestHWOptimizeConfusionMulGradFusion : public BackendCommon { + public: + TestHWOptimizeConfusionMulGradFusion() : get_py_fun_("gtest_input.pre_activate.confusion_mul_grad_fusion", true) {} + ~TestHWOptimizeConfusionMulGradFusion() override = default; + + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestHWOptimizeConfusionMulGradFusion, test_fusion) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_confusion_mul_grad_fusion", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{1, 1, 1, 1}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 3; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_confusion_mul_grad_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fusion/derelu_fusion_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fusion/derelu_fusion_test.cc new file mode 100644 index 0000000000..ffa5a42b4d --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/ir_fusion/derelu_fusion_test.cc @@ -0,0 +1,54 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#include "pre_activate/common/optimizer.h" +#include "pre_activate/ascend/ir_fusion/derelu_fusion.h" +#include "debug/anf_ir_dump.h" + +namespace mindspore { +namespace opt { +class TestHWOptimizeDereluFusion : public BackendCommon { + public: + TestHWOptimizeDereluFusion() : get_py_fun_("gtest_input.pre_activate.derelu_fusion", true) {} + ~TestHWOptimizeDereluFusion() override = default; + + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestHWOptimizeDereluFusion, test_fusion) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_derelu_fusion", "before"); + EXPECT_NE(g, nullptr); + std::vector shp{1, 1, 1, 1}; + auto x_abstract = std::make_shared(kFloat32, shp); + AbstractBasePtrList args_spec_list; + for (size_t i = 0; i < 2; ++i) { + args_spec_list.push_back(x_abstract); + } + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_derelu_fusion", "after"); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} + +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fusion/layer_norm_beta_gamma_backprop_fusion_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fusion/layer_norm_beta_gamma_backprop_fusion_test.cc index e7831ec353..44b9b3df69 100644 --- a/tests/ut/cpp/pre_activate/ascend/ir_fusion/layer_norm_beta_gamma_backprop_fusion_test.cc +++ b/tests/ut/cpp/pre_activate/ascend/ir_fusion/layer_norm_beta_gamma_backprop_fusion_test.cc @@ -80,6 +80,8 @@ TEST_F(TestHWLayerNormBetaGammaBackpropFusion, layernorm_beta_gamma_backprop_fus builder1.SetOutputsDeviceType({kNumberTypeFloat32}); cast0->set_kernel_info(std::make_shared()); cast1->set_kernel_info(std::make_shared()); + cast0->set_abstract(x_abstract); + cast1->set_abstract(x_abstract); AnfAlgo::SetSelectKernelBuildInfo(builder1.Build(), cast0.get()); AnfAlgo::SetSelectKernelBuildInfo(builder1.Build(), cast1.get()); diff --git a/tests/ut/cpp/pre_activate/common/ir_fusion/allreduce_fusion_test.cc b/tests/ut/cpp/pre_activate/common/ir_fusion/allreduce_fusion_test.cc index 79a1cf1a8a..d5f2fa636d 100644 --- a/tests/ut/cpp/pre_activate/common/ir_fusion/allreduce_fusion_test.cc +++ b/tests/ut/cpp/pre_activate/common/ir_fusion/allreduce_fusion_test.cc @@ -20,7 +20,7 @@ #include "ir/manager.h" #include "debug/anf_ir_dump.h" #include "session/anf_runtime_algorithm.h" -#include "pre_activate/common/ir_fusion/allreduce_fusion.h" +#include "pre_activate/pass/allreduce_fusion.h" #include "pre_activate/common/optimizer.h" #include "device/kernel_info.h" #include "pre_activate/common/pass_manager.h" diff --git a/tests/ut/cpp/pre_activate/common/pattern_engine_test.cc b/tests/ut/cpp/pre_activate/common/pattern_engine_test.cc index 9124f5cf74..7b0e2cc9db 100644 --- a/tests/ut/cpp/pre_activate/common/pattern_engine_test.cc +++ b/tests/ut/cpp/pre_activate/common/pattern_engine_test.cc @@ -40,6 +40,7 @@ class TestMatchEngine : public UT::Common { public: PatternEngine TU; EquivPtr equiv_null; + PrimitiveVarMap primitive_vars_null; }; TEST_F(TestMatchEngine, Var) { @@ -106,30 +107,30 @@ TEST_F(TestMatchEngine, MatchRaw_Var) { // common equiv_null->clear(); - d = TU.Match(v1, 1, equiv_null); + d = TU.Match(v1, 1, primitive_vars_null, equiv_null); ASSERT_EQ((*d)[v1], 1); equiv_null->clear(); (*equiv_null)[v1] = v2; - d = TU.Match(v1, 1, equiv_null); + d = TU.Match(v1, 1, primitive_vars_null, equiv_null); ASSERT_EQ(d->count(v2), std::size_t(1)); ASSERT_EQ((*d)[v2], 1); equiv_null->clear(); (*equiv_null)[v1] = v2; (*equiv_null)[v3] = 1; - d = TU.Match(v1, 1, equiv_null); + d = TU.Match(v1, 1, primitive_vars_null, equiv_null); ASSERT_EQ(d->count(v2), std::size_t(1)); ASSERT_EQ((*d)[v2], 1); equiv_null->clear(); - d = TU.Match(VectorRef({v1}), VectorRef({1}), equiv_null); + d = TU.Match(VectorRef({v1}), VectorRef({1}), primitive_vars_null, equiv_null); ASSERT_EQ(d->size(), std::size_t(1)); ASSERT_EQ(d->count(v1), std::size_t(1)); ASSERT_EQ((*d)[v1], 1); equiv_null->clear(); - ASSERT_EQ(TU.Match(1, 2, equiv_null), nullptr); + ASSERT_EQ(TU.Match(1, 2, primitive_vars_null, equiv_null), nullptr); } TEST_F(TestMatchEngine, MatchRaw_SVar) { @@ -139,22 +140,22 @@ TEST_F(TestMatchEngine, MatchRaw_SVar) { EquivPtr d; equiv_null->clear(); - d = TU.Match(VectorRef({sv1}), VectorRef({1, 2}), equiv_null); + d = TU.Match(VectorRef({sv1}), VectorRef({1, 2}), primitive_vars_null, equiv_null); ASSERT_EQ(d->size(), std::size_t(1)); ASSERT_EQ(d->count(sv1), std::size_t(1)); ASSERT_EQ(utils::cast((*d)[sv1]), Seq({1, 2})); equiv_null->clear(); - d = TU.Match(VectorRef({v1, sv1}), VectorRef({1, 2}), equiv_null); + d = TU.Match(VectorRef({v1, sv1}), VectorRef({1, 2}), primitive_vars_null, equiv_null); ASSERT_EQ(d->size(), std::size_t(2)); ASSERT_EQ(utils::cast((*d)[sv1]), Seq({2})); equiv_null->clear(); - ASSERT_EQ(TU.Match(VectorRef({sv1, sv2}), VectorRef({1, 2}), equiv_null), nullptr); + ASSERT_EQ(TU.Match(VectorRef({sv1, sv2}), VectorRef({1, 2}), primitive_vars_null, equiv_null), nullptr); equiv_null->clear(); (*equiv_null)[sv1] = std::make_shared(PatternListType{1, 2}); - d = TU.Match(VectorRef({v1, sv1}), VectorRef({1, 1, 2}), equiv_null); + d = TU.Match(VectorRef({v1, sv1}), VectorRef({1, 1, 2}), primitive_vars_null, equiv_null); ASSERT_EQ(d->size(), std::size_t(2)); ASSERT_EQ((*d)[v1], 1); } @@ -167,13 +168,13 @@ TEST_F(TestMatchEngine, Match) { EquivPtr d; equiv_null->clear(); - d = TU.Match(VectorRef({v1, v1, v2}), VectorRef({1, 1, 2}), equiv_null); + d = TU.Match(VectorRef({v1, v1, v2}), VectorRef({1, 1, 2}), primitive_vars_null, equiv_null); ASSERT_EQ(d->size(), std::size_t(2)); ASSERT_EQ((*d)[v1], 1); ASSERT_EQ((*d)[v2], 2); equiv_null->clear(); - d = TU.Match(static_cast(1), static_cast(1), equiv_null); + d = TU.Match(static_cast(1), static_cast(1), primitive_vars_null, equiv_null); ASSERT_EQ(d, nullptr); } @@ -197,18 +198,19 @@ TEST_F(TestMatchEngine, Match_CondVar) { EquivPtr d; equiv_null->clear(); - d = TU.Match(VectorRef({vf, vn}), VectorRef({static_cast(1.0), -1}), equiv_null); + d = TU.Match(VectorRef({vf, vn}), VectorRef({static_cast(1.0), -1}), primitive_vars_null, equiv_null); ASSERT_GE(d->size(), std::size_t(0)); auto vfn = (*d)[vf]; ASSERT_EQ((*d)[vf], static_cast(1.0)); ASSERT_EQ((*d)[vn], -1); equiv_null->clear(); - d = TU.Match(VectorRef({vf, vn}), VectorRef({1, static_cast(-1.0)}), equiv_null); + d = TU.Match(VectorRef({vf, vn}), VectorRef({1, static_cast(-1.0)}), primitive_vars_null, equiv_null); ASSERT_EQ(d, nullptr); equiv_null->clear(); - d = TU.Match(VectorRef({vf, vn}), VectorRef({static_cast(1.0), static_cast(1)}), equiv_null); + d = TU.Match(VectorRef({vf, vn}), VectorRef({static_cast(1.0), static_cast(1)}), primitive_vars_null, + equiv_null); ASSERT_EQ(d, nullptr); } diff --git a/tests/ut/cpp/pre_activate/pass/convert_tuple_output_to_maketuple_test.cc b/tests/ut/cpp/pre_activate/pass/convert_tuple_output_to_maketuple_test.cc new file mode 100644 index 0000000000..da01a74d76 --- /dev/null +++ b/tests/ut/cpp/pre_activate/pass/convert_tuple_output_to_maketuple_test.cc @@ -0,0 +1,65 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common/backend_common_test.h" +#include "ir/anf.h" +#include "ir/meta_tensor.h" +#include "debug/anf_ir_dump.h" +#include "common/py_func_graph_fetcher.h" +#include "session/anf_runtime_algorithm.h" +#include "pre_activate/common/optimizer.h" +#include "pre_activate/common/pass_manager.h" +#include "pre_activate/pass/convert_tuple_output_to_maketuple.h" +#include "utils/utils.h" + +namespace mindspore { +namespace opt { +class TestHWTupleOutputToMakeTuple : public BackendCommon { + public: + TestHWTupleOutputToMakeTuple() + : getPyFun_("gtest_input.pre_activate.convert_tuple_output_to_maketuple_test", true) {} + ~TestHWTupleOutputToMakeTuple() override = default; + + public: + UT::PyFuncGraphFetcher getPyFun_; +}; + +TEST_F(TestHWTupleOutputToMakeTuple, test_convert_tuple_output_to_maketuple) { + FuncGraphPtr g = getPyFun_.CallAndParseRet("test_convert_tuple_output_to_maketuple", "before"); + ASSERT_TRUE(g != nullptr); + std::vector shp_x{5, 2, 10}; + std::vector shp_h{1, 2, 2}; + std::vector shp_c{1, 2, 2}; + std::vector shp_w{112, 1, 1}; + auto x_abstract = std::make_shared(kFloat32, shp_x); + auto h_abstract = std::make_shared(kFloat32, shp_h); + auto c_abstract = std::make_shared(kFloat32, shp_c); + auto w_abstract = std::make_shared(kFloat32, shp_w); + AbstractBasePtrList args_spec_list{x_abstract, h_abstract, c_abstract, w_abstract}; + auto func_graph = GetKernelGraph(g, args_spec_list); + ASSERT_TRUE(func_graph != nullptr); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + optimizer->Optimize(func_graph); + + FuncGraphPtr g_after = getPyFun_.CallAndParseRet("test_convert_tuple_output_to_maketuple", "after"); + ASSERT_TRUE(g_after != nullptr); + EXPECT_TRUE(CheckEqualGraph(func_graph, g_after)); +} +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/adam_apply_one_fusion_test.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/adam_apply_one_fusion_test.py index b55764b18d..225964ee38 100644 --- a/tests/ut/cpp/python_input/gtest_input/pre_activate/adam_apply_one_fusion_test.py +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/adam_apply_one_fusion_test.py @@ -58,6 +58,78 @@ def test_adam_apply_one_fusion(tag): output = tuple_getitem(outputs, 0) return output + @fns + def before_cond1(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + square0 = Square(input0) + mul1 = Mul(mul1_x, input0) + mul0 = Mul(mul0_x, input2) + mul2 = Mul(mul2_x, input1) + mul3 = Mul(mul3_x, square0) + add0 = Add(mul0, mul1) + add1 = Add(mul2, mul3) + sqrt0 = Sqrt(add1) + add2 = Add(add2_y, sqrt0) + true_div0 = RealDiv(add0, add2) + mul4 = Mul(input4, true_div0) + sub0 = Sub(input3, mul4) + outputs = make_tuple(add1, add0, sub0) + output = tuple_getitem(outputs, 0) + return output + + @fns + def before_cond2(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + square0 = Square(input0) + mul1 = Mul(mul1_x, input0) + mul0 = Mul(mul0_x, input2) + mul2 = Mul(mul2_x, input1) + mul3 = Mul(square0, mul3_x) + add0 = Add(mul0, mul1) + add1 = Add(mul2, mul3) + sqrt0 = Sqrt(add1) + add2 = Add(sqrt0, add2_y) + true_div0 = RealDiv(add0, add2) + mul4 = Mul(true_div0, input4) + sub0 = Sub(input3, mul4) + outputs = make_tuple(add1, add0, sub0) + output = tuple_getitem(outputs, 0) + return output + + @fns + def before_cond3(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + square0 = Square(input0) + mul1 = Mul(mul1_x, input0) + mul0 = Mul(mul0_x, input2) + mul2 = Mul(mul2_x, input1) + mul3 = Mul(mul3_x, square0) + add0 = Add(mul0, mul1) + add1 = Add(mul2, mul3) + sqrt0 = Sqrt(add1) + add2 = Add(sqrt0, add2_y) + true_div0 = RealDiv(add0, add2) + mul4 = Mul(true_div0, input4) + sub0 = Sub(input3, mul4) + outputs = make_tuple(add1, add0, sub0) + output = tuple_getitem(outputs, 0) + return output + + @fns + def before_cond4(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): + square0 = Square(input0) + mul1 = Mul(mul1_x, input0) + mul0 = Mul(mul0_x, input2) + mul2 = Mul(mul2_x, input1) + mul3 = Mul(mul3_x, square0) + add0 = Add(mul0, mul1) + add1 = Add(mul2, mul3) + sqrt0 = Sqrt(add1) + add2 = Add(add2_y, sqrt0) + true_div0 = RealDiv(add0, add2) + mul4 = Mul(true_div0, input4) + sub0 = Sub(input3, mul4) + outputs = make_tuple(add1, add0, sub0) + output = tuple_getitem(outputs, 0) + return output + @fns def after(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y): adam_apply_one = AdamApplyOne(input0, input1, input2, input3, input4, mul0_x, mul1_x, mul2_x, mul3_x, add2_y) diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/addn_fission_test.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/addn_fission_test.py new file mode 100644 index 0000000000..c120ac3e68 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/addn_fission_test.py @@ -0,0 +1,80 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +from mindspore.ops import operations as P +from mindspore.ops import Primitive + +addn = P.AddN() +make_tuple = Primitive('make_tuple') + + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + + +def test_addn_fission(tag): + """ test_adam_apply_one_with_decay_rule """ + fns = FnDict() + + @fns + def before(input0, input1, input2, input3, input4, input5, input6, input7, input8): + return addn((input0, input1, input2, input3, input4, input5, input6, input7, input8)) + + @fns + def after_divided_by_2(input0, input1, input2, input3, input4, input5, input6, input7, input8): + a = addn((input0, input1)) + b = addn((input2, input3)) + c = addn((input4, input5)) + d = addn((input6, input7)) + e = addn((input8,)) + f = addn((a, b)) + g = addn((c, d)) + h = addn((e,)) + i = addn((f, g)) + j = addn((h,)) + return addn((i, j)) + + @fns + def after_divided_by_3(input0, input1, input2, input3, input4, input5, input6, input7, input8): + a = addn((input0, input1, input2)) + b = addn((input3, input4, input5)) + c = addn((input6, input7, input8)) + return addn((a, b, c)) + + @fns + def after_divided_by_4(input0, input1, input2, input3, input4, input5, input6, input7, input8): + a = addn((input0, input1, input2, input3)) + b = addn((input4, input5, input6, input7)) + c = addn((input8,)) + return addn((a, b, c)) + + @fns + def after_divided_by_8(input0, input1, input2, input3, input4, input5, input6, input7, input8): + a = addn((input0, input1, input2, input3, input4, input5, input6, input7)) + b = addn((input8,)) + return addn((a, b)) + + @fns + def after_divided_by_9(input0, input1, input2, input3, input4, input5, input6, input7, input8): + return addn((input0, input1, input2, input3, input4, input5, input6, input7, input8)) + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/confusion_mul_grad_fusion.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/confusion_mul_grad_fusion.py new file mode 100644 index 0000000000..d8f7bcc996 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/confusion_mul_grad_fusion.py @@ -0,0 +1,55 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +from mindspore.ops import operations as P +from mindspore.ops import Primitive + +mul = P.Mul() +reduce_sum = P.ReduceSum() +confusion_mul_grad = Primitive('ConfusionMulGrad') +make_tuple = Primitive('make_tuple') +tuple_getitem = Primitive('tuple_getitem') +axis = 2 + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + +def test_confusion_mul_grad_fusion(tag): + fns = FnDict() + + @fns + def before(input1, input2, input3): + output1 = mul(input1, input2) + mul1 = mul(input3, input2) + # input axis will be convert to attr in step ConstructKernelGraph + output2 = reduce_sum(mul1, axis) + res = make_tuple(output1, output2) + return res + + @fns + def after(input1, input2, input3): + res = confusion_mul_grad(input1, input2, input3) + item0 = tuple_getitem(res, 0) + item1 = tuple_getitem(res, 1) + res = make_tuple(item0, item1) + return make_tuple(res) + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/convert_tuple_output_to_maketuple_test.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/convert_tuple_output_to_maketuple_test.py new file mode 100644 index 0000000000..961f7b6232 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/convert_tuple_output_to_maketuple_test.py @@ -0,0 +1,54 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +from mindspore.ops import operations as P +from mindspore.ops import Primitive +import mindspore as ms +import mindspore.common.dtype as mstype +from mindspore.common.tensor import Tensor +import numpy as np + +make_tuple = Primitive('make_tuple') +tuple_get_item = Primitive("tuple_getitem"); +LSTM = P.LSTM(input_size=10,hidden_size=2,num_layers=1,has_bias=True,bidirectional=False,dropout=0.0) +add = P.TensorAdd() + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + + +def test_convert_tuple_output_to_maketuple(tag): + fns = FnDict() + + @fns + def before(x, h, c, w): + res = LSTM(x, h, c, w) + return res + + @fns + def after(x, h, c, w): + res = LSTM(x, h, c, w) + res = make_tuple( + make_tuple(tuple_get_item(res, 0), tuple_get_item(res, 1), tuple_get_item(res, 2), tuple_get_item(res, 3), + tuple_get_item(res, 4))); + return res + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/derelu_fusion.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/derelu_fusion.py new file mode 100644 index 0000000000..497975542b --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/derelu_fusion.py @@ -0,0 +1,56 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +from mindspore.ops import operations as P +from mindspore.ops import Primitive + +relu = P.ReLU() +relu_grad = Primitive('ReluGrad') +relu_v2 = Primitive('ReluV2') +relu_grad_v2 = Primitive('ReluGradV2') +make_tuple = Primitive('make_tuple') +tuple_getitem = Primitive('tuple_getitem') + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + +def test_derelu_fusion(tag): + fns = FnDict() + + @fns + def before(i0, i1): + relu_res = relu(i1) + res = relu_grad(i0, relu_res) + other = relu(relu_res) + res = make_tuple(res, other) + return res + + @fns + def after(i0, i1): + relu_res = relu_v2(i1) + item0 = tuple_getitem(relu_res, 0) + item1 = tuple_getitem(relu_res, 1) + other = relu(item0) + res = relu_grad_v2(i0, item1) + res = make_tuple(res, other) + return make_tuple(res) + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/getnext_memcpy_elimination_test.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/getnext_memcpy_elimination_test.py new file mode 100644 index 0000000000..39b60d72d6 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/getnext_memcpy_elimination_test.py @@ -0,0 +1,117 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +from mindspore.ops import operations as P +from mindspore.ops import Primitive +import mindspore as ms + +get_next = P.GetNext([ms.float32], [[1, 64, 112, 112]], 1, "") +memcpy_async_attr = Primitive('memcpy_async') +memcpy_async_attr.add_prim_attr("label_for_insert_stream_active", True) +memcpy_async = Primitive('memcpy_async') +cast = P.Cast() +add = P.TensorAdd() + + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + + +def test_getnext_memcpy_elimination(tag): + fns = FnDict() + + @fns + def before(x): + res = get_next() + res = memcpy_async_attr(res) + res = cast(res) + return res + + @fns + def after(x): + res = get_next() + res = cast(res) + return res + + return fns[tag] + + +def test_getnext_memcpy_elimination_no_attr(tag): + fns = FnDict() + + @fns + def before(x): + res = get_next() + res = memcpy_async(res) + res = cast(res) + return res + + @fns + def after(x): + res = get_next() + res = memcpy_async(res) + res = cast(res) + return res + + return fns[tag] + + +def test_getnext_memcpy_elimination_memcpy_multi_users(tag): + fns = FnDict() + + @fns + def before(x): + res = get_next() + memcpy_out = memcpy_async_attr(res) + res = cast(memcpy_out) + res = add(memcpy_out, res) + return res + + @fns + def after(x): + res = get_next() + memcpy_out = memcpy_async_attr(res) + res = cast(memcpy_out) + res = add(memcpy_out, res) + return res + + return fns[tag] + + +def test_getnext_memcpy_elimination_next_multi_inputs(tag): + fns = FnDict() + + @fns + def before(x): + res = get_next() + memcpy_out = memcpy_async_attr(res) + res = add(memcpy_out, res) + return res + + @fns + def after(x): + res = get_next() + memcpy_out = memcpy_async_attr(res) + res = add(memcpy_out, res) + return res + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/insert_memcpy_async_for_getnext.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/insert_memcpy_async_for_getnext.py new file mode 100644 index 0000000000..f0320fef79 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/insert_memcpy_async_for_getnext.py @@ -0,0 +1,58 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +from mindspore.ops import operations as P +from mindspore.ops import Primitive +import mindspore as ms + +get_next = P.GetNext([ms.float32, ms.int32], [[32, 64], [32]], 2, "") +memcpy_async = Primitive('memcpy_async') +make_tuple = Primitive('make_tuple') +tuple_getitem = Primitive('tuple_getitem') + + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + + +def test_insert_memcpy_async_for_getnext(tag): + fns = FnDict() + + @fns + def getnext_multi_output_before(): + res = get_next() + return res + + @fns + def getnext_multi_output_after(): + res = get_next() + data = tuple_getitem(res, 0) + label = tuple_getitem(res, 1) + memcpy_async_data = memcpy_async(data) + memcpy_async_label = memcpy_async(label) + bind_tuple = make_tuple(memcpy_async_data, memcpy_async_label) + get_item0 = tuple_getitem(bind_tuple, 0) + get_item1 = tuple_getitem(bind_tuple, 1) + bind_tuple = make_tuple(make_tuple(get_item0, get_item1)) + return bind_tuple + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py b/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py index 46c6fdd1cf..c7de09dbcb 100644 --- a/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py +++ b/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py @@ -21,17 +21,17 @@ from mindspore.common.tensor import Tensor def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1): """Rearranges an image to row vector""" batch_num, channel, height, width = img.shape - out_h = (height + 2*pad - filter_h - (filter_h - 1) * (dilation - 1))//stride + 1 - out_w = (width + 2*pad - filter_w - (filter_w - 1) * (dilation - 1))//stride + 1 + out_h = (height + 2*pad - filter_h - (filter_h - 1) * (dilation[2] - 1))//stride[2] + 1 + out_w = (width + 2*pad - filter_w - (filter_w - 1) * (dilation[3] - 1))//stride[3] + 1 img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant') col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype) for y in range(filter_h): - y_max = y + stride*out_h + y_max = y + stride[2]*out_h for x in range(filter_w): - x_max = x + stride*out_w - col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride] + x_max = x + stride[2]*out_w + col[:, :, y, x, :, :] = img[:, :, y:y_max:stride[2], x:x_max:stride[2]] col = col.transpose(0, 4, 5, 1, 2, 3).reshape(batch_num*out_h*out_w, -1) return col @@ -42,8 +42,8 @@ def conv2d(x, weight, bias=None, stride=1, pad=0, """Convolution 2D""" batch_num, _, x_h, x_w = x.shape filter_num, _, filter_h, filter_w = weight.shape - out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation - 1)) / stride) - out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation - 1)) / stride) + out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation[2] - 1)) / stride[2]) + out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation[3] - 1)) / stride[3]) col = im2col(x, filter_h, filter_w, stride, pad, dilation) col_w = np.reshape(weight, (filter_num, -1)).T out = np.dot(col, col_w) diff --git a/tests/ut/cpp/session/anf_runtime_algorithm_test.cc b/tests/ut/cpp/session/anf_runtime_algorithm_test.cc index 2af2a7413b..6375d1a758 100644 --- a/tests/ut/cpp/session/anf_runtime_algorithm_test.cc +++ b/tests/ut/cpp/session/anf_runtime_algorithm_test.cc @@ -211,8 +211,8 @@ TEST_F(AnfRuntimeAlgorithmTest, EraseNodeAttr) { TEST_F(AnfRuntimeAlgorithmTest, GetInputTensorNum) { auto kernel_graph = std::make_shared(); // test cnode node - auto parameter_one = kernel_graph->add_parameter(); - auto parameter_two = kernel_graph->add_parameter(); + auto parameter_one = kernel_graph->NewParameter(); + auto parameter_two = kernel_graph->NewParameter(); std::vector add_inputs{NewValueNode(prim::kPrimTensorAdd), parameter_one, parameter_two}; auto add = kernel_graph->NewCNode(add_inputs); EXPECT_EQ(AnfAlgo::GetInputTensorNum(add), 2); @@ -247,9 +247,11 @@ TEST_F(AnfRuntimeAlgorithmTest, GetOutputTensorNum) { TEST_F(AnfRuntimeAlgorithmTest, GetOutputFormat) { auto kernel_graph = std::make_shared(); - std::vector inputs; - inputs.push_back(NewValueNode(prim::kPrimTensorAdd)); + std::vector inputs = {NewValueNode(prim::kPrimTensorAdd), kernel_graph->NewParameter(), + kernel_graph->NewParameter()}; auto add = kernel_graph->NewCNode(inputs); + std::vector shape = {1, 2, 3, 4}; + AnfAlgo::SetOutputInferTypeAndShape({kNumberTypeFloat32, kNumberTypeFloat32}, {shape, shape}, add.get()); MS_EXCEPTION_IF_NULL(add); add->set_kernel_info(std::make_shared()); auto d_kernel_info = add->kernel_info(); @@ -266,8 +268,8 @@ TEST_F(AnfRuntimeAlgorithmTest, GetOutputFormat) { TEST_F(AnfRuntimeAlgorithmTest, GetInputFormat) { auto kernel_graph = std::make_shared(); - std::vector inputs; - inputs.push_back(NewValueNode(prim::kPrimTensorAdd)); + std::vector inputs = {NewValueNode(prim::kPrimTensorAdd), kernel_graph->NewParameter(), + kernel_graph->NewParameter()}; auto add = kernel_graph->NewCNode(inputs); MS_EXCEPTION_IF_NULL(add); add->set_kernel_info(std::make_shared()); @@ -345,7 +347,7 @@ TEST_F(AnfRuntimeAlgorithmTest, GetPrevNodeOutputInferShape) { std::vector shp{2, 32, 224, 224}; auto x_abstract = std::make_shared(kFloat32, shp); // test parameter node as input - auto parameter_node = kernel_graph->add_parameter(); + auto parameter_node = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(parameter_node); parameter_node->set_abstract(x_abstract); EXPECT_THROW(AnfAlgo::GetPrevNodeOutputInferShape(parameter_node, 0), std::runtime_error); @@ -387,13 +389,13 @@ TEST_F(AnfRuntimeAlgorithmTest, GetInputDeviceShape) { auto kernel_graph = std::make_shared(); std::vector shp{2, 32, 224, 224}; auto x_abstract = std::make_shared(kFloat32, shp); - auto parameter_one = kernel_graph->add_parameter(); + auto parameter_one = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(parameter_one); parameter_one->set_abstract(x_abstract); - auto parameter_two = kernel_graph->add_parameter(); + auto parameter_two = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(parameter_two); parameter_two->set_abstract(x_abstract); - auto parameter_third = kernel_graph->add_parameter(); + auto parameter_third = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(parameter_third); parameter_third->set_abstract(x_abstract); // test cnode as input @@ -466,8 +468,8 @@ TEST_F(AnfRuntimeAlgorithmTest, GetOutputDeviceDataTypeTest) { TEST_F(AnfRuntimeAlgorithmTest, GetInputDeviceDataTypeTest) { auto kernel_graph = std::make_shared(); - std::vector inputs; - inputs.push_back(NewValueNode(prim::kPrimTensorAdd)); + std::vector inputs = {NewValueNode(prim::kPrimTensorAdd), kernel_graph->NewParameter(), + kernel_graph->NewParameter()}; auto add = kernel_graph->NewCNode(inputs); MS_EXCEPTION_IF_NULL(add); add->set_kernel_info(std::make_shared()); diff --git a/tests/ut/cpp/session/kernel_graph_test.cc b/tests/ut/cpp/session/kernel_graph_test.cc index 55e1b1b28e..a62af9c892 100644 --- a/tests/ut/cpp/session/kernel_graph_test.cc +++ b/tests/ut/cpp/session/kernel_graph_test.cc @@ -140,11 +140,11 @@ TEST_F(KernelGraphTest, SetExecOrderByDefault) { std::vector shape = {2, 32, 224, 224}; auto abstract = std::make_shared(kFloat32, shape); - auto x_parameter = kernel_graph->add_parameter(); + auto x_parameter = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(x_parameter); x_parameter->set_name("x_parameter"); x_parameter->set_abstract(abstract); - auto y_parameter = kernel_graph->add_parameter(); + auto y_parameter = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(y_parameter); y_parameter->set_name("y_parameter"); y_parameter->set_abstract(abstract); @@ -153,7 +153,7 @@ TEST_F(KernelGraphTest, SetExecOrderByDefault) { MS_EXCEPTION_IF_NULL(add); add->set_abstract(abstract); - auto z_parameter = kernel_graph->add_parameter(); + auto z_parameter = kernel_graph->NewParameter(); MS_EXCEPTION_IF_NULL(z_parameter); z_parameter->set_name("z_parameter"); z_parameter->set_abstract(abstract); diff --git a/tests/ut/cpp/transform/convert_test.cc b/tests/ut/cpp/transform/convert_test.cc index c7cd394002..4388312592 100644 --- a/tests/ut/cpp/transform/convert_test.cc +++ b/tests/ut/cpp/transform/convert_test.cc @@ -621,6 +621,12 @@ TEST_F(TestConvert, TestTensorSummaryOps) { ASSERT_TRUE(ret); } +TEST_F(TestConvert, TestHistogramSummaryOps) { + auto prim = prim::kPrimHistogramSummary; + bool ret = MakeDfGraph(prim, 2); + ASSERT_TRUE(ret); +} + TEST_F(TestConvert, TestGreaterOps) { auto prim = std::make_shared("Greater"); bool ret = MakeDfGraph(prim, 2); diff --git a/tests/ut/cpp/transform/transform_base_test.cc b/tests/ut/cpp/transform/transform_base_test.cc index 944721ec83..eb083e2dd1 100644 --- a/tests/ut/cpp/transform/transform_base_test.cc +++ b/tests/ut/cpp/transform/transform_base_test.cc @@ -73,7 +73,8 @@ FuncGraphPtr MakeFuncGraph(const PrimitivePtr prim, unsigned int nparam) { std::vector inputs; inputs.push_back(NewValueNode(prim)); for (unsigned int i = 0; i < nparam; i++) { - if ((prim->name() == "ScalarSummary" || prim->name() == "TensorSummary" || prim->name() == "ImageSummary") && + if ((prim->name() == "ScalarSummary" || prim->name() == "TensorSummary" || + prim->name() == "ImageSummary" || prim->name() == "HistogramSummary") && i == 0) { auto input = NewValueNode("testSummary"); inputs.push_back(input); diff --git a/tests/ut/python/communication/test_comm.py b/tests/ut/python/communication/test_comm.py index 885c8fa9e3..38fd7199fd 100644 --- a/tests/ut/python/communication/test_comm.py +++ b/tests/ut/python/communication/test_comm.py @@ -55,7 +55,7 @@ class BroadCastNet(nn.Cell): self.broadcast = Broadcast(0) def construct(self, x): - x, = self.broadcast((x,)) + x = self.broadcast((x)) x = self.dense(x) return x diff --git a/tests/ut/python/dataset/test_apply.py b/tests/ut/python/dataset/test_apply.py new file mode 100644 index 0000000000..f2e7a79011 --- /dev/null +++ b/tests/ut/python/dataset/test_apply.py @@ -0,0 +1,236 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +import mindspore.dataset as ds +from mindspore import log as logger +import mindspore.dataset.transforms.vision.c_transforms as vision +import numpy as np + +DATA_DIR = "../data/dataset/testPK/data" + +# Generate 1d int numpy array from 0 - 64 +def generator_1d(): + for i in range(64): + yield (np.array([i]),) + +def test_apply_generator_case(): + # apply dataset operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + data2 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + ds = ds.repeat(2) + return ds.batch(4) + + data1 = data1.apply(dataset_fn) + data2 = data2.repeat(2) + data2 = data2.batch(4) + + for item1, item2 in zip(data1.create_dict_iterator(), data2.create_dict_iterator()): + assert np.array_equal(item1["data"], item2["data"]) + +def test_apply_imagefolder_case(): + # apply dataset map operations + data1 = ds.ImageFolderDatasetV2(DATA_DIR, num_shards=4, shard_id=3) + data2 = ds.ImageFolderDatasetV2(DATA_DIR, num_shards=4, shard_id=3) + + decode_op = vision.Decode() + normalize_op = vision.Normalize([121.0, 115.0, 100.0], [70.0, 68.0, 71.0]) + + def dataset_fn(ds): + ds = ds.map(operations = decode_op) + ds = ds.map(operations = normalize_op) + ds = ds.repeat(2) + return ds + + data1 = data1.apply(dataset_fn) + data2 = data2.map(operations = decode_op) + data2 = data2.map(operations = normalize_op) + data2 = data2.repeat(2) + + for item1, item2 in zip(data1.create_dict_iterator(), data2.create_dict_iterator()): + assert np.array_equal(item1["image"], item2["image"]) + +def test_apply_flow_case_0(id=0): + # apply control flow operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + if id == 0: + ds = ds.batch(4) + elif id == 1: + ds = ds.repeat(2) + elif id == 2: + ds = ds.batch(4) + ds = ds.repeat(2) + else: + ds = ds.shuffle(buffer_size=4) + return ds + + data1 = data1.apply(dataset_fn) + num_iter = 0 + for _ in data1.create_dict_iterator(): + num_iter = num_iter + 1 + + if id == 0: + assert num_iter == 16 + elif id == 1: + assert num_iter == 128 + elif id == 2: + assert num_iter == 32 + else: + assert num_iter == 64 + +def test_apply_flow_case_1(id=1): + # apply control flow operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + if id == 0: + ds = ds.batch(4) + elif id == 1: + ds = ds.repeat(2) + elif id == 2: + ds = ds.batch(4) + ds = ds.repeat(2) + else: + ds = ds.shuffle(buffer_size=4) + return ds + + data1 = data1.apply(dataset_fn) + num_iter = 0 + for _ in data1.create_dict_iterator(): + num_iter = num_iter + 1 + + if id == 0: + assert num_iter == 16 + elif id == 1: + assert num_iter == 128 + elif id == 2: + assert num_iter == 32 + else: + assert num_iter == 64 + +def test_apply_flow_case_2(id=2): + # apply control flow operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + if id == 0: + ds = ds.batch(4) + elif id == 1: + ds = ds.repeat(2) + elif id == 2: + ds = ds.batch(4) + ds = ds.repeat(2) + else: + ds = ds.shuffle(buffer_size=4) + return ds + + data1 = data1.apply(dataset_fn) + num_iter = 0 + for _ in data1.create_dict_iterator(): + num_iter = num_iter + 1 + + if id == 0: + assert num_iter == 16 + elif id == 1: + assert num_iter == 128 + elif id == 2: + assert num_iter == 32 + else: + assert num_iter == 64 + +def test_apply_flow_case_3(id=3): + # apply control flow operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + if id == 0: + ds = ds.batch(4) + elif id == 1: + ds = ds.repeat(2) + elif id == 2: + ds = ds.batch(4) + ds = ds.repeat(2) + else: + ds = ds.shuffle(buffer_size=4) + return ds + + data1 = data1.apply(dataset_fn) + num_iter = 0 + for _ in data1.create_dict_iterator(): + num_iter = num_iter + 1 + + if id == 0: + assert num_iter == 16 + elif id == 1: + assert num_iter == 128 + elif id == 2: + assert num_iter == 32 + else: + assert num_iter == 64 + +def test_apply_exception_case(): + # apply exception operations + data1 = ds.GeneratorDataset(generator_1d, ["data"]) + + def dataset_fn(ds): + ds = ds.repeat(2) + return ds.batch(4) + + def exception_fn(ds): + return np.array([[0], [1], [3], [4], [5]]) + + try: + data1 = data1.apply("123") + for _ in data1.create_dict_iterator(): + pass + assert False + except TypeError: + pass + + try: + data1 = data1.apply(exception_fn) + for _ in data1.create_dict_iterator(): + pass + assert False + except TypeError: + pass + + try: + data2 = data1.apply(dataset_fn) + data3 = data1.apply(dataset_fn) + for item1, item2 in zip(data1.create_dict_iterator(), data2.create_dict_iterator()): + pass + assert False + except ValueError: + pass + +if __name__ == '__main__': + logger.info("Running test_apply.py test_apply_generator_case() function") + test_apply_generator_case() + + logger.info("Running test_apply.py test_apply_imagefolder_case() function") + test_apply_imagefolder_case() + + logger.info("Running test_apply.py test_apply_flow_case(id) function") + test_apply_flow_case_0() + test_apply_flow_case_1() + test_apply_flow_case_2() + test_apply_flow_case_3() + + logger.info("Running test_apply.py test_apply_exception_case() function") + test_apply_exception_case() + diff --git a/tests/ut/python/dataset/test_generator.py b/tests/ut/python/dataset/test_generator.py index 07556d9c7f..c224c5a2ea 100644 --- a/tests/ut/python/dataset/test_generator.py +++ b/tests/ut/python/dataset/test_generator.py @@ -439,6 +439,74 @@ def test_case_error_4(): assert "Unexpected error. Result of a tensorOp doesn't match output column names" in str(info.value) +def test_sequential_sampler(): + source = [(np.array([x]),) for x in range(64)] + ds1 = ds.GeneratorDataset(source, ["data"], sampler=ds.SequentialSampler()) + i = 0 + for data in ds1.create_dict_iterator(): # each data is a dictionary + golden = np.array([i]) + assert np.array_equal(data["data"], golden) + i = i + 1 + + +def test_random_sampler(): + source = [(np.array([x]),) for x in range(64)] + ds1 = ds.GeneratorDataset(source, ["data"], shuffle = True) + for data in ds1.create_dict_iterator(): # each data is a dictionary + pass + + +def test_distributed_sampler(): + source = [(np.array([x]),) for x in range(64)] + for sid in range(8): + ds1 = ds.GeneratorDataset(source, ["data"], shuffle = False, num_shards=8, shard_id=sid) + i = sid + for data in ds1.create_dict_iterator(): # each data is a dictionary + golden = np.array([i]) + assert np.array_equal(data["data"], golden) + i = i + 8 + + +def test_num_samples(): + source = [(np.array([x]),) for x in range(64)] + num_samples = 32 + ds1 = ds.GeneratorDataset(source, ["data"], sampler=ds.SequentialSampler(), num_samples = num_samples) + ds2 = ds.GeneratorDataset(source, ["data"], sampler=[i for i in range(32)], num_samples = num_samples) + ds3 = ds.GeneratorDataset(generator_1d, ["data"], num_samples = num_samples) + + count = 0 + for _ in ds1.create_dict_iterator(): + count = count + 1 + assert count == num_samples + + count = 0 + for _ in ds2.create_dict_iterator(): + count = count + 1 + assert count == num_samples + + count = 0 + for _ in ds3.create_dict_iterator(): + count = count + 1 + assert count == num_samples + + +def test_num_samples_underflow(): + source = [(np.array([x]),) for x in range(64)] + num_samples = 256 + ds2 = ds.GeneratorDataset(source, ["data"], sampler=[i for i in range(64)], num_samples = num_samples) + ds3 = ds.GeneratorDataset(generator_1d, ["data"], num_samples = num_samples) + + count = 0 + for _ in ds2.create_dict_iterator(): + count = count + 1 + assert count == 64 + + count = 0 + for _ in ds3.create_dict_iterator(): + count = count + 1 + assert count == 64 + + if __name__ == "__main__": test_case_0() test_case_1() @@ -458,3 +526,6 @@ if __name__ == "__main__": test_case_error_2() test_case_error_3() test_case_error_4() + test_sequential_sampler() + test_distributed_sampler() + test_random_sampler() diff --git a/tests/ut/python/dataset/test_iterator.py b/tests/ut/python/dataset/test_iterator.py index d2518e1119..102fd0eea1 100644 --- a/tests/ut/python/dataset/test_iterator.py +++ b/tests/ut/python/dataset/test_iterator.py @@ -13,8 +13,10 @@ # limitations under the License. # ============================================================================== import numpy as np +import pytest import mindspore.dataset as ds +from mindspore.dataset.engine.iterators import ITERATORS_LIST, _cleanup DATA_DIR = ["../data/dataset/testTFTestAllTypes/test.data"] SCHEMA_DIR = "../data/dataset/testTFTestAllTypes/datasetSchema.json" @@ -41,3 +43,41 @@ def test_case_iterator(): check(COLUMNS[0:7]) check(COLUMNS[7:8]) check(COLUMNS[0:2:8]) + + +def test_iterator_weak_ref(): + ITERATORS_LIST.clear() + data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR) + itr1 = data.create_tuple_iterator() + itr2 = data.create_tuple_iterator() + itr3 = data.create_tuple_iterator() + + assert len(ITERATORS_LIST) == 3 + assert sum(itr() is not None for itr in ITERATORS_LIST) == 3 + + del itr1 + assert len(ITERATORS_LIST) == 3 + assert sum(itr() is not None for itr in ITERATORS_LIST) == 2 + + del itr2 + assert len(ITERATORS_LIST) == 3 + assert sum(itr() is not None for itr in ITERATORS_LIST) == 1 + + del itr3 + assert len(ITERATORS_LIST) == 3 + assert sum(itr() is not None for itr in ITERATORS_LIST) == 0 + + itr1 = data.create_tuple_iterator() + itr2 = data.create_tuple_iterator() + itr3 = data.create_tuple_iterator() + + _cleanup() + with pytest.raises(AttributeError) as info: + itr2.get_next() + assert "object has no attribute 'depipeline'" in str(info.value) + + del itr1 + assert len(ITERATORS_LIST) == 6 + assert sum(itr() is not None for itr in ITERATORS_LIST) == 2 + + _cleanup() diff --git a/tests/ut/python/dataset/test_minddataset_sampler.py b/tests/ut/python/dataset/test_minddataset_sampler.py new file mode 100644 index 0000000000..3cad3877ef --- /dev/null +++ b/tests/ut/python/dataset/test_minddataset_sampler.py @@ -0,0 +1,212 @@ +# Copyright 2019 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +""" +This is the test module for mindrecord +""" +import collections +import json +import os +import re +import string + +import mindspore.dataset.transforms.vision.c_transforms as vision +import numpy as np +import pytest +from mindspore.dataset.transforms.vision import Inter +from mindspore import log as logger + +import mindspore.dataset as ds +from mindspore.mindrecord import FileWriter + +FILES_NUM = 4 +CV_FILE_NAME = "../data/mindrecord/imagenet.mindrecord" +CV_DIR_NAME = "../data/mindrecord/testImageNetData" + + +@pytest.fixture +def add_and_remove_cv_file(): + """add/remove cv file""" + paths = ["{}{}".format(CV_FILE_NAME, str(x).rjust(1, '0')) + for x in range(FILES_NUM)] + for x in paths: + if os.path.exists("{}".format(x)): + os.remove("{}".format(x)) + if os.path.exists("{}.db".format(x)): + os.remove("{}.db".format(x)) + writer = FileWriter(CV_FILE_NAME, FILES_NUM) + data = get_data(CV_DIR_NAME) + cv_schema_json = {"id": {"type": "int32"}, + "file_name": {"type": "string"}, + "label": {"type": "int32"}, + "data": {"type": "bytes"}} + writer.add_schema(cv_schema_json, "img_schema") + writer.add_index(["file_name", "label"]) + writer.write_raw_data(data) + writer.commit() + yield "yield_cv_data" + for x in paths: + os.remove("{}".format(x)) + os.remove("{}.db".format(x)) + + +def test_cv_minddataset_subset_random_sample_basic(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [1, 2, 3, 5, 7] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + logger.info( + "-------------- cv reader basic: {} ------------------------".format(num_iter)) + logger.info( + "-------------- item[data]: {} -----------------------------".format(item["data"])) + logger.info( + "-------------- item[file_name]: {} ------------------------".format(item["file_name"])) + logger.info( + "-------------- item[label]: {} ----------------------------".format(item["label"])) + num_iter += 1 + assert num_iter == 5 + + +def test_cv_minddataset_subset_random_sample_replica(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [1, 2, 2, 5, 7, 9] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + logger.info( + "-------------- cv reader basic: {} ------------------------".format(num_iter)) + logger.info( + "-------------- item[data]: {} -----------------------------".format(item["data"])) + logger.info( + "-------------- item[file_name]: {} ------------------------".format(item["file_name"])) + logger.info( + "-------------- item[label]: {} ----------------------------".format(item["label"])) + num_iter += 1 + assert num_iter == 6 + + +def test_cv_minddataset_subset_random_sample_empty(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + logger.info( + "-------------- cv reader basic: {} ------------------------".format(num_iter)) + logger.info( + "-------------- item[data]: {} -----------------------------".format(item["data"])) + logger.info( + "-------------- item[file_name]: {} ------------------------".format(item["file_name"])) + logger.info( + "-------------- item[label]: {} ----------------------------".format(item["label"])) + num_iter += 1 + assert num_iter == 0 + + +def test_cv_minddataset_subset_random_sample_out_range(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [1, 2, 4, 11, 13] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + logger.info( + "-------------- cv reader basic: {} ------------------------".format(num_iter)) + logger.info( + "-------------- item[data]: {} -----------------------------".format(item["data"])) + logger.info( + "-------------- item[file_name]: {} ------------------------".format(item["file_name"])) + logger.info( + "-------------- item[label]: {} ----------------------------".format(item["label"])) + num_iter += 1 + assert num_iter == 5 + + +def test_cv_minddataset_subset_random_sample_negative(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [1, 2, 4, -1, -2] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + logger.info( + "-------------- cv reader basic: {} ------------------------".format(num_iter)) + logger.info( + "-------------- item[data]: {} -----------------------------".format(item["data"])) + logger.info( + "-------------- item[file_name]: {} ------------------------".format(item["file_name"])) + logger.info( + "-------------- item[label]: {} ----------------------------".format(item["label"])) + num_iter += 1 + assert num_iter == 5 + + +def get_data(dir_name): + """ + usage: get data from imagenet dataset + params: + dir_name: directory containing folder images and annotation information + + """ + if not os.path.isdir(dir_name): + raise IOError("Directory {} not exists".format(dir_name)) + img_dir = os.path.join(dir_name, "images") + ann_file = os.path.join(dir_name, "annotation.txt") + with open(ann_file, "r") as file_reader: + lines = file_reader.readlines() + + data_list = [] + for i, line in enumerate(lines): + try: + filename, label = line.split(",") + label = label.strip("\n") + with open(os.path.join(img_dir, filename), "rb") as file_reader: + img = file_reader.read() + data_json = {"id": i, + "file_name": filename, + "data": img, + "label": int(label)} + data_list.append(data_json) + except FileNotFoundError: + continue + return data_list diff --git a/tests/ut/python/dataset/test_repeat.py b/tests/ut/python/dataset/test_repeat.py index 196a62c315..cb7a80e3d1 100644 --- a/tests/ut/python/dataset/test_repeat.py +++ b/tests/ut/python/dataset/test_repeat.py @@ -16,6 +16,7 @@ import mindspore.dataset.transforms.vision.c_transforms as vision from util import save_and_check import mindspore.dataset as ds +import numpy as np from mindspore import log as logger DATA_DIR_TF = ["../data/dataset/testTFTestAllTypes/test.data"] @@ -95,6 +96,141 @@ def test_tf_repeat_03(): assert num_iter == 2 +def generator(): + for i in range(3): + yield np.array([i]), + + +def test_nested_repeat1(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(2) + data = data.repeat(3) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data]) == 2 * 3 * 3 + + +def test_nested_repeat2(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(1) + data = data.repeat(1) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data]) == 3 + + +def test_nested_repeat3(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(1) + data = data.repeat(2) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data]) == 2 * 3 + + +def test_nested_repeat4(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(2) + data = data.repeat(1) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data]) == 2 * 3 + + +def test_nested_repeat5(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.batch(3) + data = data.repeat(2) + data = data.repeat(3) + + for i, d in enumerate(data): + assert np.array_equal(d[0], np.asarray([[0], [1], [2]])) + + assert sum([1 for _ in data]) == 6 + + +def test_nested_repeat6(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(2) + data = data.batch(3) + data = data.repeat(3) + + for i, d in enumerate(data): + assert np.array_equal(d[0], np.asarray([[0], [1], [2]])) + + assert sum([1 for _ in data]) == 6 + + +def test_nested_repeat7(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(2) + data = data.repeat(3) + data = data.batch(3) + + for i, d in enumerate(data): + assert np.array_equal(d[0], np.asarray([[0], [1], [2]])) + + assert sum([1 for _ in data]) == 6 + + +def test_nested_repeat8(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.batch(2, drop_remainder=False) + data = data.repeat(2) + data = data.repeat(3) + + for i, d in enumerate(data): + if i % 2 == 0: + assert np.array_equal(d[0], np.asarray([[0], [1]])) + else: + assert np.array_equal(d[0], np.asarray([[2]])) + + assert sum([1 for _ in data]) == 6 * 2 + + +def test_nested_repeat9(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat() + data = data.repeat(3) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + if i == 10: + break + + +def test_nested_repeat10(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(3) + data = data.repeat() + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + if i == 10: + break + + +def test_nested_repeat11(): + data = ds.GeneratorDataset(generator, ["data"]) + data = data.repeat(2) + data = data.repeat(3) + data = data.repeat(4) + data = data.repeat(5) + + for i, d in enumerate(data): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data]) == 2 * 3 * 4 * 5 * 3 + + if __name__ == "__main__": logger.info("--------test tf repeat 01---------") # test_repeat_01() @@ -104,4 +240,3 @@ if __name__ == "__main__": logger.info("--------test tf repeat 03---------") test_tf_repeat_03() - diff --git a/tests/ut/python/dataset/test_sampler.py b/tests/ut/python/dataset/test_sampler.py index ca618311cb..7a58249f9c 100644 --- a/tests/ut/python/dataset/test_sampler.py +++ b/tests/ut/python/dataset/test_sampler.py @@ -87,7 +87,28 @@ def test_random_sampler_multi_iter(print_res=False): test_config(replacement=True, num_samples=5, num_repeats=5, validate=[0, 1, 2, 3, 4, 5]) +def test_sampler_py_api(): + sampler = ds.SequentialSampler().create() + sampler.set_num_rows(128) + sampler.set_num_samples(64) + sampler.initialize() + sampler.get_indices() + + sampler = ds.RandomSampler().create() + sampler.set_num_rows(128) + sampler.set_num_samples(64) + sampler.initialize() + sampler.get_indices() + + sampler = ds.DistributedSampler(8, 4).create() + sampler.set_num_rows(128) + sampler.set_num_samples(64) + sampler.initialize() + sampler.get_indices() + + if __name__ == '__main__': test_sequential_sampler(True) test_random_sampler(True) test_random_sampler_multi_iter(True) + test_sampler_py_api() diff --git a/tests/ut/python/dataset/test_serdes_dataset.py b/tests/ut/python/dataset/test_serdes_dataset.py index 2ef93dbcd6..7fdb0f1dde 100644 --- a/tests/ut/python/dataset/test_serdes_dataset.py +++ b/tests/ut/python/dataset/test_serdes_dataset.py @@ -19,7 +19,7 @@ import filecmp import glob import json import os - +import pytest import numpy as np import mindspore.dataset as ds @@ -28,7 +28,6 @@ import mindspore.dataset.transforms.vision.c_transforms as vision from mindspore.dataset.transforms.vision import Inter from mindspore import log as logger - def test_imagefolder(remove_json_files=True): """ Test simulating resnet50 dataset pipeline. @@ -217,6 +216,38 @@ def delete_json_files(): except IOError: logger.info("Error while deleting: {}".format(f)) +# Test save load minddataset +from test_minddataset_sampler import add_and_remove_cv_file, get_data, CV_DIR_NAME, CV_FILE_NAME, FILES_NUM, \ + FileWriter, Inter + +def test_minddataset(add_and_remove_cv_file): + """tutorial for cv minderdataset.""" + columns_list = ["data", "file_name", "label"] + num_readers = 4 + indices = [1, 2, 3, 5, 7] + sampler = ds.SubsetRandomSampler(indices) + data_set = ds.MindDataset(CV_FILE_NAME + "0", columns_list, num_readers, + sampler=sampler) + + # Serializing into python dictionary + ds1_dict = ds.serialize(data_set) + # Serializing into json object + ds1_json = json.dumps(ds1_dict, sort_keys=True) + + # Reconstruct dataset pipeline from its serialized form + data_set = ds.deserialize(input_dict=ds1_dict) + ds2_dict = ds.serialize(data_set) + # Serializing into json object + ds2_json = json.dumps(ds2_dict, sort_keys=True) + + assert ds1_json == ds2_json + + data = get_data(CV_DIR_NAME) + assert data_set.get_dataset_size() == 10 + num_iter = 0 + for item in data_set.create_dict_iterator(): + num_iter += 1 + assert num_iter == 5 if __name__ == '__main__': diff --git a/tests/ut/python/dataset/test_skip.py b/tests/ut/python/dataset/test_skip.py new file mode 100644 index 0000000000..bea7db4e05 --- /dev/null +++ b/tests/ut/python/dataset/test_skip.py @@ -0,0 +1,130 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +import numpy as np + +import mindspore.dataset.transforms.vision.c_transforms as vision +import mindspore.dataset as ds +from mindspore import log as logger + +DATA_DIR_TF2 = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"] +SCHEMA_DIR_TF2 = "../data/dataset/test_tf_file_3_images/datasetSchema.json" + +def test_tf_skip(): + data1 = ds.TFRecordDataset(DATA_DIR_TF2, SCHEMA_DIR_TF2, shuffle=False) + + resize_height, resize_width = 32, 32 + decode_op = vision.Decode() + resize_op = vision.Resize((resize_height, resize_width), interpolation=ds.transforms.vision.Inter.LINEAR) + data1 = data1.map(input_columns=["image"], operations=decode_op) + data1 = data1.map(input_columns=["image"], operations=resize_op) + data1 = data1.skip(2) + + num_iter = 0 + for item in data1.create_dict_iterator(): + num_iter += 1 + assert num_iter == 1 + +def generator_md(): + # Create a dataset with [0, 1, 2, 3, 4] + for i in range(5): + yield (np.array([i]), ) + +def test_generator_skip(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [3, 4] + ds1 = ds1.skip(3) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 2 + +def test_skip_1(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [] + ds1 = ds1.skip(7) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 0 + +def test_skip_2(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [0, 1, 2, 3, 4] + ds1 = ds1.skip(0) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 5 + +def test_skip_repeat_1(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] + ds1 = ds1.repeat(2) + + # Here ds1 should be [3, 4, 0, 1, 2, 3, 4] + ds1 = ds1.skip(3) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 7 + +def test_skip_repeat_2(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [3, 4] + ds1 = ds1.skip(3) + + # Here ds1 should be [3, 4, 3, 4] + ds1 = ds1.repeat(2) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 4 + +def test_skip_repeat_3(): + ds1 = ds.GeneratorDataset(generator_md, ["data"]) + + # Here ds1 should be [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] + ds1 = ds1.repeat(2) + + # Here ds1 should be [3, 4] + ds1 = ds1.skip(8) + + # Here ds1 should be [3, 4, 3, 4, 3, 4] + ds1 = ds1.repeat(3) + + buf = [] + for data in ds1: + buf.append(data[0][0]) + assert len(buf) == 6 + +if __name__ == "__main__": + test_tf_skip() + test_generator_skip() + test_skip_1() + test_skip_2() + test_skip_repeat_1() + test_skip_repeat_2() + test_skip_repeat_3() \ No newline at end of file diff --git a/tests/ut/python/dataset/test_take.py b/tests/ut/python/dataset/test_take.py new file mode 100644 index 0000000000..ed71f67e26 --- /dev/null +++ b/tests/ut/python/dataset/test_take.py @@ -0,0 +1,317 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +import mindspore.dataset as ds +import mindspore.dataset.transforms.vision.c_transforms as vision +from mindspore import log as logger +import numpy as np + + +# In generator dataset: Number of rows is 3, its value is 0, 1, 2 +def generator(): + for i in range(3): + yield np.array([i]), + + +# In generator dataset: Number of rows is 10, its value is 0, 1, 2 ... 10 +def generator_10(): + for i in range(10): + yield np.array([i]), + + +def test_take_01(): + """ + Test take: origin there are 3 row, and take 1 row, in this case: will not meet eoe and eof + """ + logger.info("test_take_01") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(1) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert 0 == d[0][0] + + assert sum([1 for _ in data1]) == 2 + + +def test_take_02(): + """ + Test take: origin there are 3 row, and take 2 row, in this case: will meet eoe + """ + logger.info("test_take_02") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(2) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 2 == d[0][0] + + assert sum([1 for _ in data1]) == 4 + + +def test_take_03(): + """ + Test take: origin there are 3 row, and take 3 row, in this case: will meet eoe and eof + """ + logger.info("test_take_03") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(3) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data1]) == 6 + + +def test_take_04(): + """ + Test take: origin there are 3 row, and take 4 row, this is more than the total rows + """ + logger.info("test_take_04") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(4) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data1]) == 6 + + +def test_take_05(): + """ + Test take: there is no repeat op + """ + logger.info("test_take_05") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i == d[0][0] + + assert sum([1 for _ in data1]) == 2 + + +def test_take_06(): + """ + Test take: repeat is before take + """ + logger.info("test_take_06") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.repeat(2) + data1 = data1.take(4) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data1]) == 4 + + +def test_take_07(): + """ + Test take: take is before batch, that mean take(N), N refer to rows num + """ + logger.info("test_take_07") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(2) + data1 = data1.batch(2) + assert sum([1 for _ in data1]) == 1 + + +def test_take_08(): + """ + Test take: take is after batch, that mean take(N), N refer to batches num + """ + logger.info("test_take_08") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.batch(2) + data1 = data1.take(2) + assert sum([1 for _ in data1]) == 2 + + +def test_take_09(): + """ + Test take: repeat count is -1, and read the whole dataset, take after repeat + """ + logger.info("test_take_09") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.repeat(2) + data1 = data1.take(-1) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data1]) == 6 + + +def test_take_10(): + """ + Test take: repeat count is -1, and read the whole dataset, take before repeat + """ + logger.info("test_take_10") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(-1) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert i % 3 == d[0][0] + + assert sum([1 for _ in data1]) == 6 + + +def test_take_11(): + """ + Test take: batch first, then do repeat and take operation + """ + logger.info("test_take_11") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.batch(2) + data1 = data1.repeat(2) + data1 = data1.take(-1) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert 2 * (i % 2) == d[0][0] + + assert sum([1 for _ in data1]) == 4 + + +def test_take_12(): + """ + Test take: take first, then do batch and repeat operation + """ + logger.info("test_take_12") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(2) + data1 = data1.batch(2) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert 0 == d[0][0] + + assert sum([1 for _ in data1]) == 2 + + +def test_take_13(): + """ + Test take: skip first, then do take, batch and repeat operation + """ + logger.info("test_take_13") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.skip(2) + data1 = data1.take(-1) + data1 = data1.batch(2) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert 2 == d[0][0] + + assert sum([1 for _ in data1]) == 2 + + +def test_take_14(): + """ + Test take: take first, then do batch, skip and repeat operation + """ + logger.info("test_take_14") + data1 = ds.GeneratorDataset(generator, ["data"]) + + data1 = data1.take(-1) + data1 = data1.batch(2) + data1 = data1.skip(1) + data1 = data1.repeat(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert 2 == d[0][0] + + assert sum([1 for _ in data1]) == 2 + + +def test_take_15(): + """ + Test take: large amount data, take a part, then do skip operation + """ + logger.info("test_take_15") + data1 = ds.GeneratorDataset(generator_10, ["data"]) + + data1 = data1.take(6) + data1 = data1.skip(2) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert (i + 2) == d[0][0] + + assert sum([1 for _ in data1]) == 4 + + +def test_take_16(): + """ + Test take: large amount data, skip a part, then do take operation + """ + logger.info("test_take_16") + data1 = ds.GeneratorDataset(generator_10, ["data"]) + + data1 = data1.skip(3) + data1 = data1.take(5) + + # Here i refers to index, d refers to data element + for i, d in enumerate(data1): + assert (i + 3) == d[0][0] + + assert sum([1 for _ in data1]) == 5 + + +if __name__ == '__main__': + test_take_01() + test_take_02() + test_take_03() + test_take_04() + test_take_05() + test_take_06() + test_take_07() + test_take_08() + test_take_09() + test_take_10() + test_take_11() + test_take_12() + test_take_13() + test_take_14() + test_take_15() + test_take_16() + logger.info('== test take operation finished ==') \ No newline at end of file diff --git a/tests/ut/python/ir/test_tensor.py b/tests/ut/python/ir/test_tensor.py index 1757567db5..b7bf1bebf5 100644 --- a/tests/ut/python/ir/test_tensor.py +++ b/tests/ut/python/ir/test_tensor.py @@ -24,6 +24,7 @@ import pytest import mindspore as ms import mindspore.common.api as me import mindspore.nn as nn +from mindspore import Tensor from mindspore.common.parameter import Parameter from mindspore.common.initializer import initializer from ..ut_filter import non_graph_engine @@ -396,3 +397,24 @@ def test_tensor_dtype_fp32_to_bool(): input = ms.Tensor(input) input_me = ms.Tensor(input, dtype=ms.bool_) + +def test_tensor_operation(): + x = Tensor(np.ones((3,3)) * 4) + res = x + 1 + assert np.all(res.asnumpy() == np.ones((3, 3)) * 5) + res = 1 + x + assert np.all(res.asnumpy() == np.ones((3, 3)) * 5) + res = x - 2 + assert np.all(res.asnumpy() == np.ones((3, 3)) * 2) + res = 6 - x + assert np.all(res.asnumpy() == np.ones((3, 3)) * 2) + res = x * 3 + assert np.all(res.asnumpy() == np.ones((3, 3)) * 12) + res = 3 * x + assert np.all(res.asnumpy() == np.ones((3, 3)) * 12) + res = x / 2 + assert np.all(res.asnumpy() == np.ones((3, 3)) * 2) + res = 8 / x + assert np.all(res.asnumpy() == np.ones((3, 3)) * 2) + with pytest.raises(TypeError): + res = x * (2, 3) diff --git a/tests/ut/python/mindrecord/test_mindrecord_base.py b/tests/ut/python/mindrecord/test_mindrecord_base.py index 7fdf1f0f94..93e5c609f7 100644 --- a/tests/ut/python/mindrecord/test_mindrecord_base.py +++ b/tests/ut/python/mindrecord/test_mindrecord_base.py @@ -13,6 +13,7 @@ # limitations under the License. # ============================================================================ """test mindrecord base""" +import numpy as np import os import uuid from mindspore.mindrecord import FileWriter, FileReader, MindPage, SUCCESS @@ -25,6 +26,105 @@ CV2_FILE_NAME = "./imagenet_loop.mindrecord" CV3_FILE_NAME = "./imagenet_append.mindrecord" NLP_FILE_NAME = "./aclImdb.mindrecord" +def test_write_read_process(): + mindrecord_file_name = "test.mindrecord" + data = [{"file_name": "001.jpg", "label": 43, "score": 0.8, "mask": np.array([3, 6, 9], dtype=np.int64), + "segments": np.array([[5.0, 1.6], [65.2, 8.3]], dtype=np.float32), + "data": bytes("image bytes abc", encoding='UTF-8')}, + {"file_name": "002.jpg", "label": 91, "score": 5.4, "mask": np.array([1, 4, 7], dtype=np.int64), + "segments": np.array([[5.1, 9.1], [2.0, 65.4]], dtype=np.float32), + "data": bytes("image bytes def", encoding='UTF-8')}, + {"file_name": "003.jpg", "label": 61, "score": 6.4, "mask": np.array([7, 6, 3], dtype=np.int64), + "segments": np.array([[0.0, 5.6], [3.0, 16.3]], dtype=np.float32), + "data": bytes("image bytes ghi", encoding='UTF-8')}, + {"file_name": "004.jpg", "label": 29, "score": 8.1, "mask": np.array([2, 8, 0], dtype=np.int64), + "segments": np.array([[5.9, 7.2], [4.0, 89.0]], dtype=np.float32), + "data": bytes("image bytes jkl", encoding='UTF-8')}, + {"file_name": "005.jpg", "label": 78, "score": 7.7, "mask": np.array([3, 1, 2], dtype=np.int64), + "segments": np.array([[0.6, 8.1], [5.3, 49.3]], dtype=np.float32), + "data": bytes("image bytes mno", encoding='UTF-8')}, + {"file_name": "006.jpg", "label": 37, "score": 9.4, "mask": np.array([7, 6, 7], dtype=np.int64), + "segments": np.array([[4.2, 6.3], [8.9, 81.8]], dtype=np.float32), + "data": bytes("image bytes pqr", encoding='UTF-8')} + ] + writer = FileWriter(mindrecord_file_name) + schema = {"file_name": {"type": "string"}, + "label": {"type": "int32"}, + "score": {"type": "float64"}, + "mask": {"type": "int64", "shape": [-1]}, + "segments": {"type": "float32", "shape": [2, 2]}, + "data": {"type": "bytes"}} + writer.add_schema(schema, "data is so cool") + writer.write_raw_data(data) + writer.commit() + + reader = FileReader(mindrecord_file_name) + count = 0 + for index, x in enumerate(reader.get_next()): + assert len(x) == 6 + for field in x: + if isinstance(x[field], np.ndarray): + assert (x[field] == data[count][field]).all() + else: + assert x[field] == data[count][field] + count = count + 1 + logger.info("#item{}: {}".format(index, x)) + assert count == 6 + reader.close() + + os.remove("{}".format(mindrecord_file_name)) + os.remove("{}.db".format(mindrecord_file_name)) + +def test_write_read_process_with_define_index_field(): + mindrecord_file_name = "test.mindrecord" + data = [{"file_name": "001.jpg", "label": 43, "score": 0.8, "mask": np.array([3, 6, 9], dtype=np.int64), + "segments": np.array([[5.0, 1.6], [65.2, 8.3]], dtype=np.float32), + "data": bytes("image bytes abc", encoding='UTF-8')}, + {"file_name": "002.jpg", "label": 91, "score": 5.4, "mask": np.array([1, 4, 7], dtype=np.int64), + "segments": np.array([[5.1, 9.1], [2.0, 65.4]], dtype=np.float32), + "data": bytes("image bytes def", encoding='UTF-8')}, + {"file_name": "003.jpg", "label": 61, "score": 6.4, "mask": np.array([7, 6, 3], dtype=np.int64), + "segments": np.array([[0.0, 5.6], [3.0, 16.3]], dtype=np.float32), + "data": bytes("image bytes ghi", encoding='UTF-8')}, + {"file_name": "004.jpg", "label": 29, "score": 8.1, "mask": np.array([2, 8, 0], dtype=np.int64), + "segments": np.array([[5.9, 7.2], [4.0, 89.0]], dtype=np.float32), + "data": bytes("image bytes jkl", encoding='UTF-8')}, + {"file_name": "005.jpg", "label": 78, "score": 7.7, "mask": np.array([3, 1, 2], dtype=np.int64), + "segments": np.array([[0.6, 8.1], [5.3, 49.3]], dtype=np.float32), + "data": bytes("image bytes mno", encoding='UTF-8')}, + {"file_name": "006.jpg", "label": 37, "score": 9.4, "mask": np.array([7, 6, 7], dtype=np.int64), + "segments": np.array([[4.2, 6.3], [8.9, 81.8]], dtype=np.float32), + "data": bytes("image bytes pqr", encoding='UTF-8')} + ] + writer = FileWriter(mindrecord_file_name) + schema = {"file_name": {"type": "string"}, + "label": {"type": "int32"}, + "score": {"type": "float64"}, + "mask": {"type": "int64", "shape": [-1]}, + "segments": {"type": "float32", "shape": [2, 2]}, + "data": {"type": "bytes"}} + writer.add_schema(schema, "data is so cool") + writer.add_index(["label"]) + writer.write_raw_data(data) + writer.commit() + + reader = FileReader(mindrecord_file_name) + count = 0 + for index, x in enumerate(reader.get_next()): + assert len(x) == 6 + for field in x: + if isinstance(x[field], np.ndarray): + assert (x[field] == data[count][field]).all() + else: + assert x[field] == data[count][field] + count = count + 1 + logger.info("#item{}: {}".format(index, x)) + assert count == 6 + reader.close() + + os.remove("{}".format(mindrecord_file_name)) + os.remove("{}.db".format(mindrecord_file_name)) + def test_cv_file_writer_tutorial(): """tutorial for cv dataset writer.""" writer = FileWriter(CV_FILE_NAME, FILES_NUM) @@ -137,6 +237,51 @@ def test_cv_page_reader_tutorial(): assert len(row1[0]) == 3 assert row1[0]['label'] == 822 +def test_cv_page_reader_tutorial_by_file_name(): + """tutorial for cv page reader.""" + reader = MindPage(CV_FILE_NAME + "0") + fields = reader.get_category_fields() + assert fields == ['file_name', 'label'],\ + 'failed on getting candidate category fields.' + + ret = reader.set_category_field("file_name") + assert ret == SUCCESS, 'failed on setting category field.' + + info = reader.read_category_info() + logger.info("category info: {}".format(info)) + + row = reader.read_at_page_by_id(0, 0, 1) + assert len(row) == 1 + assert len(row[0]) == 3 + assert row[0]['label'] == 490 + + row1 = reader.read_at_page_by_name("image_00007.jpg", 0, 1) + assert len(row1) == 1 + assert len(row1[0]) == 3 + assert row1[0]['label'] == 13 + +def test_cv_page_reader_tutorial_new_api(): + """tutorial for cv page reader.""" + reader = MindPage(CV_FILE_NAME + "0") + fields = reader.candidate_fields + assert fields == ['file_name', 'label'],\ + 'failed on getting candidate category fields.' + + reader.category_field = "file_name" + + info = reader.read_category_info() + logger.info("category info: {}".format(info)) + + row = reader.read_at_page_by_id(0, 0, 1) + assert len(row) == 1 + assert len(row[0]) == 3 + assert row[0]['label'] == 490 + + row1 = reader.read_at_page_by_name("image_00007.jpg", 0, 1) + assert len(row1) == 1 + assert len(row1[0]) == 3 + assert row1[0]['label'] == 13 + paths = ["{}{}".format(CV_FILE_NAME, str(x).rjust(1, '0')) for x in range(FILES_NUM)] for x in paths: diff --git a/tests/ut/python/mindrecord/test_mindrecord_exception.py b/tests/ut/python/mindrecord/test_mindrecord_exception.py index 1f7a3f859d..75a32eb347 100644 --- a/tests/ut/python/mindrecord/test_mindrecord_exception.py +++ b/tests/ut/python/mindrecord/test_mindrecord_exception.py @@ -15,8 +15,9 @@ """test mindrecord exception""" import os import pytest -from mindspore.mindrecord import FileWriter, FileReader, MindPage -from mindspore.mindrecord import MRMOpenError, MRMGenerateIndexError, ParamValueError, MRMGetMetaError +from mindspore.mindrecord import FileWriter, FileReader, MindPage, SUCCESS +from mindspore.mindrecord import MRMOpenError, MRMGenerateIndexError, ParamValueError, MRMGetMetaError, \ + MRMFetchDataError from mindspore import log as logger from utils import get_data @@ -286,3 +287,67 @@ def test_add_index_without_add_schema(): fw = FileWriter(CV_FILE_NAME) fw.add_index(["label"]) assert 'Failed to get meta info' in str(err.value) + +def test_mindpage_pageno_pagesize_not_int(): + """test page reader when some partition does not exist.""" + create_cv_mindrecord(4) + reader = MindPage(CV_FILE_NAME + "0") + fields = reader.get_category_fields() + assert fields == ['file_name', 'label'],\ + 'failed on getting candidate category fields.' + + ret = reader.set_category_field("label") + assert ret == SUCCESS, 'failed on setting category field.' + + info = reader.read_category_info() + logger.info("category info: {}".format(info)) + + with pytest.raises(ParamValueError) as err: + reader.read_at_page_by_id(0, "0", 1) + + with pytest.raises(ParamValueError) as err: + reader.read_at_page_by_id(0, 0, "b") + + with pytest.raises(ParamValueError) as err: + reader.read_at_page_by_name("822", "e", 1) + + with pytest.raises(ParamValueError) as err: + reader.read_at_page_by_name("822", 0, "qwer") + + with pytest.raises(MRMFetchDataError, match="Failed to fetch data by category."): + reader.read_at_page_by_id(99999, 0, 1) + + paths = ["{}{}".format(CV_FILE_NAME, str(x).rjust(1, '0')) + for x in range(FILES_NUM)] + for x in paths: + os.remove("{}".format(x)) + os.remove("{}.db".format(x)) + +def test_mindpage_filename_not_exist(): + """test page reader when some partition does not exist.""" + create_cv_mindrecord(4) + reader = MindPage(CV_FILE_NAME + "0") + fields = reader.get_category_fields() + assert fields == ['file_name', 'label'],\ + 'failed on getting candidate category fields.' + + ret = reader.set_category_field("file_name") + assert ret == SUCCESS, 'failed on setting category field.' + + info = reader.read_category_info() + logger.info("category info: {}".format(info)) + + with pytest.raises(MRMFetchDataError) as err: + reader.read_at_page_by_id(9999, 0, 1) + + with pytest.raises(MRMFetchDataError) as err: + reader.read_at_page_by_name("abc.jpg", 0, 1) + + with pytest.raises(ParamValueError) as err: + reader.read_at_page_by_name(1, 0, 1) + + paths = ["{}{}".format(CV_FILE_NAME, str(x).rjust(1, '0')) + for x in range(FILES_NUM)] + for x in paths: + os.remove("{}".format(x)) + os.remove("{}.db".format(x)) diff --git a/tests/ut/python/nn/optim/test_optimizer.py b/tests/ut/python/nn/optim/test_optimizer.py index 860d751fd5..89fb1d812b 100644 --- a/tests/ut/python/nn/optim/test_optimizer.py +++ b/tests/ut/python/nn/optim/test_optimizer.py @@ -15,17 +15,11 @@ """ test optimizer """ import numpy as np import pytest -from mindspore.nn.optim import Optimizer, SGD, Adam, AdamWeightDecay, AdamWeightDecayDynamicLR from mindspore import Tensor +from mindspore.nn.optim import Optimizer, SGD, Adam, AdamWeightDecay, AdamWeightDecayDynamicLR from mindspore.common.parameter import Parameter -gradient = Tensor(np.zeros([1, 2, 3])) -accumulation = gradient -variable = accumulation - - -paramsTensor = Tensor(np.zeros([1, 2, 3])) class IterableObjc: def __iter__(self): cont = 0 @@ -56,6 +50,7 @@ class TestAdam(): def test_construct(self): with pytest.raises(TypeError): + gradient = Tensor(np.zeros([1, 2, 3])) adam = Adam(params, learning_rate=1e-3, beta1=0.9, beta2=0.999, eps=1e-8, use_locking=False, use_nesterov=False, weight_decay=0.0, loss_scale=1.0) adam.construct(gradient) @@ -105,4 +100,5 @@ class TestUnsupportParam(): def test_Sgd_init(self): with pytest.raises(TypeError): + paramsTensor = Tensor(np.zeros([1, 2, 3])) SGD(paramsTensor) diff --git a/tests/ut/python/nn/test_batchnorm.py b/tests/ut/python/nn/test_batchnorm.py index eaafdd81b4..e73b7ebbf0 100644 --- a/tests/ut/python/nn/test_batchnorm.py +++ b/tests/ut/python/nn/test_batchnorm.py @@ -56,3 +56,17 @@ def test_compile(): net = Net() input_data = Tensor(np.random.randint(0, 255, [1, 3, 224, 224]).astype(np.float32)) _executor.compile(net, input_data) + + +class GroupNet(nn.Cell): + def __init__(self): + super(GroupNet, self).__init__() + self.group_bn = nn.GroupNorm() + def construct(self, x): + return self.group_bn(x) + + +def test_compile_groupnorm(): + net = nn.GroupNorm(16, 64) + input_data = Tensor(np.random.rand(1,64,256,256).astype(np.float32)) + _executor.compile(net, input_data) diff --git a/tests/ut/python/nn/test_dense.py b/tests/ut/python/nn/test_dense.py index 8581576c6b..0845983bb0 100644 --- a/tests/ut/python/nn/test_dense.py +++ b/tests/ut/python/nn/test_dense.py @@ -27,11 +27,6 @@ def test_dense_none(): nn.Dense(3, 2, None, None) -def test_dense_invalid_activation(): - with pytest.raises(KeyError): - nn.Dense(3, 2, activation='relu6') - - @non_graph_engine def test_dense_str_activation(): dense = nn.Dense(1, 1, activation='relu') diff --git a/tests/ut/python/nn/test_dynamic_lr.py b/tests/ut/python/nn/test_dynamic_lr.py new file mode 100644 index 0000000000..cb959956d6 --- /dev/null +++ b/tests/ut/python/nn/test_dynamic_lr.py @@ -0,0 +1,234 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +""" Test Dynamic Learning Rate """ +import pytest +import mindspore +from mindspore.nn import dynamic_lr as dr + +milestone = [10, 20, 30] +learning_rates = [0.1, 0.05, 0.01] +learning_rate = 0.1 +end_learning_rate = 0.01 +decay_rate = 0.9 +total_step = 30 +step_per_epoch = 3 +decay_epoch = 2 +min_lr = 0.01 +max_lr = 0.1 +power = 0.5 + +class TestInputs: + def test_milestone1(self): + milestone1 = 1 + with pytest.raises(ValueError): + dr.piecewise_constant_lr(milestone1, learning_rates) + + def test_milestone2(self): + milestone1 = [20, 10, 1] + with pytest.raises(ValueError): + dr.piecewise_constant_lr(milestone1, learning_rates) + + milestone2 = [1.0, 2.0, True] + with pytest.raises(ValueError): + dr.piecewise_constant_lr(milestone2, learning_rates) + + def test_learning_rates1(self): + lr = True + with pytest.raises(ValueError): + dr.piecewise_constant_lr(milestone, lr) + + def test_learning_rates2(self): + lr = [1, 2, 1] + with pytest.raises(ValueError): + dr.piecewise_constant_lr(milestone, lr) + + def test_learning_rate_type(self): + lr = True + with pytest.raises(TypeError): + dr.exponential_decay_lr(lr, decay_rate, total_step, step_per_epoch, decay_epoch) + + with pytest.raises(TypeError): + dr.polynomial_decay_lr(lr, end_learning_rate, total_step, step_per_epoch, decay_epoch, power) + + def test_learning_rate_value(self): + lr = -1.0 + with pytest.raises(ValueError): + dr.exponential_decay_lr(lr, decay_rate, total_step, step_per_epoch, decay_epoch) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(lr, end_learning_rate, total_step, step_per_epoch, decay_epoch, power) + + def test_end_learning_rate_type(self): + lr = True + with pytest.raises(TypeError): + dr.polynomial_decay_lr(learning_rate, lr, total_step, step_per_epoch, decay_epoch, power) + + def test_end_learning_rate_value(self): + lr = -1.0 + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, lr, total_step, step_per_epoch, decay_epoch, power) + + def test_decay_rate_type(self): + rate = 'a' + with pytest.raises(TypeError): + dr.exponential_decay_lr(learning_rate, rate, total_step, step_per_epoch, decay_epoch) + + def test_decay_rate_value(self): + rate = -1.0 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, rate, total_step, step_per_epoch, decay_epoch) + + def test_total_step1(self): + total_step1 = 2.0 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step1, step_per_epoch, decay_epoch) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step1, step_per_epoch, decay_epoch) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step1, step_per_epoch, decay_epoch, power) + + def test_total_step2(self): + total_step1 = -1 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step1, step_per_epoch, decay_epoch) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step1, step_per_epoch, decay_epoch) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step1, step_per_epoch, decay_epoch, power) + + def test_step_per_epoch1(self): + step_per_epoch1 = True + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch1, decay_epoch) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch1, decay_epoch) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch1, decay_epoch, power) + + def test_step_per_epoch2(self): + step_per_epoch1 = -1 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch1, decay_epoch) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch1, decay_epoch) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch1, decay_epoch, power) + + def test_decay_epoch1(self): + decay_epoch1 = 'm' + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch1) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch, decay_epoch1) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch1, power) + + def test_decay_epoch2(self): + decay_epoch1 = -1 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch1) + + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch, decay_epoch1) + + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch1, power) + + def test_is_stair(self): + is_stair = 1 + with pytest.raises(ValueError): + dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, is_stair) + + def test_min_lr_type(self): + min_lr1 = True + with pytest.raises(TypeError): + dr.cosine_decay_lr(min_lr1, max_lr, total_step, step_per_epoch, decay_epoch) + + def test_min_lr_value(self): + min_lr1 = -1.0 + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr1, max_lr, total_step, step_per_epoch, decay_epoch) + + def test_max_lr_type(self): + max_lr1 = 'a' + with pytest.raises(TypeError): + dr.cosine_decay_lr(min_lr, max_lr1, total_step, step_per_epoch, decay_epoch) + + def test_max_lr_value(self): + max_lr1 = -1.0 + with pytest.raises(ValueError): + dr.cosine_decay_lr(min_lr, max_lr1, total_step, step_per_epoch, decay_epoch) + + def test_power(self): + power1 = True + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, power1) + + def test_update_decay_epoch(self): + update_decay_epoch = 1 + with pytest.raises(ValueError): + dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, + power, update_decay_epoch) + + +def test_learning_rate(): + lr = dr.piecewise_constant_lr(milestone, learning_rates) + assert len(lr) == milestone[-1] + + +def test_exponential_decay(): + lr1 = dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch) + assert len(lr1) == total_step + + lr2 = dr.exponential_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, True) + assert len(lr2) == total_step + + +def test_enatural_exp_decay(): + lr1 = dr.natural_exp_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch) + assert len(lr1) == total_step + + lr2 = dr.natural_exp_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, True) + assert len(lr2) == total_step + + +def test_inverse_decay(): + lr1 = dr.inverse_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch) + assert len(lr1) == total_step + + lr2 = dr.inverse_decay_lr(learning_rate, decay_rate, total_step, step_per_epoch, decay_epoch, True) + assert len(lr2) == total_step + + +def test_cosine_decay(): + lr = dr.cosine_decay_lr(min_lr, max_lr, total_step, step_per_epoch, decay_epoch) + assert len(lr) == total_step + +def test_polynomial_decay(): + lr1 = dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, power) + assert len(lr1) == total_step + lr2 = dr.polynomial_decay_lr(learning_rate, end_learning_rate, total_step, step_per_epoch, decay_epoch, power, + True) + assert len(lr2) == total_step diff --git a/tests/ut/python/nn/test_image_gradients.py b/tests/ut/python/nn/test_image_gradients.py index f65f38ec0a..a2b9495443 100644 --- a/tests/ut/python/nn/test_image_gradients.py +++ b/tests/ut/python/nn/test_image_gradients.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ -""" test loss """ +""" test image gradients """ import numpy as np import mindspore.nn as nn import mindspore.context as context diff --git a/tests/ut/python/nn/test_nn_pad.py b/tests/ut/python/nn/test_nn_pad.py new file mode 100644 index 0000000000..a8b66bae5c --- /dev/null +++ b/tests/ut/python/nn/test_nn_pad.py @@ -0,0 +1,64 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +""" test nn pad """ +from mindspore import Tensor +from mindspore.ops import operations as P +import mindspore.nn as nn +from mindspore.ops.composite import GradOperation +from mindspore.common.api import ms_function +import numpy as np +import mindspore.context as context + + +class Net(nn.Cell): + def __init__(self, raw_paddings, mode): + super(Net, self).__init__() + self.pad = nn.Pad(raw_paddings, mode=mode) + + @ms_function + def construct(self, x): + return self.pad(x) + + +class Grad(nn.Cell): + def __init__(self, network): + super(Grad, self).__init__() + self.grad = GradOperation(name="get_all", get_all=True, sens_param=True) + self.network = network + + @ms_function + def construct(self, x, grads): + return self.grad(self.network)(x, grads) + + +def test_pad_train(): + mode = 'CONSTANT' + x = np.random.random(size=(2, 3)).astype(np.float32) + raw_paddings = ((1, 1), (2, 2)) + grads = np.random.random(size=(4, 7)).astype(np.float32) + grad = Grad(Net(raw_paddings, mode)) + output = grad(Tensor(x), Tensor(grads)) + print("=================output====================") + print(output) + + +def test_pad_infer(): + mode = 'CONSTANT' + x = np.random.random(size=(2, 3)).astype(np.float32) + raw_paddings = ((1, 1), (2, 2)) + net = Net(raw_paddings, mode) + output = net(Tensor(x)) + print("=================output====================") + print(output) diff --git a/tests/ut/python/nn/test_psnr.py b/tests/ut/python/nn/test_psnr.py new file mode 100644 index 0000000000..5a908b308d --- /dev/null +++ b/tests/ut/python/nn/test_psnr.py @@ -0,0 +1,61 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +""" +test psnr +""" +import numpy as np +import pytest +import mindspore.nn as nn +from mindspore.common.api import _executor +from mindspore import Tensor + + +class PSNRNet(nn.Cell): + def __init__(self, max_val=1.0): + super(PSNRNet, self).__init__() + self.net = nn.PSNR(max_val) + + def construct(self, img1, img2): + return self.net(img1, img2) + + +def test_compile_psnr(): + max_val = 1.0 + net = PSNRNet(max_val) + img1 = Tensor(np.random.random((8, 3, 16, 16))) + img2 = Tensor(np.random.random((8, 3, 16, 16))) + _executor.compile(net, img1, img2) + +def test_compile_psnr_grayscale(): + max_val = 255 + net = PSNRNet(max_val) + img1 = Tensor(np.random.randint(0, 256, (8, 1, 16, 16), np.uint8)) + img2 = Tensor(np.random.randint(0, 256, (8, 1, 16, 16), np.uint8)) + _executor.compile(net, img1, img2) + +def test_psnr_max_val_negative(): + max_val = -1 + with pytest.raises(ValueError): + net = PSNRNet(max_val) + +def test_psnr_max_val_bool(): + max_val = True + with pytest.raises(ValueError): + net = PSNRNet(max_val) + +def test_psnr_max_val_zero(): + max_val = 0 + with pytest.raises(ValueError): + net = PSNRNet(max_val) diff --git a/tests/ut/python/nn/test_ssim.py b/tests/ut/python/nn/test_ssim.py new file mode 100644 index 0000000000..a698b59f69 --- /dev/null +++ b/tests/ut/python/nn/test_ssim.py @@ -0,0 +1,95 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +""" +test ssim +""" +import numpy as np +import pytest +import mindspore.nn as nn +from mindspore.common.api import _executor +from mindspore import Tensor + + +class SSIMNet(nn.Cell): + def __init__(self, max_val=1.0, filter_size=11, filter_sigma=1.5, k1=0.01, k2=0.03): + super(SSIMNet, self).__init__() + self.net = nn.SSIM(max_val, filter_size, filter_sigma, k1, k2) + + def construct(self, img1, img2): + return self.net(img1, img2) + + +def test_compile(): + net = SSIMNet() + img1 = Tensor(np.random.random((8, 3, 16, 16))) + img2 = Tensor(np.random.random((8, 3, 16, 16))) + _executor.compile(net, img1, img2) + +def test_compile_grayscale(): + max_val = 255 + net = SSIMNet(max_val = max_val) + img1 = Tensor(np.random.randint(0, 256, (8, 1, 16, 16), np.uint8)) + img2 = Tensor(np.random.randint(0, 256, (8, 1, 16, 16), np.uint8)) + _executor.compile(net, img1, img2) + +def test_ssim_max_val_negative(): + max_val = -1 + with pytest.raises(ValueError): + net = SSIMNet(max_val) + +def test_ssim_max_val_bool(): + max_val = True + with pytest.raises(ValueError): + net = SSIMNet(max_val) + +def test_ssim_max_val_zero(): + max_val = 0 + with pytest.raises(ValueError): + net = SSIMNet(max_val) + +def test_ssim_filter_size_float(): + with pytest.raises(ValueError): + net = SSIMNet(filter_size=1.1) + +def test_ssim_filter_size_zero(): + with pytest.raises(ValueError): + net = SSIMNet(filter_size=0) + +def test_ssim_filter_sigma_zero(): + with pytest.raises(ValueError): + net = SSIMNet(filter_sigma=0.0) + +def test_ssim_filter_sigma_negative(): + with pytest.raises(ValueError): + net = SSIMNet(filter_sigma=-0.1) + +def test_ssim_k1_k2_wrong_value(): + with pytest.raises(ValueError): + net = SSIMNet(k1=1.1) + with pytest.raises(ValueError): + net = SSIMNet(k1=1.0) + with pytest.raises(ValueError): + net = SSIMNet(k1=0.0) + with pytest.raises(ValueError): + net = SSIMNet(k1=-1.0) + + with pytest.raises(ValueError): + net = SSIMNet(k2=1.1) + with pytest.raises(ValueError): + net = SSIMNet(k2=1.0) + with pytest.raises(ValueError): + net = SSIMNet(k2=0.0) + with pytest.raises(ValueError): + net = SSIMNet(k2=-1.0) \ No newline at end of file diff --git a/tests/ut/python/ops/test_math_ops.py b/tests/ut/python/ops/test_math_ops.py index 7c0cca9b40..8b7f627e81 100755 --- a/tests/ut/python/ops/test_math_ops.py +++ b/tests/ut/python/ops/test_math_ops.py @@ -30,6 +30,8 @@ from ....mindspore_test_framework.pipeline.forward.compile_forward \ import pipeline_for_compile_forward_ge_graph_for_case_by_case_config from ....mindspore_test_framework.pipeline.forward.verify_exception \ import pipeline_for_verify_exception_for_case_by_case_config + + # pylint: disable=W0613 # pylint: disable=W0231 # W0613: unused-argument @@ -82,9 +84,10 @@ def test_sqrt(): def test_pow(): """ test_pow """ input_tensor = Tensor(np.array([[2, 2], [3, 3]])) + power = Tensor(np.array(3.0, np.int64)) testpow = P.Pow() expect = np.array([[8, 8], [27, 27]]) - result = testpow(input_tensor, 3.0) + result = testpow(input_tensor, power) assert np.all(result.asnumpy() == expect) @@ -105,7 +108,7 @@ def test_realdiv(): result = div(x, y) x = x.asnumpy() y = y.asnumpy() - expect = x/y + expect = x / y assert np.all(result.asnumpy() == expect) @@ -121,6 +124,7 @@ def test_eye(): class VirtualLossGrad(PrimitiveWithInfer): """ VirtualLossGrad definition """ + @prim_attr_register def __init__(self): """init VirtualLossGrad""" @@ -137,6 +141,7 @@ class VirtualLossGrad(PrimitiveWithInfer): class VirtualLoss(PrimitiveWithInfer): """ VirtualLoss definition """ + @prim_attr_register def __init__(self): """init VirtualLoss""" @@ -150,6 +155,7 @@ class VirtualLoss(PrimitiveWithInfer): def bprop(x, out, dout): dx = loss_grad(x, out, dout) return (dx,) + return bprop def infer_shape(self, x_shape): @@ -161,6 +167,7 @@ class VirtualLoss(PrimitiveWithInfer): class NetWithLoss(nn.Cell): """ NetWithLoss definition """ + def __init__(self, network): super(NetWithLoss, self).__init__() self.loss = VirtualLoss() @@ -173,6 +180,7 @@ class NetWithLoss(nn.Cell): class GradWrap(nn.Cell): """ GradWrap definition """ + def __init__(self, network): super(GradWrap, self).__init__() self.network = network @@ -183,6 +191,7 @@ class GradWrap(nn.Cell): class MatMulNet(nn.Cell): """ MatMulNet definition """ + def __init__(self): super(MatMulNet, self).__init__() self.matmul = P.MatMul() @@ -194,6 +203,7 @@ class MatMulNet(nn.Cell): class NetWithLossSub(nn.Cell): """ NetWithLossSub definition """ + def __init__(self, network): super(NetWithLossSub, self).__init__() self.loss = VirtualLoss() @@ -206,6 +216,7 @@ class NetWithLossSub(nn.Cell): class GradWrapSub(nn.Cell): """ GradWrapSub definition """ + def __init__(self, network): super(GradWrapSub, self).__init__() self.network = network @@ -216,6 +227,7 @@ class GradWrapSub(nn.Cell): class SubNet(nn.Cell): """ SubNet definition """ + def __init__(self): super(SubNet, self).__init__() self.sub = P.Sub() @@ -226,6 +238,7 @@ class SubNet(nn.Cell): class NpuFloatNet(nn.Cell): """ NpuFloat definition """ + def __init__(self): super(NpuFloatNet, self).__init__() self.mul = P.Mul() @@ -257,6 +270,7 @@ class NpuFloatNet(nn.Cell): class DiagNet(nn.Cell): """ DiagNet definition """ + def __init__(self): super(DiagNet, self).__init__() self.fill = P.Fill() @@ -268,6 +282,7 @@ class DiagNet(nn.Cell): class NetWithLossCumSum(nn.Cell): """ NetWithLossCumSum definition """ + def __init__(self, network): super(NetWithLossCumSum, self).__init__() self.loss = VirtualLoss() @@ -280,6 +295,7 @@ class NetWithLossCumSum(nn.Cell): class GradWrapCumSum(nn.Cell): """ GradWrap definition """ + def __init__(self, network): super(GradWrapCumSum, self).__init__() self.network = network @@ -290,6 +306,7 @@ class GradWrapCumSum(nn.Cell): class NetCumSum(nn.Cell): """ NetCumSum definition """ + def __init__(self): super(NetCumSum, self).__init__() self.cumsum = P.CumSum() @@ -320,8 +337,8 @@ test_case_math_ops = [ 'skip': ['backward']}), ('CumSumGrad', { 'block': GradWrapCumSum(NetWithLossCumSum(NetCumSum())), - 'desc_inputs': [Tensor(np.array([[3, 4, 6, 10],[1, 6, 7, 9],[4, 3, 8, 7],[1, 3, 7, 9]]).astype(np.float16))], - 'desc_bprop': [Tensor(np.array([[3, 4, 6, 10],[1, 6, 7, 9],[4, 3, 8, 7],[1, 3, 7, 9]]).astype(np.float16))], + 'desc_inputs': [Tensor(np.array([[3, 4, 6, 10], [1, 6, 7, 9], [4, 3, 8, 7], [1, 3, 7, 9]]).astype(np.float16))], + 'desc_bprop': [Tensor(np.array([[3, 4, 6, 10], [1, 6, 7, 9], [4, 3, 8, 7], [1, 3, 7, 9]]).astype(np.float16))], 'skip': ['backward']}), ('Diag', { 'block': DiagNet(), @@ -350,7 +367,6 @@ test_case_math_ops = [ 'skip': ['backward']}), ] - test_case_lists = [test_case_math_ops] test_exec_case = functools.reduce(lambda x, y: x + y, test_case_lists) # use -k to select certain testcast @@ -359,6 +375,7 @@ test_exec_case = functools.reduce(lambda x, y: x + y, test_case_lists) import mindspore.context as context + @non_graph_engine @mindspore_test(pipeline_for_compile_forward_ge_graph_for_case_by_case_config) def test_exec(): @@ -368,16 +385,16 @@ def test_exec(): raise_set = [ ('StridedSlice_1_Error', { - 'block': (lambda x : P.StridedSlice(begin_mask="1"), {'exception': ValueError}), + 'block': (lambda x: P.StridedSlice(begin_mask="1"), {'exception': ValueError}), 'desc_inputs': [0]}), ('StridedSlice_2_Error', { - 'block': (lambda x : P.StridedSlice(end_mask="1"), {'exception': ValueError}), + 'block': (lambda x: P.StridedSlice(end_mask="1"), {'exception': ValueError}), 'desc_inputs': [0]}), ('StridedSlice_3_Error', { - 'block': (lambda x : P.StridedSlice(ellipsis_mask=1.1), {'exception': ValueError}), + 'block': (lambda x: P.StridedSlice(ellipsis_mask=1.1), {'exception': ValueError}), 'desc_inputs': [0]}), ('StridedSlice_4_Error', { - 'block': (lambda x : P.StridedSlice(new_axis_mask="1.1"), {'exception': ValueError}), + 'block': (lambda x: P.StridedSlice(new_axis_mask="1.1"), {'exception': ValueError}), 'desc_inputs': [0]}), ] diff --git a/tests/ut/python/ops/test_nn_ops.py b/tests/ut/python/ops/test_nn_ops.py index cadac6dfb4..bb2bb3ea9f 100644 --- a/tests/ut/python/ops/test_nn_ops.py +++ b/tests/ut/python/ops/test_nn_ops.py @@ -198,6 +198,19 @@ class ScalarSummaryNet(nn.Cell): return out +class HistogramSummaryNet(nn.Cell): + """HistogramSummaryNet definition""" + + def __init__(self): + super(HistogramSummaryNet, self).__init__() + self.summary = P.HistogramSummary() + + def construct(self, tensor): + string_in = "wight_value" + out = self.summary(string_in, tensor) + return out + + class FusedBatchNormGrad(nn.Cell): """ FusedBatchNormGrad definition """ @@ -382,6 +395,46 @@ def test_max_pool_with_arg_max(): print(ret) +class GradWrapUnfold(nn.Cell): + """ GradWrapUnfold definition """ + + def __init__(self, network): + super(GradWrapUnfold, self).__init__() + self.network = network + self.sens = Tensor(np.ones([1, 4, 2, 2], np.float32)) + + def construct(self, x): + return C.grad_all_with_sens(self.network)(x, self.sens) + + +class UnfoldNetValid(nn.Cell): + """ UnfoldNetValid definition """ + + def __init__(self): + super(UnfoldNetValid, self).__init__() + self.unfold = nn.Unfold(ksizes=[1, 2, 2, 1], + strides=[1, 1, 1, 1], + rates=[1, 1, 1, 1], + padding='VALID') + + def construct(self, x): + return self.unfold(x) + + +class UnfoldNetSame(nn.Cell): + """ UnfoldNetSame definition """ + + def __init__(self): + super(UnfoldNetSame, self).__init__() + self.unfold = nn.Unfold(ksizes=[1, 2, 2, 1], + strides=[1, 1, 1, 1], + rates=[1, 1, 1, 1], + padding='SAME') + + def construct(self, x): + return self.unfold(x) + + test_cases = [ ('SoftMaxGrad', { 'block': SoftMaxGrad(VirtualNetWithLoss(P.Softmax())), @@ -403,6 +456,10 @@ test_cases = [ 'block': ScalarSummaryNet(), 'desc_inputs': [2.2], }), + ('HistogramSummary', { + 'block': HistogramSummaryNet(), + 'desc_inputs': [[1,2,3]], + }), ('FusedBatchNormGrad', { 'block': FusedBatchNormGrad(nn.BatchNorm2d(num_features=512, eps=1e-5, momentum=0.1)), 'desc_inputs': [[64, 512, 7, 7], [64, 512, 7, 7]], @@ -440,6 +497,21 @@ test_cases = [ 'block': ComparisonNet(), 'desc_inputs': [Tensor(np.ones([6, 9, 10], np.int32)), Tensor(np.ones([6, 9, 10], np.int32))], }), + ('UnfoldValid', { + 'block': UnfoldNetValid(), + 'desc_inputs': [Tensor(np.ones([1, 1, 3, 3], np.float32))], + 'desc_bprop': [Tensor(np.ones([1, 4, 2, 2], np.float32))], + 'skip': ['backward']}), + ('UnfoldSame', { + 'block': UnfoldNetSame(), + 'desc_inputs': [Tensor(np.ones([1, 1, 3, 3], np.float32))], + 'desc_bprop': [Tensor(np.ones([1, 4, 3, 3], np.float32))], + 'skip': ['backward']}), + ('UnfoldGrad', { + 'block': GradWrapUnfold(UnfoldNetValid()), + 'desc_inputs': [Tensor(np.ones([1, 1, 3, 3], np.float32))], + 'desc_bprop': [Tensor(np.ones([1, 4, 2, 2], np.float32))], + 'skip': ['backward']}), ] test_cases_for_verify_exception = [ diff --git a/tests/ut/python/ops/test_ops.py b/tests/ut/python/ops/test_ops.py index a3d771d7ec..3345f77862 100755 --- a/tests/ut/python/ops/test_ops.py +++ b/tests/ut/python/ops/test_ops.py @@ -160,6 +160,19 @@ class SummaryNet(nn.Cell): return self.add(x, y) +class HistogramSummaryNet(nn.Cell): + def __init__(self,): + super(HistogramSummaryNet, self).__init__() + self.summary = P.HistogramSummary() + self.add = P.TensorAdd() + + def construct(self, x, y): + out = self.add(x, y) + string_in = "out" + self.summary(string_in, out) + return out + + test_case_math_ops = [ ('Neg', { 'block': P.Neg(), @@ -224,11 +237,15 @@ test_case_math_ops = [ 'block': P.Minimum(), 'desc_inputs': [[2, 3, 3, 5], [2, 3, 3, 5]], 'desc_bprop': [[2, 3, 3, 5]]}), - ('Pow', { + ('Pow_0', { 'block': P.Pow(), 'desc_const': [2.0], 'desc_inputs': [[2, 3, 3, 5]], 'desc_bprop': [[2, 3, 3, 5]]}), + ('Pow_1', { + 'block': P.Pow(), + 'desc_inputs': [[3, 5], [2, 3, 3, 5]], + 'desc_bprop': [[2, 3, 3, 5]]}), ('Exp', { 'block': P.Exp(), 'desc_inputs': [[2, 3]], @@ -786,11 +803,6 @@ test_case_nn_ops = [ 'desc_inputs': [[3, 3], [3, 3], [3, 3], Tensor(np.ones((3,), np.int32))], 'desc_bprop': [3, 3], 'skip': ['backward']}), - ('SparseApplyFtrlD', { - 'block': P.SparseApplyFtrlD(0.1, 0.1, 0.1, -0.1), - 'desc_inputs': [[3, 3], [3, 3], [3, 3], [3, 3], Tensor(2*np.ones((3,), np.int32))], - 'desc_bprop': [3, 3], - 'skip': ['backward']}), ('Flatten_1', { 'block': NetForFlatten(), 'desc_inputs': [Tensor(np.ones([2, 3, 4]).astype(np.int32)), Tensor(np.ones([2, 12]).astype(np.int32))], @@ -1105,6 +1117,12 @@ test_case_other_ops = [ 'desc_inputs': [Tensor(np.array([1.1]).astype(np.float32)), Tensor(np.array([1.2]).astype(np.float32))], 'skip': ['backward']}), + ('HistogramSummary', { + 'block': HistogramSummaryNet(), + 'desc_inputs': [Tensor(np.array([1.1]).astype(np.float32)), + Tensor(np.array([1.2]).astype(np.float32))], + 'skip': ['backward']}), + ] test_case_lists = [test_case_nn_ops, test_case_math_ops, test_case_array_ops, test_case_other_ops] diff --git a/tests/ut/python/ops/test_python_operators.py b/tests/ut/python/ops/test_python_operators.py index eb65a7f373..705774068d 100644 --- a/tests/ut/python/ops/test_python_operators.py +++ b/tests/ut/python/ops/test_python_operators.py @@ -25,11 +25,13 @@ from ....mindspore_test_framework.mindspore_test import mindspore_test from ....mindspore_test_framework.pipeline.forward.compile_forward \ import pipeline_for_compile_forward_ge_graph_for_case_by_case_config -context.set_context(mode=context.GRAPH_MODE, save_graphs=True) +context.set_context(mode=context.GRAPH_MODE) + class ComparisonOpsNet(nn.Cell): def __init__(self): super(ComparisonOpsNet, self).__init__() + def construct(self, x, y): a = x <= y b = x <= 1.0 @@ -46,22 +48,60 @@ class ComparisonOpsNet(nn.Cell): m = k != l return a or b or c or d or e or f or g or h or i or j or m + +class MathOpsNet(nn.Cell): + def __init__(self): + super(MathOpsNet, self).__init__() + self.relu = P.ReLU() + + def construct(self, x, y): + x = x - (-1) + return self.relu(x) + + +class ScalarCompareNet(nn.Cell): + def __init__(self): + super(ScalarCompareNet, self).__init__() + self.relu = P.ReLU() + + def construct(self, x, y): + t = 0 + if 3 > 3.2: + t = x + y + else: + t = x - y + if 3.1 <= 5: + t = t - x + else: + t = t + x + a = 32.0 * 12 + b = 12/3.0 + if a > b: + t = t * x + else: + t = t / x + return t + + class LogicalNumberOpsNet(nn.Cell): def __init__(self): super(LogicalNumberOpsNet, self).__init__() self.cond = True self.one = 0 self.zero = 0.0 + def construct(self, x, y): if self.cond and self.one or self.zero and not self.one: return x + y return x - y + class LogicalTensorOpsNet(nn.Cell): def __init__(self): """""" super(LogicalTensorOpsNet, self).__init__() self.const_true = Tensor(True, dtype=mstype.bool_) + def construct(self, x, y): ret = x and y and (y or self.const_true) and (not self.const_true) return ret @@ -71,20 +111,29 @@ test_case_ops = [ ('CompareOpsNet', { 'block': ComparisonOpsNet(), 'desc_inputs': [Tensor(np.ones([6, 9, 10]), dtype=mstype.float32), - Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), + Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), + ('MathOpsNet', { + 'block': MathOpsNet(), + 'desc_inputs': [Tensor(np.ones([6, 9, 10]), dtype=mstype.float32), + Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), + ('ScalarCompareNet', { + 'block': ScalarCompareNet(), + 'desc_inputs': [Tensor(np.ones([6, 9, 10]), dtype=mstype.float32), + Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), ('LogicalNumberOps', { 'block': LogicalNumberOpsNet(), 'desc_inputs': [Tensor(np.ones([6, 9, 10]), dtype=mstype.float32), - Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), + Tensor(np.zeros([6, 9, 10]), dtype=mstype.float32)]}), ('LogicalTensorOps', { 'block': LogicalTensorOpsNet(), 'desc_inputs': [Tensor(np.ones([6, 9, 10]).astype(np.bool_), dtype=mstype.bool_), - Tensor(np.zeros([6, 9, 10]).astype(np.bool_), dtype=mstype.bool_)]}), + Tensor(np.zeros([6, 9, 10]).astype(np.bool_), dtype=mstype.bool_)]}), ] test_case_lists = [test_case_ops] test_exec_case = functools.reduce(lambda x, y: x + y, test_case_lists) + @mindspore_test(pipeline_for_compile_forward_ge_graph_for_case_by_case_config) def test_compile(): - return test_exec_case \ No newline at end of file + return test_exec_case diff --git a/tests/ut/python/parallel/test_auto_parallel_two_matmul.py b/tests/ut/python/parallel/test_auto_parallel_two_matmul.py index bd6639a501..db6190ab89 100644 --- a/tests/ut/python/parallel/test_auto_parallel_two_matmul.py +++ b/tests/ut/python/parallel/test_auto_parallel_two_matmul.py @@ -100,7 +100,7 @@ def test_two_matmul(): set_algo_parameters(simplify_cal=True, tensor_slice_align_enable=False, tensor_slice_align_size=32, - not_fully_use_devices=True, + fully_use_devices=False, elementwise_op_strategy_follow=False) para_simplify_cal = get_algo_parameters("simplify_cal") assert para_simplify_cal == True @@ -108,8 +108,8 @@ def test_two_matmul(): assert para_slice_align_enable == False para_slice_align_size = get_algo_parameters("tensor_slice_align_size") assert para_slice_align_size == 32 - not_fully_use_devices = get_algo_parameters("not_fully_use_devices") - assert not_fully_use_devices == True + fully_use_devices = get_algo_parameters("fully_use_devices") + assert fully_use_devices == False elementwise_op_strategy_follow = get_algo_parameters("elementwise_op_strategy_follow") assert elementwise_op_strategy_follow == False @@ -120,8 +120,8 @@ def test_two_matmul(): assert para_slice_align_enable == False para_slice_align_size = get_algo_parameters("tensor_slice_align_size") assert para_slice_align_size == 16 - not_fully_use_devices = get_algo_parameters("not_fully_use_devices") - assert not_fully_use_devices == False + fully_use_devices = get_algo_parameters("fully_use_devices") + assert fully_use_devices == True elementwise_op_strategy_follow = get_algo_parameters("elementwise_op_strategy_follow") assert elementwise_op_strategy_follow == False diff --git a/tests/ut/python/parallel/test_comparison_function_info.py b/tests/ut/python/parallel/test_comparison_function_info.py index 74de04f1df..93ec5e5981 100644 --- a/tests/ut/python/parallel/test_comparison_function_info.py +++ b/tests/ut/python/parallel/test_comparison_function_info.py @@ -54,11 +54,10 @@ def test_matmul_equal(): out = self.equal(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 2), (2, 2)) strategy2 = ((4, 2), (4, 2)) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([128, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 64]), dtype=ms.float32) @@ -78,11 +77,10 @@ def test_matmul_not_equal(): out = self.notequal(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 2), (2, 2)) strategy2 = ((4, 2), (4, 2)) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([128, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 64]), dtype=ms.float32) @@ -102,11 +100,10 @@ def test_matmul_not_equal_repeated_calculation(): out = self.notequal(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 2), (2, 2)) strategy2 = ((4, 1), (4, 1)) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([128, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 64]), dtype=ms.float32) @@ -126,11 +123,10 @@ def test_matmul_maximum(): out = self.maximum(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 2), (2, 2)) strategy2 = ((4, 2), (4, 2)) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([64, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 64]), dtype=ms.float32) @@ -150,11 +146,10 @@ def test_matmul_maximum_broadcast(): out = self.maximum(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 2), (2, 2)) strategy2 = ((4, 2), (2, )) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([64, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 64]), dtype=ms.float32) @@ -174,13 +169,102 @@ def test_matmul_maximum_broadcast2(): out = self.maximum(out, b) return out - context.set_auto_parallel_context(device_num=8, global_rank=0) + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") strategy1 = ((2, 4), (4, 1)) strategy2 = ((4, 1), (1, 2)) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) - context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") x = Tensor(np.ones([64, 32]), dtype=ms.float32) y = Tensor(np.ones([32, 1]), dtype=ms.float32) b = Tensor(np.ones([1, 64]), dtype=ms.float32) - _executor.compile(net, x, y, b) \ No newline at end of file + _executor.compile(net, x, y, b) + + +def test_matmul_minimum(): + class Net(nn.Cell): + def __init__(self, strategy1, strategy2): + super().__init__() + self.matmul = P.MatMul().set_strategy(strategy1) + self.minimum = P.Minimum().set_strategy(strategy2) + + def construct(self, x, y, b): + out = self.matmul(x, y) + out = self.minimum(out, b) + return out + + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") + strategy1 = ((2, 2), (2, 2)) + strategy2 = ((4, 2), (4, 2)) + net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) + + x = Tensor(np.ones([64, 32]), dtype=ms.float32) + y = Tensor(np.ones([32, 64]), dtype=ms.float32) + b = Tensor(np.ones([64, 64]), dtype=ms.float32) + _executor.compile(net, x, y, b) + + +def test_matmul_minimum_broadcast(): + class Net(nn.Cell): + def __init__(self, strategy1, strategy2): + super().__init__() + self.matmul = P.MatMul().set_strategy(strategy1) + self.minimum = P.Maximum().set_strategy(strategy2) + + def construct(self, x, y, b): + out = self.matmul(x, y) + out = self.minimum(out, b) + return out + + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") + strategy1 = ((2, 2), (2, 2)) + strategy2 = ((4, 2), (2, )) + net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) + + x = Tensor(np.ones([64, 32]), dtype=ms.float32) + y = Tensor(np.ones([32, 64]), dtype=ms.float32) + b = Tensor(np.ones([64]), dtype=ms.float32) + _executor.compile(net, x, y, b) + + +def test_matmul_minimum_broadcast2(): + class Net(nn.Cell): + def __init__(self, strategy1, strategy2): + super().__init__() + self.matmul = P.MatMul().set_strategy(strategy1) + self.minimum = P.Minimum().set_strategy(strategy2) + + def construct(self, x, y, b): + out = self.matmul(x, y) + out = self.minimum(out, b) + return out + + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="semi_auto_parallel") + strategy1 = ((2, 4), (4, 1)) + strategy2 = ((4, 1), (1, 2)) + net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) + + x = Tensor(np.ones([64, 32]), dtype=ms.float32) + y = Tensor(np.ones([32, 1]), dtype=ms.float32) + b = Tensor(np.ones([1, 64]), dtype=ms.float32) + _executor.compile(net, x, y, b) + + +def test_matmul_minimum_auto_parallel(): + class Net(nn.Cell): + def __init__(self): + super().__init__() + self.matmul = P.MatMul() + self.minimum = P.Minimum() + + def construct(self, x, y, b): + out = self.matmul(x, y) + out = self.minimum(out, b) + return out + + context.set_auto_parallel_context(device_num=8, global_rank=0, parallel_mode="auto_parallel") + net = GradWrap(NetWithLoss(Net())) + + x = Tensor(np.ones([64, 32]), dtype=ms.float32) + y = Tensor(np.ones([32, 1]), dtype=ms.float32) + b = Tensor(np.ones([1, 64]), dtype=ms.float32) + _executor.compile(net, x, y, b) diff --git a/tests/ut/python/parallel/test_dropout_do_mask.py b/tests/ut/python/parallel/test_dropout_do_mask.py new file mode 100644 index 0000000000..cfa7f50135 --- /dev/null +++ b/tests/ut/python/parallel/test_dropout_do_mask.py @@ -0,0 +1,94 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import mindspore as ms +from mindspore import context, Tensor, Parameter +from mindspore.nn import Cell, TrainOneStepCell, Momentum +from mindspore.ops import operations as P +from mindspore.common.api import _executor + + +class Net(Cell): + def __init__(self, mul_weight, strategy1=None, strategy2=None): + super().__init__() + self.mul = P.Mul().set_strategy(strategy1) + self.mul2 = P.Mul().set_strategy(strategy1) + self.dropout_do_mask = P.DropoutDoMask().set_strategy(strategy2) + self.dropout_gen_mask = P.DropoutGenMask() + self.get_shape = P.Shape() + self.cast = P.Cast() + self.mul_weight = Parameter(mul_weight, "w1") + self.mul_weight2 = Parameter(mul_weight, "w2") + self.keep_prob = Tensor(0.9) + + def construct(self, x, b): + out = self.mul(x, self.mul_weight) + shape = self.get_shape(out) + dtype = P.DType()(out) + keep_prob = self.cast(self.keep_prob, dtype) + mask = self.dropout_gen_mask(shape, keep_prob) + out = self.dropout_do_mask(out, mask, keep_prob) + out = self.mul2(out, self.mul_weight2) + return out + + +_x = Tensor(np.ones([128, 64]), dtype=ms.float32) +_w1 = Tensor(np.ones([128, 64]), dtype=ms.float32) +_b = Tensor(np.ones([128, 64]), dtype=ms.float32) + + +def compile(net): + optimizer = Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + train_net = TrainOneStepCell(net, optimizer) + _executor.compile(train_net, _x, _b) + context.reset_auto_parallel_context() + + +def test_dropout_do_mask_data_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((16, 1), (16, 1)) + strategy2 = ((16, 1),) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_dropout_do_mask_model_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 16), (1, 16)) + strategy2 = ((1, 16),) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_dropout_do_mask_hybrid_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((4, 4), (4, 4)) + strategy2 = ((4, 4),) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_dropout_do_mask_auto_parallel(): + context.set_auto_parallel_context(parallel_mode="auto_parallel", device_num=16, global_rank=0) + net = Net(_w1) + compile(net) + + +def test_dropout_do_mask_repeat_calc(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((4, 4), (4, 4)) + strategy2 = ((2, 4),) + net = Net(_w1, strategy1, strategy2) + compile(net) diff --git a/tests/ut/python/parallel/test_element_wise_function.py b/tests/ut/python/parallel/test_element_wise_function.py index 2eb3a22ed2..641eb19f20 100644 --- a/tests/ut/python/parallel/test_element_wise_function.py +++ b/tests/ut/python/parallel/test_element_wise_function.py @@ -59,7 +59,7 @@ def test_matmul_pow(): context.set_auto_parallel_context(device_num=8, global_rank=0) strategy1 = ((2, 2), (2, 2)) - strategy2 = ((4, 2), ) + strategy2 = ((4, 2), ()) net = GradWrap(NetWithLoss(Net(strategy1, strategy2))) context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") diff --git a/tests/ut/python/parallel/test_gather_v2_primitive.py b/tests/ut/python/parallel/test_gather_v2_primitive.py index c623595b53..3ea0795e9c 100644 --- a/tests/ut/python/parallel/test_gather_v2_primitive.py +++ b/tests/ut/python/parallel/test_gather_v2_primitive.py @@ -29,6 +29,8 @@ from mindspore.nn import Dense, Cell from mindspore import context context.set_context(mode=context.GRAPH_MODE) +device_number = 32 +batch_size_per_device = 128 class Dataset(): @@ -57,15 +59,22 @@ class Dataset(): class GatherV2(_Loss): - def __init__(self, batchsize): + def __init__(self, index_dim, strategy, index_size=16): super(GatherV2, self).__init__() self.pow = P.Pow() - emb_list = list(range(batchsize)) - emb1_list = emb_list[0::2] - emb2_list = emb_list[1::2] + emb1_list = 21 + emb2_list = 2 + if index_dim == 1: + emb_list = list(range(index_size)) + emb1_list = emb_list[0::2] + emb2_list = emb_list[1::2] + if index_dim == 2: + emb_list = np.arange(index_size*16) + emb1_list = np.reshape(emb_list[0::2], (int(index_size/2), 16)) + emb2_list = np.reshape(emb_list[1::2], (int(index_size/2), 16)) self.emb1_param = Tensor(emb1_list, dtype=mstype.int32) self.emb2_param = Tensor(emb2_list, dtype=mstype.int32) - self.gatherv2 = P.GatherV2() + self.gatherv2 = P.GatherV2().set_strategy(strategy) def construct(self, nembeddings): emb1 = self.gatherv2(nembeddings, self.emb1_param, 0) @@ -73,10 +82,6 @@ class GatherV2(_Loss): return self.pow((emb1 - emb2), 2.0) -def get_loss(batchsize): - return GatherV2(batchsize) - - def fc_with_initialize(input_channels, out_channels): return Dense(input_channels, out_channels) @@ -114,26 +119,23 @@ class TrainOneStepCell(Cell): return F.depend(loss, self.optimizer(grads)) -def test_trains(): +def net_trains(gather_v2_strategy, criterion, rank): init() lr = 0.1 momentum = 0.9 max_epoch = 20 - device_number = 32 - batch_size_per_device = 128 input_channels = 256 out_channels = 512 - + context.set_context(mode=context.GRAPH_MODE, save_graphs=False) context.reset_auto_parallel_context() - context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL, device_num=device_number) + context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL, device_num=device_number, + global_rank=rank) predict = Tensor(np.ones([batch_size_per_device, input_channels]), dtype=ms.float32) dataset = Dataset(predict, 4) network = fc_with_initialize(input_channels, out_channels) network.set_train() - criterion = get_loss(batch_size_per_device * device_number) - train_network = BuildTrainNetwork(network, criterion) train_network.set_train() opt = Momentum(train_network.trainable_params(), lr, momentum) @@ -143,5 +145,90 @@ def test_trains(): model.train(max_epoch, dataset, dataset_sink_mode=False) context.reset_auto_parallel_context() -if __name__ == "__main__": - test_trains() + +def test_auto_batch_parallel(): + gather_v2_strategy = None + criterion = GatherV2(1, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + rank = 2 + net_trains(gather_v2_strategy, criterion, rank) + + +def test_2d_index_auto_batch_parallel(): + gather_v2_strategy = None + criterion = GatherV2(2, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + rank = 2 + net_trains(gather_v2_strategy, criterion, rank) + + +def test_batch_parallel(): + gather_v2_strategy = ((device_number, 1),) + criterion = GatherV2(1, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + rank = 2 + net_trains(gather_v2_strategy, criterion, rank) + + +def test_strategy1(): + gather_v2_strategy = ((16, 2),) + rank = 2 + criterion = GatherV2(1, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + net_trains(gather_v2_strategy, criterion, rank) + + +def test_strategy2(): + gather_v2_strategy = ((1, device_number),) + rank = 2 + criterion = GatherV2(1, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + net_trains(gather_v2_strategy, criterion, rank) + + +def test_strategy3(): + gather_v2_strategy = ((8, 1),) + rank = 2 + criterion = GatherV2(1, strategy=gather_v2_strategy, index_size=batch_size_per_device * device_number) + net_trains(gather_v2_strategy, criterion, rank) + + +class GatherV2Axis1(_Loss): + def __init__(self, index_dim, strategy, index_size=16): + super(GatherV2Axis1, self).__init__() + self.pow = P.Pow() + emb1_list = 21 + emb2_list = 2 + if index_dim == 1: + emb_list = list(range(index_size)) + emb1_list = emb_list[0::2] + emb2_list = emb_list[1::2] + if index_dim == 2: + emb_list = np.arange(index_size*index_size) + emb1_list = np.reshape(emb_list[0::2], (int(index_size/2), index_size)) + emb2_list = np.reshape(emb_list[1::2], (int(index_size/2), index_size)) + self.emb1_param = Tensor(emb1_list, dtype=mstype.int32) + self.emb2_param = Tensor(emb2_list, dtype=mstype.int32) + self.gatherv2 = P.GatherV2().set_strategy(strategy) + + def construct(self, nembeddings): + emb1 = self.gatherv2(nembeddings, self.emb1_param, 1) + emb2 = self.gatherv2(nembeddings, self.emb2_param, 1) + return self.pow((emb1 - emb2), 2.0) + + +def test_axis1_auto_batch_parallel(): + gather_v2_strategy = None + criterion = GatherV2Axis1(1, strategy=gather_v2_strategy, index_size=512) + rank = 2 + net_trains(gather_v2_strategy, criterion, rank) + + +def test_axis1_batch_parallel(): + gather_v2_strategy = ((device_number, 1),) + criterion = GatherV2Axis1(1, strategy=gather_v2_strategy, index_size=512) + rank = 2 + net_trains(gather_v2_strategy, criterion, rank) + + +def test_axis1_strategy1(): + gather_v2_strategy = ((16, 2),) + rank = 17 + criterion = GatherV2Axis1(1, strategy=gather_v2_strategy, index_size=512) + net_trains(gather_v2_strategy, criterion, rank) + diff --git a/tests/ut/python/parallel/test_layer_norm.py b/tests/ut/python/parallel/test_layer_norm.py new file mode 100644 index 0000000000..c65ee5fc8e --- /dev/null +++ b/tests/ut/python/parallel/test_layer_norm.py @@ -0,0 +1,96 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import mindspore as ms +from mindspore import context, Tensor, Parameter +from mindspore.nn import Cell, TrainOneStepCell, Momentum +from mindspore.ops import operations as P +from mindspore.common.api import _executor +from mindspore.common.initializer import initializer + + +class Net(Cell): + def __init__(self, mul_weight, strategy1=None, strategy2=None, strategy3=None): + super().__init__() + self.begin_norm_axis = -1 + self.begin_params_axis = 1 + self.mul = P.Mul().set_strategy(strategy1) + self.layer_norm = P.LayerNorm(self.begin_norm_axis, self.begin_params_axis).set_strategy(strategy2) + self.mul2 = P.Mul().set_strategy(strategy3) + self.mul_weight = Parameter(mul_weight, "w1") + self.normalized_shape = [64, 32, 16] + self.gamma = Parameter(initializer('ones', self.normalized_shape), name="gamma") + self.beta = Parameter(initializer('zeros', self.normalized_shape), name="beta") + + def construct(self, x, b): + out = self.mul(x, self.mul_weight) + out, _, _ = self.layer_norm(out, self.gamma, self.beta) + out = self.mul2(out, b) + return out + + +_x = Tensor(np.ones([128, 64, 32, 16]), dtype=ms.float32) +_w = Tensor(np.ones([128, 64, 32, 16]), dtype=ms.float32) +_b = Tensor(np.ones([128, 64, 32, 16]), dtype=ms.float32) + + +def compile(net): + optimizer = Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + train_net = TrainOneStepCell(net, optimizer) + _executor.compile(train_net, _x, _b) + context.reset_auto_parallel_context() + + +def test_layer_norm_data_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((16, 1, 1, 1), (16, 1, 1, 1)) + strategy2 = ((16, 1, 1, 1), (1, 1, 1), (1, 1, 1)) + strategy3 = ((16, 1, 1, 1), (16, 1, 1, 1)) + net = Net(_w, strategy1, strategy2, strategy3) + compile(net) + + +def test_layer_norm_model_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 1, 16, 1), (1, 1, 16, 1)) + strategy2 = ((1, 1, 16, 1), (1, 16, 1), (1, 16, 1)) + strategy3 = ((1, 1, 16, 1), (1, 1, 16, 1)) + net = Net(_w, strategy1, strategy2, strategy3) + compile(net) + + +def test_layer_norm_hybrid_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 2, 4, 1), (2, 2, 4, 1)) + strategy2 = ((2, 2, 4, 1), (2, 4, 1), (2, 4, 1)) + strategy3 = ((2, 2, 4, 1), (2, 2, 4, 1)) + net = Net(_w, strategy1, strategy2, strategy3) + compile(net) + + +def test_layer_norm_auto_parallel(): + context.set_auto_parallel_context(parallel_mode="auto_parallel", device_num=16, global_rank=0) + net = Net(_w) + compile(net) + + +def test_layer_norm_repeat_calc(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 2, 4, 1), (2, 2, 4, 1)) + strategy2 = ((1, 2, 2, 1), (2, 2, 1), (2, 2, 1)) + strategy3 = ((2, 2, 4, 1), (2, 2, 4, 1)) + net = Net(_w, strategy1, strategy2, strategy3) + compile(net) + diff --git a/tests/ut/python/parallel/test_reshape.py b/tests/ut/python/parallel/test_reshape.py index 43906aec23..f72e5f909b 100644 --- a/tests/ut/python/parallel/test_reshape.py +++ b/tests/ut/python/parallel/test_reshape.py @@ -576,7 +576,7 @@ def test_flatten_reshape2(parallel_mode="auto_parallel"): epoch_size = 2 context.reset_auto_parallel_context() context.set_auto_parallel_context(parallel_mode=parallel_mode, device_num=8) - set_algo_parameters(not_fully_use_devices=True) + set_algo_parameters(fully_use_devices=False) net = ParallelReduceMeanNet(conv_in_channel=3, conv_out_channel=64, reducemean_axis=(2, 3), strategy=((4, 1, 1, 1),)) loss = CrossEntropyLoss() predict = Tensor(np.ones([batch_size, 3, 32, 32]), dtype=ms.float32) @@ -617,7 +617,7 @@ def test_flatten_reshape3(parallel_mode="auto_parallel"): epoch_size = 2 context.reset_auto_parallel_context() context.set_auto_parallel_context(parallel_mode=parallel_mode, device_num=8) - set_algo_parameters(not_fully_use_devices=True) + set_algo_parameters(fully_use_devices=False) net = ParallelReshapeNet(dense_in_channel=2048, dense_out_channel=1000, shape=(128, 1000), strategy=((16, 1),)) loss = CrossEntropyLoss() predict = Tensor(np.ones([batch_size, 1, 2, 1024]), dtype=ms.float32) @@ -646,7 +646,7 @@ def test_flatten_reshape4(parallel_mode="semi_auto_parallel"): epoch_size = 2 context.reset_auto_parallel_context() context.set_auto_parallel_context(parallel_mode=parallel_mode, device_num=8) - set_algo_parameters(not_fully_use_devices=True) + set_algo_parameters(fully_use_devices=False) net = ParallelReduceMeanNet(conv_in_channel=3, conv_out_channel=64, reducemean_keep_dims=True, strategy=((4, 1, 1, 1),)) loss = CrossEntropyLoss2() predict = Tensor(np.ones([batch_size, 3, 32, 32]), dtype=ms.float32) diff --git a/tests/ut/python/parallel/test_sigmoid_cross_entropy_with_logits.py b/tests/ut/python/parallel/test_sigmoid_cross_entropy_with_logits.py new file mode 100644 index 0000000000..d59d053b07 --- /dev/null +++ b/tests/ut/python/parallel/test_sigmoid_cross_entropy_with_logits.py @@ -0,0 +1,83 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import mindspore as ms +from mindspore import context, Tensor, Parameter +from mindspore.nn import Cell, TrainOneStepCell, Momentum +from mindspore.ops import operations as P +from mindspore.common.api import _executor + + +class Net(Cell): + def __init__(self, mul_weight, strategy1=None, strategy2=None): + super().__init__() + self.mul = P.Mul().set_strategy(strategy1) + self.loss = P.SigmoidCrossEntropyWithLogits().set_strategy(strategy2) + self.mul_weight = Parameter(mul_weight, "w1") + + def construct(self, x, b): + out = self.mul(x, self.mul_weight) + out = self.loss(out, b) + return out + + +_x = Tensor(np.ones([128, 64]), dtype=ms.float32) +_w1 = Tensor(np.ones([128, 64]), dtype=ms.float32) +_b = Tensor(np.ones([128, 64]), dtype=ms.float32) + + +def compile(net): + optimizer = Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + train_net = TrainOneStepCell(net, optimizer) + _executor.compile(train_net, _x, _b) + context.reset_auto_parallel_context() + + +def test_sigmoid_cross_entropy_with_logits_data_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((16, 1), (16, 1)) + strategy2 = ((16, 1), (16, 1)) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_sigmoid_cross_entropy_with_logits_model_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 16), (1, 16)) + strategy2 = ((1, 16), (1, 16)) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_sigmoid_cross_entropy_with_logits_hybrid_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 8), (2, 8)) + strategy2 = ((2, 8), (2, 8)) + net = Net(_w1, strategy1, strategy2) + compile(net) + + +def test_sigmoid_cross_entropy_with_logits_auto_parallel(): + context.set_auto_parallel_context(parallel_mode="auto_parallel", device_num=16, global_rank=0) + net = Net(_w1) + compile(net) + + +def test_sigmoid_cross_entropy_with_logits_repeat_calc(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 8), (2, 8)) + strategy2 = ((2, 2), (2, 2)) + net = Net(_w1, strategy1, strategy2) + compile(net) diff --git a/tests/ut/python/parallel/test_square.py b/tests/ut/python/parallel/test_square.py new file mode 100644 index 0000000000..e9c182a439 --- /dev/null +++ b/tests/ut/python/parallel/test_square.py @@ -0,0 +1,85 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import mindspore as ms +from mindspore import context, Tensor, Parameter +from mindspore.nn import Cell, TrainOneStepCell, Momentum +from mindspore.ops import operations as P +from mindspore.common.api import _executor + + +class Net(Cell): + def __init__(self, mul_weight, strategy1=None, strategy2=None): + super(Net, self).__init__() + self.mul = P.Mul().set_strategy(strategy1) + self.square = P.Square().set_strategy(strategy2) + self.mul2 = P.Mul().set_strategy(strategy1) + self.mul_weight = Parameter(mul_weight, "w1") + + def construct(self, x, b): + out = self.mul(x, self.mul_weight) + out = self.square(out) + out = self.mul2(out, b) + return out + + +_x = Tensor(np.ones([128, 64, 32]), dtype=ms.float32) +_w1 = Tensor(np.ones([128, 64, 32]), dtype=ms.float32) +_b = Tensor(np.ones([128, 64, 32]), dtype=ms.float32) + + +def compile_net(net): + optimizer = Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + train_net = TrainOneStepCell(net, optimizer) + _executor.compile(train_net, _x, _b) + context.reset_auto_parallel_context() + + +def test_square_data_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((16, 1, 1), (16, 1, 1)) + strategy2 = ((16, 1, 1), ) + net = Net(_w1, strategy1, strategy2) + compile_net(net) + + +def test_square_model_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 1, 16), (1, 1, 16)) + strategy2 = ((1, 1, 16), ) + net = Net(_w1, strategy1, strategy2) + compile_net(net) + + +def test_square_hybrid_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 2, 4), (2, 2, 4)) + strategy2 = ((2, 2, 4), ) + net = Net(_w1, strategy1, strategy2) + compile_net(net) + + +def test_square_auto_parallel(): + context.set_auto_parallel_context(parallel_mode="auto_parallel", device_num=16, global_rank=0) + net = Net(_w1) + compile_net(net) + + +def test_square_repeat_calc(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((2, 2, 4), (2, 2, 4)) + strategy2 = ((1, 2, 2), ) + net = Net(_w1, strategy1, strategy2) + compile_net(net) diff --git a/tests/ut/python/parallel/test_squeeze_info.py b/tests/ut/python/parallel/test_squeeze_info.py new file mode 100644 index 0000000000..3169e2fb1b --- /dev/null +++ b/tests/ut/python/parallel/test_squeeze_info.py @@ -0,0 +1,79 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import mindspore as ms +from mindspore import context, Tensor, Parameter +from mindspore.nn import Cell, TrainOneStepCell, Momentum +from mindspore.ops import operations as P +from mindspore.common.api import _executor + + +class Net(Cell): + def __init__(self, strategy1=None, strategy2=None, axis=()): + super().__init__() + self.squeeze = P.Squeeze(axis=axis).set_strategy(strategy1) + self.mul = P.Mul().set_strategy(strategy2) + + def construct(self, x, b): + out = self.squeeze(x) + out = self.mul(out, b) + return out + + +_x = Tensor(np.ones([64, 1, 32, 1]), dtype=ms.float32) +_b = Tensor(np.ones([64, 32]), dtype=ms.float32) + + +def compile(net): + _executor.compile(net, _x, _b) + context.reset_auto_parallel_context() + + +def test_squeeze_data_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((16, 1, 1, 1), ) + strategy2 = ((16, 1), (16, 1)) + net = Net(strategy1, strategy2) + compile(net) + + +def test_squeeze_model_parallel(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 1, 16, 1), ) + strategy2 = ((1, 16), (1, 16)) + net = Net(strategy1, strategy2) + compile(net) + + +def test_squeeze_specified_axis(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((4, 1, 4, 1), ) + strategy2 = ((8, 2), (8, 2)) + net = Net(strategy1, strategy2, (1, 3)) + compile(net) + + +def test_squeeze_auto_parallel(): + context.set_auto_parallel_context(parallel_mode="auto_parallel", device_num=16, global_rank=0) + net = Net() + compile(net) + + +def test_squeeze_repeat_calc(): + context.set_auto_parallel_context(parallel_mode="semi_auto_parallel", device_num=16, global_rank=0) + strategy1 = ((1, 1, 8, 1), ) + strategy2 = ((2, 8), (2, 8)) + net = Net(strategy1, strategy2) + compile(net) diff --git a/tests/ut/python/parameter_feature/test_parameter.py b/tests/ut/python/parameter_feature/test_parameter.py index 696b107f56..1409fef386 100644 --- a/tests/ut/python/parameter_feature/test_parameter.py +++ b/tests/ut/python/parameter_feature/test_parameter.py @@ -19,7 +19,7 @@ from mindspore.nn import Cell from mindspore.ops import operations as P import mindspore.ops.composite as C -context.set_context(mode=context.GRAPH_MODE) +context.set_context(mode=context.GRAPH_MODE, save_graphs=True) def test_parser_three_default_mixed_args_subnet(): @@ -227,3 +227,43 @@ def test_net_vargs_expand(): net.set_train() net(x, y, sens) + + +def test_mixed_precision_const_parameter(): + class NetLoss(Cell): + def __init__(self): + super(NetLoss, self).__init__() + self.shape = P.Shape() + self.up_sample1 = P.ResizeBilinear((14, 14)) + self.up_sample2 = P.ResizeBilinear((28, 28)) + self.up_sample3 = P.ResizeBilinear((36, 36)) + def construct(self, x, y, z, *args): + ret = 0 + if args[0] == self.shape(z)[2]: + if args[0] == 14: + ret = self.up_sample1(y) + x + elif args[0] == 28: + ret = self.up_sample2(y) - x + else: + ret = x / y + else: + ret = x * y + ret = ret * z + return ret + class NetMain(Cell): + def __init__(self, loss_fn): + super(NetMain, self).__init__() + self.loss_fn = loss_fn + self.shape = P.Shape() + def construct(self, x, y, z): + size_x = self.shape(x)[2] + size_y = self.shape(y)[2] + ret = self.loss_fn(x, y, z, size_x, size_y) + return ret + loss_fn = NetLoss() + net = NetMain(loss_fn) + net.add_flags_recursive(fp32=True) + x = Tensor(np.ones((1, 3, 28, 28), np.float32)) + y = Tensor(np.ones((1, 3, 14, 14), np.float32)) + z = Tensor(np.ones((1, 3, 28, 28), np.float32)) + out = net(x, y, z) \ No newline at end of file diff --git a/tests/ut/python/parameter_feature/test_var_grad.py b/tests/ut/python/parameter_feature/test_var_grad.py index 12c05d0594..528456d02e 100644 --- a/tests/ut/python/parameter_feature/test_var_grad.py +++ b/tests/ut/python/parameter_feature/test_var_grad.py @@ -24,11 +24,14 @@ from mindspore.common import dtype as mstype context.set_context(mode=context.GRAPH_MODE) + def test_net_vargs_expand(): class AddNet(Cell): def __init__(self): super(AddNet, self).__init__() - self.w = Parameter(Tensor(np.ones((3, 4, 5), np.float32)), "w2", requires_grad=True) + self.w = Parameter( + Tensor(np.ones((3, 4, 5), np.float32)), "w2", requires_grad=True) + def construct(self, x, y): return x + y x = Tensor(np.random.normal(0, 1, [3, 4, 5]).astype(np.float32)) @@ -37,22 +40,59 @@ def test_net_vargs_expand(): net = AddNet() out = C.grad_all_with_sens(net, net.trainable_params())(x, y, sens) + class VarNet(Cell): def __init__(self, net): super(VarNet, self).__init__() - self.b = Parameter(Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b", requires_grad=True) - self.w = Parameter(Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "w", requires_grad=True) + self.b = Parameter( + Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b", requires_grad=True) + self.w = Parameter( + Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "w", requires_grad=True) self.net = net + def construct(self, *args): return self.net(*args)*self.w + self.b - + + class SecondNet(Cell): def __init__(self): super(SecondNet, self).__init__() - self.b2 = Parameter(Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b2", requires_grad=True) + self.b2 = Parameter( + Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b2", requires_grad=True) + def construct(self, *args): res = args[0] + args[1] return res + self.b2 + + +class Bprop(Cell): + def __init__(self, func, wrt_params, params, grad_op, sens=None): + super(Bprop, self).__init__(auto_prefix=False) + self.func = func + self.wrt_params = wrt_params + self.params = None + if self.wrt_params and params: + self.params = ParameterTuple(params) + self.grad = grad_op + self.with_sens = False + self.sens = sens + if sens: + self.sens = Tensor(sens, dtype=mstype.float32) + self.with_sens = True + + def construct(self, *inputs): + # pylint: disable=no-else-return + if self.wrt_params: + if self.with_sens: + return self.grad(self.func, self.params)(*inputs, self.sens) + else: + return self.grad(self.func, self.params)(*inputs) + elif self.with_sens: + return self.grad(self.func)(*inputs, self.sens) + else: + return self.grad(self.func)(*inputs) + + def test_all_var_args_grad_with_sens(): """"test grad_by_list_with_sens with all var args input""" class GradNet(Cell): @@ -60,6 +100,7 @@ def test_all_var_args_grad_with_sens(): super(GradNet, self).__init__() self.weights = ParameterTuple(net.trainable_params()) self.net = net + def construct(self, *inputs): return C.grad_by_list_with_sens(self.net, self.weights)(*inputs) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -69,12 +110,14 @@ def test_all_var_args_grad_with_sens(): grad_net = GradNet(net) out = grad_net(x, y, sens) + def test_grad_list_var_args(): class GradNet(Cell): def __init__(self, net): super(GradNet, self).__init__() self.weights = ParameterTuple(net.trainable_params()) self.net = net + def construct(self, *inputs): return C.grad_by_list(self.net, self.weights)(*inputs) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -83,12 +126,14 @@ def test_grad_list_var_args(): grad_net = GradNet(net) out = grad_net(x, y) + def test_grad_all_var_args(): class GradNet(Cell): def __init__(self, net): super(GradNet, self).__init__() self.weights = ParameterTuple(net.trainable_params()) self.net = net + def construct(self, *inputs): return C.grad_all(self.net)(*inputs) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -97,12 +142,14 @@ def test_grad_all_var_args(): grad_net = GradNet(net) out = grad_net(x, y) + def test_grad_all_var_args_with_sens(): class GradNet(Cell): def __init__(self, net): super(GradNet, self).__init__() self.weights = ParameterTuple(net.trainable_params()) self.net = net + def construct(self, *inputs): return C.grad_all_with_sens(self.net)(*inputs) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -112,12 +159,14 @@ def test_grad_all_var_args_with_sens(): grad_net = GradNet(net) out = grad_net(x, y, sens) + def test_grad_var_args_with_sens(): class GradNet(Cell): def __init__(self, net): super(GradNet, self).__init__() self.weights = ParameterTuple(net.trainable_params()) self.net = net + def construct(self, *inputs): return C.grad_with_sens(self.net)(*inputs) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -127,27 +176,34 @@ def test_grad_var_args_with_sens(): grad_net = GradNet(net) out = grad_net(x, y, sens) + def test_var_args_grad(): class VarNet(Cell): def __init__(self, net): super(VarNet, self).__init__() - self.b = Parameter(Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b", requires_grad=True) + self.b = Parameter( + Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b", requires_grad=True) self.net = net + def construct(self, *args): return self.net(*args) + self.b - + class SecondNet(Cell): def __init__(self): super(SecondNet, self).__init__() - self.b2 = Parameter(Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b2", requires_grad=True) + self.b2 = Parameter( + Tensor(np.ones([3, 4, 5]), dtype=mstype.float32), "b2", requires_grad=True) + def construct(self, *args): res = args[0] + args[1] return res + self.b2 + class GradNet(Cell): def __init__(self, net): super(GradNet, self).__init__() self.net = net self.weights = ParameterTuple(net.trainable_params()) + def construct(self, x, y, sens): return C.grad_by_list_with_sens(self.net, self.weights)(x, y, sens) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -164,12 +220,14 @@ def test_var_args_positional(): def __init__(self, net): super(VarNet, self).__init__() self.net = net + def construct(self, x, y): return self.net(x, y)*x class SecondNet(Cell): def __init__(self): super(SecondNet, self).__init__() + def construct(self, *args): return args[0] + args[1] @@ -178,6 +236,7 @@ def test_var_args_positional(): super(GradNet, self).__init__() self.net = net self.weights = ParameterTuple(net.trainable_params()) + def construct(self, x, y): return C.grad_all(self.net)(x, y) x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) @@ -185,3 +244,71 @@ def test_var_args_positional(): net = VarNet(SecondNet()) grad_net = GradNet(net) out = grad_net(x, y) + + +def test_grad_within_if_else(): + class GradNet(Cell): + def __init__(self, net): + super(GradNet, self).__init__() + self.weights = ParameterTuple(net.trainable_params()) + self.net = net + grad_op = C.GradOperation( + name='grad', get_all=False, get_by_list=True, sens_param=True) + self.grad = Bprop(self.net, True, self.weights, grad_op, 1.0) + + def construct(self, *inputs): + return self.grad(*inputs) + x = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) + y = Tensor(np.ones([3, 4, 5]), dtype=mstype.float32) + sens = Tensor(1.0, dtype=mstype.float32) + net = VarNet(SecondNet()) + grad_net = GradNet(net) + out = grad_net(x, y) + print("test_grad_var_args_with_sens out=", out) + + +def test_grad_for_concat(): + class GradNet(Cell): + def __init__(self, net): + super(GradNet, self).__init__() + self.weights = ParameterTuple(net.trainable_params()) + self.net = net + grad_op = C.GradOperation( + name='grad', get_all=True, get_by_list=False, sens_param=True) + self.grad = Bprop(self.net, False, self.weights, grad_op) + + def construct(self, *inputs): + return self.grad(*inputs) + + class Concat(Cell): + def __init__(self, axis): + super().__init__() + self.concat = P.Concat(axis=axis) + + def construct(self, *input1): + return self.concat(input1) + + class ConcatFactory: + def __init__(self, input_shape, axis, dtype=np.float32): + super(ConcatFactory, self).__init__() + self.inputs_np = [] + for s in input_shape: + self.inputs_np.append(np.random.randn(*s).astype(dtype)) + self.axis = axis + self.out_numpy = np.concatenate(self.inputs_np, axis=self.axis) + self.out_grad_np = self.out_numpy + + def grad_mindspore_impl(self): + inputs = [] + for i in self.inputs_np: + inputs.append(Tensor(i)) + net = Concat(axis=self.axis) + grad_net = GradNet(net) + grad_net.set_train() + input_grad = grad_net(*inputs, Tensor(self.out_grad_np)) + + def grad_cmp(self): + input_grad_mindspore = self.grad_mindspore_impl() + fact = ConcatFactory(input_shape=( + (2, 184320, 1), (2, 46080, 1), (2, 11520, 1), (2, 2880, 1), (2, 720, 1)), axis=1) + fact.grad_cmp() diff --git a/tests/ut/python/pipeline/parse/test_operator.py b/tests/ut/python/pipeline/parse/test_operator.py index a3412a6f8f..a3c5f7e422 100644 --- a/tests/ut/python/pipeline/parse/test_operator.py +++ b/tests/ut/python/pipeline/parse/test_operator.py @@ -131,3 +131,72 @@ def test_ME_arithmetic_operator_0070(): def test_ME_logical_operator_0020(): """ test_ME_logical_operator_0020 """ logical_operator_base('or') + + +def test_ops(): + class OpsNet(Cell): + """ OpsNet definition """ + + def __init__(self, x, y): + super(OpsNet, self).__init__() + self.x = x + self.y = y + self.int = 4 + self.float = 3.2 + self.str_a = "hello" + self.str_b = "world" + + def construct(self, x, y): + h = x // y + m = x ** y + n = x % y + r = self.x // self.y + s = self.x ** self.y + t = self.x % self.y + p = h + m + n + q = r + s + t + ret_pow = p ** q + q ** p + ret_mod = p % q + q % p + ret_floor = p // q + q // p + ret = ret_pow + ret_mod + ret_floor + if self.int > self.float: + if self.str_a + self.str_b == "helloworld": + return ret + return x + + net = OpsNet(9, 2) + x = Tensor(np.random.randint(low=1, high=10, size=(2, 3, 4), dtype=np.int32)) + y = Tensor(np.random.randint(low=10, high=20, size=(2, 3, 4), dtype=np.int32)) + context.set_context(mode=context.GRAPH_MODE, save_graphs=True) + net(x, y) + + +def test_in_dict(): + class InDictNet(Cell): + """ InDictNet definition """ + + def __init__(self, key_in, key_not_in): + super(InDictNet, self).__init__() + self.key_in = key_in + self.key_not_in = key_not_in + + def construct(self, x, y, z): + d = {"a": x, "b": y} + ret_in = 1 + ret_not_in = 2 + if self.key_in in d: + ret_in = d[self.key_in] + if self.key_not_in not in d: + ret_not_in = z + ret = ret_in + ret_not_in + return ret + + net = InDictNet("a", "c") + x = Tensor(np.random.randint(low=1, high=10, size=(2, 3, 4), dtype=np.int32)) + y = Tensor(np.random.randint(low=10, high=20, size=(2, 3, 4), dtype=np.int32)) + z = Tensor(np.random.randint(low=20, high=30, size=(2, 3, 4), dtype=np.int32)) + context.set_context(mode=context.GRAPH_MODE) + net(x, y, z) + + + diff --git a/tests/ut/python/pynative_mode/nn/test_activation.py b/tests/ut/python/pynative_mode/nn/test_activation.py index 7230fa272b..1b8a6f5d76 100644 --- a/tests/ut/python/pynative_mode/nn/test_activation.py +++ b/tests/ut/python/pynative_mode/nn/test_activation.py @@ -51,11 +51,6 @@ def test_activation_empty(): assert nn.get_activation('') is None -def test_activation_invalid(): - with pytest.raises(KeyError): - nn.get_activation('relu6') - - # test softmax def test_softmax_axis(): layer = nn.Softmax(1) diff --git a/tests/ut/python/pynative_mode/nn/test_dense.py b/tests/ut/python/pynative_mode/nn/test_dense.py index 48bfcc6674..cc9d280521 100644 --- a/tests/ut/python/pynative_mode/nn/test_dense.py +++ b/tests/ut/python/pynative_mode/nn/test_dense.py @@ -68,11 +68,6 @@ def test_dense_none(): nn.Dense(3, 2, None, None) -def test_dense_invalid_activation(): - with pytest.raises(KeyError): - nn.Dense(3, 2, activation='relu6') - - def test_dense_str_activation(): dense = nn.Dense(1, 1, activation='relu') assert isinstance(dense.activation, nn.ReLU) diff --git a/tests/ut/python/pynative_mode/test_cell_bprop.py b/tests/ut/python/pynative_mode/test_cell_bprop.py index 054afe36c9..da1e14974f 100644 --- a/tests/ut/python/pynative_mode/test_cell_bprop.py +++ b/tests/ut/python/pynative_mode/test_cell_bprop.py @@ -64,14 +64,15 @@ def test_grad_inline_mul_add(): class WithParameter(nn.Cell): def __init__(self): super(WithParameter, self).__init__() - self.param = Parameter(2, 'param') + self.param1 = Parameter(1, 'param1') + self.param2 = Parameter(2, 'param2') def construct(self, x, y): - return self.param * x + y + return self.param1 * self.param2 * x + y def bprop(self, x, y, out, dout): # In this test case, The user defined bprop is wrong defined purposely to distinguish from ad result - return self.param * dout, 2 * y + return self.param1 * self.param2 * dout, 2 * y def test_with_param(): with_param = WithParameter() diff --git a/tests/ut/python/pynative_mode/test_framstruct.py b/tests/ut/python/pynative_mode/test_framstruct.py index ff7cf67f52..eb3b76765a 100644 --- a/tests/ut/python/pynative_mode/test_framstruct.py +++ b/tests/ut/python/pynative_mode/test_framstruct.py @@ -38,16 +38,6 @@ def setup_module(module): context.set_context(mode=context.PYNATIVE_MODE) -@ms_function -def refactor_fac(n): - """ grad_refactor_fac """ - if n == 0: - return 1 - return n * refactor_fac(n-1) -def test_refactor(): - res = refactor_fac(3) - assert res == 6 - @ms_function def while_upper_bound(upper): rval = 2 @@ -386,16 +376,19 @@ def test_grad_while(): assert grad_while(5) == (60,) @ms_function -def fac(n): - """ fac """ +def factorial(n): + """ factorial """ if n == 0: return 1 - return n * fac(n-1) + return n * factorial(n-1) + +def test_factorial(): + res = factorial(3) + assert res == 6 -def test_fac(): - """ test_fac """ - res = fac(4) - assert res == 24 +def test_grad_factorial(): + res = C.grad(factorial)(3) + assert res == 11 def _for(x): """ _for """ diff --git a/tests/ut/python/pynative_mode/test_insert_grad_of.py b/tests/ut/python/pynative_mode/test_insert_grad_of.py index 104ac4d1c7..a11c5fa2b1 100644 --- a/tests/ut/python/pynative_mode/test_insert_grad_of.py +++ b/tests/ut/python/pynative_mode/test_insert_grad_of.py @@ -129,7 +129,7 @@ def test_cell_assign(): self.matrix_g = mindspore.Parameter(Tensor(np.ones([2, 2], np.float32)), name="matrix_g") def save_gradient(self, dout): - self.matrix_g = dout + self.matrix_g = dout + self.matrix_g return dout def construct(self, x, y): diff --git a/tests/ut/python/pynative_mode/test_stop_gradient.py b/tests/ut/python/pynative_mode/test_stop_gradient.py index b274b3988a..a26d635aad 100644 --- a/tests/ut/python/pynative_mode/test_stop_gradient.py +++ b/tests/ut/python/pynative_mode/test_stop_gradient.py @@ -366,3 +366,15 @@ def test_stop_gradient_11(): with pytest.raises(RuntimeError): bprop(PrimWithNoBprop_(), Tensor(np.ones([2]).astype(np.float32)), Tensor(np.ones([2]).astype(np.float32))) + +def test_stop_print(): + class StopPrint(nn.Cell): + def __init__(self): + super(StopPrint, self).__init__() + self.printm = P.Print() + def construct(self, x, y): + self.printm("StopPrint", x) + self.printm(y) + return x, y + C.grad_all(StopPrint())(Tensor(np.ones([2]).astype(np.float32)), + Tensor(np.ones([2]).astype(np.float32))) diff --git a/tests/ut/python/train/summary/summary_reader.py b/tests/ut/python/train/summary/summary_reader.py new file mode 100644 index 0000000000..647c25f25c --- /dev/null +++ b/tests/ut/python/train/summary/summary_reader.py @@ -0,0 +1,43 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Summary reader.""" +import struct + +import mindspore.train.summary_pb2 as summary_pb2 + +_HEADER_SIZE = 8 +_HEADER_CRC_SIZE = 4 +_DATA_CRC_SIZE = 4 + + +class SummaryReader: + """Read events from summary file.""" + + def __init__(self, file_name): + self._file_name = file_name + self._file_handler = open(self._file_name, "rb") + # skip version event + self.read_event() + + def read_event(self): + """Read next event.""" + file_handler = self._file_handler + header = file_handler.read(_HEADER_SIZE) + data_len = struct.unpack('Q', header)[0] + file_handler.read(_HEADER_CRC_SIZE) + event_str = file_handler.read(data_len) + file_handler.read(_DATA_CRC_SIZE) + summary_event = summary_pb2.Event.FromString(event_str) + return summary_event diff --git a/tests/ut/python/train/summary/test_histogram_summary.py b/tests/ut/python/train/summary/test_histogram_summary.py new file mode 100644 index 0000000000..50204cd757 --- /dev/null +++ b/tests/ut/python/train/summary/test_histogram_summary.py @@ -0,0 +1,210 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Test histogram summary.""" + +import logging +import os +import tempfile + +import numpy as np + +from mindspore.common.tensor import Tensor +from mindspore.train.summary.summary_record import SummaryRecord, _cache_summary_tensor_data +from .summary_reader import SummaryReader + +CUR_DIR = os.getcwd() +SUMMARY_DIR = os.path.join(CUR_DIR, "/test_temp_summary_event_file/") + +LOG = logging.getLogger("test") +LOG.setLevel(level=logging.ERROR) + + +def _wrap_test_data(input_data: Tensor): + """ + Wraps test data to summary format. + + Args: + input_data (Tensor): Input data. + + Returns: + dict, the wrapped data. + """ + + return [{ + "name": "test_data[:Histogram]", + "data": input_data + }] + + +def test_histogram_summary(): + """Test histogram summary.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + test_data = _wrap_test_data(Tensor([[1, 2, 3], [4, 5, 6]])) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + assert event.summary.value[0].histogram.count == 6 + + +def test_histogram_multi_summary(): + """Test histogram multiple step.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + rng = np.random.RandomState(10) + size = 50 + num_step = 5 + + for i in range(num_step): + arr = rng.normal(size=size) + + test_data = _wrap_test_data(Tensor(arr)) + _cache_summary_tensor_data(test_data) + test_writer.record(step=i) + + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + for _ in range(num_step): + event = reader.read_event() + assert event.summary.value[0].histogram.count == size + + +def test_histogram_summary_scalar_tensor(): + """Test histogram summary, input is a scalar tensor.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + test_data = _wrap_test_data(Tensor(1)) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + assert event.summary.value[0].histogram.count == 1 + + +def test_histogram_summary_empty_tensor(): + """Test histogram summary, input is an empty tensor.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + test_data = _wrap_test_data(Tensor([])) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + assert event.summary.value[0].histogram.count == 0 + + +def test_histogram_summary_same_value(): + """Test histogram summary, input is an ones tensor.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + dim1 = 100 + dim2 = 100 + + test_data = _wrap_test_data(Tensor(np.ones([dim1, dim2]))) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + LOG.debug(event) + + assert len(event.summary.value[0].histogram.buckets) == 1 + + +def test_histogram_summary_high_dims(): + """Test histogram summary, input is a 4-dimension tensor.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + dim = 10 + + rng = np.random.RandomState(0) + tensor_data = rng.normal(size=[dim, dim, dim, dim]) + test_data = _wrap_test_data(Tensor(tensor_data)) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + LOG.debug(event) + + assert event.summary.value[0].histogram.count == tensor_data.size + + +def test_histogram_summary_nan_inf(): + """Test histogram summary, input tensor has nan.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + dim1 = 100 + dim2 = 100 + + arr = np.ones([dim1, dim2]) + arr[0][0] = np.nan + arr[0][1] = np.inf + arr[0][2] = -np.inf + test_data = _wrap_test_data(Tensor(arr)) + + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + LOG.debug(event) + + assert event.summary.value[0].histogram.nan_count == 1 + + +def test_histogram_summary_all_nan_inf(): + """Test histogram summary, input tensor has no valid number.""" + with tempfile.TemporaryDirectory() as tmp_dir: + test_writer = SummaryRecord(tmp_dir, file_suffix="_MS_HISTOGRAM") + + test_data = _wrap_test_data(Tensor(np.array([np.nan, np.nan, np.nan, np.inf, -np.inf]))) + _cache_summary_tensor_data(test_data) + test_writer.record(step=1) + test_writer.close() + + file_name = os.path.join(tmp_dir, test_writer.event_file_name) + reader = SummaryReader(file_name) + event = reader.read_event() + LOG.debug(event) + + histogram = event.summary.value[0].histogram + assert histogram.nan_count == 3 + assert histogram.pos_inf_count == 1 + assert histogram.neg_inf_count == 1 diff --git a/tests/ut/python/train/summary/test_summary.py b/tests/ut/python/train/summary/test_summary.py index cc595ea883..82287c4290 100644 --- a/tests/ut/python/train/summary/test_summary.py +++ b/tests/ut/python/train/summary/test_summary.py @@ -132,6 +132,7 @@ class SummaryDemo(nn.Cell): def __init__(self,): super(SummaryDemo, self).__init__() self.s = P.ScalarSummary() + self.histogram_summary = P.HistogramSummary() self.add = P.TensorAdd() def construct(self, x, y): @@ -139,6 +140,7 @@ class SummaryDemo(nn.Cell): z = self.add(x, y) self.s("z1", z) self.s("y1", y) + self.histogram_summary("histogram", z) return z diff --git a/tests/ut/python/train/summary/test_summary_ops_params_valid_check.py b/tests/ut/python/train/summary/test_summary_ops_params_valid_check.py index 98dfd6aaef..23c85d398c 100644 --- a/tests/ut/python/train/summary/test_summary_ops_params_valid_check.py +++ b/tests/ut/python/train/summary/test_summary_ops_params_valid_check.py @@ -40,6 +40,7 @@ class SummaryDemoTag(nn.Cell): def __init__(self, tag1, tag2, tag3): super(SummaryDemoTag, self).__init__() self.s = P.ScalarSummary() + self.histogram_summary = P.HistogramSummary() self.add = P.TensorAdd() self.tag1 = tag1 self.tag2 = tag2 @@ -50,6 +51,7 @@ class SummaryDemoTag(nn.Cell): z = self.add(x, y) self.s(self.tag2, z) self.s(self.tag3, y) + self.histogram_summary(self.tag1, x) return z @@ -58,6 +60,7 @@ class SummaryDemoTagForSet(nn.Cell): def __init__(self, tag_tuple): super(SummaryDemoTagForSet, self).__init__() self.s = P.ScalarSummary() + self.histogram_summary = P.HistogramSummary() self.add = P.TensorAdd() self.tag_tuple = tag_tuple @@ -65,6 +68,7 @@ class SummaryDemoTagForSet(nn.Cell): z = self.add(x, y) for tag in self.tag_tuple: self.s(tag, x) + self.histogram_summary(tag, x) return z @@ -98,6 +102,19 @@ class SummaryDemoValueForSet(nn.Cell): self.s(tag, self.v) return z + +class HistogramSummaryNet(nn.Cell): + "HistogramSummaryNet definition" + def __init__(self, value): + self.histogram_summary = P.HistogramSummary() + self.add = P.TensorAdd() + self.value = value + + def construct(self, tensors1, tensor2): + self.histogram_summary("value", self.value) + return self.add(tensors1, tensor2) + + def run_case(net): """ run_case """ # step 0: create the thread @@ -121,8 +138,8 @@ def run_case(net): # Test 1: use the repeat tag -def test_scalar_summary_use_repeat_tag(): - log.debug("begin test_scalar_summary_use_repeat_tag") +def test_summary_use_repeat_tag(): + log.debug("begin test_summary_use_repeat_tag") net = SummaryDemoTag("x", "x", "x") try: run_case(net) @@ -130,12 +147,12 @@ def test_scalar_summary_use_repeat_tag(): assert False else: assert True - log.debug("finished test_scalar_summary_use_repeat_tag") + log.debug("finished test_summary_use_repeat_tag") # Test 2: repeat tag use for set summary -def test_scalar_summary_use_repeat_tag_for_set(): - log.debug("begin test_scalar_summary_use_repeat_tag_for_set") +def test_summary_use_repeat_tag_for_set(): + log.debug("begin test_summary_use_repeat_tag_for_set") net = SummaryDemoTagForSet(("x", "x", "x")) try: run_case(net) @@ -143,12 +160,12 @@ def test_scalar_summary_use_repeat_tag_for_set(): assert False else: assert True - log.debug("finished test_scalar_summary_use_repeat_tag_for_set") + log.debug("finished test_summary_use_repeat_tag_for_set") # Test3: test with invalid tag(None, bool, "", int) -def test_scalar_summary_use_invalid_tag_None(): - log.debug("begin test_scalar_summary_use_invalid_tag_None") +def test_summary_use_invalid_tag_None(): + log.debug("begin test_summary_use_invalid_tag_None") net = SummaryDemoTag(None, None, None) try: run_case(net) @@ -156,31 +173,31 @@ def test_scalar_summary_use_invalid_tag_None(): assert True else: assert False - log.debug("finished test_scalar_summary_use_invalid_tag_None") + log.debug("finished test_summary_use_invalid_tag_None") # Test4: test with invalid tag(None, bool, "", int) -def test_scalar_summary_use_invalid_tag_Bool(): - log.debug("begin test_scalar_summary_use_invalid_tag_Bool") +def test_summary_use_invalid_tag_Bool(): + log.debug("begin test_summary_use_invalid_tag_Bool") net = SummaryDemoTag(True, True, True) run_case(net) - log.debug("finished test_scalar_summary_use_invalid_tag_Bool") + log.debug("finished test_summary_use_invalid_tag_Bool") # Test5: test with invalid tag(None, bool, "", int) -def test_scalar_summary_use_invalid_tag_null(): - log.debug("begin test_scalar_summary_use_invalid_tag_null") +def test_summary_use_invalid_tag_null(): + log.debug("begin test_summary_use_invalid_tag_null") net = SummaryDemoTag("", "", "") run_case(net) - log.debug("finished test_scalar_summary_use_invalid_tag_null") + log.debug("finished test_summary_use_invalid_tag_null") # Test6: test with invalid tag(None, bool, "", int) -def test_scalar_summary_use_invalid_tag_Int(): - log.debug("begin test_scalar_summary_use_invalid_tag_Int") +def test_summary_use_invalid_tag_Int(): + log.debug("begin test_summary_use_invalid_tag_Int") net = SummaryDemoTag(1, 2, 3) run_case(net) - log.debug("finished test_scalar_summary_use_invalid_tag_Int") + log.debug("finished test_summary_use_invalid_tag_Int") # Test7: test with invalid value(None, "") @@ -196,7 +213,6 @@ def test_scalar_summary_use_invalid_value_None(): log.debug("finished test_scalar_summary_use_invalid_tag_Int") - # Test8: test with invalid value(None, "") def test_scalar_summary_use_invalid_value_None_ForSet(): log.debug("begin test_scalar_summary_use_invalid_value_None_ForSet") @@ -221,3 +237,30 @@ def test_scalar_summary_use_invalid_value_null(): else: assert False log.debug("finished test_scalar_summary_use_invalid_value_null") + + +def test_histogram_summary_use_valid_value(): + """Test histogram summary with valid value""" + log.debug("Begin test_histogram_summary_use_valid_value") + try: + net = HistogramSummaryNet(Tensor(np.array([1,2,3]))) + run_case(net) + except: + assert True + else: + assert False + log.debug("Finished test_histogram_summary_use_valid_value") + + +def test_histogram_summary_use_scalar_value(): + """Test histogram summary use scalar value""" + log.debug("Begin test_histogram_summary_use_scalar_value") + try: + scalar = Tensor(1) + net = HistogramSummaryNet(scalar) + run_case(net) + except: + assert True + else: + assert False + log.debug("Finished test_histogram_summary_use_scalar_value") diff --git a/tests/ut/python/train/test_amp.py b/tests/ut/python/train/test_amp.py index 1a26c21775..2afb1e00b5 100644 --- a/tests/ut/python/train/test_amp.py +++ b/tests/ut/python/train/test_amp.py @@ -14,12 +14,15 @@ # ============================================================================ """ auto mixed precision """ import numpy as np +import pytest from mindspore import amp from mindspore import nn from mindspore import Tensor from mindspore.common import dtype as mstype import mindspore.context as context from mindspore.model_zoo.resnet import resnet50 +from mindspore.train import Model +from ....dataset_mock import MindData def setup_module(module): @@ -85,3 +88,52 @@ def test_amp_o0_loss(): optimizer = nn.Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) train_network = amp.build_train_network(net, optimizer, loss) output = train_network(inputs, label) + + +class MindDataSet(MindData): + def __init__(self, dataset_types, dataset_shapes): + super(MindDataSet, self).__init__(size=2, batch_size=32, + np_types=dataset_types, + output_shapes=dataset_shapes, + input_indexs=(0, 1)) + def __next__(self): + if self._size < self._iter_num: + raise StopIteration + self._iter_num += 1 + next = [] + for shape, type in zip(self._output_shapes, self._np_types): + next.append(Tensor(np.ones(shape).astype(type))) + return tuple(next) + + +def test_compile_model_train_O0(): + dataset_types = (np.float32, np.float32) + dataset_shapes = ((16, 16), (16, 16)) + + dataset = MindDataSet(dataset_types, dataset_shapes) + + net = NetNoLoss(16, 16) + loss = nn.MSELoss() + optimizer = nn.Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + + model = Model(net, loss_fn=loss, optimizer=optimizer, metrics={"acc"}, amp_level="O0") + model.train(2, dataset, dataset_sink_mode=False) + with pytest.raises(ValueError): + # not actual run, the metrics step will fail, check if compile ok. + model.eval(dataset) + +def test_compile_model_train_O2(): + dataset_types = (np.float32, np.float32) + dataset_shapes = ((16, 16), (16, 16)) + + dataset = MindDataSet(dataset_types, dataset_shapes) + + net = NetNoLoss(16, 16) + loss = nn.MSELoss() + optimizer = nn.Momentum(net.trainable_params(), learning_rate=0.1, momentum=0.9) + + model = Model(net, loss_fn=loss, optimizer=optimizer, metrics={"acc"}, amp_level="O2") + model.train(2, dataset, dataset_sink_mode=False) + with pytest.raises(ValueError): + # not actual run, the metrics step will fail, check if compile ok. + model.eval(dataset) diff --git a/tests/vm_impl/array_ops_vm_impl.py b/tests/vm_impl/array_ops_vm_impl.py index 4258dadc62..38c613012e 100644 --- a/tests/vm_impl/array_ops_vm_impl.py +++ b/tests/vm_impl/array_ops_vm_impl.py @@ -190,7 +190,7 @@ def vm_impl_slice(self): return vm_impl -@vm_impl_getters.register(P.ConcatOffset) +@vm_impl_getters.register(P._grad_ops.ConcatOffset) def vm_impl_concatOffset(self): """Generate vm_impl function for ConcatOffset""" def vm_impl(x): diff --git a/tests/vm_impl/math_ops_vm_impl.py b/tests/vm_impl/math_ops_vm_impl.py index fd132280d1..01df0b824e 100644 --- a/tests/vm_impl/math_ops_vm_impl.py +++ b/tests/vm_impl/math_ops_vm_impl.py @@ -117,6 +117,7 @@ def vm_impl_pow(self): """Generate vm_impl function for Pow.""" def vm_impl(x, y): x = x.asnumpy() + y = y.asnumpy() res = vm.power(x, y) return Tensor(res) return vm_impl diff --git a/tests/vm_impl/vm_me.py b/tests/vm_impl/vm_me.py index ba51a3b13b..da7fc1ecbe 100644 --- a/tests/vm_impl/vm_me.py +++ b/tests/vm_impl/vm_me.py @@ -155,23 +155,35 @@ def batch_norm_grad(dy, x, scale, save_mean, save_inv_variance): def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0): """Rearranges a row vector to an image.""" - validator.check_integer("stride", stride, 0, Rel.GT) + if isinstance(stride, int): + stride_h = stride + stride_w = stride + elif isinstance(stride, tuple) and len(stride) == 2: + stride_h = stride[0] + stride_w = stride[1] + elif isinstance(stride, tuple) and len(stride) == 4: + stride_h = stride[2] + stride_w = stride[3] + else: + raise ValueError(f"The \'stride\' should be an int number or " + f"a tuple of two or four int numbers, but got {stride}") + batch_num, channel, height, width = input_shape - out_h = (height + 2*pad - filter_h)//stride + 1 - out_w = (width + 2*pad - filter_w)//stride + 1 + out_h = (height + 2*pad - filter_h)//stride_h + 1 + out_w = (width + 2*pad - filter_w)//stride_w + 1 col = col.reshape(batch_num, out_h, out_w, channel, filter_h, filter_w) \ .transpose(0, 3, 4, 5, 1, 2) img = np.zeros((batch_num, channel, - height + 2*pad + stride - 1, - width + 2*pad + stride - 1)) \ + height + 2*pad + stride_h - 1, + width + 2*pad + stride_w - 1)) \ .astype(col.dtype) for y in range(filter_h): - y_max = y + stride*out_h + y_max = y + stride_h*out_h for x in range(filter_w): - x_max = x + stride*out_w - img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :] + x_max = x + stride_h*out_w + img[:, :, y:y_max:stride_h, x:x_max:stride_h] += col[:, :, y, x, :, :] return img[:, :, pad:height + pad, pad:width + pad] @@ -205,11 +217,35 @@ def conv2d(x, weight, bias=None, stride=1, pad=0, dilation=1, groups=1, padding_mode='zeros'): """Convolution 2D.""" # pylint: disable=unused-argument - validator.check_integer("stride", stride, 0, Rel.GT) + validator.check_type('stride', stride, (int, tuple)) + if isinstance(stride, int): + stride = (stride, stride) + elif len(stride) == 4: + stride = (stride[2], stride[3]) + if len(stride) != 2 or (not isinstance(stride[0], int)) or \ + (not isinstance(stride[1], int)) or \ + stride[0] < 1 or stride[1] < 1: + raise ValueError(f"The \'stride\' of \'conv2d\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {stride}") + stride_h = stride[0] + stride_w = stride[1] + validator.check_type('dilation', dilation, (int, tuple)) + if isinstance(dilation, int): + dilation = (dilation, dilation) + elif len(dilation) == 4: + dilation = (dilation[2], dilation[3]) + if len(dilation) != 2 or (not isinstance(dilation[0], int)) or \ + (not isinstance(dilation[1], int)) or \ + dilation[0] < 1 or dilation[1] < 1: + raise ValueError(f"The \'dilation\' of \'conv2d\' should be an positive int number or " + f"a tuple of two positive int numbers, but got {dilation}") + dilation_h = dilation[0] + dilation_w = dilation[1] + batch_num, _, x_h, x_w = x.shape filter_num, _, filter_h, filter_w = weight.shape - out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation - 1)) / stride) - out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation - 1)) / stride) + out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation_h - 1)) / stride_h) + out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation_w - 1)) / stride_w) col = im2col(x, filter_h, filter_w, stride, pad, dilation) col_w = np.reshape(weight, (filter_num, -1)).T out = np.dot(col, col_w) @@ -286,19 +322,43 @@ def flatten_grad(dout, x): def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1): """Rearranges an image to row vector.""" - validator.check_integer("stride", stride, 0, Rel.GT) + if isinstance(stride, int): + stride_h = stride + stride_w = stride + elif isinstance(stride, tuple) and len(stride) == 2: + stride_h = stride[0] + stride_w = stride[1] + elif isinstance(stride, tuple) and len(stride) == 4: + stride_h = stride[2] + stride_w = stride[3] + else: + raise ValueError(f"The \'stride\' should be an int number or " + f"a tuple of two or four int numbers, but got {stride}") + if isinstance(dilation, int): + dilation_h = dilation + dilation_w = dilation + elif isinstance(dilation, tuple) and len(dilation) == 2: + dilation_h = dilation[0] + dilation_w = dilation[1] + elif isinstance(dilation, tuple) and len(dilation) == 4: + dilation_h = dilation[2] + dilation_w = dilation[3] + else: + raise ValueError(f"The \'dilation\' should be an int number or " + f"a tuple of two or four int numbers, but got {dilation}") + batch_num, channel, height, width = img.shape - out_h = (height + 2*pad - filter_h- (filter_h - 1) * (dilation - 1))//stride + 1 - out_w = (width + 2*pad - filter_w- (filter_w - 1) * (dilation - 1))//stride + 1 + out_h = (height + 2*pad - filter_h- (filter_h - 1) * (dilation_h - 1))//stride_h + 1 + out_w = (width + 2*pad - filter_w- (filter_w - 1) * (dilation_w - 1))//stride_w + 1 img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant') col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype) for y in range(filter_h): - y_max = y + stride*out_h + y_max = y + stride_h*out_h for x in range(filter_w): - x_max = x + stride*out_w - col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride] + x_max = x + stride_h*out_w + col[:, :, y, x, :, :] = img[:, :, y:y_max:stride_h, x:x_max:stride_h] col = col.transpose(0, 4, 5, 1, 2, 3).reshape(batch_num*out_h*out_w, -1) return col diff --git a/third_party/patch/sqlite/sqlite.windows.patch001 b/third_party/patch/sqlite/sqlite.windows.patch001 new file mode 100644 index 0000000000..f92548e15e --- /dev/null +++ b/third_party/patch/sqlite/sqlite.windows.patch001 @@ -0,0 +1,133 @@ +diff -uprN sqlite-amalgamation-3310100/CMakeLists.txt sqlite-patch/CMakeLists.txt +--- sqlite-amalgamation-3310100/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 ++++ sqlite-patch/CMakeLists.txt 2020-04-18 09:16:28.258637600 +0800 +@@ -0,0 +1,6 @@ ++cmake_minimum_required(VERSION 3.14) ++project (Sqlite[C]) ++add_library(sqlite3 SHARED sqlite3.c) ++set_target_properties(sqlite3 PROPERTIES PUBLIC_HEADER "sqlite3.h;sqlite3ext.h") ++include(GNUInstallDirs) ++install(TARGETS sqlite3 PUBLIC_HEADER) +diff -uprN sqlite-amalgamation-3310100/sqlite3.c sqlite-patch/sqlite3.c +--- sqlite-amalgamation-3310100/sqlite3.c 2020-01-28 03:25:14.000000000 +0800 ++++ sqlite-patch/sqlite3.c 2020-04-17 15:40:21.005440300 +0800 +@@ -1167,7 +1167,7 @@ extern "C" { + */ + #define SQLITE_VERSION "3.31.1" + #define SQLITE_VERSION_NUMBER 3031001 +-#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6" ++#define SQLITE_SOURCE_ID "2020-02-17 19:25:07 387240fc85ea3549ff8a6ed060ef07c6184548457fb91cd7c6fc39ddb678alt1" + + /* + ** CAPI3REF: Run-Time Library Version Numbers +@@ -17428,8 +17428,11 @@ struct Table { + */ + #ifndef SQLITE_OMIT_VIRTUALTABLE + # define IsVirtual(X) ((X)->nModuleArg) ++# define ExprIsVtab(X) \ ++ ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) + #else + # define IsVirtual(X) 0 ++# define ExprIsVtab(X) 0 + #endif + + /* +@@ -104133,19 +104136,25 @@ static int impliesNotNullRow(Walker *pWa + case TK_LT: + case TK_LE: + case TK_GT: +- case TK_GE: ++ case TK_GE: { ++ Expr *pLeft = pExpr->pLeft; ++ Expr *pRight = pExpr->pRight; + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); +- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) +- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) ++ /* The y.pTab=0 assignment in wherecode.c always happens after the ++ ** impliesNotNullRow() test */ ++ if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) ++ && IsVirtual(pLeft->y.pTab)) ++ || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) ++ && IsVirtual(pRight->y.pTab)) + ){ +- return WRC_Prune; ++ return WRC_Prune; + } +- ++ } + default: + return WRC_Continue; + } +@@ -142591,7 +142600,8 @@ static int isAuxiliaryVtabOperator( + ** MATCH(expression,vtab_column) + */ + pCol = pList->a[1].pExpr; +- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ ++ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); ++ if( ExprIsVtab(pCol) ){ + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; +@@ -142613,7 +142623,8 @@ static int isAuxiliaryVtabOperator( + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; +- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ ++ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); ++ if( ExprIsVtab(pCol) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); +@@ -142636,10 +142647,12 @@ static int isAuxiliaryVtabOperator( + int res = 0; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; +- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ ++ testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); ++ if( ExprIsVtab(pLeft) ){ + res++; + } +- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ ++ testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); ++ if( pRight && ExprIsVtab(pRight) ){ + res++; + SWAP(Expr*, pLeft, pRight); + } +@@ -223667,7 +223680,7 @@ static void fts5SourceIdFunc( + ){ + assert( nArg==0 ); + UNUSED_PARAM2(nArg, apUnused); +- sqlite3_result_text(pCtx, "fts5: 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6", -1, SQLITE_TRANSIENT); ++ sqlite3_result_text(pCtx, "fts5: 2020-02-17 19:25:07 abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d", -1, SQLITE_TRANSIENT); + } + + /* +@@ -228440,9 +228453,9 @@ SQLITE_API int sqlite3_stmt_init( + #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ + + /************** End of stmt.c ************************************************/ +-#if __LINE__!=228443 ++#if __LINE__!=228456 + #undef SQLITE_SOURCE_ID +-#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837balt2" ++#define SQLITE_SOURCE_ID "2020-02-17 19:25:07 387240fc85ea3549ff8a6ed060ef07c6184548457fb91cd7c6fc39ddb678alt2" + #endif + /* Return the source-id for this library */ + SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +diff -uprN sqlite-amalgamation-3310100/sqlite3.h sqlite-patch/sqlite3.h +--- sqlite-amalgamation-3310100/sqlite3.h 2020-01-28 03:25:14.000000000 +0800 ++++ sqlite-patch/sqlite3.h 2020-04-17 15:40:21.005440300 +0800 +@@ -125,7 +125,7 @@ extern "C" { + */ + #define SQLITE_VERSION "3.31.1" + #define SQLITE_VERSION_NUMBER 3031001 +-#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6" ++#define SQLITE_SOURCE_ID "2020-02-17 19:25:07 387240fc85ea3549ff8a6ed060ef07c6184548457fb91cd7c6fc39ddb678alt1" + + /* + ** CAPI3REF: Run-Time Library Version Numbers diff --git a/third_party/securec/CMakeLists.txt b/third_party/securec/CMakeLists.txt index e360a6ebae..f012b05860 100644 --- a/third_party/securec/CMakeLists.txt +++ b/third_party/securec/CMakeLists.txt @@ -1,11 +1,14 @@ SET(CMAKE_BUILD_TYPE "Debug") -SET(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -fPIC -O0 -Wall -Wno-deprecated-declarations -g2 -ggdb -fno-inline-functions -fno-omit-frame-pointer -D_LIBCPP_INLINE_VISIBILITY='' -D'_LIBCPP_EXTERN_TEMPLATE(...)='") +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + SET(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -fPIC -O0 -Wall -Wno-deprecated-declarations -g2 -ggdb -fno-inline-functions -fno-omit-frame-pointer") +else() + SET(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -fPIC -O0 -Wall -Wno-deprecated-declarations -g2 -ggdb -fno-inline-functions -fno-omit-frame-pointer -D_LIBCPP_INLINE_VISIBILITY='' -D'_LIBCPP_EXTERN_TEMPLATE(...)='") +endif() SET(CMAKE_C_FLAGS_RELEASE "$ENV{CFLAGS} -fPIC -O3 -Wall -Wno-deprecated-declarations") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #add flags set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include -Werror") - include_directories(./include) add_subdirectory(src) diff --git a/third_party/securec/src/CMakeLists.txt b/third_party/securec/src/CMakeLists.txt index 60ec0a90ee..2af0f764c8 100644 --- a/third_party/securec/src/CMakeLists.txt +++ b/third_party/securec/src/CMakeLists.txt @@ -1,3 +1,6 @@ -aux_source_directory(. SECUREC_SRCS) - +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + list(APPEND SECUREC_SRCS "memset_s.c") +else() + aux_source_directory(. SECUREC_SRCS) +endif() add_library(securec STATIC ${SECUREC_SRCS})