diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4de09bb8b3c..924b96ea0d1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -55,6 +55,7 @@ jobs: -DMIGRAPHX_ENABLE_GPU=On \ -DMIGRAPHX_ENABLE_CPU=On \ -DMIGRAPHX_ENABLE_FPGA=On \ + -DMIGRAPHX_ENABLE_MLIR=On \ -DBUILD_DEV=On \ -DROCM_ENABLE_GH_ANNOTATIONS=On \ -DCLANG_TIDY_DEPEND_ON_TARGET=Off \ @@ -169,6 +170,71 @@ jobs: git config --global --add safe.directory /data python3 tools/format.py origin/${{ github.event_name == 'pull_request' && github.base_ref || 'develop' }} + sles: + runs-on: ROCM-Ubuntu + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + # In this step, this action saves a list of existing images, + # the cache is created without them in the post run. + # It also restores the cache if it exists. + - name: Docker layer cache + uses: jpribyl/action-docker-layer-caching@v0.1.1 + with: + key: docker-layer-caching-migraphx-sles-${{hashFiles('hip-clang.docker', '**/*requirements.txt', '**/install_prereqs.sh', 'rbuild.ini')}} + restore-keys: + docker-layer-caching-migraphx-sles- + # Ignore the failure of a step and avoid terminating the job. + continue-on-error: true + + - name: Build the Docker image + run: docker build . --file tools/docker/sles.docker --tag migraphx-sles + + - name: Restore cache files for ccache + uses: actions/cache/restore@v3 + id: ccache_restore + with: + path: ${{ github.workspace }}/ccache + key: ccache-sles-${{ github.ref }} + restore-keys: ccache-sles- + + - name: Build migraphx + shell: bash -c "docker run -i -v=$GITHUB_WORKSPACE:/data -w /data migraphx-sles bash < {0}" + run: | + set -e + export CCACHE_COMPRESSLEVEL=10 + export CCACHE_DIR=/data/ccache + export CCACHE_NOHASHDIR=true + export CCACHE_BASEDIR=/data + export CCACHE_MAXSIZE=1 + mkdir build + cd build + CXX=/opt/rocm/llvm/bin/clang++ CC=/opt/rocm/llvm/bin/clang cmake \ + -DBUILD_DEV=On \ + -DCMAKE_CXX_COMPILER_LAUNCHER=/usr/local/bin/ccache \ + -DCMAKE_C_COMPILER_LAUNCHER=/usr/local/bin/ccache \ + .. + make -j$(nproc) tests driver + + - name: Clear ccache cache before saving + if: ${{ steps.ccache_restore.outputs.cache-hit }} + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set +x + gh extension install actions/gh-actions-cache --pin v1.0.1 + gh actions-cache delete ${{ steps.ccache_restore.outputs.cache-matched-key }} --confirm + + - name: Save cache files for ccache + uses: actions/cache/save@v3 + if: always() + with: + path: ${{ github.workspace }}/ccache + key: ccache-sles-${{ github.ref }} + pyflakes: runs-on: ubuntu-20.04 @@ -274,11 +340,10 @@ jobs: # This path is specific to Ubuntu path: ${{ github.workspace }}/cget # Look to see if there is a cache hit for the corresponding requirements file - key: ${{ matrix.os }}-cget-4-${{ hashFiles('requirements.txt', 'dev-requirements.txt') }} + key: ${{ matrix.os }}-cget-4-${{ hashFiles('requirements.txt', 'dev-requirements.txt', 'rbuild.ini') }} restore-keys: ${{ matrix.os }}-cget-4- - name: Install dependencies - if: steps.deps_cache.outputs.cache-hit != 'true' run: rbuild prepare -d cget -s gh - name: Restore cache files for ccache diff --git a/.github/workflows/sync-onnxrt-main.yaml b/.github/workflows/sync-onnxrt-main.yaml index 701d4ac4b64..f14128fb703 100644 --- a/.github/workflows/sync-onnxrt-main.yaml +++ b/.github/workflows/sync-onnxrt-main.yaml @@ -47,6 +47,7 @@ jobs: onnxruntime dependancies automated + skip bot checks assignees: TedThemistokleous reviewers: TedThemistokleous causten draft: false diff --git a/CHANGELOG.md b/CHANGELOG.md index dedcac00d05..dc183f127a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,49 @@ Full documentation for MIGraphX is available at [MIGraphX Documentation](https://rocmdocs.amd.com/projects/AMDMIGraphX/en/latest/). -## MIGraphX 2.5 for ROCm 5.5.0 +## MIGraphX 2.7 for ROCm 5.7.0 +### Added +- Enabled hipRTC to not require dev packages for migraphx runtime and allow the ROCm install to be in a different directory than it was during build time +- Add support for multi-target execution +- Added Dynamic Batch support with C++/Python APIs +- Add migraphx.create_argument to python API +- Added dockerfile example for Ubuntu 22.04 +- Add TensorFlow supported ops in driver similar to exist onnx operator list +- Add a MIGRAPHX_TRACE_MATCHES_FOR env variable to filter the matcher trace +- Improved debugging by printing max,min,mean and stddev values for TRACE_EVAL = 2 +- use fast_math flag instead of ENV flag for GELU +- Print message from driver if offload copy is set for compiled program +### Optimizations +- Optimized for ONNX Runtime 1.14.0 +- Improved compile times by only building for the GPU on the system +- Improve performance of pointwise/reduction kernels when using NHWC layouts +- Load specific version of the migraphx_py library +- Annotate functions with the block size so the compiler can do a better job of optimizing +- Enable reshape on nonstandard shapes +- Use half HIP APIs to compute max and min +- Added support for broadcasted scalars to unsqueeze operator +- Improved multiplies with dot operator +- Handle broadcasts across dot and concat +- Add verify namespace for better symbol resolution +### Fixed +- Resolved accuracy issues with FP16 resnet50 +- Update cpp generator to handle inf from float +- Fix assertion error during verify and make DCE work with tuples +- Fix convert operation for NaNs +- Fix shape typo in API test +- Fix compile warnings for shadowing variable names +- Add missing specialization for the `nullptr` for the hash function +### Changed +- Bumped version of half library to 5.6.0 +- Bumped CI to support rocm 5.6 +- Make building tests optional +- replace np.bool with bool as per numpy request +### Removed +- Removed int8x4 rocBlas calls due to deprecation +- removed std::reduce usage since not all OS' support it + +## MIGraphX 2.5 for ROCm 5.5.0 ### Added - Y-Model feature to store tuning information with the optimized model - Added Python 3.10 bindings @@ -12,15 +53,11 @@ Full documentation for MIGraphX is available at [MIGraphX Documentation](https:/ - Build support for ROCm MLIR - Added migraphx-driver flag to print optimizations in python (--python) - Added JIT implementation of the Gather and Pad operator which results in better handling of larger tensor sizes. - - ### Optimizations - Improved performance of Transformer based models - Improved performance of the Pad, Concat, Gather, and Pointwise operators - Improved onnx/pb file loading speed - Added general optimize pass which runs several passes such as simplify_reshapes/algebra and DCE in loop. - - ### Fixed - Improved parsing Tensorflow Protobuf files - Resolved various accuracy issues with some onnx models @@ -29,6 +66,5 @@ Full documentation for MIGraphX is available at [MIGraphX Documentation](https:/ - Use --offload-arch instead of --cuda-gpu-arch for the HIP compiler - Changes inside JIT to use float accumulator for large reduce ops of half type to avoid overflow. - Changes inside JIT to temporarily use cosine to compute sine function. - ### Changed - Changed version/location of 3rd party build dependencies to pick up fixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 53af89e8a65..2619237af5f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ project(migraphx LANGUAGES C CXX) include(CTest) find_package(ROCM REQUIRED) +find_package(Threads REQUIRED) find_path(HALF_INCLUDE_DIR half.hpp PATH_SUFFIXES half) if (NOT HALF_INCLUDE_DIR) @@ -227,14 +228,12 @@ rocm_enable_cppcheck( shadowVar shadowVariable unsafeClassDivZero + # Disable because of too many FPs + arithOperationsOnVoidPointer definePrefix:*test/include/test.hpp ctuOneDefinitionRuleViolation:*test/* useSmartPointer:*src/api/api.cpp useSmartPointer:*make_shared_array.hpp - constParameter:*src/targets/gpu/*.cpp - constParameter:*src/targets/gpu/*.hpp - # Suppress mlir_conv.cpp since this file will be deleted - *:*src/targets/gpu/mlir_conv.cpp FORCE INCONCLUSIVE RULE_FILE @@ -251,10 +250,13 @@ rocm_enable_cppcheck( ${CMAKE_CURRENT_SOURCE_DIR}/src/targets/gpu/kernels/include ${CMAKE_CURRENT_SOURCE_DIR}/test/include DEFINE + MIGRAPHX_MLIR=1 CPPCHECK=1 __device__= __host__= __global__= + UNDEFINE + MIGRAPHX_USE_CLANG_TIDY ) enable_testing() diff --git a/Dockerfile b/Dockerfile index f75caec2a84..f7a9c953701 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,6 +77,9 @@ ADD dev-requirements.txt /dev-requirements.txt ADD requirements.txt /requirements.txt ADD rbuild.ini /rbuild.ini +# Temporarily install a new cmake until switching to ubuntu 22.04 +RUN pip3 install cmake==3.22.1 + COPY ./tools/install_prereqs.sh / RUN /install_prereqs.sh /usr/local / && rm /install_prereqs.sh RUN test -f /usr/local/hash || exit 1 @@ -98,6 +101,9 @@ RUN cget -p $PREFIX install facebook/zstd@v1.4.5 -X subdir -DCMAKE_DIR=build/cma RUN cget -p $PREFIX install ccache@v4.1 -DENABLE_TESTING=OFF RUN cget -p /opt/cmake install kitware/cmake@v3.26.4 +# Install MLIR +ADD mlir-requirements.txt /mlir-requirements.txt +RUN cget -p /usr/local install -f /mlir-requirements.txt COPY ./test/onnx/.onnxrt-commit / @@ -113,9 +119,6 @@ RUN git clone --single-branch --branch ${ONNXRUNTIME_BRANCH} --recursive ${ONNXR ADD tools/build_and_test_onnxrt.sh /onnxruntime/build_and_test_onnxrt.sh -# Use the /opt/cmake install because LLVM/MLIR need cmake >= 3.20 -RUN env PATH=/opt/cmake/bin:$PATH cget -p /usr/local install ROCmSoftwarePlatform/rocMLIR@1ad9d6df32acc6d29d58e8ed6710e36746d0a4d6 -DBUILD_FAT_LIBROCKCOMPILER=On - ENV MIOPEN_FIND_DB_PATH=/tmp/miopen/find-db ENV MIOPEN_USER_DB_PATH=/tmp/miopen/user-db ENV LD_LIBRARY_PATH=$PREFIX/lib diff --git a/Jenkinsfile b/Jenkinsfile index 7ef665f605d..1c402e96b1a 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -26,7 +26,7 @@ def rocmtestnode(Map conf) { rm -rf build mkdir build cd build - cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DBUILD_DEV=On ${flags} .. + cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DBUILD_DEV=On -DCMAKE_EXECUTE_PROCESS_COMMAND_ECHO=STDOUT ${flags} .. git diff git diff-index --quiet HEAD || (echo "Git repo is not clean after running cmake." && exit 1) make -j\$(nproc) generate VERBOSE=1 @@ -90,7 +90,7 @@ def rocmnodename(name) { } else if(name == "mi100+") { node_name = "${rocmtest_name} && (gfx908 || gfx90a) && !vm"; } else if(name == "cdna") { - node_name = "${rocmtest_name} && (gfx908 || gfx90a || vega) && !vm"; + node_name = "${rocmtest_name} && (gfx908 || gfx90a || vega20) && !vm"; } else if(name == "nogpu") { node_name = "${rocmtest_name} && nogpu"; } @@ -114,6 +114,10 @@ rocmtest clang_debug: rocmnode('cdna') { cmake_build -> cmake_build(flags: "-DCMAKE_BUILD_TYPE=release") stash includes: 'build/*.deb', name: 'migraphx-package' } +// }, hidden_symbols: rocmnode('cdna') { cmake_build -> +// stage('Hidden symbols') { +// cmake_build(flags: "-DMIGRAPHX_ENABLE_PYTHON=Off -DMIGRAPHX_ENABLE_GPU=On -DMIGRAPHX_ENABLE_CPU=On -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_C_VISIBILITY_PRESET=hidden") +// } }, all_targets_debug : rocmnode('cdna') { cmake_build -> stage('All targets Release') { cmake_build(flags: "-DCMAKE_BUILD_TYPE=release -DMIGRAPHX_ENABLE_GPU=On -DMIGRAPHX_ENABLE_CPU=On -DMIGRAPHX_ENABLE_FPGA=On") diff --git a/cmake/Embed.cmake b/cmake/Embed.cmake index 66ba4a53b9d..5a120e18339 100755 --- a/cmake/Embed.cmake +++ b/cmake/Embed.cmake @@ -24,11 +24,7 @@ find_program(EMBED_LD ld) find_program(EMBED_OBJCOPY objcopy) -if(LINUX) - option(EMBED_USE_LD "Use ld to embed data files" ON) -else() - option(EMBED_USE_LD "Use ld to embed data files" OFF) -endif() +option(EMBED_USE_LD "Use ld to embed data files" OFF) function(wrap_string) set(options) @@ -60,8 +56,8 @@ endfunction() function(generate_embed_source EMBED_NAME) set(options) - set(oneValueArgs SRC HEADER) - set(multiValueArgs OBJECTS SYMBOLS) + set(oneValueArgs SRC HEADER RELATIVE) + set(multiValueArgs OBJECTS SYMBOLS FILES) cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -78,6 +74,8 @@ function(generate_embed_source EMBED_NAME) foreach(idx RANGE ${LEN}) list(GET PARSE_SYMBOLS ${idx} SYMBOL) list(GET PARSE_OBJECTS ${idx} OBJECT) + list(GET PARSE_FILES ${idx} FILE) + set(START_SYMBOL "_binary_${SYMBOL}_start") set(END_SYMBOL "_binary_${SYMBOL}_end") if(EMBED_USE_LD) @@ -92,9 +90,11 @@ function(generate_embed_source EMBED_NAME) ") endif() - # TODO: Should use NAME_WLE - get_filename_component(BASE_NAME "${OBJECT}" NAME) - string(REGEX REPLACE ".[A-Za-z0-9_]+$" "" BASE_NAME ${BASE_NAME}) + if(PARSE_RELATIVE) + file(RELATIVE_PATH BASE_NAME ${PARSE_RELATIVE} "${FILE}") + else() + get_filename_component(BASE_NAME "${FILE}" NAME) + endif() string(APPEND INIT_KERNELS " { \"${BASE_NAME}\", { ${START_SYMBOL}, ${END_SYMBOL}} }, @@ -162,6 +162,11 @@ function(embed_file OUTPUT_FILE OUTPUT_SYMBOL FILE) endfunction() function(add_embed_library EMBED_NAME) + set(options) + set(oneValueArgs RELATIVE) + set(multiValueArgs) + cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/embed) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/embed/${EMBED_NAME}) set(EMBED_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed/${EMBED_NAME}) @@ -171,15 +176,26 @@ function(add_embed_library EMBED_NAME) set(OUTPUT_FILES) set(SYMBOLS) message(STATUS "Embedding files") - foreach(FILE ${ARGN}) + foreach(FILE ${PARSE_UNPARSED_ARGUMENTS}) embed_file(OUTPUT_FILE OUTPUT_SYMBOL ${FILE}) list(APPEND OUTPUT_FILES ${OUTPUT_FILE}) list(APPEND SYMBOLS ${OUTPUT_SYMBOL}) endforeach() message(STATUS "Generating embedding library ${EMBED_NAME}") - generate_embed_source(${EMBED_NAME} SRC ${SRC_FILE} HEADER ${HEADER_FILE} OBJECTS ${OUTPUT_FILES} SYMBOLS ${SYMBOLS}) - add_library(${EMBED_NAME} STATIC ${OUTPUT_FILES} "${SRC_FILE}") - target_include_directories(${EMBED_NAME} PUBLIC "${EMBED_DIR}/include") - target_compile_options(${EMBED_NAME} PRIVATE -Wno-reserved-identifier -Wno-extern-initializer -Wno-missing-variable-declarations) - set_target_properties(${EMBED_NAME} PROPERTIES POSITION_INDEPENDENT_CODE On) + generate_embed_source(${EMBED_NAME} SRC ${SRC_FILE} HEADER ${HEADER_FILE} OBJECTS ${OUTPUT_FILES} SYMBOLS ${SYMBOLS} RELATIVE ${PARSE_RELATIVE} FILES ${PARSE_UNPARSED_ARGUMENTS}) + + set(INTERNAL_EMBED_LIB embed_lib_${EMBED_NAME}) + add_library(${INTERNAL_EMBED_LIB} OBJECT "${SRC_FILE}") + target_include_directories(${INTERNAL_EMBED_LIB} PRIVATE "${EMBED_DIR}/include") + target_compile_options(${INTERNAL_EMBED_LIB} PRIVATE -Wno-reserved-identifier -Wno-extern-initializer -Wno-missing-variable-declarations) + set_target_properties(${INTERNAL_EMBED_LIB} PROPERTIES POSITION_INDEPENDENT_CODE On) + + add_library(${EMBED_NAME} INTERFACE) + if(EMBED_USE_LD) + target_sources(${EMBED_NAME} INTERFACE ${OUTPUT_FILES}) + else() + target_sources(${INTERNAL_EMBED_LIB} PRIVATE ${OUTPUT_FILES}) + endif() + target_sources(${EMBED_NAME} INTERFACE $) + target_include_directories(${EMBED_NAME} INTERFACE "${EMBED_DIR}/include") endfunction() diff --git a/cmake/ExportHeader.cmake b/cmake/ExportHeader.cmake index f9d20dba0bf..a098f58f0ef 100644 --- a/cmake/ExportHeader.cmake +++ b/cmake/ExportHeader.cmake @@ -29,7 +29,10 @@ endif() include(GenerateExportHeader) function(migraphx_generate_export_header TARGET) - cmake_parse_arguments(PARSE "" "DIRECTORY" "" ${ARGN}) + set(options) + set(oneValueArgs DIRECTORY) + set(multiValueArgs) + cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(PARSE_DIRECTORY) set(__directory ${PARSE_DIRECTORY}) else() diff --git a/cmake/PythonModules.cmake b/cmake/PythonModules.cmake index b5818cef5b2..224a2378e54 100755 --- a/cmake/PythonModules.cmake +++ b/cmake/PythonModules.cmake @@ -38,12 +38,22 @@ macro(find_python version) find_program(PYTHON_CONFIG_${version} python${version}-config) if(EXISTS ${PYTHON_CONFIG_${version}}) py_exec(COMMAND ${PYTHON_CONFIG_${version}} --includes OUTPUT_VARIABLE _python_include_args) + execute_process(COMMAND ${PYTHON_CONFIG_${version}} --ldflags --embed OUTPUT_VARIABLE _python_ldflags_args RESULT_VARIABLE _python_ldflags_result) + if(NOT _python_ldflags_result EQUAL 0) + py_exec(COMMAND ${PYTHON_CONFIG_${version}} --ldflags OUTPUT_VARIABLE _python_ldflags_args) + endif() separate_arguments(_python_includes UNIX_COMMAND "${_python_include_args}") + separate_arguments(_python_ldflags UNIX_COMMAND "${_python_ldflags_args}") string(REPLACE "-I" "" _python_includes "${_python_includes}") add_library(python${version}::headers INTERFACE IMPORTED GLOBAL) set_target_properties(python${version}::headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_python_includes}" ) + add_library(python${version}::runtime INTERFACE IMPORTED GLOBAL) + set_target_properties(python${version}::runtime PROPERTIES + INTERFACE_LINK_OPTIONS "${_python_ldflags}" + INTERFACE_LINK_LIBRARIES python${version}::headers + ) py_exec(COMMAND ${PYTHON_CONFIG_${version}} --prefix OUTPUT_VARIABLE _python_prefix) string(STRIP "${_python_prefix}" _python_prefix) set(PYTHON_${version}_EXECUTABLE "${_python_prefix}/bin/python${version}" CACHE PATH "") diff --git a/cppcheck.rules b/cppcheck.rules index 013cb03896e..5e47caf5a61 100755 --- a/cppcheck.rules +++ b/cppcheck.rules @@ -107,6 +107,24 @@ Use make_shared or make_unique instead of new + + raw + + + UseNamedLogicOperator + style + Use 'and' instead of && + + + + raw + + + UseNamedLogicOperator + style + Use 'and' instead of && + + raw diff --git a/dev-requirements.txt b/dev-requirements.txt index 9b463f29dc7..4b19a54d38e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -25,6 +25,6 @@ ROCmSoftwarePlatform/rocm-recipes facebook/zstd@v1.4.5 -X subdir -DCMAKE_DIR=build/cmake ccache@v4.1 -DENABLE_TESTING=OFF pcre,pfultz2/pcre@8.45 -H sha256:d6f7182602a775a7d500a0cedca6449af0400c6493951513046d17615ed0bf11 -danmar/cppcheck@2.9 -DHAVE_RULES=1 -RadeonOpenCompute/rocm-cmake@027404a8326da6e7e9338e0b81f9428660190724 --build +danmar/cppcheck@bb2711c22a0be09efe7f1a8da3030876471026c8 -DHAVE_RULES=1 # 2.11 +RadeonOpenCompute/rocm-cmake@189d497ed185683154ae9766393b9a10ff21201f --build -f requirements.txt diff --git a/docs/.sphinx/requirements.in b/docs/.sphinx/requirements.in index b8366edf9ec..781cd3ac310 100644 --- a/docs/.sphinx/requirements.in +++ b/docs/.sphinx/requirements.in @@ -1 +1 @@ -rocm-docs-core==0.11.0 +rocm-docs-core>=0.20.0 diff --git a/docs/.sphinx/requirements.txt b/docs/.sphinx/requirements.txt index 8a597fc88c3..55d6c9742f0 100644 --- a/docs/.sphinx/requirements.txt +++ b/docs/.sphinx/requirements.txt @@ -1,29 +1,4 @@ # Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile requirements.in -# accessible-pygments==0.0.4 # via pydata-sphinx-theme alabaster==0.7.13 @@ -46,7 +21,7 @@ charset-normalizer==3.1.0 # via requests click==8.1.3 # via sphinx-external-toc -cryptography==40.0.2 +cryptography==41.0.3 # via pyjwt deprecated==1.2.13 # via pygithub @@ -60,22 +35,16 @@ fastjsonschema==2.16.3 # via rocm-docs-core gitdb==4.0.10 # via gitpython -gitpython==3.1.31 +gitpython==3.1.32 # via rocm-docs-core idna==3.4 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==6.4.1 - # via sphinx -importlib-resources==5.12.0 - # via rocm-docs-core jinja2==3.1.2 # via # myst-parser # sphinx -linkify-it-py==1.0.3 - # via myst-parser markdown-it-py==2.2.0 # via # mdit-py-plugins @@ -86,7 +55,7 @@ mdit-py-plugins==0.3.5 # via myst-parser mdurl==0.1.2 # via markdown-it-py -myst-parser[linkify]==1.0.0 +myst-parser==1.0.0 # via rocm-docs-core packaging==23.1 # via @@ -109,8 +78,6 @@ pyjwt[crypto]==2.6.0 # via pygithub pynacl==1.5.0 # via pygithub -pytz==2023.3 - # via babel pyyaml==6.0 # via # myst-parser @@ -120,7 +87,7 @@ requests==2.28.2 # via # pygithub # sphinx -rocm-docs-core==0.11.0 +rocm-docs-core>=0.20.0 # via -r requirements.in smmap==5.0.0 # via gitdb @@ -163,13 +130,7 @@ sphinxcontrib-serializinghtml==1.1.5 # via sphinx typing-extensions==4.5.0 # via pydata-sphinx-theme -uc-micro-py==1.0.1 - # via linkify-it-py urllib3==1.26.15 # via requests wrapt==1.15.0 # via deprecated -zipp==3.15.0 - # via - # importlib-metadata - # importlib-resources diff --git a/docs/driver/read.rst b/docs/driver/read.rst index baf5d63530b..58baf9d32c5 100755 --- a/docs/driver/read.rst +++ b/docs/driver/read.rst @@ -82,6 +82,10 @@ Print out program in text format. Print out program in binary format. +.. option:: --py + +Print out program using python API. + .. option:: --output, -o [std::string] Output to file. diff --git a/examples/migraphx/cpp_parse_load_save/parse_load_save.cpp b/examples/migraphx/cpp_parse_load_save/parse_load_save.cpp index 79cc03d7bc1..70d31daf451 100644 --- a/examples/migraphx/cpp_parse_load_save/parse_load_save.cpp +++ b/examples/migraphx/cpp_parse_load_save/parse_load_save.cpp @@ -114,7 +114,7 @@ int main(int argc, char** argv) char* getCmdOption(char** begin, char** end, const std::string& option) { char** itr = std::find(begin, end, option); - if(itr != end && ++itr != end) + if(itr != end and ++itr != end) { return *itr; } diff --git a/examples/vision/cpp_mnist/mnist_inference.cpp b/examples/vision/cpp_mnist/mnist_inference.cpp index 5db9de902e2..8f46e2c0965 100644 --- a/examples/vision/cpp_mnist/mnist_inference.cpp +++ b/examples/vision/cpp_mnist/mnist_inference.cpp @@ -160,9 +160,9 @@ int main(int argc, char** argv) auto lengths = shape.lengths(); auto num_results = std::accumulate(lengths.begin(), lengths.end(), 1, std::multiplies()); - float* results = reinterpret_cast(outputs[0].data()); - float* max = std::max_element(results, results + num_results); - int answer = max - results; + float* results = reinterpret_cast(outputs[0].data()); + const float* max = std::max_element(results, results + num_results); + int answer = max - results; std::cout << std::endl << "Randomly chosen digit: " << rand_digit << std::endl @@ -192,12 +192,12 @@ void read_nth_digit(const int n, std::vector& digit) for(int i = 0; i < HEIGHT * WIDTH; ++i) { unsigned char temp = 0; - file.read((char*)&temp, sizeof(temp)); + file.read(reinterpret_cast(&temp), sizeof(temp)); if(d == n) { float data = temp / 255.0; digit.push_back(data); - std::cout << SYMBOLS[(int)(data * 10) % 11]; + std::cout << SYMBOLS[static_cast(data * 10) % 11]; if((i + 1) % WIDTH == 0) std::cout << std::endl; } diff --git a/hip-clang.docker b/hip-clang.docker index 815969a8863..c44e09fe73b 100755 --- a/hip-clang.docker +++ b/hip-clang.docker @@ -54,5 +54,12 @@ ADD dev-requirements.txt /dev-requirements.txt ADD requirements.txt /requirements.txt ADD rbuild.ini /rbuild.ini +# Temporarily install a new cmake until switching to ubuntu 22.04 +RUN pip3 install cmake==3.22.1 + COPY ./tools/install_prereqs.sh / RUN /install_prereqs.sh /usr/local / && rm /install_prereqs.sh + +# Install MLIR +ADD mlir-requirements.txt /mlir-requirements.txt +RUN cget -p /usr/local install -f /mlir-requirements.txt diff --git a/mlir-requirements.txt b/mlir-requirements.txt new file mode 100644 index 00000000000..2e3f001355f --- /dev/null +++ b/mlir-requirements.txt @@ -0,0 +1,24 @@ +##################################################################################### +# The MIT License (MIT) +# +# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +##################################################################################### +ROCmSoftwarePlatform/rocMLIR@3657f509bfed86bb79d5c6e24aa237e48f09f9f3 -DBUILD_FAT_LIBROCKCOMPILER=On diff --git a/rbuild.ini b/rbuild.ini index 90ccb1ab108..4c0973f265f 100755 --- a/rbuild.ini +++ b/rbuild.ini @@ -6,7 +6,9 @@ deps = -f requirements.txt [gh] -ignore = danmar/cppcheck +ignore = + danmar/cppcheck + ROCmSoftwarePlatform/rocMLIR deps = -f dev-requirements.txt oneapi-src/oneDNN@v1.7 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b5e600a199..62815382990 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -249,8 +249,6 @@ endif() target_link_libraries(migraphx PRIVATE -ldl) target_include_directories(migraphx SYSTEM PUBLIC $) - -find_package(Threads) target_link_libraries(migraphx PUBLIC Threads::Threads) find_package(nlohmann_json 3.8.0 REQUIRED) diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 1354e386d72..89cd0ad8cff 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(migraphx_c api.cpp ) set_target_properties(migraphx_c PROPERTIES EXPORT_NAME c) +migraphx_generate_export_header(migraphx_c DIRECTORY migraphx/api) # migraphx_c is stable API interface library. SO version of this should be # bumped when binary compatibility is broken. diff --git a/src/api/api.cpp b/src/api/api.cpp index 8e2bf1629a1..7a1bbabf1f5 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -44,7 +44,7 @@ namespace migraphx { static thread_local bool disable_exception_catch = false; // NOLINT -extern "C" void migraphx_test_private_disable_exception_catch(bool b) +extern "C" MIGRAPHX_C_EXPORT void migraphx_test_private_disable_exception_catch(bool b) { disable_exception_catch = b; } @@ -899,7 +899,7 @@ migraphx_dynamic_dimensions_assign_to(migraphx_dynamic_dimensions_t output, extern "C" migraphx_status migraphx_dynamic_dimensions_create(migraphx_dynamic_dimensions_t* dynamic_dimensions, - const_migraphx_dynamic_dimension_t* ptr, + const const_migraphx_dynamic_dimension_t* ptr, size_t size) { auto api_error_result = migraphx::try_([&] { @@ -1432,7 +1432,7 @@ extern "C" migraphx_status migraphx_instructions_assign_to(migraphx_instructions } extern "C" migraphx_status migraphx_instructions_create(migraphx_instructions_t* instructions, - const_migraphx_instruction_t* ptr, + const const_migraphx_instruction_t* ptr, size_t size) { auto api_error_result = migraphx::try_([&] { diff --git a/src/api/include/migraphx/migraphx.h b/src/api/include/migraphx/migraphx.h index 4a5509343b8..bb26ec2a3d9 100644 --- a/src/api/include/migraphx/migraphx.h +++ b/src/api/include/migraphx/migraphx.h @@ -26,6 +26,9 @@ #include #include + +#include + // Add new types here // clang-format off #define MIGRAPHX_SHAPE_VISIT_TYPES(m) \ @@ -166,430 +169,460 @@ typedef migraphx_status (*migraphx_experimental_custom_op_copy)(void** out, void typedef migraphx_status (*migraphx_experimental_custom_op_delete)(void* input); -migraphx_status migraphx_optimals_destroy(migraphx_optimals_t optimals); +MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_destroy(migraphx_optimals_t optimals); -migraphx_status migraphx_optimals_assign_to(migraphx_optimals_t output, - const_migraphx_optimals_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_assign_to(migraphx_optimals_t output, + const_migraphx_optimals_t input); -migraphx_status -migraphx_optimals_create(migraphx_optimals_t* optimals, const size_t* ptr, size_t size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_create(migraphx_optimals_t* optimals, + const size_t* ptr, + size_t size); -migraphx_status migraphx_dynamic_dimension_destroy(migraphx_dynamic_dimension_t dynamic_dimension); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_dynamic_dimension_destroy(migraphx_dynamic_dimension_t dynamic_dimension); -migraphx_status migraphx_dynamic_dimension_assign_to(migraphx_dynamic_dimension_t output, - const_migraphx_dynamic_dimension_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_assign_to( + migraphx_dynamic_dimension_t output, const_migraphx_dynamic_dimension_t input); -migraphx_status migraphx_dynamic_dimension_create_min_max( +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_create_min_max( migraphx_dynamic_dimension_t* dynamic_dimension, size_t min, size_t max); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_create_min_max_optimals(migraphx_dynamic_dimension_t* dynamic_dimension, size_t min, size_t max, migraphx_optimals_t optimals); -migraphx_status -migraphx_dynamic_dimension_is_fixed(bool* out, - const_migraphx_dynamic_dimension_t dynamic_dimension); +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_is_fixed( + bool* out, const_migraphx_dynamic_dimension_t dynamic_dimension); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_equal(bool* out, const_migraphx_dynamic_dimension_t dynamic_dimension, const_migraphx_dynamic_dimension_t x); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimensions_destroy(migraphx_dynamic_dimensions_t dynamic_dimensions); -migraphx_status migraphx_dynamic_dimensions_assign_to(migraphx_dynamic_dimensions_t output, - const_migraphx_dynamic_dimensions_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimensions_assign_to( + migraphx_dynamic_dimensions_t output, const_migraphx_dynamic_dimensions_t input); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimensions_create(migraphx_dynamic_dimensions_t* dynamic_dimensions, - const_migraphx_dynamic_dimension_t* ptr, + const const_migraphx_dynamic_dimension_t* ptr, size_t size); -migraphx_status migraphx_dynamic_dimensions_size(size_t* out, - migraphx_dynamic_dimensions_t dynamic_dimensions); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_dynamic_dimensions_size(size_t* out, migraphx_dynamic_dimensions_t dynamic_dimensions); -migraphx_status migraphx_dynamic_dimensions_get(const_migraphx_dynamic_dimension_t* out, - migraphx_dynamic_dimensions_t dynamic_dimensions, - size_t idx); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_dynamic_dimensions_get(const_migraphx_dynamic_dimension_t* out, + migraphx_dynamic_dimensions_t dynamic_dimensions, + size_t idx); -migraphx_status migraphx_shape_destroy(migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_destroy(migraphx_shape_t shape); -migraphx_status migraphx_shape_assign_to(migraphx_shape_t output, const_migraphx_shape_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_assign_to(migraphx_shape_t output, + const_migraphx_shape_t input); -migraphx_status migraphx_shape_create(migraphx_shape_t* shape, - migraphx_shape_datatype_t type, - size_t* lengths, - size_t lengths_size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create(migraphx_shape_t* shape, + migraphx_shape_datatype_t type, + size_t* lengths, + size_t lengths_size); -migraphx_status migraphx_shape_create_with_strides(migraphx_shape_t* shape, - migraphx_shape_datatype_t type, - size_t* lengths, - size_t lengths_size, - size_t* strides, - size_t strides_size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_with_strides(migraphx_shape_t* shape, + migraphx_shape_datatype_t type, + size_t* lengths, + size_t lengths_size, + size_t* strides, + size_t strides_size); -migraphx_status migraphx_shape_create_scalar(migraphx_shape_t* shape, - migraphx_shape_datatype_t type); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_scalar(migraphx_shape_t* shape, + migraphx_shape_datatype_t type); -migraphx_status migraphx_shape_create_dynamic(migraphx_shape_t* shape, - migraphx_shape_datatype_t type, - migraphx_dynamic_dimensions_t dims); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_dynamic(migraphx_shape_t* shape, + migraphx_shape_datatype_t type, + migraphx_dynamic_dimensions_t dims); -migraphx_status -migraphx_shape_lengths(const size_t** out, size_t* out_size, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_lengths(const size_t** out, + size_t* out_size, + const_migraphx_shape_t shape); -migraphx_status -migraphx_shape_strides(const size_t** out, size_t* out_size, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_strides(const size_t** out, + size_t* out_size, + const_migraphx_shape_t shape); -migraphx_status migraphx_shape_dyn_dims(migraphx_dynamic_dimensions_t* out, - const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_dyn_dims(migraphx_dynamic_dimensions_t* out, + const_migraphx_shape_t shape); -migraphx_status migraphx_shape_type(migraphx_shape_datatype_t* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_type(migraphx_shape_datatype_t* out, + const_migraphx_shape_t shape); -migraphx_status migraphx_shape_elements(size_t* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_elements(size_t* out, + const_migraphx_shape_t shape); -migraphx_status migraphx_shape_bytes(size_t* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_bytes(size_t* out, const_migraphx_shape_t shape); -migraphx_status migraphx_shape_ndim(size_t* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_ndim(size_t* out, const_migraphx_shape_t shape); -migraphx_status -migraphx_shape_equal(bool* out, const_migraphx_shape_t shape, const_migraphx_shape_t x); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_equal(bool* out, + const_migraphx_shape_t shape, + const_migraphx_shape_t x); -migraphx_status migraphx_shape_standard(bool* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_standard(bool* out, const_migraphx_shape_t shape); -migraphx_status migraphx_shape_dynamic(bool* out, const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_dynamic(bool* out, const_migraphx_shape_t shape); -migraphx_status migraphx_shape_index(size_t* out, const_migraphx_shape_t shape, size_t i); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_index(size_t* out, + const_migraphx_shape_t shape, + size_t i); -migraphx_status migraphx_argument_destroy(migraphx_argument_t argument); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_destroy(migraphx_argument_t argument); -migraphx_status migraphx_argument_assign_to(migraphx_argument_t output, - const_migraphx_argument_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_assign_to(migraphx_argument_t output, + const_migraphx_argument_t input); -migraphx_status -migraphx_argument_create(migraphx_argument_t* argument, const_migraphx_shape_t shape, void* buffer); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_create(migraphx_argument_t* argument, + const_migraphx_shape_t shape, + void* buffer); -migraphx_status migraphx_argument_create_empty(migraphx_argument_t* argument, - const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_create_empty(migraphx_argument_t* argument, + const_migraphx_shape_t shape); -migraphx_status migraphx_argument_shape(const_migraphx_shape_t* out, - const_migraphx_argument_t argument); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_shape(const_migraphx_shape_t* out, + const_migraphx_argument_t argument); -migraphx_status migraphx_argument_buffer(char** out, const_migraphx_argument_t argument); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_buffer(char** out, + const_migraphx_argument_t argument); -migraphx_status -migraphx_argument_equal(bool* out, const_migraphx_argument_t argument, const_migraphx_argument_t x); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_equal(bool* out, + const_migraphx_argument_t argument, + const_migraphx_argument_t x); -migraphx_status -migraphx_argument_generate(migraphx_argument_t* out, const_migraphx_shape_t s, size_t seed); +MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_generate(migraphx_argument_t* out, + const_migraphx_shape_t s, + size_t seed); -migraphx_status migraphx_target_destroy(migraphx_target_t target); +MIGRAPHX_C_EXPORT migraphx_status migraphx_target_destroy(migraphx_target_t target); -migraphx_status migraphx_target_assign_to(migraphx_target_t output, const_migraphx_target_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_target_assign_to(migraphx_target_t output, + const_migraphx_target_t input); -migraphx_status migraphx_target_create(migraphx_target_t* target, const char* name); +MIGRAPHX_C_EXPORT migraphx_status migraphx_target_create(migraphx_target_t* target, + const char* name); -migraphx_status migraphx_program_parameter_shapes_destroy( +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_destroy( migraphx_program_parameter_shapes_t program_parameter_shapes); -migraphx_status -migraphx_program_parameter_shapes_assign_to(migraphx_program_parameter_shapes_t output, - const_migraphx_program_parameter_shapes_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_assign_to( + migraphx_program_parameter_shapes_t output, const_migraphx_program_parameter_shapes_t input); -migraphx_status migraphx_program_parameter_shapes_size( +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_size( size_t* out, migraphx_program_parameter_shapes_t program_parameter_shapes); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_get(const_migraphx_shape_t* out, migraphx_program_parameter_shapes_t program_parameter_shapes, const char* name); -migraphx_status migraphx_program_parameter_shapes_names( +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_names( const char** out, migraphx_program_parameter_shapes_t program_parameter_shapes); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameters_destroy(migraphx_program_parameters_t program_parameters); -migraphx_status migraphx_program_parameters_assign_to(migraphx_program_parameters_t output, - const_migraphx_program_parameters_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameters_assign_to( + migraphx_program_parameters_t output, const_migraphx_program_parameters_t input); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameters_create(migraphx_program_parameters_t* program_parameters); -migraphx_status migraphx_program_parameters_add(migraphx_program_parameters_t program_parameters, - const char* name, - const_migraphx_argument_t argument); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_program_parameters_add(migraphx_program_parameters_t program_parameters, + const char* name, + const_migraphx_argument_t argument); -migraphx_status migraphx_arguments_destroy(migraphx_arguments_t arguments); +MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_destroy(migraphx_arguments_t arguments); -migraphx_status migraphx_arguments_assign_to(migraphx_arguments_t output, - const_migraphx_arguments_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_assign_to(migraphx_arguments_t output, + const_migraphx_arguments_t input); -migraphx_status migraphx_arguments_size(size_t* out, migraphx_arguments_t arguments); +MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_size(size_t* out, + migraphx_arguments_t arguments); -migraphx_status -migraphx_arguments_get(const_migraphx_argument_t* out, migraphx_arguments_t arguments, size_t idx); +MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_get(const_migraphx_argument_t* out, + migraphx_arguments_t arguments, + size_t idx); -migraphx_status migraphx_shapes_destroy(migraphx_shapes_t shapes); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_destroy(migraphx_shapes_t shapes); -migraphx_status migraphx_shapes_assign_to(migraphx_shapes_t output, const_migraphx_shapes_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_assign_to(migraphx_shapes_t output, + const_migraphx_shapes_t input); -migraphx_status migraphx_shapes_size(size_t* out, migraphx_shapes_t shapes); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_size(size_t* out, migraphx_shapes_t shapes); -migraphx_status -migraphx_shapes_get(const_migraphx_shape_t* out, migraphx_shapes_t shapes, size_t idx); +MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_get(const_migraphx_shape_t* out, + migraphx_shapes_t shapes, + size_t idx); -migraphx_status migraphx_instruction_destroy(migraphx_instruction_t instruction); +MIGRAPHX_C_EXPORT migraphx_status migraphx_instruction_destroy(migraphx_instruction_t instruction); -migraphx_status migraphx_instruction_assign_to(migraphx_instruction_t output, - const_migraphx_instruction_t input); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_instruction_assign_to(migraphx_instruction_t output, const_migraphx_instruction_t input); -migraphx_status migraphx_instructions_destroy(migraphx_instructions_t instructions); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_instructions_destroy(migraphx_instructions_t instructions); -migraphx_status migraphx_instructions_assign_to(migraphx_instructions_t output, - const_migraphx_instructions_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_instructions_assign_to( + migraphx_instructions_t output, const_migraphx_instructions_t input); -migraphx_status migraphx_instructions_create(migraphx_instructions_t* instructions, - const_migraphx_instruction_t* ptr, - size_t size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_instructions_create( + migraphx_instructions_t* instructions, const const_migraphx_instruction_t* ptr, size_t size); -migraphx_status migraphx_modules_destroy(migraphx_modules_t modules); +MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_destroy(migraphx_modules_t modules); -migraphx_status migraphx_modules_assign_to(migraphx_modules_t output, - const_migraphx_modules_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_assign_to(migraphx_modules_t output, + const_migraphx_modules_t input); -migraphx_status -migraphx_modules_create(migraphx_modules_t* modules, migraphx_module_t* ptr, size_t size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_create(migraphx_modules_t* modules, + migraphx_module_t* ptr, + size_t size); -migraphx_status migraphx_module_create(migraphx_module_t* module, char* name); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_create(migraphx_module_t* module, char* name); -migraphx_status migraphx_module_print(const_migraphx_module_t module); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_print(const_migraphx_module_t module); -migraphx_status migraphx_module_add_instruction(migraphx_instruction_t* out, - migraphx_module_t module, - migraphx_operation_t op, - migraphx_instructions_t args); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_instruction(migraphx_instruction_t* out, + migraphx_module_t module, + migraphx_operation_t op, + migraphx_instructions_t args); -migraphx_status migraphx_module_add_instruction_with_mod_args(migraphx_instruction_t* out, - migraphx_module_t module, - migraphx_operation_t op, - migraphx_instructions_t args, - migraphx_modules_t module_refs); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_module_add_instruction_with_mod_args(migraphx_instruction_t* out, + migraphx_module_t module, + migraphx_operation_t op, + migraphx_instructions_t args, + migraphx_modules_t module_refs); -migraphx_status migraphx_module_add_literal(migraphx_instruction_t* out, - migraphx_module_t module, - const_migraphx_shape_t shape, - const char* buffer); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_literal(migraphx_instruction_t* out, + migraphx_module_t module, + const_migraphx_shape_t shape, + const char* buffer); -migraphx_status migraphx_module_add_parameter(migraphx_instruction_t* out, - migraphx_module_t module, - const char* name, - const_migraphx_shape_t shape); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_parameter(migraphx_instruction_t* out, + migraphx_module_t module, + const char* name, + const_migraphx_shape_t shape); -migraphx_status migraphx_module_add_return(migraphx_instruction_t* out, - migraphx_module_t module, - migraphx_instructions_t args); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_return(migraphx_instruction_t* out, + migraphx_module_t module, + migraphx_instructions_t args); -migraphx_status migraphx_module_add_allocation(migraphx_instruction_t* out, - migraphx_module_t module, - const_migraphx_shape_t s); +MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_allocation(migraphx_instruction_t* out, + migraphx_module_t module, + const_migraphx_shape_t s); -migraphx_status migraphx_program_destroy(migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_destroy(migraphx_program_t program); -migraphx_status migraphx_program_assign_to(migraphx_program_t output, - const_migraphx_program_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_assign_to(migraphx_program_t output, + const_migraphx_program_t input); -migraphx_status migraphx_program_create(migraphx_program_t* program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_create(migraphx_program_t* program); -migraphx_status migraphx_program_get_main_module(migraphx_module_t* out, - migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_main_module(migraphx_module_t* out, + migraphx_program_t program); -migraphx_status migraphx_program_create_module(migraphx_module_t* out, - migraphx_program_t program, - const char* name); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_create_module(migraphx_module_t* out, + migraphx_program_t program, + const char* name); -migraphx_status migraphx_program_compile(migraphx_program_t program, - migraphx_target_t target, - migraphx_compile_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_compile(migraphx_program_t program, + migraphx_target_t target, + migraphx_compile_options_t options); -migraphx_status migraphx_program_get_parameter_shapes(migraphx_program_parameter_shapes_t* out, - migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_parameter_shapes( + migraphx_program_parameter_shapes_t* out, migraphx_program_t program); -migraphx_status migraphx_program_get_output_shapes(migraphx_shapes_t* out, - migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_output_shapes(migraphx_shapes_t* out, + migraphx_program_t program); -migraphx_status migraphx_program_print(const_migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_print(const_migraphx_program_t program); -migraphx_status migraphx_program_sort(migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_sort(migraphx_program_t program); -migraphx_status migraphx_program_run(migraphx_arguments_t* out, - migraphx_program_t program, - migraphx_program_parameters_t params); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_run(migraphx_arguments_t* out, + migraphx_program_t program, + migraphx_program_parameters_t params); -migraphx_status migraphx_program_run_async(migraphx_arguments_t* out, - migraphx_program_t program, - migraphx_program_parameters_t params, - void* s, - const char* name); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_run_async(migraphx_arguments_t* out, + migraphx_program_t program, + migraphx_program_parameters_t params, + void* s, + const char* name); -migraphx_status -migraphx_program_equal(bool* out, const_migraphx_program_t program, const_migraphx_program_t x); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_equal(bool* out, + const_migraphx_program_t program, + const_migraphx_program_t x); -migraphx_status migraphx_program_experimental_get_context(migraphx_context_t* out, - const_migraphx_program_t program); +MIGRAPHX_C_EXPORT migraphx_status migraphx_program_experimental_get_context( + migraphx_context_t* out, const_migraphx_program_t program); -migraphx_status migraphx_operation_destroy(migraphx_operation_t operation); +MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_destroy(migraphx_operation_t operation); -migraphx_status migraphx_operation_assign_to(migraphx_operation_t output, - const_migraphx_operation_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_assign_to(migraphx_operation_t output, + const_migraphx_operation_t input); -migraphx_status migraphx_operation_create(migraphx_operation_t* operation, - const char* name, - const char* attributes, - ...); +MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_create(migraphx_operation_t* operation, + const char* name, + const char* attributes, + ...); -migraphx_status migraphx_operation_name(char* out, size_t out_size, migraphx_operation_t operation); +MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_name(char* out, + size_t out_size, + migraphx_operation_t operation); -migraphx_status -migraphx_load(migraphx_program_t* out, const char* name, migraphx_file_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_load(migraphx_program_t* out, + const char* name, + migraphx_file_options_t options); -migraphx_status -migraphx_save(migraphx_program_t p, const char* name, migraphx_file_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_save(migraphx_program_t p, + const char* name, + migraphx_file_options_t options); -migraphx_status migraphx_onnx_options_destroy(migraphx_onnx_options_t onnx_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_onnx_options_destroy(migraphx_onnx_options_t onnx_options); -migraphx_status migraphx_onnx_options_assign_to(migraphx_onnx_options_t output, - const_migraphx_onnx_options_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_assign_to( + migraphx_onnx_options_t output, const_migraphx_onnx_options_t input); -migraphx_status migraphx_onnx_options_create(migraphx_onnx_options_t* onnx_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_onnx_options_create(migraphx_onnx_options_t* onnx_options); -migraphx_status migraphx_onnx_options_set_input_parameter_shape( +MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_input_parameter_shape( migraphx_onnx_options_t onnx_options, const char* name, size_t* dims, size_t dims_size); -migraphx_status migraphx_onnx_options_set_dyn_input_parameter_shape( +MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_dyn_input_parameter_shape( migraphx_onnx_options_t onnx_options, const char* name, migraphx_dynamic_dimensions_t dims); -migraphx_status migraphx_onnx_options_set_default_dim_value(migraphx_onnx_options_t onnx_options, - size_t value); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_onnx_options_set_default_dim_value(migraphx_onnx_options_t onnx_options, size_t value); -migraphx_status -migraphx_onnx_options_set_default_dyn_dim_value(migraphx_onnx_options_t onnx_options, - const_migraphx_dynamic_dimension_t dd); +MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_default_dyn_dim_value( + migraphx_onnx_options_t onnx_options, const_migraphx_dynamic_dimension_t dd); -migraphx_status -migraphx_onnx_options_set_default_loop_iterations(migraphx_onnx_options_t onnx_options, - int64_t value); +MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_default_loop_iterations( + migraphx_onnx_options_t onnx_options, int64_t value); -migraphx_status migraphx_file_options_destroy(migraphx_file_options_t file_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_file_options_destroy(migraphx_file_options_t file_options); -migraphx_status migraphx_file_options_assign_to(migraphx_file_options_t output, - const_migraphx_file_options_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_file_options_assign_to( + migraphx_file_options_t output, const_migraphx_file_options_t input); -migraphx_status migraphx_file_options_create(migraphx_file_options_t* file_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_file_options_create(migraphx_file_options_t* file_options); -migraphx_status migraphx_file_options_set_file_format(migraphx_file_options_t file_options, - const char* format); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_file_options_set_file_format(migraphx_file_options_t file_options, const char* format); -migraphx_status migraphx_compile_options_destroy(migraphx_compile_options_t compile_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_compile_options_destroy(migraphx_compile_options_t compile_options); -migraphx_status migraphx_compile_options_assign_to(migraphx_compile_options_t output, - const_migraphx_compile_options_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_compile_options_assign_to( + migraphx_compile_options_t output, const_migraphx_compile_options_t input); -migraphx_status migraphx_compile_options_create(migraphx_compile_options_t* compile_options); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_compile_options_create(migraphx_compile_options_t* compile_options); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_compile_options_set_offload_copy(migraphx_compile_options_t compile_options, bool value); -migraphx_status migraphx_compile_options_set_fast_math(migraphx_compile_options_t compile_options, - bool value); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_compile_options_set_fast_math(migraphx_compile_options_t compile_options, bool value); -migraphx_status -migraphx_compile_options_set_exhaustive_tune_flag(migraphx_compile_options_t compile_options, - bool value); +MIGRAPHX_C_EXPORT migraphx_status migraphx_compile_options_set_exhaustive_tune_flag( + migraphx_compile_options_t compile_options, bool value); -migraphx_status -migraphx_parse_onnx(migraphx_program_t* out, const char* name, migraphx_onnx_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_onnx(migraphx_program_t* out, + const char* name, + migraphx_onnx_options_t options); -migraphx_status migraphx_parse_onnx_buffer(migraphx_program_t* out, - const void* data, - size_t size, - migraphx_onnx_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_onnx_buffer(migraphx_program_t* out, + const void* data, + size_t size, + migraphx_onnx_options_t options); -migraphx_status migraphx_tf_options_destroy(migraphx_tf_options_t tf_options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_destroy(migraphx_tf_options_t tf_options); -migraphx_status migraphx_tf_options_assign_to(migraphx_tf_options_t output, - const_migraphx_tf_options_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_assign_to(migraphx_tf_options_t output, + const_migraphx_tf_options_t input); -migraphx_status migraphx_tf_options_create(migraphx_tf_options_t* tf_options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_create(migraphx_tf_options_t* tf_options); -migraphx_status migraphx_tf_options_set_nhwc(migraphx_tf_options_t tf_options, bool is_nhwc); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_nhwc(migraphx_tf_options_t tf_options, + bool is_nhwc); -migraphx_status migraphx_tf_options_set_input_parameter_shape(migraphx_tf_options_t tf_options, - const char* name, - size_t* dims, - size_t dims_size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_input_parameter_shape( + migraphx_tf_options_t tf_options, const char* name, size_t* dims, size_t dims_size); -migraphx_status migraphx_tf_options_set_default_dim_value(migraphx_tf_options_t tf_options, - size_t value); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_tf_options_set_default_dim_value(migraphx_tf_options_t tf_options, size_t value); -migraphx_status migraphx_tf_options_set_output_names(migraphx_tf_options_t tf_options, - const char** names, - size_t names_size); +MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_output_names( + migraphx_tf_options_t tf_options, const char** names, size_t names_size); -migraphx_status -migraphx_parse_tf(migraphx_program_t* out, const char* name, migraphx_tf_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_tf(migraphx_program_t* out, + const char* name, + migraphx_tf_options_t options); -migraphx_status migraphx_quantize_op_names_destroy(migraphx_quantize_op_names_t quantize_op_names); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_quantize_op_names_destroy(migraphx_quantize_op_names_t quantize_op_names); -migraphx_status migraphx_quantize_op_names_assign_to(migraphx_quantize_op_names_t output, - const_migraphx_quantize_op_names_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_op_names_assign_to( + migraphx_quantize_op_names_t output, const_migraphx_quantize_op_names_t input); -migraphx_status migraphx_quantize_op_names_create(migraphx_quantize_op_names_t* quantize_op_names); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_quantize_op_names_create(migraphx_quantize_op_names_t* quantize_op_names); -migraphx_status migraphx_quantize_op_names_add(migraphx_quantize_op_names_t quantize_op_names, - const char* name); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_quantize_op_names_add(migraphx_quantize_op_names_t quantize_op_names, const char* name); -migraphx_status migraphx_quantize_fp16_with_op_names(migraphx_program_t prog, - migraphx_quantize_op_names_t name); +MIGRAPHX_C_EXPORT migraphx_status +migraphx_quantize_fp16_with_op_names(migraphx_program_t prog, migraphx_quantize_op_names_t name); -migraphx_status migraphx_quantize_fp16(migraphx_program_t prog); +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_fp16(migraphx_program_t prog); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_destroy(migraphx_quantize_int8_options_t quantize_int8_options); -migraphx_status -migraphx_quantize_int8_options_assign_to(migraphx_quantize_int8_options_t output, - const_migraphx_quantize_int8_options_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_assign_to( + migraphx_quantize_int8_options_t output, const_migraphx_quantize_int8_options_t input); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_create(migraphx_quantize_int8_options_t* quantize_int8_options); -migraphx_status -migraphx_quantize_int8_options_add_op_name(migraphx_quantize_int8_options_t quantize_int8_options, - const char* name); +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_add_op_name( + migraphx_quantize_int8_options_t quantize_int8_options, const char* name); -migraphx_status migraphx_quantize_int8_options_add_calibration_data( +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_add_calibration_data( migraphx_quantize_int8_options_t quantize_int8_options, migraphx_program_parameters_t data); -migraphx_status migraphx_quantize_int8(migraphx_program_t prog, - migraphx_target_t target, - migraphx_quantize_int8_options_t options); +MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8(migraphx_program_t prog, + migraphx_target_t target, + migraphx_quantize_int8_options_t options); -migraphx_status migraphx_context_finish(const_migraphx_context_t context); +MIGRAPHX_C_EXPORT migraphx_status migraphx_context_finish(const_migraphx_context_t context); -migraphx_status migraphx_context_get_queue(void** out, migraphx_context_t context); +MIGRAPHX_C_EXPORT migraphx_status migraphx_context_get_queue(void** out, + migraphx_context_t context); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_destroy(migraphx_experimental_custom_op_t experimental_custom_op); -migraphx_status -migraphx_experimental_custom_op_assign_to(migraphx_experimental_custom_op_t output, - const_migraphx_experimental_custom_op_t input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_assign_to( + migraphx_experimental_custom_op_t output, const_migraphx_experimental_custom_op_t input); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_create(migraphx_experimental_custom_op_t* experimental_custom_op, void* obj, migraphx_experimental_custom_op_copy c, @@ -597,21 +630,20 @@ migraphx_experimental_custom_op_create(migraphx_experimental_custom_op_t* experi const char* obj_typename, const char* name); -migraphx_status -migraphx_experimental_custom_op_set_compute(migraphx_experimental_custom_op_t obj, - migraphx_experimental_custom_op_compute input); +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_compute( + migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_compute input); -migraphx_status migraphx_experimental_custom_op_set_compute_shape( +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_compute_shape( migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_compute_shape input); -migraphx_status migraphx_experimental_custom_op_set_output_alias( +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_output_alias( migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_output_alias input); -migraphx_status migraphx_experimental_custom_op_set_runs_on_offload_target( +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_runs_on_offload_target( migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_runs_on_offload_target input); -migraphx_status +MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_register(migraphx_experimental_custom_op_t experimental_custom_op); #ifdef __cplusplus diff --git a/src/api/migraphx.py b/src/api/migraphx.py index a15d5670e52..5e25e4fa651 100755 --- a/src/api/migraphx.py +++ b/src/api/migraphx.py @@ -79,7 +79,8 @@ def dynamic_dimension(h): def dynamic_dimensions(h): h.constructor( 'create', - api.params(ptr='const_migraphx_dynamic_dimension_t*', size='size_t'), + api.params(ptr='const const_migraphx_dynamic_dimension_t*', + size='size_t'), fname='migraphx::to_obj_vector') h.method('size', returns='size_t') h.method('get', @@ -215,7 +216,7 @@ def instruction(h): def instructions(h): h.constructor( 'create', - api.params(ptr='const_migraphx_instruction_t*', size='size_t'), + api.params(ptr='const const_migraphx_instruction_t*', size='size_t'), fname='migraphx::to_obj_vector') diff --git a/src/driver/CMakeLists.txt b/src/driver/CMakeLists.txt index 603d623e295..294c34ceaa7 100755 --- a/src/driver/CMakeLists.txt +++ b/src/driver/CMakeLists.txt @@ -32,18 +32,20 @@ add_executable(driver marker_roctx.cpp ) set_target_properties(driver PROPERTIES OUTPUT_NAME migraphx-driver) -# Copy driver for backwards compatibility -add_custom_command( - TARGET driver +if(NOT WIN32) + # Copy driver for backwards compatibility (Linux only) + add_custom_command( + TARGET driver POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver BYPRODUCTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver -) -set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver) + ) + set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver) +endif() rocm_clang_tidy_check(driver) -target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf) +target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf migraphx_py) rocm_install_targets( TARGETS driver diff --git a/src/driver/argument_parser.hpp b/src/driver/argument_parser.hpp index 1ce3cf61d10..683df8478d3 100644 --- a/src/driver/argument_parser.hpp +++ b/src/driver/argument_parser.hpp @@ -338,11 +338,22 @@ struct argument_parser MIGRAPHX_DRIVER_STATIC auto file_exist() { - return validate([](auto&, auto&, auto& params) { + return validate([](auto&, auto&, const auto& params) { if(params.empty()) throw std::runtime_error("No argument passed."); if(not fs::exists(params.back())) - throw std::runtime_error("Path does not exists: " + params.back()); + throw std::runtime_error("Path does not exist: " + params.back()); + }); + } + + MIGRAPHX_DRIVER_STATIC auto matches(const std::unordered_set& names) + { + return validate([=](auto&, auto&, const auto& params) { + auto invalid_param = std::find_if( + params.begin(), params.end(), [&](const auto& p) { return names.count(p) == 0; }); + if(invalid_param != params.end()) + throw std::runtime_error("Invalid argument: " + *invalid_param + + ". Valid arguments are {" + to_string_range(names) + "}"); }); } @@ -570,8 +581,7 @@ struct argument_parser continue; if(flag[0] != '-') continue; - auto d = - levenshtein_distance(flag.begin(), flag.end(), input.begin(), input.end()); + std::ptrdiff_t d = levenshtein_distance(flag, input); if(d < result.distance) result = result_t{&arg, flag, input, d}; } diff --git a/src/driver/main.cpp b/src/driver/main.cpp index 9e57f55f851..56b65c5eab1 100644 --- a/src/driver/main.cpp +++ b/src/driver/main.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -81,6 +82,7 @@ struct loader {"--model"}, ap.help("Load model"), ap.type("resnet50|inceptionv3|alexnet"), + ap.matches({"resnet50", "inceptionv3", "alexnet"}), ap.group("input")); ap(file_type, {"--onnx"}, ap.help("Load as onnx"), ap.set_value("onnx")); ap(file_type, {"--tf"}, ap.help("Load as tensorflow"), ap.set_value("tf")); @@ -241,6 +243,20 @@ struct loader return options; } + static std::string get_file_type(const std::string& file) + { + if(ends_with(file, ".onnx")) + return "onnx"; + else if(ends_with(file, ".pb")) + return "tf"; + else if(ends_with(file, ".json")) + return "json"; + else if(ends_with(file, ".py")) + return "py"; + else + return "migraphx"; + } + program load() { program p; @@ -248,14 +264,7 @@ struct loader { if(file_type.empty()) { - if(ends_with(file, ".onnx")) - file_type = "onnx"; - else if(ends_with(file, ".pb")) - file_type = "tf"; - else if(ends_with(file, ".json")) - file_type = "json"; - else - file_type = "migraphx"; + file_type = get_file_type(file); } std::cout << "Reading: " << file << std::endl; if(file_type == "onnx") @@ -272,6 +281,10 @@ struct loader options.format = "json"; p = migraphx::load(file, options); } + else if(file_type == "py") + { + p = migraphx::load_py(file); + } else if(file_type == "migraphx") { p = migraphx::load(file); @@ -757,7 +770,7 @@ struct main_command { std::cout << "'" << color::fg_yellow << wrong_commands.front() << color::reset << "' is not a valid command." << std::endl; - std::cout << get_command_help("Available commands:") << std::endl; + std::cout << get_command_help("Available commands:"); } else { diff --git a/src/dynamic_loader.cpp b/src/dynamic_loader.cpp index 9b2979cbc89..7c88df5f20a 100644 --- a/src/dynamic_loader.cpp +++ b/src/dynamic_loader.cpp @@ -48,7 +48,7 @@ struct dynamic_loader_impl #pragma GCC diagnostic ignored "-Wignored-attributes" #endif dynamic_loader_impl(const fs::path& p, std::shared_ptr t = nullptr) - : handle(dlopen(p.string().c_str(), RTLD_LAZY), + : handle(dlopen(p.string().c_str(), RTLD_GLOBAL | RTLD_NOW), manage_deleter{}), temp(std::move(t)) { @@ -81,6 +81,18 @@ fs::path dynamic_loader::path(void* address) return p; } +optional dynamic_loader::try_load(const fs::path& p) +{ + try + { + return dynamic_loader{p}; + } + catch(const std::exception&) + { + return nullopt; + } +} + dynamic_loader::dynamic_loader(const fs::path& p) : impl(std::make_shared(p)) { } diff --git a/src/eliminate_contiguous.cpp b/src/eliminate_contiguous.cpp index abfd6f5f019..ac1189761e1 100644 --- a/src/eliminate_contiguous.cpp +++ b/src/eliminate_contiguous.cpp @@ -35,6 +35,8 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { +MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS) + static bool try_compute_shape(instruction_ref ins, const std::vector& inputs, const std::vector& mods) @@ -78,14 +80,26 @@ static bool try_compute_shape(instruction_ref ins, return (arg == ins) ? new_shape : arg->get_shape(); }); - if(not try_compute_shape(output, input_shapes, mods)) + if(not try_compute_shape(output, input_shapes, output->module_inputs())) { return false; } } } + catch(const std::exception& e) + { + if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{})) + { + std::cout << "Exception: " << e.what() << std::endl; + } + return false; + } catch(...) { + if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{})) + { + std::cout << "Unknown exception" << std::endl; + } return false; } @@ -127,6 +141,11 @@ static void remove_contiguous(const std::string& op_name, module& m, F f) { if(arg->name() != op_name) continue; + if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{})) + { + std::cout << "eliminate_contiguous: "; + m.debug_print(ins); + } auto prev = arg->inputs().front(); replace(new_args, arg, prev); if(try_compute_shape(ins, new_args, mod_args)) diff --git a/src/fuse_pointwise.cpp b/src/fuse_pointwise.cpp index 2b9e0df0119..54f362c57fa 100644 --- a/src/fuse_pointwise.cpp +++ b/src/fuse_pointwise.cpp @@ -44,7 +44,7 @@ static literal get_scalar(instruction_ref ins) if(ins->name() == "contiguous") return get_scalar(ins->inputs().front()); const auto& s = ins->get_shape(); - if(s.elements() != 1 && not(s.scalar())) + if(s.elements() != 1 and not(s.scalar())) return {}; if(not ins->can_eval()) return {}; diff --git a/src/fuse_reduce.cpp b/src/fuse_reduce.cpp index d05c642c979..862ea5c367b 100644 --- a/src/fuse_reduce.cpp +++ b/src/fuse_reduce.cpp @@ -52,7 +52,7 @@ struct fused_reduce { if(mods.size() != 1) MIGRAPHX_THROW("should have one submodule."); - auto* sm = mods.front(); + const auto* sm = mods.front(); if(sm->get_output_shapes().size() != 1) MIGRAPHX_THROW("Only one output supported"); auto names = sm->get_parameter_names(); @@ -143,7 +143,7 @@ insert_module_in_submodule(module_ref sm, } static std::vector -find_inputs(module_ref sm, +find_inputs(const_module_ref sm, const module& parent, const std::unordered_map& map_ins) { diff --git a/src/include/migraphx/algorithm.hpp b/src/include/migraphx/algorithm.hpp index 2aec3ce6ec5..7130ed7cb17 100644 --- a/src/include/migraphx/algorithm.hpp +++ b/src/include/migraphx/algorithm.hpp @@ -26,6 +26,8 @@ #include #include +#include +#include #include namespace migraphx { @@ -90,6 +92,42 @@ levenshtein_distance(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterat return std::ptrdiff_t{1} + std::min({x1, x2, x3}); } +inline size_t levenshtein_distance(const std::string& s1, const std::string& s2) +{ + const size_t l1 = s1.length(); + const size_t l2 = s2.length(); + + if(l1 < l2) + levenshtein_distance(s2, s1); + + std::vector d(l2 + 1); + + std::iota(d.begin(), d.end(), 0); + + for(size_t i = 1; i <= l1; i++) + { + size_t prev_cost = d[0]; + d[0] = i; + + for(size_t j = 1; j <= l2; j++) + { + if(s1[i - 1] == s2[j - 1]) + { + d[j] = prev_cost; + } + else + { + size_t cost_insert_or_delete = std::min(d[j - 1], d[j]); + size_t cost_substitute = prev_cost; + prev_cost = d[j]; + d[j] = std::min(cost_substitute, cost_insert_or_delete) + 1; + } + } + } + + return d[l2]; +} + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/include/migraphx/builtin.hpp b/src/include/migraphx/builtin.hpp index 8e3c021340f..674c994dc7d 100644 --- a/src/include/migraphx/builtin.hpp +++ b/src/include/migraphx/builtin.hpp @@ -90,7 +90,17 @@ struct param struct returns { std::string name() const { return "@return"; } - shape compute_shape(const std::vector&) const { return {}; } + + shape compute_shape(const std::vector& arg) const + { + if(arg.empty()) + return {}; + else if(arg.size() == 1) + return arg[0]; + else + return arg; + } + argument compute(context&, const shape&, const std::vector&) const { MIGRAPHX_THROW("builtin"); diff --git a/src/include/migraphx/check_shapes.hpp b/src/include/migraphx/check_shapes.hpp index f5def91bd96..ced99e5d593 100644 --- a/src/include/migraphx/check_shapes.hpp +++ b/src/include/migraphx/check_shapes.hpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,21 +34,37 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { +// Check that deduced type is incrementable, dereferencable, and comparable +template +struct is_iterator +{ +}; + +template +struct is_iterator()), + decltype(*std::declval()), + decltype(std::declval() == std::declval())>> : std::true_type +{ +}; + +template struct check_shapes { - const shape* begin; - const shape* end; + static_assert(is_iterator{}, "CHECK_SHAPES: Deduced type must be an iterator"); + Iterator begin; + Iterator end; std::string name; bool dynamic_allowed; - check_shapes(const shape* b, const shape* e, const std::string& n, const bool d = false) + check_shapes(Iterator b, Iterator e, const std::string& n, const bool d = false) : begin(b), end(e), name(n), dynamic_allowed(d) { check_dynamic(); } template - check_shapes(const shape* b, const shape* e, const Op& op, const bool d = false) + check_shapes(Iterator b, Iterator e, const Op& op, const bool d = false) : begin(b), end(e), name(op.name()), dynamic_allowed(d) { check_dynamic(); @@ -56,7 +72,7 @@ struct check_shapes template check_shapes(const std::vector& s, const Op& op, const bool d = false) - : begin(s.data()), end(s.data() + s.size()), name(op.name()), dynamic_allowed(d) + : begin(s.begin()), end(s.end()), name(op.name()), dynamic_allowed(d) { check_dynamic(); } @@ -81,8 +97,6 @@ struct check_shapes { if(begin == end) return 0; - assert(begin != nullptr); - assert(end != nullptr); return end - begin; } @@ -131,8 +145,6 @@ struct check_shapes */ const check_shapes& only_dims(std::size_t n) const { - assert(begin != nullptr); - assert(end != nullptr); if(begin != end) { if(begin->max_lens().size() != n) @@ -148,8 +160,6 @@ struct check_shapes */ const check_shapes& max_ndims(std::size_t n) const { - assert(begin != nullptr); - assert(end != nullptr); if(begin != end) { if(begin->max_lens().size() > n) @@ -166,8 +176,6 @@ struct check_shapes */ const check_shapes& min_ndims(std::size_t n) const { - assert(begin != nullptr); - assert(end != nullptr); if(begin != end) { if(begin->max_lens().size() < n) @@ -330,8 +338,6 @@ struct check_shapes { if(begin == end) return true; - assert(begin != nullptr); - assert(end != nullptr); auto&& key = f(*begin); return this->all_of([&](const shape& s) { return f(s) == key; }); } @@ -341,8 +347,6 @@ struct check_shapes { if(begin == end) return true; - assert(begin != nullptr); - assert(end != nullptr); return std::all_of(begin, end, p); } @@ -351,17 +355,13 @@ struct check_shapes { if(begin == end) return false; - assert(begin != nullptr); - assert(end != nullptr); return std::any_of(begin, end, p); } - const shape* get(long i) const + Iterator get(long i) const { if(i >= size()) MIGRAPHX_THROW(prefix() + "Accessing shape out of bounds"); - assert(begin != nullptr); - assert(end != nullptr); if(i < 0) return end - i; return begin + i; @@ -394,6 +394,11 @@ struct check_shapes } }; +// Deduction guide for std::vector constructor +template +check_shapes(const std::vector&, const Op&, bool d = false) + -> check_shapes::const_iterator>; + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/include/migraphx/dynamic_loader.hpp b/src/include/migraphx/dynamic_loader.hpp index 71e14fe24ce..6b9feee2174 100644 --- a/src/include/migraphx/dynamic_loader.hpp +++ b/src/include/migraphx/dynamic_loader.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,9 @@ struct MIGRAPHX_EXPORT dynamic_loader return path(reinterpret_cast(address)); } static fs::path path(void* address); + + static optional try_load(const fs::path& p); + dynamic_loader() = default; dynamic_loader(const fs::path& p); diff --git a/src/include/migraphx/matcher.hpp b/src/include/migraphx/matcher.hpp index d1e00debbef..2d0f26a5d6b 100644 --- a/src/include/migraphx/matcher.hpp +++ b/src/include/migraphx/matcher.hpp @@ -381,22 +381,24 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M const int trace = value_of(MIGRAPHX_TRACE_MATCHES{}); const bool validate = enabled(MIGRAPHX_VALIDATE_MATCHES{}); const auto trace_filter = string_value_of(MIGRAPHX_TRACE_MATCHES_FOR{}); - const bool trace_for = not trace_filter.empty() and - (contains(std::string{location.file_name()}, trace_filter) or - contains(std::string{location.function_name()}, trace_filter)); - bool match = false; + bool match = false; each_args( [&](auto&& m) { + const auto& matcher_name = get_type_name(m); + const bool trace_for = not trace_filter.empty() and + (contains(std::string{location.file_name()}, trace_filter) or + contains(std::string{location.function_name()}, trace_filter) or + contains(matcher_name, trace_filter)); if(match) return; - if(trace > 1 or trace_for) - std::cout << "Match: " << get_type_name(m) << std::endl; + if(trace > 1 and trace_for) + std::cout << "Match: " << matcher_name << std::endl; auto r = match_instruction(get_module(mod), ins, m.matcher()); if(r.result == get_module(mod).end()) return; if(trace > 0 or trace_for) { - std::cout << "Matched by " << get_type_name(m) << std::endl; + std::cout << "Matched by " << matcher_name << std::endl; get_module(mod).debug_print(ins); } // If its already invalid dont validate it again @@ -407,7 +409,7 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M auto invalid = get_module(mod).validate(); if(invalid != get_module(mod).end()) { - std::cout << "Invalid program from match: " << get_type_name(m) << std::endl; + std::cout << "Invalid program from match: " << matcher_name << std::endl; std::cout << "Invalid instructions: " << std::endl; get_module(mod).debug_print(invalid->inputs()); get_module(mod).debug_print(invalid); diff --git a/src/include/migraphx/module.hpp b/src/include/migraphx/module.hpp index 5145b413651..f986dc3d663 100644 --- a/src/include/migraphx/module.hpp +++ b/src/include/migraphx/module.hpp @@ -222,7 +222,17 @@ struct MIGRAPHX_EXPORT module void annotate(std::ostream& os, std::function a) const; std::vector get_sub_modules(bool shallow = false) const; + /* sorts the module in topological order aka reverse-post order (RPO) DFS order + it takes last instruction or @return as the root and walks back the graph and moves inputs + of the each instruction such that it appears before the instruction itself. + */ module& sort(); + /* Any instruction "X" can have module arguments and those modules inside them can use any other + * instruction "Y" from predecessor modules of the instruction "X". Such instruction "Y" inside + * module args are not listed as input instructions to "X". But those instructions "Y" must be + * evaluted before the instruction "X" can. Therefore such "Y" instructions are considered + * implicit dependency to "X". + */ ins_dep_map calc_implicit_deps() const; MIGRAPHX_EXPORT friend std::ostream& operator<<(std::ostream& os, const module& m); diff --git a/src/include/migraphx/normalize_attributes.hpp b/src/include/migraphx/normalize_attributes.hpp index 40c1bdda9b0..e88003e6d85 100644 --- a/src/include/migraphx/normalize_attributes.hpp +++ b/src/include/migraphx/normalize_attributes.hpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -42,6 +43,36 @@ struct select_dependent_type template using dependent_type = typename select_dependent_type::type; +/** + * Used to normalize variable input axes at model runtime. + * Example: the axes inputs of the slice operator. + * + * \param axes the axes to normalize + * \param input_shape shape of the input tensor + * \param attr_val the normalize_axes attributes from the operator + * \param prefix error message prefix + */ +std::vector normalize_axes(const std::vector& axes, + const shape& input_shape, + const value& attr_val, + const std::string& prefix = ""); + +/** + * Used to normalize variable input axes at model runtime. + * Example: the starts and ends inputs of the slice operator. + * + * \param indices the indices to normalize + * \param axes which axes the indices apply over + * \param input_shape shape of the input tensor + * \param attr_val the normalize_axes attributes from the operator + * \param prefix error message prefix + */ +std::vector normalize_indices(const std::vector& indices, + const std::vector& axes, + const shape& input_shape, + const value& attr_val, + const std::string& prefix = ""); + MIGRAPHX_EXPORT bool normalize_attributes(operation& op, const shape& input_shape); diff --git a/src/include/migraphx/op/common.hpp b/src/include/migraphx/op/common.hpp index cb28b41ff24..e6b85f19e23 100644 --- a/src/include/migraphx/op/common.hpp +++ b/src/include/migraphx/op/common.hpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,8 +33,12 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace op { +// Specifies where to add the "extra" cell of padding if the +// calculated padding is an odd number. // Padding mode is default_ for fixed shape padding. -// same_lower and same_upper used for dynamic padding. +// same_lower and same_upper specify dynamic padding. +// The odd cell goes at the beginning of the dimension +// (same_lower) or end (same_upper). enum padding_mode_t { default_, // NOLINT diff --git a/src/include/migraphx/op/convolution.hpp b/src/include/migraphx/op/convolution.hpp index fe4f1b6e7bc..ce2f157eabd 100644 --- a/src/include/migraphx/op/convolution.hpp +++ b/src/include/migraphx/op/convolution.hpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -82,7 +82,7 @@ struct convolution const auto input_ndim = inputs[0].ndim(); const auto padding_size = padding.size(); - if(input_ndim != padding_size / 2 + 2 && input_ndim != padding_size + 2) + if(input_ndim != padding_size / 2 + 2 and input_ndim != padding_size + 2) { MIGRAPHX_THROW("CONVOLUTION: input and attribute size mismatch!"); } @@ -206,6 +206,7 @@ struct convolution std::vector new_padding; if(padding_mode != op::padding_mode_t::default_) { + // auto-Calculate the padding sizes with calc_dyn_auto_pad auto input_lens = args[0].get_shape().lens(); auto weights_lens = args[1].get_shape().lens(); new_padding = @@ -217,6 +218,7 @@ struct convolution } else { + // Use the padding that was given new_padding = padding; if(output_shape.dynamic()) { diff --git a/src/include/migraphx/op/if_op.hpp b/src/include/migraphx/op/if_op.hpp index 46c8d2c18e7..ee8ef51fd95 100644 --- a/src/include/migraphx/op/if_op.hpp +++ b/src/include/migraphx/op/if_op.hpp @@ -71,7 +71,7 @@ struct if_op std::unordered_map params; std::set pnames; - for(const auto& smod : mods) + for(const_module_ref smod : mods) { auto names = smod->get_parameter_names(); pnames.insert(names.begin(), names.end()); diff --git a/src/include/migraphx/op/loop.hpp b/src/include/migraphx/op/loop.hpp index 404f32befe9..d6db7dc873d 100644 --- a/src/include/migraphx/op/loop.hpp +++ b/src/include/migraphx/op/loop.hpp @@ -59,9 +59,9 @@ struct loop MIGRAPHX_THROW("LOOP: operator should have one submodule."); } - const auto& mod = mods.front(); - auto mod_out_shapes = mod->get_output_shapes(); - auto dep_param_num = inputs.size() - 2; + const_module_ref mod = mods.front(); + auto mod_out_shapes = mod->get_output_shapes(); + auto dep_param_num = inputs.size() - 2; // first item of the mod output shapes is condition used in loop, // which is not needed to compute output shape diff --git a/src/include/migraphx/op/pooling.hpp b/src/include/migraphx/op/pooling.hpp index 3d31e5d9181..684d539e32b 100644 --- a/src/include/migraphx/op/pooling.hpp +++ b/src/include/migraphx/op/pooling.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -40,10 +41,20 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace op { +// The Pooling operator mostly follows the specifications for the Onnx pooling op. +// It assumes an NCHW layout, extended to support any number of spatial dimensions +// from 1 on up; dimensions are +// struct pooling { + // Class members mode, ceil_mode, padding_mode have similar names but refer to separate + // concepts. pooling_mode mode = {pooling_mode::average}; + // If the input has rank other than 4 then padding, stride, lengths must all be specified + // since the defaults have 2-dimensions. Exception: padding not required if + // padding_mode != default_ + // Padding along each spatial input dimension // Can be ndim or 2*ndim values where ndim is size of lengths // ndim values means pad the same before and after each dimension @@ -63,13 +74,14 @@ struct pooling // ceiling mode is a flag affecting output size // or equivalently, placements of the pooling kernel. - // When true, round the size upwards, possibly - // including partial placements where the kernel extends beyond the edge - // of input and even padding. When false, round down so that all + // When true, round the size upwards. When false, round down so that all // kernel placements fit but some input values may be dropped. bool ceil_mode = false; int lp_order = 2; + // Mode for auto padding. default_ indicates no auto padding. + padding_mode_t padding_mode = padding_mode_t::default_; + // Global pooling with dynamic shape input bool dyn_global = false; @@ -84,6 +96,7 @@ struct pooling { return pack(f(self.mode, "mode"), f(self.padding, "padding"), + f(self.padding_mode, "padding_mode"), f(self.stride, "stride"), f(self.lengths, "lengths"), f(self.ceil_mode, "ceil_mode"), @@ -97,7 +110,8 @@ struct pooling { if(dyn_global) return; - if((padding.size() != stride.size() and (padding.size()) != stride.size() * 2) or + if((padding_mode != default_ and padding.size() != stride.size() and + (padding.size()) != stride.size() * 2) or stride.size() != lengths.size()) { MIGRAPHX_THROW("POOLING: inconsistent attribute sizes"); @@ -137,8 +151,19 @@ struct pooling std::size_t padding_factor = 2 * padding[i]; if(padding.size() == 2 * kdims) padding_factor = padding[i] + padding[i + kdims]; - assert(input_lens[i + 2] + padding_factor >= lengths[i]); - std::size_t dim_size = input_lens[i + 2] + padding_factor - lengths[i]; + std::size_t dim_size; + if(input_lens[i + 2] + padding_factor < lengths[i]) + { + if(padding_mode == default_) + MIGRAPHX_THROW("POOLING: not enough padding for the given kernel size"); + // lengths can be legitimately larger only if we're doing auto padding + // with a dynamic shape, in which case given padding is ignored. Set a dummy value. + dim_size = 2; + } + else + { + dim_size = input_lens[i + 2] + padding_factor - lengths[i]; + } std::size_t len = (ceil_mode) ? dim_size / stride[i] + @@ -151,17 +176,13 @@ struct pooling shape normalize_compute_shape(std::vector inputs) const { - check_shapes{inputs, *this, true}.has(1); + check_shapes{inputs, *this, true}.has(1).min_ndims(3); check_attribute_size(); const shape& input = inputs.at(0); - auto padding_size = padding.size(); + auto stride_size = stride.size(); size_t kdims = input.ndim() - 2; - if(input.ndim() < 3) - { - MIGRAPHX_THROW("POOLING: input must have 3 or more dimensions and be nonempty"); - } - if(input.ndim() * 2 != padding_size + 4 and input.ndim() != padding_size + 2) + if(input.ndim() != stride_size + 2) { MIGRAPHX_THROW("POOLING: input and attribute size mismatch!"); } @@ -179,6 +200,28 @@ struct pooling } return {input.type(), output_dyn_dims}; } + else if(padding_mode != default_) + { + const size_t num_spatial_dims = inputs[0].ndim() - 2; + const shape& x_shape = inputs[0]; + // same as convolution::dynamic_compute_shape() + + for(std::size_t i = 0; i < num_spatial_dims; ++i) + { + auto ceil_div = [](std::size_t x, std::size_t y) { return (x + y - 1) / y; }; + auto s = stride[i]; + + auto x = x_shape.dyn_dims()[i + 2]; + std::set optimals{}; + std::transform(x.optimals.begin(), + x.optimals.end(), + std::inserter(optimals, optimals.begin()), + [&](auto o) { return ceil_div(o, s); }); + output_dyn_dims.push_back( + shape::dynamic_dimension{ceil_div(x.min, s), ceil_div(x.max, s), optimals}); + } + return {input.type(), output_dyn_dims}; + } else { // does not compute optimals @@ -267,6 +310,7 @@ struct pooling Out& output, const In& input, const std::vector& kernel_dims, + const std::vector& padding_vals, Op op) const { auto in_s = input.get_shape(); @@ -283,9 +327,9 @@ struct pooling // For each spatial dimension, find starting and ending index of pooling kernel for(std::size_t dim = 2; dim < n_dim; ++dim) { - auto d_2 = dim - 2; - int start = - static_cast(idx_o[dim] * stride[d_2]) - static_cast(padding[d_2]); + auto d_2 = dim - 2; + int start = static_cast(idx_o[dim] * stride[d_2]) - + static_cast(padding_vals[d_2]); int end; // NOLINT if(count_include_pad and ceil_mode and (mode != pooling_mode::max)) @@ -297,7 +341,7 @@ struct pooling // Check if this kernel extends beyond the padding at end of dimension end = std::min(start + kernel_dims[d_2], - in_lens[dim] + static_cast(padding[d_2])); + in_lens[dim] + static_cast(padding_vals[d_2])); } else { @@ -316,6 +360,7 @@ struct pooling } shape win_shape{output_shape.type(), win_size}; + auto pool_size = win_shape.elements(); double output_val = op.template init(); @@ -354,30 +399,65 @@ struct pooling argument compute(const dyn_output& dyn_out, std::vector args) const { - argument result{dyn_out.computed_shape}; + argument result; auto input_lens = args[0].get_shape().lens(); std::vector kernel_dims; + shape output_shape; + // If we have to auto-calculate padding, it will be passed to calc_pooling() as an argument + // instead of the member variable padding. + std::vector temp_padding(padding); if(dyn_global) { + // for dynamic GlobalPooling, there's no padding kernel_dims.insert(kernel_dims.end(), input_lens.begin() + 2, input_lens.end()); + output_shape = dyn_out.computed_shape; + result = dyn_out.computed_shape; } - else + else if((padding_mode != op::padding_mode_t::default_)) { + // if padding_mode is set, input was a dynamic size. Calculate padded size now. + + // kernel_lens is the same as kernel_dims, but prepended with the 2 non- + // spatial dimensions. For size computations, it's used like the weights + // tensor for convolutions. + std::vector kernel_lens; + kernel_lens.insert(kernel_lens.end(), input_lens.begin(), input_lens.begin() + 2); + kernel_lens.insert(kernel_lens.end(), lengths.begin(), lengths.end()); kernel_dims = this->lengths; + + auto type = args[0].get_shape().type(); + // dilation not currently supported for pooling, so default to all 1's + temp_padding = calc_dyn_auto_pad( + input_lens, kernel_lens, stride, {1, 1}, bool(padding_mode == op::same_upper)); + + output_shape = compute_padded_pool_shape( + args[0].get_shape(), shape(type, kernel_dims), temp_padding, stride, {1, 1}); + + result = argument(output_shape); + } + else // fixed/static input + { + kernel_dims = this->lengths; + output_shape = dyn_out.computed_shape; + result = dyn_out.computed_shape; } + + // Perform the computation and populate result visit_all(result, args[0])([&](auto output, auto input) { using type = typename decltype(output)::value_type; switch(mode) { case migraphx::op::pooling_mode::average: - calc_pooling(dyn_out.computed_shape, output, input, kernel_dims, avg_pool{}); + calc_pooling( + output_shape, output, input, kernel_dims, temp_padding, avg_pool{}); break; case migraphx::op::pooling_mode::max: - calc_pooling(dyn_out.computed_shape, output, input, kernel_dims, max_pool{}); + calc_pooling( + output_shape, output, input, kernel_dims, temp_padding, max_pool{}); break; case migraphx::op::pooling_mode::lpnorm: calc_pooling( - dyn_out.computed_shape, output, input, kernel_dims, lpnorm_pool{lp_order}); + output_shape, output, input, kernel_dims, temp_padding, lpnorm_pool{lp_order}); break; } }); diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index 7b77f333657..49db0012afc 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -27,19 +27,34 @@ #include #include #include -#include #include +#include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace op { +/** + * Slice operator that accepts variable axes, starts and ends. + * + * Attributes: + * axes: constant axes to slice over (optional) + * starts: constant slice starting indices (optional) + * ends: constant slice ending indices (optional) + * + * Parameters: + * data: the input tensor to slice (dynamic or static shape) + * input_starts: starting indicies of slice (optional, static shape) + * input_ends: ending indicies of slice (optional, static shape) + * input_axes: axes to slice over (optional, static shape) + */ struct slice { - std::vector axes; - std::vector starts; - std::vector ends; + std::vector axes{}; + std::vector starts{}; + std::vector ends{}; template static auto reflect(Self& self, F f) @@ -48,8 +63,8 @@ struct slice } /** - * Ensure that attribute vectors axes, starts, and ends are all the same size and values are in - * limits. + * Ensure that attribute vectors axes, starts, and ends are all the same size and values are + * within limits. */ value attributes() const { @@ -70,6 +85,90 @@ struct slice std::string name() const { return "slice"; } + /** + * Computes the slice output shape dimensions for given starts, ends,and axes. + * Templated to also handle tensor views. + * Possibily different type between [in_starts, in_ends] and [in_axes] if in_axes is this + * object's axes attribute. Assumes in_starts and in_ends are normalized; in_axes are valid. + */ + template + std::vector + lens_calc(const std::vector& lengths, A in_starts, A in_ends, B in_axes) const + { + auto new_lens = lengths; + for(std::size_t i = 0; i < in_axes.size(); ++i) + { + auto axis = in_axes[i]; + new_lens[axis] = in_ends[i] - in_starts[i]; + } + return new_lens; + } + + shape normalize_compute_shape(std::vector inputs) const + { + check_shapes{inputs, *this, true}.has(1, 3, 4); + auto input_shape = inputs[0]; + if(inputs.size() == 1) + { + auto t = input_shape.type(); + if(input_shape.dynamic() and std::any_of(axes.begin(), axes.end(), [&](auto axis) { + return not input_shape.dyn_dims()[axis].is_fixed(); + })) + { + MIGRAPHX_THROW("SLICE: slicing is not allowed on non-fixed dynamic input axis "); + } + if(input_shape.dynamic()) + { + return shape{t, + lens_calc(input_shape.min_lens(), starts, ends, axes), + lens_calc(input_shape.max_lens(), starts, ends, axes), + {}}; + } + else + { + return shape{ + t, lens_calc(input_shape.lens(), starts, ends, axes), input_shape.strides()}; + } + } + else + { + // check that starts, ends, and optionally input_axes are all 1D, have the same + // dimension, and are static + check_shapes{inputs.begin() + 1, + inputs.end(), + std::string("SLICE: inputs (starts, ends, and input_axes)"), + false} + .only_dims(1) + .same_dims(); + auto dds = input_shape.to_dynamic().dyn_dims(); + if(inputs.size() == 3) + { + if(inputs[1].lens().at(0) != axes.size()) + { + MIGRAPHX_THROW("SLICE: inputs starts and ends do not have the same dimension " + "as the axes attribute"); + } + std::for_each(axes.cbegin(), axes.cend(), [&](const auto& axis) { + dds.at(axis) = {0, dds.at(axis).max}; + }); + } + else + { + // if axes is an input, then all the output dimensions could be 0 to the max value + std::transform(dds.begin(), dds.end(), dds.begin(), [](auto dd) { + return shape::dynamic_dimension{0, dd.max}; + }); + } + return shape{input_shape.type(), dds}; + } + } + + /** + * Calculates the starting offset for the sliced tensor. + * Used in compute when only data input and all other information are in the attributes. + * + * \param s static input shape + */ auto compute_offset(const shape& s) const { const std::vector& lens = s.lens(); @@ -90,80 +189,131 @@ struct slice offset += starts[axis] * strides[axis]; } } - return offset; + return offset * s.type_size(); } - shape normalize_compute_shape(std::vector inputs) const + /** + * Calculates the starting offset for the sliced tensor (for aliasing). + * Used when the starts and/or the axes are inputs. + * + * \param s static input shape + * \param input_starts starting indices of slice + * \param ax_vec axes to slice on + */ + template + auto compute_offset(const shape& s, const IndView& input_starts, const Axes& ax_vec) const { - check_shapes{inputs, *this, true}.has(1); - auto input_shape = inputs[0]; - auto t = input_shape.type(); - - // TODO: When support for dynamic shapes is added to normalize_attributes, - // remove this restriction. - if(input_shape.dynamic() and std::any_of(axes.begin(), axes.end(), [&](auto axis) { - return not input_shape.dyn_dims()[axis].is_fixed(); - })) + auto ret = 0; + for(std::size_t i = 0; i < ax_vec.size(); ++i) { - MIGRAPHX_THROW("SLICE: slicing is not allowed on non-fixed dynamic input axis "); + auto axis = ax_vec[i]; + ret += input_starts[i] * s.strides().at(axis); } + return ret * s.type_size(); + } + + std::unordered_map> + normalize_inputs(const shape& input_shape, + const std::vector& input_starts, + const std::vector& input_ends) const + { + auto attrs = this->attributes().at("normalize_axes"); + return {{"input_starts", + normalize_indices(input_starts, + this->axes, + input_shape, + attrs.at("starts"), + "Slice variable input_starts")}, + {"input_ends", + normalize_indices(input_ends, + this->axes, + input_shape, + attrs.at("ends"), + "Slice variable input_ends")}}; + } + + /** + * Three input version of the normalize_inputs. + * This one also checks that the input_axes are valid. + */ + std::unordered_map> + normalize_inputs(shape input_shape, + const std::vector& input_starts, + const std::vector& input_ends, + const std::vector& input_axes) const + { + auto attrs = this->attributes().at("normalize_axes"); + auto norm_axes = + normalize_axes(input_axes, input_shape, attrs.at("axes"), "Slice variable input_axes"); + return {{"input_starts", + normalize_indices(input_starts, + norm_axes, + input_shape, + attrs.at("starts"), + "Slice variable input_starts")}, + {"input_ends", + normalize_indices(input_ends, + norm_axes, + input_shape, + attrs.at("ends"), + "Slice variable input ends")}, + {"input_axes", norm_axes}}; + } - // For a static shape, old_lens will be adjusted to a new size - // for those axes that are sliced. - // For dynamic shape, the adjusted old_lens become the new max values, - // while updating the old mins and optimals if possible. - std::vector new_mins; - std::vector old_lens; - std::vector old_strides; - // Doesn't handle optimals - if(input_shape.dynamic()) + argument compute(const dyn_output& dyn_out, std::vector args) const + { + auto input = args[0]; + auto input_shape = input.get_shape(); + switch(args.size()) { - old_lens = input_shape.max_lens(); - new_mins = input_shape.min_lens(); + case 1: { + std::size_t offset = compute_offset(input_shape); + return {dyn_out.computed_shape, [=] { return input.data() + offset; }}; } - else - { - old_lens = input_shape.lens(); - // For static shape (including during eval step after a dynamic input) the strides are - // indexed into the pre-slice array, so they are larger than the apparent size of the - // resulting shape. - old_strides = input_shape.strides(); + case 3: { + shape calc_shape; + std::size_t offset = 0; + visit_all(args[1], args[2])([&](auto input_starts, auto input_ends) { + auto norm_inputs = normalize_inputs(input_shape, + input_starts.template to_vector(), + input_ends.template to_vector()); + offset = compute_offset(input_shape, norm_inputs.at("input_starts"), this->axes); + calc_shape = {input_shape.type(), + lens_calc(input_shape.lens(), + norm_inputs.at("input_starts"), + norm_inputs.at("input_ends"), + this->axes), + input_shape.strides()}; + }); + return {calc_shape, [=] { return input.data() + offset; }}; } - - std::vector new_lens = old_lens; - for(std::size_t i = 0; i < axes.size(); i++) - { - auto axis = axes[i]; - size_t sliced_length = ends[i] - starts[i]; - // A Numpy indexing convention: a slice size larger than the actual dimension - // is legal and the "ends" value is clipped to the axis size - new_lens[axis] = std::min(new_lens[axis], sliced_length); - if(input_shape.dynamic()) - { - // TODO: when non-fixed shape slicing is allowed, this will be different than - // sliced_length, making use of TBD start/end values. - std::size_t sliced_min_length = ends[i] - starts[i]; - // if the slice size is smaller than maxes but larger than mins - new_mins[axis] = std::min(sliced_min_length, new_mins[axis]); - } + case 4: { + shape calc_shape; + std::size_t offset = 0; + visit_all(args[1], args[2], args[3])( + [&](auto input_starts, auto input_ends, auto input_axes) { + auto norm_inputs = normalize_inputs(input_shape, + input_starts.template to_vector(), + input_ends.template to_vector(), + input_axes.template to_vector()); + offset = compute_offset( + input_shape, norm_inputs.at("input_starts"), norm_inputs.at("input_axes")); + calc_shape = shape{input_shape.type(), + lens_calc(input_shape.lens(), + norm_inputs.at("input_starts"), + norm_inputs.at("input_ends"), + norm_inputs.at("input_axes")), + input_shape.strides()}; + }); + return {calc_shape, [=] { return input.data() + offset; }}; } - if(input_shape.dynamic()) - { - return shape{t, new_mins, new_lens, {}}; + default: { + // Should never get here; covering in case some code change occurs + MIGRAPHX_THROW("SLICE: invalid number of inputs"); } - else - { - return shape{t, new_lens, old_strides}; } } - argument compute(const dyn_output& dyn_out, std::vector args) const - { - auto input = args[0]; - - auto offset = compute_offset(input.get_shape()) * dyn_out.computed_shape.type_size(); - return {dyn_out.computed_shape, [=] { return input.data() + offset; }}; - } std::ptrdiff_t output_alias(const std::vector&) const { return 0; } }; diff --git a/src/include/migraphx/pad_calc.hpp b/src/include/migraphx/pad_calc.hpp index 06c209f6073..a17c0bc3028 100644 --- a/src/include/migraphx/pad_calc.hpp +++ b/src/include/migraphx/pad_calc.hpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,6 +62,14 @@ shape compute_padded_shape(const shape& input, const std::vector& stride, const std::vector& dilation); +// Used for dynamic auto padding of pooling operators where padding needs to be computed at +// evaulation time. +shape compute_padded_pool_shape(const shape& input, + const shape& kernel, + const std::vector& padding, + const std::vector& stride, + const std::vector& dilation); + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/include/migraphx/permutation.hpp b/src/include/migraphx/permutation.hpp index 3a3fdac5618..2325eae506e 100644 --- a/src/include/migraphx/permutation.hpp +++ b/src/include/migraphx/permutation.hpp @@ -66,6 +66,10 @@ MIGRAPHX_EXPORT std::vector invert_permutation(const std::vector find_permutation(const shape& s); MIGRAPHX_EXPORT std::vector find_permutation(const std::vector& shapes); +/// Normalize the shapes so the order of dimensions will be in the order it is +/// in memory as much as possible. +MIGRAPHX_EXPORT std::vector normalize_permutation(const std::vector& shapes); + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/instruction.cpp b/src/instruction.cpp index 25818ca1c12..7a8f73c2a4f 100644 --- a/src/instruction.cpp +++ b/src/instruction.cpp @@ -64,10 +64,7 @@ void instruction::replace(const shape& r) result = r; for(auto&& ins : output) { - if(ins->name() == "@return") - continue; - - assert(ins->name().front() != '@'); + assert(ins->name() == "@return" or ins->name().front() != '@'); ins->recompute_shape(); } } @@ -122,10 +119,6 @@ bool instruction::valid() const { computed = result; } - else if(op.name() == "@return") - { - computed = {}; - } else { try @@ -145,6 +138,7 @@ bool instruction::valid() const } shape instruction::get_shape() const { return result; } + const literal& instruction::get_literal() const { assert(op.name() == "@literal"); @@ -395,7 +389,7 @@ void instruction::print(std::ostream& os, if(not ins->module_inputs().empty()) { std::string delim = ", ["; - for(auto&& mod_arg : ins->module_inputs()) + for(const const_module_ref& mod_arg : ins->module_inputs()) { os << delim << mod_arg->name(); delim = ", "; diff --git a/src/memory_coloring.cpp b/src/memory_coloring.cpp index 548356da4f6..e6583184dae 100644 --- a/src/memory_coloring.cpp +++ b/src/memory_coloring.cpp @@ -23,9 +23,9 @@ */ #include #include -#include #include #include +#include #include #include #include @@ -382,7 +382,8 @@ void memory_coloring::apply(module& m) const auto s = ins->get_shape(); std::size_t offset = seg.first * alignment; assert(offset < n); - m.replace_instruction(ins, op::load{s, offset}, mem); + m.replace_instruction( + ins, make_op("load", {{"shape", to_value(s)}, {"offset", offset}}), mem); } // Replace zero allocation @@ -391,7 +392,8 @@ void memory_coloring::apply(module& m) const if(ins->name() != allocation_op) continue; assert(ins->get_shape().bytes() == 0); - m.replace_instruction(ins, op::load{ins->get_shape(), 0}, mem); + m.replace_instruction( + ins, make_op("load", {{"shape", to_value(ins->get_shape())}, {"offset", 0}}), mem); } // Remove scratch parameter if its not used diff --git a/src/module.cpp b/src/module.cpp index 5311111a85b..bd9542cd81f 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -460,11 +460,11 @@ instruction_ref module::add_parameter(std::string name, shape s) instruction_ref module::add_return(std::vector args) { - impl->push_back({builtin::returns{}, {}, std::move(args)}); + shape instr_shape = compute_shape(builtin::returns{}, args); + impl->push_back({builtin::returns{}, instr_shape, std::move(args)}); auto result = std::prev(impl->instructions.end()); instruction::backreference(result); assert(result->valid(begin())); - return result; } @@ -873,12 +873,11 @@ module::print_py(std::ostream& os, if(ins->name() == "@literal") { os << mname << ".add_literal("; - bool use_abs = false; - ins->get_literal().visit([&](auto v) { - use_abs = std::none_of(v.begin(), v.end(), [](auto x) { return x < 0; }); - }); + const bool use_abs = false; // Disable abs for now - use_abs = false; + // ins->get_literal().visit([&](auto v) { + // use_abs = std::none_of(v.begin(), v.end(), [](auto x) { return x < 0; }); + // }); if(use_abs) os << "migraphx.abs_literal("; os << "migraphx.generate_argument("; @@ -1011,9 +1010,17 @@ std::vector module::get_sub_modules(bool shallow) const module& module::sort() { + auto implicit_deps = calc_implicit_deps(); fix([&](auto self, auto ins) { this->move_instruction(ins, this->begin()); - for(auto child : ins->inputs()) + auto ins_inputs = ins->inputs(); + if(implicit_deps.find(ins) != implicit_deps.end()) + { + auto ins_implict_inputs = implicit_deps.at(ins); + ins_inputs.insert( + ins_inputs.end(), ins_implict_inputs.begin(), ins_implict_inputs.end()); + } + for(auto child : ins_inputs) { if(not contains(this->impl->instructions, child)) { diff --git a/src/normalize_attributes.cpp b/src/normalize_attributes.cpp index 36f6b1be17f..6402d4ee2ec 100644 --- a/src/normalize_attributes.cpp +++ b/src/normalize_attributes.cpp @@ -26,7 +26,7 @@ #include #include #include - +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -49,6 +49,10 @@ auto tune_attribute(const std::vector& vec, Message m) { std::vector result(vec); + if(result.empty()) + { + return result; + }; int64_t n_rank = input_shape.ndim(); std::vector vec_attrs = val.to_vector(); if(contains(vec_attrs, op::normalize_attribute::use_output)) @@ -188,20 +192,27 @@ bool normalize_attributes(operation& op, const shape& input_shape) auto val = op.to_value(); if(attrs.contains("normalize_padding")) { - auto padding = val.at(attrs.at("normalize_padding").to()); - auto padding_size = padding.size(); - auto padding_start = 2; - - if(padding_size == 2 * (input_shape.ndim() - padding_start)) - tuned = true; - else if(padding_size != (input_shape.ndim() - padding_start)) - MIGRAPHX_THROW("inconsistent padding size"); - else + bool use_auto_padding = + (val.contains("padding_mode") and + (val.at("padding_mode").to() != migraphx::op::padding_mode_t::default_)); + if(not use_auto_padding) { - auto result = tune_pad_attribute(padding); - val["padding"] = result; - op.from_value(val); - tuned = true; + auto padding = val.at(attrs.at("normalize_padding").to()); + auto padding_size = padding.size(); + auto padding_start = 2; + if(padding_size == 2 * (input_shape.ndim() - padding_start)) + tuned = true; + else if(padding_size != (input_shape.ndim() - padding_start)) + { + MIGRAPHX_THROW("normalize_attributes: inconsistent padding vector size "); + } + else + { + auto result = tune_pad_attribute(padding); + val["padding"] = result; + op.from_value(val); + tuned = true; + } } } if(not attrs.contains("normalize_axes")) @@ -251,5 +262,22 @@ bool normalize_attributes(operation& op, const shape& input_shape) return tuned; } +std::vector normalize_axes(const std::vector& axes, + const shape& input_shape, + const value& attr_val, + const std::string& prefix) +{ + return tune_attribute(axes, {}, attr_val, input_shape, [&] { return prefix; }); +} + +std::vector normalize_indices(const std::vector& indices, + const std::vector& axes, + const shape& input_shape, + const value& attr_val, + const std::string& prefix) +{ + return tune_attribute(indices, axes, attr_val, input_shape, [&] { return prefix; }); +} + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/onnx/include/migraphx/onnx/onnx_parser.hpp b/src/onnx/include/migraphx/onnx/onnx_parser.hpp index 5fb9550ac43..fcd4ebe9b81 100644 --- a/src/onnx/include/migraphx/onnx/onnx_parser.hpp +++ b/src/onnx/include/migraphx/onnx/onnx_parser.hpp @@ -117,6 +117,7 @@ struct onnx_parser parse_graph(module* mod, const onnx::GraphProto& graph, bool inlining = false); literal parse_value(const onnx::AttributeProto& attr) const; literal parse_tensor(const onnx::TensorProto& t) const; + shape parse_type(const onnx::TypeProto& t) const; shape parse_type(const onnx::TypeProto& t, const std::vector& input_dims) const; }; diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index 6a3c463df39..0a28fcf926f 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -357,10 +357,9 @@ parse_inputs(const onnx_parser& parser, } shape s; - std::vector dims; if(parser.map_input_dims.count(name) > 0) { - dims = parser.map_input_dims.at(name); + std::vector dims = parser.map_input_dims.at(name); s = parser.parse_type(input.type(), dims); } else if(parser.map_dyn_input_dims.count(name) > 0) @@ -370,7 +369,7 @@ parse_inputs(const onnx_parser& parser, } else { - s = parser.parse_type(input.type(), dims); + s = parser.parse_type(input.type()); } mod_insts[name] = mod->add_parameter(name, s); } @@ -553,14 +552,9 @@ literal onnx_parser::parse_tensor(const onnx::TensorProto& t) const } MIGRAPHX_THROW("PARSE_TENSOR: Invalid tensor type"); } -shape onnx_parser::parse_type(const onnx::TypeProto& t, - const std::vector& input_dims) const +shape onnx_parser::parse_type(const onnx::TypeProto& t) const { shape::type_t shape_type = get_type(t.tensor_type().elem_type()); - if(not input_dims.empty()) - { - return {shape_type, input_dims}; - } std::vector dynamic_dims; auto&& tensor_dims = t.tensor_type().shape().dim(); @@ -590,6 +584,15 @@ shape onnx_parser::parse_type(const onnx::TypeProto& t, return shape_from_dyn_dims(shape_type, dynamic_dims); } +shape onnx_parser::parse_type(const onnx::TypeProto& t, + const std::vector& input_dims) const +{ + shape::type_t shape_type = get_type(t.tensor_type().elem_type()); + if(input_dims.empty()) + return {shape_type}; + return {shape_type, input_dims}; +} + shape::type_t get_type(int dtype) { switch(dtype) diff --git a/src/onnx/parse_constant_of_shape.cpp b/src/onnx/parse_constant_of_shape.cpp index 9c56b9027b5..d3dceec4561 100644 --- a/src/onnx/parse_constant_of_shape.cpp +++ b/src/onnx/parse_constant_of_shape.cpp @@ -55,9 +55,6 @@ struct parse_constant_of_shape : op_parser l_val = literal({shape::float_type, {1}, {0}}, {0.0f}); } - // input is empty, output is a scalar - auto type = l_val.get_shape().type(); - if(args.empty()) { MIGRAPHX_THROW("ConstantOfShape : must have 1 input!"); @@ -65,6 +62,8 @@ struct parse_constant_of_shape : op_parser else { migraphx::shape s; + // input is empty, output is a scalar + auto type = l_val.get_shape().type(); // empty input tensor, output is a scalar if(args[0]->get_shape().elements() == 0) { diff --git a/src/onnx/parse_pooling.cpp b/src/onnx/parse_pooling.cpp index 556d3297061..4a9cb35c875 100644 --- a/src/onnx/parse_pooling.cpp +++ b/src/onnx/parse_pooling.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -151,26 +151,6 @@ struct parse_pooling : op_parser kdims, paddings.size() / 2, "PARSE_POOLING: inconsistent explicit paddings"); } - if(contains(info.attributes, "auto_pad")) - { - if(in_shape.dynamic()) - { - MIGRAPHX_THROW( - "PARSE_POOLING: Auto padding pooling with dynamic input shape not supported"); - } - else - { - values["padding"].clear(); - // return paddings could be empty, then setting to 0 for no padding - cal_auto_padding_size(info, - values, - values["lengths"].to_vector(), - {1, 1}, - in_shape.lens(), - paddings); - } - } - if(paddings.size() != 2 * kdims) { paddings.resize(kdims * 2); @@ -192,6 +172,36 @@ struct parse_pooling : op_parser // used to calculate the supposed output shape std::vector orig_padding = paddings; + // TODO: add parsing for dilations + if(contains(info.attributes, "auto_pad") and + to_upper(info.attributes["auto_pad"].s()) != "NOTSET") + { + auto auto_pad = to_upper(info.attributes["auto_pad"].s()); + // don't use the given padding sizes, if any + // values["padding"].clear(); + if(in_shape.dynamic()) + { + // set padding_mode to trigger auto padding at runtime + bool is_same_upper = (auto_pad.find("SAME_UPPER") != std::string::npos); + values["padding_mode"] = is_same_upper ? to_value(op::padding_mode_t::same_upper) + : to_value(op::padding_mode_t::same_lower); + } + else + { + // Calculate auto padding + // dilations (argument 4) not supported; default to all 1's + cal_auto_padding_size(info, + values, + values["lengths"].to_vector(), + std::vector(in_shape.ndim() - 2, 1), + in_shape.lens(), + paddings); + values["padding"] = paddings; + // default padding_mode indicates that padding sizes are not calculated dynamically + values["padding_mode"] = migraphx::op::padding_mode_t::default_; + } + } + std::vector slice_start; std::vector slice_end; tune_padding_size(values, paddings, count_include_pad, slice_start); @@ -208,8 +218,9 @@ struct parse_pooling : op_parser orig_padding.insert(orig_padding.begin(), 2, 0); op::pad pad{orig_padding, 0.0f}; shape padded_shape = pad.compute_shape({l0->get_shape()}); - auto out_lens = make_op("pooling", values).compute_shape({padded_shape}).lens(); + // make an op just to get its output shape + auto out_lens = make_op("pooling", values).compute_shape({padded_shape}).lens(); // compute slice_end information slice_end.resize(slice_start.size()); std::transform(out_lens.begin() + 2, diff --git a/src/onnx/parse_randomuniform_ops.cpp b/src/onnx/parse_randomuniform_ops.cpp index 4707cce3807..c6ed6b18779 100644 --- a/src/onnx/parse_randomuniform_ops.cpp +++ b/src/onnx/parse_randomuniform_ops.cpp @@ -96,7 +96,7 @@ struct parse_randomuniform_ops : op_parser if(contains(info.attributes, "seed")) gen.seed(info.attributes.at("seed").f()); - std::uniform_real_distribution<> d(high, low); + std::uniform_real_distribution<> d(low, high); std::vector rand_vals(out_shape.elements()); std::generate(rand_vals.begin(), rand_vals.end(), [&]() { return d(gen); }); diff --git a/src/onnx/parse_slice.cpp b/src/onnx/parse_slice.cpp index 2bae22eef97..7287f6479be 100644 --- a/src/onnx/parse_slice.cpp +++ b/src/onnx/parse_slice.cpp @@ -34,16 +34,65 @@ namespace onnx { struct parse_slice : op_parser { + std::vector operators() const { return {{"Slice"}}; } + struct slice_desc + { + op::slice op; + std::vector op_args; + std::vector steps; + std::vector raxes; + + void always_insert(instruction_ref arg) { op_args.insert(op_args.begin(), arg); } + + std::vector insert(instruction_ref arg) + { + std::vector result; + migraphx::argument arg_value = arg->eval(); + if(arg_value.empty()) + { + op_args.insert(op_args.begin(), arg); + } + else + { + arg_value.visit([&](auto s) { result.assign(s.begin(), s.end()); }); + } + return result; + } + }; + instruction_ref parse(const op_desc& /*opd*/, const onnx_parser& parser, - onnx_parser::node_info info, - std::vector args) const + const onnx_parser::node_info& info, + const std::vector& args) const { - op::slice op; + auto sd = construct_slice_desc(parser, info, args); + auto ins = info.add_instruction(sd.op, sd.op_args); + if(not sd.raxes.empty()) + { + ins = info.add_instruction(make_op("reverse", {{"axes", sd.raxes}}), ins); + } + // If any steps are other than default 1, add a "steps" op + if(std::any_of(sd.steps.begin(), sd.steps.end(), [](auto s) { return std::abs(s) != 1; })) + { + std::vector nsteps; + std::transform(sd.steps.begin(), + sd.steps.end(), + std::back_inserter(nsteps), + [](auto s) { return std::abs(s); }); + return ins = info.add_instruction( + make_op("step", {{"axes", sd.op.axes}, {"steps", nsteps}}), ins); + } + else + return ins; + } - std::vector steps; + slice_desc construct_slice_desc(const onnx_parser& parser, + onnx_parser::node_info info, + std::vector args) const + { + slice_desc sd; // slice can have up to 5 inputs, we first check the 5th one // to decide whether MIGRAPHX can handle this slice. @@ -51,89 +100,73 @@ struct parse_slice : op_parser { migraphx::argument step_arg = args.back()->eval(); check_arg_empty(step_arg, "PARSE_SLICE: cannot handle variable steps for slice"); - step_arg.visit([&](auto s) { steps.assign(s.begin(), s.end()); }); + step_arg.visit([&](auto s) { sd.steps.assign(s.begin(), s.end()); }); } if(args.size() >= 4) { - migraphx::argument axes_arg = args.at(3)->eval(); - check_arg_empty(axes_arg, "PARSE_SLICE: cannot handle variable axes for slice"); - axes_arg.visit([&](auto s) { op.axes.assign(s.begin(), s.end()); }); + sd.op.axes = sd.insert(args.at(3)); } else if(contains(info.attributes, "axes")) { literal s = parser.parse_value(info.attributes.at("axes")); - s.visit([&](auto v) { copy(v, std::back_inserter(op.axes)); }); + s.visit([&](auto v) { copy(v, std::back_inserter(sd.op.axes)); }); } if(args.size() >= 3) { - migraphx::argument end_arg = args.at(2)->eval(); - check_arg_empty(end_arg, "PARSE_SLICE: cannot handle variable ends for slice"); - end_arg.visit([&](auto s) { op.ends.assign(s.begin(), s.end()); }); + sd.op.ends = sd.insert(args.at(2)); } else if(contains(info.attributes, "ends")) { literal s = parser.parse_value(info.attributes.at("ends")); - s.visit([&](auto v) { copy(v, std::back_inserter(op.ends)); }); + s.visit([&](auto v) { copy(v, std::back_inserter(sd.op.ends)); }); } if(args.size() >= 2) { - migraphx::argument start_arg = args.at(1)->eval(); - check_arg_empty(start_arg, "PARSE_SLICE: cannot handle variable starts for slice"); - start_arg.visit([&](auto s) { op.starts.assign(s.begin(), s.end()); }); + sd.op.starts = sd.insert(args.at(1)); } else if(contains(info.attributes, "starts")) { literal s = parser.parse_value(info.attributes.at("starts")); - s.visit([&](auto v) { copy(v, std::back_inserter(op.starts)); }); + s.visit([&](auto v) { copy(v, std::back_inserter(sd.op.starts)); }); } + // data input argument + sd.always_insert(args.at(0)); + // If axes arg is not given, the default is all of them. - if(op.axes.empty()) + if(sd.op.axes.empty() and sd.op_args.size() < 3) { std::vector axes(args[0]->get_shape().ndim()); std::iota(axes.begin(), axes.end(), int64_t{0}); - op.axes = axes; + sd.op.axes = axes; } - std::vector raxes; + if(not sd.steps.empty()) + { + if(sd.op.starts.empty() or sd.op.ends.empty()) + MIGRAPHX_THROW("PARSE_SLICE: steps and variable starts and ends is not supported"); + if(sd.op.axes.empty()) + MIGRAPHX_THROW("PARSE_SLICE: steps and variable axes is not supported"); + } - assert(steps.empty() or steps.size() == op.axes.size()); - assert(op.axes.size() == op.starts.size()); - assert(op.axes.size() == op.ends.size()); + assert(sd.steps.empty() or sd.steps.size() == sd.op.axes.size()); // If any axes have negative step, prepare to add a "reverse" op - for(auto i : range(steps.size())) + for(auto i : range(sd.steps.size())) { - if(steps[i] >= 0) + if(sd.steps[i] >= 0) continue; - op.starts[i] += 1; - if(op.starts[i] == 0) - op.starts[i] = INT_MAX; - op.ends[i] += 1; - raxes.push_back(op.axes[i]); - std::swap(op.starts[i], op.ends[i]); - } - - auto ins = info.add_instruction(op, args[0]); - if(not raxes.empty()) - { - ins = info.add_instruction(make_op("reverse", {{"axes", raxes}}), ins); + sd.op.starts[i] += 1; + if(sd.op.starts[i] == 0) + sd.op.starts[i] = INT_MAX; + sd.op.ends[i] += 1; + sd.raxes.push_back(sd.op.axes[i]); + std::swap(sd.op.starts[i], sd.op.ends[i]); } - // If any steps are other than default 1, add a "steps" op - if(std::any_of(steps.begin(), steps.end(), [](auto s) { return std::abs(s) != 1; })) - { - std::vector nsteps; - std::transform(steps.begin(), steps.end(), std::back_inserter(nsteps), [](auto s) { - return std::abs(s); - }); - return ins = info.add_instruction( - make_op("step", {{"axes", op.axes}, {"steps", nsteps}}), ins); - } - else - return ins; + return sd; } }; diff --git a/src/pad_calc.cpp b/src/pad_calc.cpp index 5662dfb4000..3fe9603aa45 100644 --- a/src/pad_calc.cpp +++ b/src/pad_calc.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -52,6 +52,11 @@ void calculate_padding(int64_t idx, } } +/** + * Given the input array dimensions; kernel (wei_lens); strides; and dilations, + * calculate the padding value in each dimension. + * + */ std::vector calc_dyn_auto_pad(const std::vector& input_lens, const std::vector& wei_lens, const std::vector& strides, @@ -60,6 +65,7 @@ std::vector calc_dyn_auto_pad(const std::vector& input { std::vector padding; assert(input_lens.size() >= 3); + assert(input_lens.size() == wei_lens.size()); std::size_t num_spatial_dims = input_lens.size() - 2; padding.resize(2 * num_spatial_dims); for(std::size_t i = 0; i < num_spatial_dims; i++) @@ -88,6 +94,11 @@ std::vector calc_dyn_auto_pad(const std::vector& input return padding; } +/** + * Calculate the correct output shape for a convolution with + * a given input size and other parameters. + * + */ shape compute_padded_shape(const shape& input, const shape& weights, const std::vector& padding, @@ -111,5 +122,33 @@ shape compute_padded_shape(const shape& input, return input.with_lens(output_lens); } +/** + * Calculate the correct output shape for a pooling with + * a given input size and other parameters. This uses + * the same formula for pooling that compute_padded_shape() uses + * for convolutions, but takes slightly different inputs. + * + */ +shape compute_padded_pool_shape(const shape& input, + const shape& kernel, + const std::vector& padding, + const std::vector& stride, + const std::vector& dilation) +{ + const size_t num_spatial_dims = input.lens().size() - 2; + + std::vector output_lens{input.lens()[0], input.lens()[1]}; + // calculate the output shape of the pooling: ((W - K + 2P) / S) + 1 + for(size_t i = 0; i < num_spatial_dims; ++i) + { + auto padding_factor = padding[i] + padding[i + num_spatial_dims]; + output_lens.push_back(std::size_t(std::max( + 1, + (input.lens()[i + 2] - (1 + dilation[i] * (kernel.lens()[i] - 1)) + padding_factor) / + stride[i] + + 1))); + } + return input.with_lens(output_lens); +} } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/permutation.cpp b/src/permutation.cpp index 0d484b53cdb..01ef96e9bc9 100644 --- a/src/permutation.cpp +++ b/src/permutation.cpp @@ -74,5 +74,15 @@ std::vector find_permutation(const std::vector& shapes) return it->first; } +std::vector normalize_permutation(const std::vector& shapes) +{ + auto result = shapes; + auto perm = find_permutation(shapes); + std::transform(result.begin(), result.end(), result.begin(), [&](auto s) { + return reorder_shape(s, perm); + }); + return result; +} + } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/program.cpp b/src/program.cpp index 47f0a4cebe7..8be1dd3e065 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -40,13 +40,14 @@ #include #include #include + #include +#include #include #include #include #include #include - #include #include #include @@ -222,7 +223,7 @@ void program::compile(const std::vector& targets, std::vector roots; auto mods = this->get_modules(); - for(auto* mod : mods) + for(const auto* mod : mods) { for(const auto& ins : *mod) { @@ -547,7 +548,7 @@ std::vector program::eval(parameter_map params, execution_environment ins_out[x] = ss.str(); }); ret = generic_eval(*this, contexts, std::move(params), [&](instruction_ref ins, auto f) { - auto& ctx = contexts[ins->get_target_id()]; + const auto& ctx = contexts[ins->get_target_id()]; ctx.finish(); std::cout << "Run instruction: " << ins_out.at(ins) << std::endl; timer t{}; @@ -727,7 +728,7 @@ static void mod_from_val(module_ref mod, std::back_inserter(module_inputs), [&](const value& i) { return map_mods.at(i.to()); }); - for(auto& smod : module_inputs) + for(const auto& smod : module_inputs) { mod_from_val(smod, v, instructions, map_mods); } @@ -1185,17 +1186,25 @@ void program::remove_unused_modules() std::vector unused; generic_get_unused_modules( impl->modules, generic_get_modules(this->get_main_module()), std::back_inserter(unused)); - for(auto* m : unused) + for(const auto* m : unused) this->remove_module(m->name()); } program& program::sort() { - for(auto& pp : this->impl->modules) + std::queue mqueue; + mqueue.push(get_main_module()); + while(not mqueue.empty()) { - pp.second.sort(); + module_ref current_mod = mqueue.front(); + current_mod->sort(); + mqueue.pop(); + auto child_mods = current_mod->get_sub_modules(true); + for(auto& sub_mod : child_mods) + { + mqueue.push(sub_mod); + } } - return *this; } diff --git a/src/py/CMakeLists.txt b/src/py/CMakeLists.txt index 3103f15938f..2da0f7058aa 100644 --- a/src/py/CMakeLists.txt +++ b/src/py/CMakeLists.txt @@ -23,14 +23,25 @@ ##################################################################################### option(MIGRAPHX_ENABLE_PYTHON "Enable python bindings" ON) +add_library(migraphx_py py_loader.cpp) +migraphx_generate_export_header(migraphx_py) +target_include_directories(migraphx_py PRIVATE include) +target_link_libraries(migraphx_py PUBLIC migraphx) +rocm_install_targets(TARGETS migraphx_py INCLUDE include) if(MIGRAPHX_ENABLE_PYTHON) include(PythonModules) - add_custom_target(migraphx_py) foreach(PYTHON_VERSION ${PYTHON_VERSIONS}) - py_add_module(migraphx_py_${PYTHON_VERSION} migraphx_py.cpp PYTHON_VERSION ${PYTHON_VERSION} PYTHON_MODULE migraphx) - target_link_libraries(migraphx_py_${PYTHON_VERSION} PRIVATE migraphx migraphx_tf migraphx_onnx migraphx_all_targets) + py_add_module(migraphx_pybind_${PYTHON_VERSION} migraphx_py.cpp PYTHON_VERSION ${PYTHON_VERSION} PYTHON_MODULE migraphx) + target_link_libraries(migraphx_pybind_${PYTHON_VERSION} PRIVATE migraphx migraphx_tf migraphx_onnx migraphx_all_targets) + rocm_install_targets(TARGETS migraphx_pybind_${PYTHON_VERSION}) + add_dependencies(migraphx_py migraphx_pybind_${PYTHON_VERSION}) + + add_library(migraphx_py_${PYTHON_VERSION} py.cpp) + target_include_directories(migraphx_py_${PYTHON_VERSION} PRIVATE include) + target_link_libraries(migraphx_py_${PYTHON_VERSION} PUBLIC migraphx) + target_link_libraries(migraphx_py_${PYTHON_VERSION} PRIVATE pybind11::pybind11 python${PYTHON_VERSION}::runtime) rocm_install_targets(TARGETS migraphx_py_${PYTHON_VERSION}) add_dependencies(migraphx_py migraphx_py_${PYTHON_VERSION}) endforeach() diff --git a/src/py/include/migraphx/py.hpp b/src/py/include/migraphx/py.hpp new file mode 100644 index 00000000000..35126715467 --- /dev/null +++ b/src/py/include/migraphx/py.hpp @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MIGRAPHX_GUARD_MIGRAPHX_PY_HPP +#define MIGRAPHX_GUARD_MIGRAPHX_PY_HPP + +#include +#include +#include + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { + +MIGRAPHX_PY_EXPORT program load_py(const std::string& filename); + +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx +#endif // MIGRAPHX_GUARD_MIGRAPHX_PY_HPP diff --git a/src/py/py.cpp b/src/py/py.cpp new file mode 100644 index 00000000000..5ed11eb141c --- /dev/null +++ b/src/py/py.cpp @@ -0,0 +1,76 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include + +namespace py = pybind11; + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +#endif +// extern "C" is used to disable name mangling, but the function will still be called from C++ +extern "C" program migraphx_load_py(const std::string& filename); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +const std::string& python_path() +{ + static const auto path = dynamic_loader::path(&migraphx_load_py).parent_path().string(); + return path; +} + +static py::dict run_file(const std::string& file) +{ + py::object scope = py::module_::import("__main__").attr("__dict__"); + std::string buffer; + buffer.append("import sys\n"); + buffer.append("sys.path.insert(0, '" + python_path() + "')\n"); + buffer.append("import migraphx\n"); + buffer.append(read_string(file)); + py::exec(buffer, scope); + return scope.cast(); +} + +extern "C" program migraphx_load_py(const std::string& filename) +{ + py::scoped_interpreter guard{}; + py::dict vars = run_file(filename); + auto it = std::find_if(vars.begin(), vars.end(), [](const auto& p) { + return py::isinstance(p.second); + }); + if(it == vars.end()) + MIGRAPHX_THROW("No program variable found"); + return it->second.cast(); +} + +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/py/py_loader.cpp b/src/py/py_loader.cpp new file mode 100644 index 00000000000..33e051df02d --- /dev/null +++ b/src/py/py_loader.cpp @@ -0,0 +1,74 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { + +static std::vector find_available_python_versions() +{ + std::vector result; + auto path = dynamic_loader::path(&load_py).parent_path(); + for(const auto& entry : fs::directory_iterator{path}) + { + auto p = entry.path(); + if(not fs::is_regular_file(p)) + continue; + if(not contains(p.stem().string(), "migraphx_py_")) + continue; + result.push_back(p); + } + std::sort(result.begin(), result.end(), std::greater<>{}); + return result; +} + +static dynamic_loader load_py_lib() +{ + auto libs = find_available_python_versions(); + for(const auto& lib : libs) + { + auto result = dynamic_loader::try_load(lib); + if(result.has_value()) + return *result; + } + MIGRAPHX_THROW("Cant find a viable version of python"); +} + +static dynamic_loader py_lib() +{ + static dynamic_loader lib = load_py_lib(); + return lib; +} + +MIGRAPHX_PY_EXPORT program load_py(const std::string& filename) +{ + static auto f = py_lib().get_function("migraphx_load_py"); + return f(filename); +} + +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/rewrite_quantization.cpp b/src/rewrite_quantization.cpp index 0cfc00eadb3..d2ce20868d9 100644 --- a/src/rewrite_quantization.cpp +++ b/src/rewrite_quantization.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -61,13 +62,10 @@ void apply_quantizelinear(module& m, instruction_ref ins) max_quant = qt.max(); min_quant = qt.min(); }); - auto s = add_zero_point->get_shape(); - std::vector min_data(s.elements(), min_quant); - std::vector max_data(s.elements(), max_quant); - auto min_arg = m.add_literal(literal(s, min_data)); - auto max_arg = m.add_literal(literal(s, max_data)); - - auto saturate = m.insert_instruction(ins, make_op("clip"), add_zero_point, min_arg, max_arg); + auto s = add_zero_point->get_shape(); + auto min_arg = m.add_literal(literal{shape{s.type()}, {min_quant}}); + auto max_arg = m.add_literal(literal{shape{s.type()}, {max_quant}}); + auto saturate = insert_common_op(m, ins, make_op("clip"), {add_zero_point, min_arg, max_arg}); m.replace_instruction( ins, make_op("convert", {{"target_type", ins->get_shape().type()}}), saturate); } diff --git a/src/simplify_algebra.cpp b/src/simplify_algebra.cpp index 5bd0226b017..4a74b6497cf 100644 --- a/src/simplify_algebra.cpp +++ b/src/simplify_algebra.cpp @@ -1095,8 +1095,9 @@ MIGRAPHX_PRED_MATCHER(horiz_conv_dot, instruction_ref ins) }; }; auto dots = std::count_if(ins->outputs().begin(), ins->outputs().end(), pred("dot")); + auto qdots = std::count_if(ins->outputs().begin(), ins->outputs().end(), pred("quant_dot")); auto convs = std::count_if(ins->outputs().begin(), ins->outputs().end(), pred("convolution")); - return (dots >= 2 or convs >= 2); + return (dots >= 2 or convs >= 2 or qdots >= 2); } struct find_conv_dot_horiz_fusion @@ -1110,7 +1111,7 @@ struct find_conv_dot_horiz_fusion auto pred = [](auto i, auto j) { if(i->get_operator() != j->get_operator()) return false; - if(not contains({"dot", "convolution"}, i->name())) + if(not contains({"quant_dot", "dot", "convolution"}, i->name())) return true; auto x = i->inputs()[1]->get_shape().lens(); auto y = j->inputs()[1]->get_shape().lens(); @@ -1118,7 +1119,7 @@ struct find_conv_dot_horiz_fusion return false; // Check that non-axes match int axis = 1; - if(i->name() == "dot") + if(i->name() == "dot" or i->name() == "quant_dot") { axis = x.size() - 1; } @@ -1129,7 +1130,7 @@ struct find_conv_dot_horiz_fusion if(std::distance(start, last) < 2) return; auto&& name = (*start)->name(); - if(not contains({"dot", "convolution"}, name)) + if(not contains({"quant_dot", "dot", "convolution"}, name)) return; auto op = (*start)->get_operator(); int group = 1; @@ -1144,7 +1145,7 @@ struct find_conv_dot_horiz_fusion start, last, std::back_inserter(args), [&](auto x) { return x->inputs().at(1); }); int axis = 1; int concat_axis = 0; - if(name == "dot") + if(name == "dot" or name == "quant_dot") { axis = int(args.front()->get_shape().lens().size() - 1); concat_axis = axis; @@ -1445,10 +1446,13 @@ struct find_split_transpose { return; } + if(std::any_of(split_outputs.begin(), split_outputs.end(), [](auto i) { + return i->outputs().size() != 1; + })) + return; std::vector vec_trans(split_outputs.size()); std::transform(split_outputs.begin(), split_outputs.end(), vec_trans.begin(), [](auto i) { - assert(i->outputs().size() == 1); return i->outputs().front(); }); diff --git a/src/sqlite.cpp b/src/sqlite.cpp index 806e02c294a..8102a1fcfd4 100644 --- a/src/sqlite.cpp +++ b/src/sqlite.cpp @@ -48,6 +48,7 @@ struct sqlite_impl template void exec(const char* sql, F f) { + // cppcheck-suppress constParameterPointer auto callback = [](void* obj, auto... xs) -> int { try { diff --git a/src/targets/cpu/gemm.cpp b/src/targets/cpu/gemm.cpp index 979c494bc7f..e83a9191e43 100644 --- a/src/targets/cpu/gemm.cpp +++ b/src/targets/cpu/gemm.cpp @@ -43,7 +43,11 @@ struct dnnl_gemm : dnnl_extend_op MIGRAPHX_DNNL_PREFIX(ARG_BIAS)}; } - void required(const check_shapes& cs) const { cs.not_broadcasted(); } + template + void required(const check_shapes& cs) const + { + cs.not_broadcasted(); + } dnnl::matmul::desc get_desc(const std::unordered_map& m) const { diff --git a/src/targets/cpu/include/migraphx/cpu/dnnl.hpp b/src/targets/cpu/include/migraphx/cpu/dnnl.hpp index 4d26b55787e..252247a5401 100644 --- a/src/targets/cpu/include/migraphx/cpu/dnnl.hpp +++ b/src/targets/cpu/include/migraphx/cpu/dnnl.hpp @@ -400,7 +400,11 @@ struct dnnl_extend_op : dnnl_op } // dnnl has some issues with non-packed inputs - void required(const check_shapes& cs) const { cs.packed_or_broadcasted(); } + template + void required(const check_shapes& cs) const + { + cs.packed_or_broadcasted(); + } std::string name() const { return "dnnl::" + op.name(); } shape compute_shape(std::vector inputs) const diff --git a/src/targets/cpu/target.cpp b/src/targets/cpu/target.cpp index 115390ecea5..ebec22a501d 100644 --- a/src/targets/cpu/target.cpp +++ b/src/targets/cpu/target.cpp @@ -61,7 +61,7 @@ namespace cpu { std::string target::name() const { return "cpu"; } -// cppcheck-suppress constParameter +// cppcheck-suppress constParameterReference std::vector target::get_passes(migraphx::context& gctx, const compile_options&) const { auto& ctx = any_cast(gctx); diff --git a/src/targets/gpu/CMakeLists.txt b/src/targets/gpu/CMakeLists.txt index 92316c1bb5a..0492f0680b2 100644 --- a/src/targets/gpu/CMakeLists.txt +++ b/src/targets/gpu/CMakeLists.txt @@ -48,7 +48,7 @@ include(Embed) file(GLOB KERNEL_FILES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/kernels/include/migraphx/kernels/*.hpp) message(STATUS "KERNEL_FILES: ${KERNEL_FILES}") -add_embed_library(migraphx_kernels ${KERNEL_FILES}) +add_embed_library(migraphx_kernels ${KERNEL_FILES} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/kernels/include/) file(GLOB DEVICE_GPU_SRCS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/device/*.cpp) add_library(migraphx_device ${DEVICE_GPU_SRCS}) @@ -89,7 +89,7 @@ rocm_clang_tidy_check(kernel_file_check) file(GLOB JIT_GPU_SRCS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/jit/*.cpp) -if(NOT WIN32) +if(WIN32) # TODO: re-enable when CK is ported to Windows list(REMOVE_ITEM JIT_GPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/jit/ck_gemm.cpp) endif() @@ -123,6 +123,7 @@ add_library(migraphx_gpu lrn.cpp mlir.cpp multinomial.cpp + no_device.cpp nonzero.cpp pack_args.cpp pack_int8_args.cpp diff --git a/src/targets/gpu/compile_gen.cpp b/src/targets/gpu/compile_gen.cpp index e5caf93e588..d136d180086 100644 --- a/src/targets/gpu/compile_gen.cpp +++ b/src/targets/gpu/compile_gen.cpp @@ -331,7 +331,7 @@ static std::vector get_op_names(const module& m) { if(starts_with(ins.name(), "@")) continue; - if(ins.name() == "multibroadcast") + if(contains({"multibroadcast", "contiguous"}, ins.name())) continue; if(ins.name() == "pointwise") { diff --git a/src/targets/gpu/compile_hip_code_object.cpp b/src/targets/gpu/compile_hip_code_object.cpp index 349c29e60db..c530507be16 100644 --- a/src/targets/gpu/compile_hip_code_object.cpp +++ b/src/targets/gpu/compile_hip_code_object.cpp @@ -167,7 +167,7 @@ operation compile_hip_code_object(const std::string& content, hip_compile_option [](auto&& p) { auto&& name = p.first; auto&& c = p.second; - auto path = fs::path{"migraphx"} / "kernels" / name; + auto path = name; return src_file{path, c}; }); srcs.push_back(src_file{fs::path{"main.cpp"}, diff --git a/src/targets/gpu/device/include/migraphx/gpu/device/launch.hpp b/src/targets/gpu/device/include/migraphx/gpu/device/launch.hpp index a49f4ff7ff9..8db24d51c50 100644 --- a/src/targets/gpu/device/include/migraphx/gpu/device/launch.hpp +++ b/src/targets/gpu/device/include/migraphx/gpu/device/launch.hpp @@ -41,7 +41,7 @@ struct index __device__ index_int nglobal() const { return blockDim.x * gridDim.x; } // NOLINT - __device__ index_int nlocal() const { return blockDim.x; } // NOLINT + __device__ index_int nlocal() const { return blockDim.x; } // NOLINT template __device__ void global_stride(index_int n, F f) const @@ -81,6 +81,12 @@ inline auto launch(hipStream_t stream, index_int global, index_int local) dim3 nthreads(local); // cppcheck-suppress UseDeviceLaunch hipLaunchKernelGGL((launcher), nblocks, nthreads, 0, stream, f); + hipError_t kernel_launch_status = hipGetLastError(); + if(kernel_launch_status != hipSuccess) + { + MIGRAPHX_THROW("MIGraphX device kernel failed to launch with error: " + + std::string(hipGetErrorString(kernel_launch_status))); + } }; } diff --git a/src/targets/gpu/device/include/migraphx/gpu/device/nary.hpp b/src/targets/gpu/device/include/migraphx/gpu/device/nary.hpp index 7e6acc17059..94a6af67fa3 100644 --- a/src/targets/gpu/device/include/migraphx/gpu/device/nary.hpp +++ b/src/targets/gpu/device/include/migraphx/gpu/device/nary.hpp @@ -124,7 +124,7 @@ void nary_broadcast_vec_impl( buffer[i] = binput.data()[i]; } __syncthreads(); - auto* bp = as_pointer(buffer); + const auto* bp = as_pointer(buffer); // Process the data for(size_t i = idx.global; i < nelements; i += nglobal) { @@ -219,7 +219,7 @@ void nary_double_broadcast_vec_impl( buffer[i + bdim_vec_len] = binput2.data()[i]; } __syncthreads(); - auto* bp = as_pointer(buffer); + const auto* bp = as_pointer(buffer); // Process the data for(size_t i = idx.global; i < nelements; i += nglobal) { diff --git a/src/targets/gpu/device/topk.cpp b/src/targets/gpu/device/topk.cpp index 78e89bd9770..5ceebaafa7f 100644 --- a/src/targets/gpu/device/topk.cpp +++ b/src/targets/gpu/device/topk.cpp @@ -72,12 +72,12 @@ struct hip_heap_vector index_int l = 2 * index + 1; index_int r = 2 * index + 2; - if(l < n && compare(data[data_index(l)], data[data_index(index)])) + if(l < n and compare(data[data_index(l)], data[data_index(index)])) { index = l; } - if(r < n && compare(data[data_index(r)], data[data_index(index)])) + if(r < n and compare(data[data_index(r)], data[data_index(index)])) { index = r; if(compare(data[data_index(l)], data[data_index(r)])) diff --git a/src/targets/gpu/device_name.cpp b/src/targets/gpu/device_name.cpp index 77517cc34cc..ac38d6e8057 100644 --- a/src/targets/gpu/device_name.cpp +++ b/src/targets/gpu/device_name.cpp @@ -31,20 +31,6 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace gpu { -template -std::string get_arch_name(rank<0>, const HipDeviceProp& props) -{ - return "gfx" + std::to_string(props.gcnArch); -} - -template -auto get_arch_name(rank<1>, const HipDeviceProp& props) -> decltype(std::string(props.gcnArchName)) -{ - return std::string(props.gcnArchName); -} - -std::string get_arch_name(const hipDeviceProp_t& props) { return get_arch_name(rank<1>{}, props); } - int get_device_id() { int device; @@ -60,7 +46,7 @@ std::string get_device_name() auto status = hipGetDeviceProperties(&props, get_device_id()); if(status != hipSuccess) MIGRAPHX_THROW("Failed to get device properties"); - return get_arch_name(props); + return props.gcnArchName; } } // namespace gpu diff --git a/src/targets/gpu/fuse_mlir.cpp b/src/targets/gpu/fuse_mlir.cpp index 6a241f34caa..c33adc560d3 100644 --- a/src/targets/gpu/fuse_mlir.cpp +++ b/src/targets/gpu/fuse_mlir.cpp @@ -86,7 +86,7 @@ struct mlir_op size_t param_cnt = 0; std::vector names = mod->get_parameter_names(); std::sort(names.begin(), names.end()); - for(std::string param_name : names) + for(const std::string& param_name : names) { ins_shapes[mod->get_parameter(param_name)] = inputs[param_cnt++]; } @@ -210,42 +210,47 @@ struct find_mlir_op return false; } const std::initializer_list any_type_ops = {"@literal", "@param", "@return"}; - const std::initializer_list no_bool_ops = {"convolution", - "quant_convolution", - "dot", - "quant_dot", - "add", - "clip", - "relu", - "sub", - "mul", - "div", - "pow", - "where", - "quantizelinear", - "dequantizelinear", - "abs", - "neg"}; - const std::initializer_list fp_only_ops = {"ceil", - "erf", - "exp", - "floor", - "log", - "recip", - "rsqrt", - "sigmoid" - "softmax", - "tanh"}; + const std::initializer_list no_bool_ops = { + "convolution", + "quant_convolution", + "dot", + "quant_dot", + "add", + "clip", + "relu", + "sub", + "mul", + "div", + "pow", + "where", + "quantizelinear", + "dequantizelinear", + "abs", + "neg", + }; + const std::initializer_list fp_only_ops = { + "ceil", + "erf", + "exp", + "floor", + "log", + "recip", + "rsqrt", + // There are bugs in MLIR right now for models using sigmoid so disable it for now + // "sigmoid", + "softmax", + "tanh", + }; bool is_float = contains({type_t::float_type, type_t::half_type}, result_type); if(contains(any_type_ops, name)) return true; - if(result_type != type_t::bool_type && contains(no_bool_ops, name)) + if(result_type != type_t::bool_type and contains(no_bool_ops, name)) return true; - if(is_float && contains(fp_only_ops, name)) + if(is_float and contains(fp_only_ops, name)) return true; // Only conversions between floating types are known to be unambigiously // supported. - if(is_float && name == "convert") + if(is_float and name == "convert") { return std::all_of(i.inputs().begin(), i.inputs().end(), [](const auto& arg) { return contains({type_t::float_type, type_t::half_type}, arg->get_shape().type()); diff --git a/src/targets/gpu/hip.cpp b/src/targets/gpu/hip.cpp index 6ac5415bbe6..20241b097e5 100644 --- a/src/targets/gpu/hip.cpp +++ b/src/targets/gpu/hip.cpp @@ -55,7 +55,7 @@ bool is_device_ptr(const void* ptr) auto status = hipPointerGetAttributes(&attr, ptr); if(status != hipSuccess) return false; - return attr.memoryType == hipMemoryTypeDevice; + return attr.type == hipMemoryTypeDevice; } std::size_t get_available_gpu_memory() diff --git a/src/targets/gpu/include/migraphx/gpu/compiler.hpp b/src/targets/gpu/include/migraphx/gpu/compiler.hpp index bf3f58b2222..dd9ea75b00e 100644 --- a/src/targets/gpu/include/migraphx/gpu/compiler.hpp +++ b/src/targets/gpu/include/migraphx/gpu/compiler.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include namespace migraphx { @@ -68,12 +69,6 @@ struct compiler_replace } }; -struct tuning_config -{ - value problem; - std::vector solutions; -}; - using compiler_compile = std::function; using compiler_compile_op = diff --git a/src/targets/gpu/include/migraphx/gpu/context.hpp b/src/targets/gpu/include/migraphx/gpu/context.hpp index 6267f3070a2..f376aee4730 100644 --- a/src/targets/gpu/include/migraphx/gpu/context.hpp +++ b/src/targets/gpu/include/migraphx/gpu/context.hpp @@ -46,13 +46,7 @@ using hip_event_ptr = MIGRAPHX_MANAGE_PTR(hipEvent_t, hipEventDestroy); struct hip_device { - hip_device() - { - device_props.gcnArchName[0] = '\0'; - device_props.gcnArch = 0; - device_props.multiProcessorCount = 0; - add_stream(); - } + hip_device() : device_props{} { add_stream(); } hip_device(std::size_t id, std::size_t n) : device_id(id) { @@ -171,7 +165,7 @@ struct hip_device std::size_t stream_id() const { return current_stream; } - std::string get_device_name() const { return get_arch_name(device_props); } + std::string get_device_name() const { return device_props.gcnArchName; } std::string get_gfx_name() const { return trim(split_string(get_device_name(), ':').front()); } diff --git a/src/targets/gpu/include/migraphx/gpu/device_name.hpp b/src/targets/gpu/include/migraphx/gpu/device_name.hpp index 363ffa98b4e..44312d1f845 100644 --- a/src/targets/gpu/include/migraphx/gpu/device_name.hpp +++ b/src/targets/gpu/include/migraphx/gpu/device_name.hpp @@ -33,8 +33,6 @@ namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace gpu { -MIGRAPHX_GPU_EXPORT std::string get_arch_name(const hipDeviceProp_t& props); - MIGRAPHX_GPU_EXPORT std::string get_device_name(); MIGRAPHX_GPU_EXPORT int get_device_id(); diff --git a/src/targets/gpu/include/migraphx/gpu/hip.hpp b/src/targets/gpu/include/migraphx/gpu/hip.hpp index 47db789446b..47c6e5f7905 100644 --- a/src/targets/gpu/include/migraphx/gpu/hip.hpp +++ b/src/targets/gpu/include/migraphx/gpu/hip.hpp @@ -92,7 +92,7 @@ struct hip_sync_stream return inputs.front(); } - argument compute(context& ctx, const shape&, const std::vector& args) const + argument compute(const context& ctx, const shape&, const std::vector& args) const { gpu_sync(ctx); if(args.empty()) diff --git a/src/targets/gpu/include/migraphx/gpu/mlir.hpp b/src/targets/gpu/include/migraphx/gpu/mlir.hpp index 57ffd954622..34a85d00448 100644 --- a/src/targets/gpu/include/migraphx/gpu/mlir.hpp +++ b/src/targets/gpu/include/migraphx/gpu/mlir.hpp @@ -29,6 +29,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -36,16 +37,20 @@ struct module; namespace gpu { MIGRAPHX_GPU_EXPORT std::string dump_mlir(const module& m); - -MIGRAPHX_GPU_EXPORT code_object_op compile_mlir(const context& ctx, +MIGRAPHX_GPU_EXPORT code_object_op compile_mlir(const context& migraphx_ctx, module m, - const std::vector& inputs); + const std::vector& inputs, + const value& solution); MIGRAPHX_GPU_EXPORT instruction_ref insert_mlir(module& m, instruction_ref ins, code_object_op co, const std::vector& inputs); +MIGRAPHX_GPU_EXPORT tuning_config get_tuning_config_mlir(const context& migraphx_ctx, + module m, + const std::vector& inputs); + } // namespace gpu } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx diff --git a/src/targets/gpu/include/migraphx/gpu/tuning_config.hpp b/src/targets/gpu/include/migraphx/gpu/tuning_config.hpp new file mode 100644 index 00000000000..75ed79c913e --- /dev/null +++ b/src/targets/gpu/include/migraphx/gpu/tuning_config.hpp @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MIGRAPHX_GUARD_GPU_TUNING_CONFIG_HPP +#define MIGRAPHX_GUARD_GPU_TUNING_CONFIG_HPP + +#include +#include + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace gpu { + +struct tuning_config +{ + value problem; + std::vector solutions; +}; + +} // namespace gpu +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx +#endif // MIGRAPHX_GUARD_GPU_TUNING_CONFIG_HPP diff --git a/src/targets/gpu/jit/ck_gemm.cpp b/src/targets/gpu/jit/ck_gemm.cpp index d3ac8aa8747..65bed54a800 100644 --- a/src/targets/gpu/jit/ck_gemm.cpp +++ b/src/targets/gpu/jit/ck_gemm.cpp @@ -300,7 +300,8 @@ struct ck_gemm_compiler : compiler const auto& b_shape = inputs[1]; const auto& c_shape = inputs.back(); - auto rank = a_shape.lens().size(); + // cppcheck-suppress unreadVariable + auto rank = a_shape.ndim(); auto batch_count = get_batch_count(c_shape); auto m = c_shape.lens()[rank - 2]; diff --git a/src/targets/gpu/jit/mlir.cpp b/src/targets/gpu/jit/mlir.cpp index a3dc8eebe2a..f8bca1049bf 100644 --- a/src/targets/gpu/jit/mlir.cpp +++ b/src/targets/gpu/jit/mlir.cpp @@ -36,11 +36,12 @@ struct mlir_compiler : compiler operation compile_op(context&, const std::vector&, const value&) const { return {}; } - compiler_replace compile(context& ctx, instruction_ref ins, const operation&) const + compiler_replace + compile(const context& ctx, instruction_ref ins, const operation&, const value& solution) const { auto* smod = ins->module_inputs().front(); assert(smod->get_parameter_names().size() == ins->inputs().size() - 1); - return insert(compile_mlir(ctx, *smod, ins->inputs())); + return insert(compile_mlir(ctx, *smod, ins->inputs(), solution)); } compiler_replace insert(code_object_op co) const @@ -50,6 +51,18 @@ struct mlir_compiler : compiler m.replace_instruction(ins, mlir); }}; } + + optional get_tuning_config(const context& ctx, + instruction_ref ins, + const operation&, + bool exhaustive) const + { + if(not exhaustive) + return nullopt; + auto shapes = to_shapes(ins->inputs()); + auto* smod = ins->module_inputs().front(); + return get_tuning_config_mlir(ctx, *smod, shapes); + } }; } // namespace gpu diff --git a/src/targets/gpu/jit/pointwise.cpp b/src/targets/gpu/jit/pointwise.cpp index f3817d0e370..a39e9f0bea2 100644 --- a/src/targets/gpu/jit/pointwise.cpp +++ b/src/targets/gpu/jit/pointwise.cpp @@ -72,7 +72,7 @@ struct pointwise_compiler : compiler hip_compile_options options; options.inputs = inputs; options.output = inputs.back(); - options.virtual_inputs = reduce_dims(inputs); + options.virtual_inputs = reduce_dims(normalize_permutation(inputs)); options.params = "-Wno-float-equal"; auto axis = find_fast_axis(options.virtual_inputs); auto vec = vectorize::elements(ctx, axis, options.virtual_inputs); diff --git a/src/targets/gpu/jit/reduce.cpp b/src/targets/gpu/jit/reduce.cpp index 00112d91c82..1e018d2633e 100644 --- a/src/targets/gpu/jit/reduce.cpp +++ b/src/targets/gpu/jit/reduce.cpp @@ -84,7 +84,7 @@ static shape get_reduced_shape(const shape& s, const std::vector& axes) std::fill(lens.begin(), lens.end(), 1); for(const auto& axis : axes) lens[axis] = s.lens()[axis]; - return shape{s.type(), lens}; + return s.with_lens(lens); } template @@ -93,7 +93,7 @@ static shape get_output_shape(const shape& s, const std::vector& axes) auto lens = s.lens(); for(const auto& axis : axes) lens[axis] = 1; - return shape{s.type(), lens}; + return s.with_lens(lens); } template @@ -228,7 +228,7 @@ struct fused_reduce_compiler : compiler auto virtual_inputs = inputs; virtual_inputs.push_back(get_reduced_shape(inputs.front(), axes)); virtual_inputs.push_back(get_output_shape(inputs.front(), axes)); - virtual_inputs = reduce_dims(virtual_inputs); + virtual_inputs = reduce_dims(normalize_permutation(virtual_inputs)); auto reduce_output_shape = virtual_inputs.back(); virtual_inputs.pop_back(); auto reduction_shape = virtual_inputs.back(); diff --git a/src/targets/gpu/mlir.cpp b/src/targets/gpu/mlir.cpp index 3b7cd06b180..1bf3348162b 100644 --- a/src/targets/gpu/mlir.cpp +++ b/src/targets/gpu/mlir.cpp @@ -36,7 +36,10 @@ #include #if !defined(MLIR_MIGRAPHX_DIALECT_API_VERSION) || MLIR_MIGRAPHX_DIALECT_API_VERSION != 3 #warning "Incompatible version of rocMLIR library used, disabling" +// Only undefine when not using cppcheck +#ifndef CPPCHECK #undef MIGRAPHX_MLIR +#endif #else #include #endif @@ -50,8 +53,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -88,6 +93,8 @@ struct mlir_handle friend bool operator==(ptr x, ptr y) { return x.get_value() == y.get_value(); } friend bool operator!=(ptr x, ptr y) { return not(x == y); } + + explicit operator bool() const noexcept { return obj != ptr(); } T obj{}; }; @@ -134,6 +141,10 @@ using mlir_block = MIGRAPHX_MANAGE_MLIR_HANDLE(MlirBlock, mlirBlockD using mlir_pass_manager = MIGRAPHX_MANAGE_MLIR_HANDLE(MlirPassManager, mlirPassManagerDestroy); using mlir_tuning_table = MIGRAPHX_MANAGE_MLIR_HANDLE(MlirRockTuningTable, mlirRockTuningTableDestroy); +using mlir_tuning_space = MIGRAPHX_MANAGE_MLIR_HANDLE(MlirRockTuningSpace, + mlirRockTuningSpaceDestroy); +using mlir_tuning_param = MIGRAPHX_MANAGE_MLIR_HANDLE(MlirRockTuningParam, + mlirRockTuningParamDestroy); std::string_view to_string_view(MlirStringRef s) { return {s.data, s.length}; } @@ -167,12 +178,6 @@ std::string mlir_print(F f, T x) return ss.str(); } -bool has_xdlops(const std::string& target_arch) -{ - const auto device_name = trim(split_string(target_arch, ':').front()); - return (starts_with(device_name, "gfx9") and device_name >= "gfx908"); -} - struct mlir_program { mlir_program() @@ -507,7 +512,8 @@ struct mlir_program ops.add_attributes({{"function_type", make_function_type(inputs, outputs)}, {"sym_name", sym_name}, {"kernel", std::string("mixr")}, - {"arch", target_arch}}); + {"arch", target_arch}, + {"num_cu", num_cu}}); ops.add_region(std::move(region)); insert(body, std::move(ops)); @@ -554,14 +560,7 @@ struct mlir_program static std::string get_symbol_name(const module& m) { - for(auto ins : iterator_for(m)) - { - if(ins->name() == "convolution" or ins->name() == "dot") - { - return "mlir_" + ins->name(); - } - } - return "main"; + return "mlir_" + gen::generate_name_from_ops(m); } void parse(const module& m) @@ -597,9 +596,6 @@ struct mlir_program { pp = problem_params{ins->get_operator(), to_shapes(ins->inputs()), ins->get_shape()}; - // check if HW supports xdlops - if(has_xdlops(target_arch)) - ops.add_attributes({{"xdlopsV2", true}}); } std::vector inputs; @@ -616,18 +612,30 @@ struct mlir_program } } - code_object_op compile() MIGRAPHX_TIDY_CONST + void run_high_level_pipeline() MIGRAPHX_TIDY_CONST { mlir_pass_manager pm_front{mlirPassManagerCreate(ctx.get())}; - mlir_pass_manager pm_back{mlirPassManagerCreate(ctx.get())}; - // 1st pipeline to call mlirMIGraphXAddHighLevelPipeline(pm_front.get()); mlirPassManagerRunOnOp(pm_front.get(), mlirModuleGetOperation(mmodule.get())); + } - // 2nd pipeline to call - get_module_tuned(); + void run_backend_pipeline() MIGRAPHX_TIDY_CONST + { + mlir_pass_manager pm_back{mlirPassManagerCreate(ctx.get())}; mlirMIGraphXAddBackendPipeline(pm_back.get(), target_arch.c_str()); mlirPassManagerRunOnOp(pm_back.get(), mlirModuleGetOperation(mmodule.get())); + } + + code_object_op compile(const value& solution) MIGRAPHX_TIDY_CONST + { + // 1st pipeline to call + run_high_level_pipeline(); + if(solution.is_null()) + get_module_tuned(); + else + set_tuning(solution); + // 2nd pipeline to call + run_backend_pipeline(); code_object_op op{}; op.symbol_name = sym_name; @@ -636,7 +644,12 @@ struct mlir_program return op; } - void find_target() { target_arch = get_device_name(); } + void set_gpu_properties(const context& migraphx_ctx) + { + const auto& device = migraphx_ctx.get_current_device(); + target_arch = device.get_device_name(); + num_cu = device.get_cu_count(); + } std::pair get_launch_params() const { @@ -650,7 +663,7 @@ struct mlir_program value::binary get_binary() const { - int size = 0; + size_t size = 0; mlirGetBinary(mmodule.get(), &size, nullptr); value::binary result(size); if(mlirGetBinary(mmodule.get(), &size, reinterpret_cast(result.data()))) @@ -658,14 +671,52 @@ struct mlir_program MIGRAPHX_THROW("Failed to compile mlir program"); } + void set_tuning(const value& v) MIGRAPHX_TIDY_CONST + { + const auto* str = v.if_string(); + if(str == nullptr) + MIGRAPHX_THROW("mlir tuning solutions must be strings"); + if(not mlirRockTuningSetFromStr(mmodule.get(), make_mlir_string_ref(*str))) + MIGRAPHX_THROW("Failed setting tuning key: " + *str); + } + + tuning_config get_tuning_config() MIGRAPHX_TIDY_CONST + { + tuning_config tc; + run_high_level_pipeline(); + mlir_tuning_space params{ + mlirRockTuningSpaceCreate(mmodule.get(), RocmlirTuningParamSetKindFull)}; + for(auto i : range(mlirRockTuningGetNumParams(params.get()))) + { + mlir_tuning_param param{mlirRockTuningParamCreate()}; + if(not mlirRockTuningParamGet(params.get(), i, param.get())) + MIGRAPHX_THROW("Incorrect mlir tuning parameter: " + std::to_string(i)); + std::array perf_key; + size_t perf_key_bytes = + mlirRockTuningParamToString(param.get(), perf_key.data(), perf_key.size()); + if(perf_key_bytes > perf_key.size()) + MIGRAPHX_THROW("Tuning perf key was " + std::to_string(perf_key_bytes) + + " bytes and thus too long"); + tc.solutions.emplace_back(perf_key.begin(), perf_key.begin() + perf_key_bytes); + } + std::array tuning_key; + size_t tuning_key_bytes = + mlirRockTuningGetKey(mmodule.get(), tuning_key.data(), tuning_key.size()); + if(tuning_key_bytes > tuning_key.size()) + MIGRAPHX_THROW("Tuning table key was " + std::to_string(tuning_key_bytes) + + " bytes and thus too long"); + tc.problem = std::string(tuning_key.begin(), tuning_key.begin() + tuning_key_bytes); + return tc; + } + std::string get_tune_params(bool xdlops) const { return get_mlir_perf_for_conv(pp, xdlops); } // This function appends to tuning cfg file that could be // used with rocMLIR tuning scripts. - void dump_tuning_cfg(const char* prob_config) const + void dump_tuning_cfg(const std::string& prob_config) const { std::string tuning_cfg_path = string_value_of(MIGRAPHX_MLIR_TUNING_CFG{}); - if(!tuning_cfg_path.empty()) + if(not tuning_cfg_path.empty()) { std::vector tokens = split_string(prob_config, '\t'); std::string prob = tokens[1]; @@ -682,51 +733,66 @@ struct mlir_program } } - static mlir_tuning_table create_tuning_table() + static std::pair load_tuning_table() { mlir_tuning_table tuning_table{mlirRockTuningTableCreate()}; + bool found_table = false; std::string tuning_db_path = string_value_of(MIGRAPHX_MLIR_TUNING_DB{}); - if(!tuning_db_path.empty()) + if(not tuning_db_path.empty()) { std::ifstream tuning_db_tsv(tuning_db_path); if(tuning_db_tsv) { + found_table = true; std::string line; while(std::getline(tuning_db_tsv, line)) { std::vector tokens = split_string(line, '\t'); std::string arch = tokens[0]; - std::string prob = tokens[1]; - std::string perf = tokens[2]; - std::string key = arch.append("\t").append(prob); - mlirRockTuningUpdateTable(tuning_table.get(), key.c_str(), perf.c_str(), 1.0); + std::string num_cu = tokens[1]; + std::string prob = tokens[2]; + std::string perf = tokens[3]; + std::string key = arch.append("\t").append(num_cu).append("\t").append(prob); + mlirRockTuningUpdateTable(tuning_table.get(), + make_mlir_string_ref(key), + make_mlir_string_ref(perf), + 1.0); } } } else { + found_table = false; std::cerr << "WARNING: MLIR tuning db not found. Please set MIGRAPHX_MLIR_TUNING_DB for " "optimal performance." << std::endl; } - return tuning_table; + return std::make_pair(std::move(tuning_table), found_table); } bool get_module_tuned() const { - static mlir_tuning_table tuning_table = create_tuning_table(); - // The tuning table as currently implemented is currently not - // thread safe. This will be fixed in the future. For now, - // stick a mutex around all tuning table interaction. - static std::mutex lock; - std::lock_guard guard(lock); - if(!mlirRockTuningSetFromTable(tuning_table.get(), mmodule.get())) + static std::pair tuning_table = load_tuning_table(); + if(not mlirRockTuningSetFromTable(tuning_table.first.get(), mmodule.get())) { - const char* prob_config = mlirRockTuningGetKey(tuning_table.get(), mmodule.get()); - std::stringstream key(prob_config); - std::cerr << "fails to set param on" << prob_config << std::endl; - dump_tuning_cfg(prob_config); + std::array prob_config; + size_t prob_config_bytes = + mlirRockTuningGetKey(mmodule.get(), prob_config.data(), prob_config.size()); + if(prob_config_bytes >= prob_config.size()) + { + std::cerr << "MLIR tuning key overflowed buffer, needed " << prob_config_bytes + << " bytes" << std::endl; + return false; + } + std::string prob_config_str(prob_config.begin(), + prob_config.begin() + prob_config_bytes); + if(tuning_table.second) + { + std::cerr << "NOTE: MLIR tuning table did not include a key for " << prob_config_str + << std::endl; + } + dump_tuning_cfg(prob_config_str); return false; } return true; @@ -737,7 +803,8 @@ struct mlir_program mlir_module mmodule; problem_params pp; std::deque strings{}; - std::string target_arch; + std::string target_arch = ""; + std::size_t num_cu = 0; std::string sym_name; }; @@ -749,14 +816,14 @@ std::string dump_mlir(const module& m) return mlir_print(&mlirOperationPrint, mod_op); } -void adjust_param_shapes(module& m, const std::vector& inputs) +void adjust_param_shapes(module& m, const std::vector& inputs) { auto names = m.get_parameter_names(); std::sort(names.begin(), names.end()); for(auto i : range(names.size())) { const auto& name = names[i]; - const auto& input = inputs[i]->get_shape(); + const auto& input = inputs[i]; auto param = m.get_parameter(name); if(input.standard()) continue; @@ -794,22 +861,33 @@ void adjust_param_shapes(module& m, const std::vector& inputs) } } -code_object_op compile_mlir(const context&, module m, const std::vector& inputs) +code_object_op compile_mlir(const context& migraphx_ctx, + module m, + const std::vector& inputs, + const value& solution) { - adjust_param_shapes(m, inputs); + adjust_param_shapes(m, to_shapes(inputs)); const bool trace = enabled(MIGRAPHX_TRACE_MLIR{}); + static std::mutex mutex; if(trace) + { + const std::lock_guard lock(mutex); std::cout << m << std::endl; + } mlir_program mp; - mp.find_target(); + mp.set_gpu_properties(migraphx_ctx); mp.parse(m); auto mod_op = mlirModuleGetOperation(mp.mmodule.get()); if(trace) + { + const std::lock_guard lock(mutex); std::cout << mlir_print(&mlirOperationPrint, mod_op) << std::endl; - auto co = mp.compile(); - co.output = m.get_output_shapes().front(); + } + auto co = mp.compile(solution); + co.expected_inputs = to_shapes(inputs); + co.output = m.get_output_shapes().front(); return co; } @@ -829,6 +907,17 @@ instruction_ref insert_mlir(module& m, return m.insert_instruction(ins, co, refs); } +tuning_config +get_tuning_config_mlir(const context& migraphx_ctx, module m, const std::vector& inputs) +{ + adjust_param_shapes(m, inputs); + + mlir_program mp; + mp.set_gpu_properties(migraphx_ctx); + mp.parse(m); + return mp.get_tuning_config(); +} + #else std::string dump_mlir(const module&) { return {}; } @@ -840,20 +929,27 @@ void use(T&) // Disabling clang-tidy warning on non-real useage. // NOLINTBEGIN(performance-unnecessary-value-param) -code_object_op compile_mlir(const context&, module, const std::vector&) +code_object_op +compile_mlir(const context&, module, const std::vector&, const value&) { return {}; } -// NOLINTEND(performance-unnecessary-value-param) instruction_ref // cppcheck-suppress funcArgNamesDifferent insert_mlir(module& m, instruction_ref, code_object_op co, const std::vector&) { use(co); + use(m); return m.end(); } +tuning_config get_tuning_config_mlir(const context&, module, const std::vector&) +{ + return {}; +} +// NOLINTEND(performance-unnecessary-value-param) + #endif } // namespace gpu diff --git a/src/targets/gpu/no_device.cpp b/src/targets/gpu/no_device.cpp new file mode 100644 index 00000000000..a02d5254cb2 --- /dev/null +++ b/src/targets/gpu/no_device.cpp @@ -0,0 +1,28 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifdef __HIP_DEVICE_COMPILE__ +#error \ + "Device compilation not allowed for migraphx_gpu. Do not link with hip::device. Device code should go into migraphx_device or migraphx_kernels" +#endif diff --git a/src/targets/gpu/target.cpp b/src/targets/gpu/target.cpp index 37e6c44efbe..082bc5fa949 100644 --- a/src/targets/gpu/target.cpp +++ b/src/targets/gpu/target.cpp @@ -75,7 +75,7 @@ namespace gpu { MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_DISABLE_SCHEDULE_PASS) MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_DISABLE_REDUCE_FUSION) MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_ENABLE_NHWC) -#ifdef _WIN32 +#ifndef _WIN32 MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_ENABLE_CK) #endif @@ -138,7 +138,7 @@ std::vector target::get_passes(migraphx::context& gctx, const compile_opti dead_code_elimination{}, enable_pass(not enabled(MIGRAPHX_DISABLE_REDUCE_FUSION{}), fuse_reduce{}), dead_code_elimination{}, -#ifdef _WIN32 +#ifndef _WIN32 enable_pass(enabled(MIGRAPHX_ENABLE_CK{}), fuse_ck{}), #endif dead_code_elimination{}, diff --git a/src/targets/gpu/time_op.cpp b/src/targets/gpu/time_op.cpp index 84e2f792ee3..c4f70e8785b 100644 --- a/src/targets/gpu/time_op.cpp +++ b/src/targets/gpu/time_op.cpp @@ -34,7 +34,7 @@ namespace gpu { std::vector generate_arguments(const std::vector& shapes, unsigned long seed = 0) { std::vector args; - std::transform(shapes.begin(), shapes.end(), std::back_inserter(args), [&](auto& s) { + std::transform(shapes.begin(), shapes.end(), std::back_inserter(args), [&](const auto& s) { return to_gpu(generate_argument(s, seed++)); }); return args; diff --git a/src/tf/tf_parser.cpp b/src/tf/tf_parser.cpp index f4f4ec14b17..4daa4b6d664 100644 --- a/src/tf/tf_parser.cpp +++ b/src/tf/tf_parser.cpp @@ -338,7 +338,7 @@ void tf_parser::parse_node(const std::string& name) std::string input_name = input; // if input has trailing `:0` index then remove it auto multi_out_idx = input.find(':'); - if(multi_out_idx != std::string::npos && input.substr(multi_out_idx + 1) == "0") + if(multi_out_idx != std::string::npos and input.substr(multi_out_idx + 1) == "0") { input_name = input.substr(0, multi_out_idx); } diff --git a/src/value.cpp b/src/value.cpp index 41c2e8d6bf1..15a1bf31d25 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -285,7 +285,7 @@ bool value::contains(const std::string& pkey) const } std::size_t value::size() const { - auto* a = if_array_impl(x); + const auto* a = if_array_impl(x); if(a == nullptr) return 0; return a->size(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 71fe51331a5..1f3da5e75f1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -98,17 +98,11 @@ endfunction() function(add_test_executable TEST_NAME) add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN}) - target_link_libraries(${TEST_NAME} ${CMAKE_THREAD_LIBS_INIT}) - - # Cmake does not add flags correctly for gcc - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set_target_properties(${TEST_NAME} PROPERTIES COMPILE_FLAGS -pthread LINK_FLAGS -pthread) - endif() set(TEST_COMMAND ${TEST_NAME}) add_test_command(${TEST_NAME} ${TEST_COMMAND}) add_dependencies(tests ${TEST_NAME}) add_dependencies(check ${TEST_NAME}) - target_link_libraries(${TEST_NAME} migraphx migraphx_onnx migraphx_ref) + target_link_libraries(${TEST_NAME} Threads::Threads migraphx migraphx_onnx migraphx_ref) target_include_directories(${TEST_NAME} PUBLIC include) endfunction(add_test_executable) @@ -183,6 +177,7 @@ add_dependencies(check test_tf) add_subdirectory(api) add_subdirectory(verify) +add_subdirectory(ref) if(MIGRAPHX_ENABLE_PYTHON) add_subdirectory(py) @@ -208,11 +203,16 @@ endif() function(test_header NAME HEADER) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${NAME}.cpp - "#include <${HEADER}>\nint main() {}\n" + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${NAME}.cpp " +#include <${HEADER}> +int main() {}\n" ) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${NAME}.cpp - "#include <${HEADER}>\n" + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${NAME}.cpp " +#include <${HEADER}> +#if defined(min) || defined(max) || defined(near) || defined(far) +#error \"Do not include windows.h in header files\" +#endif +\n" ) add_test_executable(${NAME} ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${NAME}.cpp diff --git a/test/api/test_cpu.cpp b/test/api/test_cpu.cpp index 90c42d80a13..6af51bd6fbe 100644 --- a/test/api/test_cpu.cpp +++ b/test/api/test_cpu.cpp @@ -145,15 +145,15 @@ TEST_CASE(zero_parameter) TEST_CASE(set_scalar_parameter) { - auto p1 = migraphx::parse_onnx("add_bcast_test.onnx"); - migraphx::shape s1(migraphx_shape_float_type, {3, 4}); + auto p1 = migraphx::parse_onnx("implicit_add_bcast_test.onnx"); + migraphx::shape s1(migraphx_shape_float_type, {3, 4, 1}); auto param_shapes = p1.get_parameter_shapes(); auto s1_orig = param_shapes["1"]; CHECK(bool{s1 == s1_orig}); migraphx::onnx_options option; option.set_input_parameter_shape("1", {}); - auto p2 = migraphx::parse_onnx("add_bcast_test.onnx", option); + auto p2 = migraphx::parse_onnx("implicit_add_bcast_test.onnx", option); migraphx::shape s_scalar(migraphx_shape_float_type); auto param_shapes_1 = p2.get_parameter_shapes(); auto s_scalar_after = param_shapes_1["1"]; diff --git a/test/api/test_custom_op.cpp b/test/api/test_custom_op.cpp index d97b5435cfb..7ed64cd1fff 100644 --- a/test/api/test_custom_op.cpp +++ b/test/api/test_custom_op.cpp @@ -99,7 +99,7 @@ TEST_CASE(run_sigmoid_custom_op) EXPECT(bool{result == migraphx::argument(s, expected_result.data())}); } -extern "C" void migraphx_test_private_disable_exception_catch(bool b); +extern "C" MIGRAPHX_C_EXPORT void migraphx_test_private_disable_exception_catch(bool); TEST_CASE(run_sigmoid_with_incorrect_shape) { diff --git a/test/eliminate_contiguous_test.cpp b/test/eliminate_contiguous_test.cpp index 5b5e4831039..7a1f4668134 100644 --- a/test/eliminate_contiguous_test.cpp +++ b/test/eliminate_contiguous_test.cpp @@ -196,15 +196,47 @@ TEST_CASE(contiguous_pointwise) migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 8, 8}}}), y); auto yc = mm->add_instruction(migraphx::make_op("contiguous"), yb); auto add = add_pointwise(p, "main:pointwise0", {x, yc}, single_pointwise("add")); - mm->add_instruction(pass_op{}, add); + auto cadd = mm->add_instruction(migraphx::make_op("contiguous"), add); + mm->add_instruction(pass_op{}, cadd); } auto count = std::distance(mm->begin(), mm->end()); run_pass(*mm); - EXPECT(std::distance(mm->begin(), mm->end()) == (count - 1)); + EXPECT(std::distance(mm->begin(), mm->end()) == (count - 2)); EXPECT(std::none_of( mm->begin(), mm->end(), [](auto&& ins) { return ins.name() == "contiguous"; })); } +TEST_CASE(contiguous_nhwc_pointwise) +{ + auto s = + migraphx::shape::from_permutation(migraphx::shape::float_type, {2, 3, 8, 8}, {0, 2, 3, 1}); + migraphx::program p1; + { + auto* mm = p1.get_main_module(); + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", migraphx::shape{migraphx::shape::float_type, {3}}); + auto yb = mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 8, 8}}}), y); + auto yc = mm->add_instruction(migraphx::make_op("contiguous"), yb); + auto add = add_pointwise(p1, "main:pointwise0", {x, yc}, single_pointwise("add")); + auto cadd = mm->add_instruction(migraphx::make_op("contiguous"), add); + mm->add_instruction(pass_op{}, cadd); + } + run_pass(*p1.get_main_module()); + migraphx::program p2; + { + auto* mm = p2.get_main_module(); + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", migraphx::shape{migraphx::shape::float_type, {3}}); + auto yb = mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 8, 8}}}), y); + auto add = add_pointwise(p2, "main:pointwise0", {x, yb}, single_pointwise("add")); + auto cadd = mm->add_instruction(migraphx::make_op("contiguous"), add); + mm->add_instruction(pass_op{}, cadd); + } + EXPECT(p1 == p2); +} + TEST_CASE(slice_contiguous) { migraphx::module m; diff --git a/test/eliminate_pad_test.cpp b/test/eliminate_pad_test.cpp index 452a204920d..ec2fd94b8a6 100644 --- a/test/eliminate_pad_test.cpp +++ b/test/eliminate_pad_test.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include @@ -58,9 +58,8 @@ create_conv(migraphx::instruction_ref& l_img, migraphx::shape s_weights{migraphx::shape::int32_type, {4, channels, 3, 3}}; std::vector weights(4 * channels * 3 * 3); auto l_weights = m.add_literal(migraphx::literal{s_weights, weights}); - migraphx::op::convolution op; - op.padding_mode = padding_mode; - return m.add_instruction(op, l_img, l_weights); + return m.add_instruction( + migraphx::make_op("convolution", {{"padding_mode", padding_mode}}), l_img, l_weights); } TEST_CASE(rewrite_pad) diff --git a/test/gpu/mlir.cpp b/test/gpu/mlir.cpp index 0a252f7a814..c927281c9b2 100644 --- a/test/gpu/mlir.cpp +++ b/test/gpu/mlir.cpp @@ -84,7 +84,7 @@ migraphx::program create_program_from_mlir(const migraphx::module& mmlir) inputs.push_back(mm->add_parameter("output", mmlir.get_output_shapes().front())); migraphx::gpu::context ctx; - migraphx::gpu::insert_mlir(*mm, mm->end(), compile_mlir(ctx, mmlir, inputs), inputs); + migraphx::gpu::insert_mlir(*mm, mm->end(), compile_mlir(ctx, mmlir, inputs, {}), inputs); return p; } @@ -140,7 +140,7 @@ TEST_CASE(conv) { const std::string mlir_output = R"__migraphx__( module { - func.func @mlir_convolution(%arg0: tensor<2x8x3x3xf32>, %arg1: tensor<1x8x4x4xf32>) -> tensor<1x2x2x2xf32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_convolution(%arg0: tensor<2x8x3x3xf32>, %arg1: tensor<1x8x4x4xf32>) -> tensor<1x2x2x2xf32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.convolution(%arg1, %arg0) {dilation = [1, 1], group = 1 : i64, padding = [0, 0, 0, 0], padding_mode = 0 : i64, stride = [1, 1]} : (tensor<1x8x4x4xf32>, tensor<2x8x3x3xf32>) -> tensor<1x2x2x2xf32> return %0 : tensor<1x2x2x2xf32> } @@ -163,7 +163,7 @@ TEST_CASE(conv_add_relu) { const std::string mlir_output = R"__migraphx__( module { - func.func @mlir_convolution(%arg0: tensor<1x2x2x2xf32>, %arg1: tensor<2x8x3x3xf32>, %arg2: tensor<1x8x4x4xf32>) -> tensor<1x2x2x2xf32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_convolution_add_relu(%arg0: tensor<1x2x2x2xf32>, %arg1: tensor<2x8x3x3xf32>, %arg2: tensor<1x8x4x4xf32>) -> tensor<1x2x2x2xf32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.convolution(%arg2, %arg1) {dilation = [1, 1], group = 1 : i64, padding = [0, 0, 0, 0], padding_mode = 0 : i64, stride = [1, 1]} : (tensor<1x8x4x4xf32>, tensor<2x8x3x3xf32>) -> tensor<1x2x2x2xf32> %1 = migraphx.add(%0, %arg0) : (tensor<1x2x2x2xf32>, tensor<1x2x2x2xf32>) -> tensor<1x2x2x2xf32> %2 = migraphx.relu(%1) : (tensor<1x2x2x2xf32>) -> tensor<1x2x2x2xf32> @@ -191,7 +191,7 @@ TEST_CASE(quant_dot_add) { const std::string mlir_output = R"__migraphx__( module { - func.func @main(%arg0: tensor<1x5x4xi8>, %arg1: tensor<1x4x3xi8>, %arg2: tensor<1x5x3xi32>) -> tensor<1x5x3xi32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_quant_dot_add(%arg0: tensor<1x5x4xi8>, %arg1: tensor<1x4x3xi8>, %arg2: tensor<1x5x3xi32>) -> tensor<1x5x3xi32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.quant_dot(%arg0, %arg1) : (tensor<1x5x4xi8>, tensor<1x4x3xi8>) -> tensor<1x5x3xi32> %1 = migraphx.add(%0, %arg2) : (tensor<1x5x3xi32>, tensor<1x5x3xi32>) -> tensor<1x5x3xi32> return %1 : tensor<1x5x3xi32> @@ -218,7 +218,7 @@ TEST_CASE(dot_add) { const std::string mlir_output = R"__migraphx__( module { - func.func @mlir_dot(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>, %arg2: tensor<1x5x3xf32>) -> tensor<1x5x3xf32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_dot_add(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>, %arg2: tensor<1x5x3xf32>) -> tensor<1x5x3xf32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.dot(%arg0, %arg1) : (tensor<1x5x4xf32>, tensor<1x4x3xf32>) -> tensor<1x5x3xf32> %1 = migraphx.add(%0, %arg2) : (tensor<1x5x3xf32>, tensor<1x5x3xf32>) -> tensor<1x5x3xf32> return %1 : tensor<1x5x3xf32> @@ -244,7 +244,7 @@ TEST_CASE(conv_int8_dequantize_quantize) { const std::string mlir_output = R"__migraphx__( module { - func.func @main(%arg0: tensor<2x8x3x3xi8>, %arg1: tensor<1x8x4x4xi8>, %arg2: tensor<1x2x2x2xf32>, %arg3: tensor<1x2x2x2xi32>) -> tensor<1x2x2x2xi32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_quant_convolution_dequantizelinear_quantizelinear(%arg0: tensor<2x8x3x3xi8>, %arg1: tensor<1x8x4x4xi8>, %arg2: tensor<1x2x2x2xf32>, %arg3: tensor<1x2x2x2xi32>) -> tensor<1x2x2x2xi32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.quant_convolution(%arg1, %arg0) {dilation = [1, 1], group = 1 : i64, padding = [0, 0, 0, 0], padding_mode = 0 : i64, stride = [1, 1]} : (tensor<1x8x4x4xi8>, tensor<2x8x3x3xi8>) -> tensor<1x2x2x2xi32> %1 = migraphx.dequantizelinear(%0, %arg2, %arg3) : (tensor<1x2x2x2xi32>, tensor<1x2x2x2xf32>, tensor<1x2x2x2xi32>) -> tensor<1x2x2x2xf32> %2 = migraphx.quantizelinear(%1, %arg2, %arg3) : (tensor<1x2x2x2xf32>, tensor<1x2x2x2xf32>, tensor<1x2x2x2xi32>) -> tensor<1x2x2x2xi32> @@ -277,7 +277,7 @@ TEST_CASE(dot_convert) { const std::string mlir_output = R"__migraphx__( module { - func.func @mlir_dot(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>) -> tensor<1x5x3xf16> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_dot_convert(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>) -> tensor<1x5x3xf16> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.dot(%arg0, %arg1) : (tensor<1x5x4xf32>, tensor<1x4x3xf32>) -> tensor<1x5x3xf32> %1 = migraphx.convert(%0) {target_type = 1 : i64} : (tensor<1x5x3xf32>) -> tensor<1x5x3xf16> return %1 : tensor<1x5x3xf16> @@ -303,7 +303,7 @@ TEST_CASE(dot_where) { const std::string mlir_output = R"__migraphx__( module { - func.func @mlir_dot(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>, %arg2: tensor<1x5x3xi8>, %arg3: tensor<1x5x3xf32>) -> tensor<1x5x3xf32> attributes {arch = "", kernel = "mixr"} { + func.func @mlir_dot_where(%arg0: tensor<1x5x4xf32>, %arg1: tensor<1x4x3xf32>, %arg2: tensor<1x5x3xi8>, %arg3: tensor<1x5x3xf32>) -> tensor<1x5x3xf32> attributes {arch = "", kernel = "mixr", num_cu = 0 : i64} { %0 = migraphx.dot(%arg0, %arg1) : (tensor<1x5x4xf32>, tensor<1x4x3xf32>) -> tensor<1x5x3xf32> %1 = migraphx.where(%arg2, %0, %arg3) : (tensor<1x5x3xi8>, tensor<1x5x3xf32>, tensor<1x5x3xf32>) -> tensor<1x5x3xf32> return %1 : tensor<1x5x3xf32> diff --git a/test/gpu/quantization.cpp b/test/gpu/quantization.cpp index a1a08f43a68..b048197eb8d 100644 --- a/test/gpu/quantization.cpp +++ b/test/gpu/quantization.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -90,7 +90,7 @@ TEST_CASE(int8_quantization) migraphx::shape sc{migraphx::shape::float_type, {5, 8}}; auto pa = mm->add_parameter("a", sa); auto pb = mm->add_parameter("b", sb); - mm->add_instruction(migraphx::op::dot{}, pa, pb); + mm->add_instruction(migraphx::make_op("dot"), pa, pb); return p; }; diff --git a/test/include/test.hpp b/test/include/test.hpp index 3492729f635..1228f888e0b 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -22,6 +22,7 @@ * THE SOFTWARE. */ +#include #include #include #include @@ -342,11 +343,19 @@ inline std::ostream& operator<<(std::ostream& os, const color& c) return os; } +inline std::atomic& failures() +{ + // NOLINTNEXTLINE + static std::atomic f = 0; + return f; +} + template void failed(T x, const char* msg, const char* func, const char* file, int line, F f) { if(not bool(x.value())) { + failures()++; std::cout << func << std::endl; std::cout << file << ":" << line << ":" << std::endl; std::cout << color::bold << color::fg_red << " FAILED: " << color::reset << msg << " " @@ -384,7 +393,7 @@ bool throws(F f, const std::string& msg = "") } template -auto near(T px, U py, double ptol = 1e-6f) +auto within_abs(T px, U py, double ptol = 1e-6f) { return make_function("near", [](auto x, auto y, auto tol) { return std::abs(x - y) < tol; })( px, py, ptol); @@ -586,13 +595,21 @@ struct driver { try { + failures() = 0; f(); } + // cppcheck-suppress EmptyCatchStatement catch(const failure_error&) { - msg = "Test failure"; } } + if(msg.empty() and failures() != 0) + { + if(failures() == 1) + msg = "Test failure"; + else + msg = std::to_string(failures()) + " test failures"; + } if(msg.empty()) { out() << color::fg_green << "[ COMPLETE ] " << color::reset << color::bold << name @@ -683,10 +700,10 @@ inline void run(int argc, const char* argv[]) #define TEST_CAPTURE(...) test::capture{}->*__VA_ARGS__ // NOLINTNEXTLINE -#define CHECK(...) \ - test::failed( \ - test::capture{}->*__VA_ARGS__, #__VA_ARGS__, __PRETTY_FUNCTION__, __FILE__, __LINE__, [] { \ - }) +#define CHECK(...) \ + test::failed( \ + TEST_CAPTURE(__VA_ARGS__), #__VA_ARGS__, __PRETTY_FUNCTION__, __FILE__, __LINE__, [] {}) + // NOLINTNEXTLINE #define EXPECT(...) \ test::failed(TEST_CAPTURE(__VA_ARGS__), \ diff --git a/test/inline_module_test.cpp b/test/inline_module_test.cpp index ef3fadbf240..6e05aceed02 100644 --- a/test/inline_module_test.cpp +++ b/test/inline_module_test.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/test/insert_pad_test.cpp b/test/insert_pad_test.cpp index 0c0662af82f..6954a217008 100644 --- a/test/insert_pad_test.cpp +++ b/test/insert_pad_test.cpp @@ -26,8 +26,8 @@ #include #include #include +#include #include -#include #include #include @@ -58,10 +58,11 @@ create_conv(migraphx::instruction_ref& l_img, migraphx::shape s_weights{migraphx::shape::int32_type, {4, channels, 3, 3}}; std::vector weights(4 * channels * 3 * 3); auto l_weights = m.add_literal(migraphx::literal{s_weights, weights}); - migraphx::op::convolution op; - op.padding_mode = padding_mode; - op.padding = {0, 0, 1, 1}; - return m.add_instruction(op, l_img, l_weights); + return m.add_instruction( + migraphx::make_op("convolution", + {{"padding_mode", padding_mode}, {"padding", {0, 0, 1, 1}}}), + l_img, + l_weights); } TEST_CASE(rewrite_pad) diff --git a/test/jit.cpp b/test/jit.cpp index 0b6409fc938..a1e5253846e 100644 --- a/test/jit.cpp +++ b/test/jit.cpp @@ -82,9 +82,9 @@ TEST_CASE(generate_module) auto f = compile_module(m); - EXPECT(test::near(f(2, 2), 2)); - EXPECT(test::near(f(10, 6), 4)); - EXPECT(test::near(f(1, 2), std::sqrt(3))); + EXPECT(test::within_abs(f(2, 2), 2)); + EXPECT(test::within_abs(f(10, 6), 4)); + EXPECT(test::within_abs(f(1, 2), std::sqrt(3))); } TEST_CASE(generate_module_with_literals) @@ -99,9 +99,9 @@ TEST_CASE(generate_module_with_literals) auto f = compile_module(m); - EXPECT(test::near(f(1, 2), 2)); - EXPECT(test::near(f(9, 6), 4)); - EXPECT(test::near(f(0, 2), std::sqrt(3))); + EXPECT(test::within_abs(f(1, 2), 2)); + EXPECT(test::within_abs(f(9, 6), 4)); + EXPECT(test::within_abs(f(0, 2), std::sqrt(3))); } int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/layout_nhwc.cpp b/test/layout_nhwc.cpp index 997024fb974..453d75cedb7 100644 --- a/test/layout_nhwc.cpp +++ b/test/layout_nhwc.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/test/memory_coloring_test.cpp b/test/memory_coloring_test.cpp index 700ec9a5e42..7716c8b89a8 100644 --- a/test/memory_coloring_test.cpp +++ b/test/memory_coloring_test.cpp @@ -89,17 +89,13 @@ bool is_overlap_load(migraphx::instruction_ref a, migraphx::instruction_ref b) bool is_disjoint(const std::vector& inss) { - for(auto ins1 : inss) - { - for(auto ins2 : inss) - { + return std::none_of(inss.begin(), inss.end(), [&](auto ins1) { + return std::none_of(inss.begin(), inss.end(), [&](auto ins2) { if(ins1 == ins2) - continue; - if(is_overlap_load(ins1, ins2)) - return false; - } - } - return true; + return true; + return is_overlap_load(ins1, ins2); + }); + }); } TEST_CASE(test1) diff --git a/test/module_test.cpp b/test/module_test.cpp index f270f04a2a1..2119bf60912 100644 --- a/test/module_test.cpp +++ b/test/module_test.cpp @@ -83,7 +83,7 @@ TEST_CASE(calc_implict_deps) auto* else_mod = p.create_module("If_5_else"); auto l2 = else_mod->add_literal(migraphx::literal(ys, datay)); auto a2 = else_mod->add_instruction(migraphx::make_op("if"), {cond}, {then_mod1, else_mod1}); - auto a3 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), a2); + auto a3 = else_mod->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), a2); else_mod->add_return({a3, l2}); auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod}); @@ -95,6 +95,15 @@ TEST_CASE(calc_implict_deps) EXPECT(migraphx::contains(implicit_deps.at(ret), x1)); EXPECT(migraphx::contains(implicit_deps.at(ret), x2)); EXPECT(migraphx::contains(implicit_deps.at(ret), y2)); + EXPECT(migraphx::contains(implicit_deps.at(ret), lx)); + EXPECT(migraphx::contains(implicit_deps.at(ret), ly)); + // test for sorting + p.sort(); + auto ret_inputs = ret->inputs(); + ret_inputs.insert(ret_inputs.end(), implicit_deps.at(ret).begin(), implicit_deps.at(ret).end()); + EXPECT(std::all_of(ret_inputs.begin(), ret_inputs.end(), [&](const auto i) { + return std::distance(mm->begin(), i) < std::distance(mm->begin(), ret); + })); } TEST_CASE(module_annotate) diff --git a/test/onnx/.onnxrt-commit b/test/onnx/.onnxrt-commit index 4a9208c4843..16c7320f3b9 100644 --- a/test/onnx/.onnxrt-commit +++ b/test/onnx/.onnxrt-commit @@ -1 +1 @@ -d3295f4329d744fe1f8419e1220e123807282b99 +a476dbf430ac8315550474a78d47bf182f202d7c diff --git a/test/onnx/averagepool_dyn_autopad_error_test.onnx b/test/onnx/averagepool_dyn_autopad_error_test.onnx deleted file mode 100644 index 524c0896399..00000000000 Binary files a/test/onnx/averagepool_dyn_autopad_error_test.onnx and /dev/null differ diff --git a/test/onnx/averagepool_dyn_autopad_test.onnx b/test/onnx/averagepool_dyn_autopad_test.onnx new file mode 100644 index 00000000000..248ae610114 Binary files /dev/null and b/test/onnx/averagepool_dyn_autopad_test.onnx differ diff --git a/test/onnx/averagepool_dyn_test.onnx b/test/onnx/averagepool_dyn_test.onnx index cb12c8ebe12..5bc54615e99 100644 Binary files a/test/onnx/averagepool_dyn_test.onnx and b/test/onnx/averagepool_dyn_test.onnx differ diff --git a/test/onnx/gen_onnx.py b/test/onnx/gen_onnx.py index 54b0963ad18..73c910c4af6 100644 --- a/test/onnx/gen_onnx.py +++ b/test/onnx/gen_onnx.py @@ -270,23 +270,26 @@ def averagepool_dyn_test(): node = onnx.helper.make_node('AveragePool', inputs=['0'], outputs=['1'], - kernel_shape=[3, 3, 3]) - + kernel_shape=[3, 3, 3], + strides=[2, 2, 2], + pads=[1, 1, 1, 1, 1, 1]) return ([node], [x], [out]) @onnx_test() -def averagepool_dyn_autopad_error_test(): - x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [None, 1, 5, 5]) - y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [None, 1, 5, 5]) +def averagepool_dyn_autopad_test(): + x = helper.make_tensor_value_info('0', TensorProto.FLOAT, + [None, 3, 5, 5, 5]) + out = helper.make_tensor_value_info('1', TensorProto.FLOAT, + [None, 3, 3, 3, 3]) node = onnx.helper.make_node('AveragePool', - inputs=['x'], - outputs=['y'], - kernel_shape=[2, 2], - auto_pad='SAME_LOWER') - - return ([node], [x], [y]) + inputs=['0'], + outputs=['1'], + kernel_shape=[3, 3, 3], + strides=[2, 2, 2], + auto_pad='SAME_UPPER') + return ([node], [x], [out]) @onnx_test() @@ -3456,7 +3459,6 @@ def instance_norm_dyn_batch_test(): outputs=['3']) return ([node], [x, scale, bias], [y]) - return ([node], [x, scale, bias], [y]) @onnx_test() @@ -6414,6 +6416,30 @@ def slice_test(): return ([node], [x], [y]) +@onnx_test() +def slice_constant_test(): + y = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1, 2]) + + x_tensor = helper.make_tensor(name='x_tensor', + data_type=TensorProto.FLOAT, + dims=[3, 2], + vals=[0, 1, 2, 3, 4, 5]) + + x = onnx.helper.make_node('Constant', + inputs=[], + outputs=['x'], + value=x_tensor) + + node = onnx.helper.make_node('Slice', + inputs=['x'], + axes=[0, 1], + starts=[1, 0], + ends=[2, 2], + outputs=['1']) + + return ([x, node], [], [y]) + + @onnx_test() def slice_dyn_test(): x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [None, None, 2]) @@ -6746,6 +6772,92 @@ def slice_max_end_test(): return ([node], [x], [y]) +@onnx_test() +def slice_var_input_static0(): + data = helper.make_tensor_value_info('data', TensorProto.FLOAT, [3, 2]) + starts = helper.make_tensor_value_info('starts', TensorProto.INT32, [2]) + ends = helper.make_tensor_value_info('ends', TensorProto.INT32, [2]) + output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 2]) + + node = onnx.helper.make_node('Slice', + inputs=['data', 'starts', 'ends'], + axes=[0, 1], + outputs=['output']) + + return ([node], [data, starts, ends], [output]) + + +@onnx_test() +def slice_var_input_static1(): + data = helper.make_tensor_value_info('data', TensorProto.FLOAT, [3, 2]) + starts = helper.make_tensor_value_info('starts', TensorProto.INT64, [2]) + ends = helper.make_tensor_value_info('ends', TensorProto.INT64, [2]) + axes = helper.make_tensor_value_info('axes', TensorProto.INT64, [2]) + output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 2]) + + node = onnx.helper.make_node('Slice', + inputs=['data', 'starts', 'ends', 'axes'], + outputs=['output']) + + return ([node], [data, starts, ends, axes], [output]) + + +@onnx_test() +def slice_var_input_dyn0(): + data = helper.make_tensor_value_info('data', TensorProto.FLOAT, [None, 2]) + starts = helper.make_tensor_value_info('starts', TensorProto.INT32, [2]) + ends = helper.make_tensor_value_info('ends', TensorProto.INT32, [2]) + output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 2]) + + node = onnx.helper.make_node('Slice', + inputs=['data', 'starts', 'ends'], + axes=[0, 1], + outputs=['output']) + + return ([node], [data, starts, ends], [output]) + + +@onnx_test() +def slice_var_input_dyn1(): + data = helper.make_tensor_value_info('data', TensorProto.FLOAT, [None, 2]) + starts = helper.make_tensor_value_info('starts', TensorProto.INT32, [2]) + ends = helper.make_tensor_value_info('ends', TensorProto.INT32, [2]) + axes = helper.make_tensor_value_info('axes', TensorProto.INT32, [2]) + output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 2]) + + node = onnx.helper.make_node('Slice', + inputs=['data', 'starts', 'ends', 'axes'], + outputs=['output']) + + return ([node], [data, starts, ends, axes], [output]) + + +@onnx_test() +def slice_var_input_steps_error(): + step = np.array([2, 1]) + step_tensor = helper.make_tensor(name="step", + data_type=TensorProto.INT32, + dims=step.shape, + vals=step.astype(int)) + arg_step = helper.make_node("Constant", + inputs=[], + outputs=['arg_step'], + value=step_tensor) + + data = helper.make_tensor_value_info('data', TensorProto.FLOAT, [3, 2]) + starts = helper.make_tensor_value_info('starts', TensorProto.FLOAT, [2]) + ends = helper.make_tensor_value_info('ends', TensorProto.FLOAT, [2]) + axes = helper.make_tensor_value_info('axes', TensorProto.FLOAT, [2]) + output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 2]) + + node = onnx.helper.make_node( + 'Slice', + inputs=['data', 'starts', 'ends', 'axes', 'arg_step'], + outputs=['output']) + + return ([arg_step, node], [data, starts, ends, axes], [output]) + + @onnx_test() def softmax_test(): x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [1, 3]) diff --git a/test/onnx/onnx_rnn_test.cpp b/test/onnx/onnx_rnn_test.cpp index 7a8f3e855d4..5ba978ae617 100644 --- a/test/onnx/onnx_rnn_test.cpp +++ b/test/onnx/onnx_rnn_test.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/onnx/onnx_test.cpp b/test/onnx/onnx_test.cpp index 11896a24faf..b23ace35073 100644 --- a/test/onnx/onnx_test.cpp +++ b/test/onnx/onnx_test.cpp @@ -292,16 +292,21 @@ TEST_CASE(averagepool_3d_test) TEST_CASE(averagepool_dyn_test) { + // Pooling with dynamic input and no auto padding migraphx::program p; auto* mm = p.get_main_module(); auto l0 = mm->add_parameter( "0", {migraphx::shape::float_type, {{1, 4}, {3, 3}, {5, 5}, {5, 5}, {5, 5}}}); - auto ret = mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, - {"padding", {0, 0, 0, 0, 0, 0}}, - {"stride", {1, 1, 1}}, - {"lengths", {3, 3, 3}}}), - l0); + auto ret = + mm->add_instruction(migraphx::make_op("pooling", + { + {"mode", migraphx::op::pooling_mode::average}, + {"stride", {2, 2, 2}}, + {"lengths", {3, 3, 3}}, + {"padding", {1, 1, 1, 1, 1, 1}}, + {"padding_mode", 0}, + }), + l0); mm->add_return({ret}); migraphx::onnx_options options; @@ -310,12 +315,29 @@ TEST_CASE(averagepool_dyn_test) EXPECT(p == prog); } -TEST_CASE(averagepool_dyn_autopad_error_test) +TEST_CASE(averagepool_dyn_autopad_test) { + // Pooling with dynamic input and auto padding. Default padding values will be overridden. + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = mm->add_parameter( + "0", {migraphx::shape::float_type, {{1, 4}, {3, 3}, {5, 5}, {5, 5}, {5, 5}}}); + auto ret = mm->add_instruction( + migraphx::make_op("pooling", + { + {"mode", migraphx::op::pooling_mode::average}, + {"stride", {2, 2, 2}}, + {"lengths", {3, 3, 3}}, + {"padding", {0, 0, 0, 0, 0, 0}}, + {"padding_mode", migraphx::op::padding_mode_t::same_upper}, + }), + l0); + mm->add_return({ret}); + migraphx::onnx_options options; options.default_dyn_dim_value = {1, 4}; - EXPECT(test::throws( - [&] { migraphx::parse_onnx("averagepool_dyn_autopad_error_test.onnx", options); })); + auto prog = migraphx::parse_onnx("averagepool_dyn_autopad_test.onnx", options); + EXPECT(p == prog); } TEST_CASE(averagepool_dyn_asym_padding_error_test) @@ -374,16 +396,22 @@ TEST_CASE(averagepool_nt_cip_test) TEST_CASE(averagepool_same_lower_test) { + // auto_pad mode of SAME_LOWER with a static input shape is handled in parsing and + // padding_mode is set to default_ when the operation is created migraphx::program p; auto* mm = p.get_main_module(); auto input = mm->add_parameter("x", migraphx::shape{migraphx::shape::float_type, {1, 1, 5, 5}}); - auto ins = mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, - {"padding", {1, 1, 1, 1}}, - {"stride", {1, 1}}, - {"lengths", {2, 2}}}), - input); - auto ret = mm->add_instruction( + auto ins = mm->add_instruction( + migraphx::make_op("pooling", + { + {"mode", migraphx::op::pooling_mode::average}, + {"padding", {1, 1, 1, 1}}, + {"stride", {1, 1}}, + {"lengths", {2, 2}}, + {"padding_mode", migraphx::op::padding_mode_t::default_}, + }), + input); + auto ret = mm->add_instruction( migraphx::make_op("slice", {{"axes", {2, 3}}, {"starts", {0, 0}}, {"ends", {5, 5}}}), ins); mm->add_return({ret}); auto prog = migraphx::parse_onnx("averagepool_same_lower_test.onnx"); @@ -4712,14 +4740,16 @@ TEST_CASE(quantizelinear_test) auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}}); auto l1_mbcast = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {5}}}), l1); - auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast); - auto round = mm->add_instruction(migraphx::make_op("round"), div); - auto s = round->get_shape(); - std::vector min_data(s.elements(), 0); - std::vector max_data(s.elements(), 255); - auto min_arg = mm->add_literal(s, min_data); - auto max_arg = mm->add_literal(s, max_data); - auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_arg, max_arg); + auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast); + auto round = mm->add_instruction(migraphx::make_op("round"), div); + auto s = round->get_shape(); + auto min_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {0}}); + auto max_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {255}}); + auto min_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), min_arg); + auto max_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), max_arg); + auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_mbcast, max_mbcast); mm->add_instruction( migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::uint8_type)}}), @@ -4741,14 +4771,16 @@ TEST_CASE(quantizelinear_int32_test) migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}), l0); - auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast); - auto round = mm->add_instruction(migraphx::make_op("round"), div); - auto s = round->get_shape(); - std::vector min_data(s.elements(), 0); - std::vector max_data(s.elements(), 255); - auto min_arg = mm->add_literal(s, min_data); - auto max_arg = mm->add_literal(s, max_data); - auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_arg, max_arg); + auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast); + auto round = mm->add_instruction(migraphx::make_op("round"), div); + auto s = round->get_shape(); + auto min_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {0}}); + auto max_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {255}}); + auto min_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), min_arg); + auto max_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), max_arg); + auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_mbcast, max_mbcast); mm->add_instruction( migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::uint8_type)}}), @@ -4775,13 +4807,15 @@ TEST_CASE(quantizelinear_zero_point_test) migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}), l2_mbcast); - auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_mbcast); - auto s = round->get_shape(); - std::vector min_data(s.elements(), -128); - std::vector max_data(s.elements(), 127); - auto min_arg = mm->add_literal(s, min_data); - auto max_arg = mm->add_literal(s, max_data); - auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_arg, max_arg); + auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_mbcast); + auto s = round->get_shape(); + auto min_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {-128}}); + auto max_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {127}}); + auto min_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), min_arg); + auto max_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), max_arg); + auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_mbcast, max_mbcast); mm->add_instruction( migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}), @@ -4812,13 +4846,15 @@ migraphx::program make_quantizelinear_axis_prog() migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}), l2_bcast); - auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_bcast); - auto s = round->get_shape(); - std::vector min_data(s.elements(), -128); - std::vector max_data(s.elements(), 127); - auto min_arg = mm->add_literal(s, min_data); - auto max_arg = mm->add_literal(s, max_data); - auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_arg, max_arg); + auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_bcast); + auto s = round->get_shape(); + auto min_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {-128}}); + auto max_arg = mm->add_literal(migraphx::literal{migraphx::shape{s.type()}, {127}}); + auto min_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), min_arg); + auto max_mbcast = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", s.lens()}}), max_arg); + auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_mbcast, max_mbcast); mm->add_instruction( migraphx::make_op("convert", {{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}), @@ -6286,6 +6322,19 @@ TEST_CASE(slice_test) EXPECT(p == prog); } +TEST_CASE(slice_constant_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = mm->add_literal(migraphx::literal{ + migraphx::shape{migraphx::shape::float_type, {3, 2}}, {0, 1, 2, 3, 4, 5}}); + mm->add_instruction( + migraphx::make_op("slice", {{"axes", {0, 1}}, {"starts", {1, 0}}, {"ends", {2, 2}}}), l0); + auto prog = optimize_onnx("slice_constant_test.onnx"); + + EXPECT(p == prog); +} + TEST_CASE(slice_dyn_test) { migraphx::program p; @@ -6418,6 +6467,74 @@ TEST_CASE(slice_max_end_test) EXPECT(p == prog); } +TEST_CASE(slice_var_input_static0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto data = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {3, 2}}); + auto starts = mm->add_parameter("starts", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto ends = mm->add_parameter("ends", migraphx::shape{migraphx::shape::int32_type, {2}}); + mm->add_instruction(migraphx::make_op("slice", {{"axes", {0, 1}}}), data, starts, ends); + auto prog = optimize_onnx("slice_var_input_static0.onnx"); + + EXPECT(p == prog); +} + +TEST_CASE(slice_var_input_static1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto data = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {3, 2}}); + auto starts = mm->add_parameter("starts", migraphx::shape{migraphx::shape::int64_type, {2}}); + auto ends = mm->add_parameter("ends", migraphx::shape{migraphx::shape::int64_type, {2}}); + auto axes = mm->add_parameter("axes", migraphx::shape{migraphx::shape::int64_type, {2}}); + mm->add_instruction(migraphx::make_op("slice"), data, starts, ends, axes); + auto prog = optimize_onnx("slice_var_input_static1.onnx"); + + EXPECT(p == prog); +} + +TEST_CASE(slice_var_input_dyn0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto data = + mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {{3, 8}, {2, 2}}}); + auto starts = mm->add_parameter("starts", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto ends = mm->add_parameter("ends", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto ret = + mm->add_instruction(migraphx::make_op("slice", {{"axes", {0, 1}}}), data, starts, ends); + mm->add_return({ret}); + + migraphx::onnx_options options; + options.default_dyn_dim_value = {3, 8}; + auto prog = parse_onnx("slice_var_input_dyn0.onnx", options); + EXPECT(p == prog); +} + +TEST_CASE(slice_var_input_dyn1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto data = + mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {{3, 8}, {2, 2}}}); + auto starts = mm->add_parameter("starts", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto ends = mm->add_parameter("ends", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto axes = mm->add_parameter("axes", migraphx::shape{migraphx::shape::int32_type, {2}}); + auto ret = mm->add_instruction(migraphx::make_op("slice"), data, starts, ends, axes); + mm->add_return({ret}); + + migraphx::onnx_options options; + options.default_dyn_dim_value = {3, 8}; + auto prog = parse_onnx("slice_var_input_dyn1.onnx", options); + EXPECT(p == prog); +} + +TEST_CASE(slice_var_input_steps_error) +{ + EXPECT(test::throws([&] { migraphx::parse_onnx("slice_var_input_steps_error.onnx"); })); +} + TEST_CASE(softmax_test) { migraphx::program p; diff --git a/test/onnx/slice_constant_test.onnx b/test/onnx/slice_constant_test.onnx new file mode 100644 index 00000000000..7c28d7d9b0f Binary files /dev/null and b/test/onnx/slice_constant_test.onnx differ diff --git a/test/onnx/slice_var_input_dyn0.onnx b/test/onnx/slice_var_input_dyn0.onnx new file mode 100644 index 00000000000..431d672e310 Binary files /dev/null and b/test/onnx/slice_var_input_dyn0.onnx differ diff --git a/test/onnx/slice_var_input_dyn1.onnx b/test/onnx/slice_var_input_dyn1.onnx new file mode 100644 index 00000000000..ebfe77bffd1 Binary files /dev/null and b/test/onnx/slice_var_input_dyn1.onnx differ diff --git a/test/onnx/slice_var_input_static0.onnx b/test/onnx/slice_var_input_static0.onnx new file mode 100644 index 00000000000..e587b2ef48c Binary files /dev/null and b/test/onnx/slice_var_input_static0.onnx differ diff --git a/test/onnx/slice_var_input_static1.onnx b/test/onnx/slice_var_input_static1.onnx new file mode 100644 index 00000000000..9b102a778bd --- /dev/null +++ b/test/onnx/slice_var_input_static1.onnx @@ -0,0 +1,26 @@ + slice_var_input_static1:´ +) +data +starts +ends +axesoutput"Sliceslice_var_input_static1Z +data +  + +Z +starts + + +Z +ends + + +Z +axes + + +b +output +  + +B \ No newline at end of file diff --git a/test/onnx/slice_var_input_steps_error.onnx b/test/onnx/slice_var_input_steps_error.onnx new file mode 100644 index 00000000000..62166ec1f60 --- /dev/null +++ b/test/onnx/slice_var_input_steps_error.onnx @@ -0,0 +1,29 @@ + slice_var_input_steps_error:ô +0arg_step"Constant* +value**Bstep  +3 +data +starts +ends +axes +arg_stepoutput"Sliceslice_var_input_steps_errorZ +data +  + +Z +starts + + +Z +ends + + +Z +axes + + +b +output +  + +B \ No newline at end of file diff --git a/test/onnx/verify_onnx.cpp b/test/onnx/verify_onnx.cpp index 4a5eef9eccb..f491c3e5b45 100644 --- a/test/onnx/verify_onnx.cpp +++ b/test/onnx/verify_onnx.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/test/op_shape_test.cpp b/test/op_shape_test.cpp index 4ca98309962..0457f1bb3b8 100644 --- a/test/op_shape_test.cpp +++ b/test/op_shape_test.cpp @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include @@ -156,13 +157,13 @@ TEST_CASE(broadcast) { std::vector lens{1, 1}; migraphx::shape input{migraphx::shape::float_type, {2}}; - throws_shape(migraphx::op::broadcast{1, lens}, input); + throws_shape(migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", lens}}), input); } { std::vector lens{2, 2}; migraphx::shape input{migraphx::shape::float_type, {1, 2}}; - throws_shape(migraphx::op::broadcast{1, lens}, input); + throws_shape(migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", lens}}), input); } { @@ -323,7 +324,7 @@ TEST_CASE(conv_dyn_batch) TEST_CASE(conv_dyn_img) { migraphx::shape input_dyn_shape = {migraphx::shape::float_type, - {{1, 1}, {3, 3}, {5, 20}, {5, 20}}}; + {{1, 1}, {3, 3}, {5, 20}, {5, 20}}}; migraphx::shape weights_shape = {migraphx::shape::float_type, {1, 3, 3, 3}}; migraphx::shape output_dyn_shape = {migraphx::shape::float_type, {{1, 1}, {1, 1}, {3, 18}, {3, 18}}}; @@ -376,7 +377,7 @@ TEST_CASE(conv_autopad_dyn_batch) { // auto_pad dynamic batch migraphx::shape input_dyn_shape = {migraphx::shape::float_type, - {{1, 10}, {3, 3}, {5, 5}, {5, 5}}}; + {{1, 10}, {3, 3}, {5, 5}, {5, 5}}}; migraphx::shape weights_shape = {migraphx::shape::float_type, {1, 3, 3, 3}}; migraphx::shape output_dyn_shape = {migraphx::shape::float_type, {{1, 10}, {1, 1}, {5, 5}, {5, 5}}}; @@ -393,7 +394,7 @@ TEST_CASE(conv_autopad_dyn_img) { // auto_pad dynamic img migraphx::shape input_dyn_shape = {migraphx::shape::float_type, - {{1, 1}, {3, 3}, {5, 10}, {5, 10}}}; + {{1, 1}, {3, 3}, {5, 10}, {5, 10}}}; migraphx::shape weights_shape = {migraphx::shape::float_type, {1, 3, 3, 3}}; migraphx::shape output_dyn_shape = {migraphx::shape::float_type, {{1, 1}, {1, 1}, {5, 10}, {5, 10}}}; @@ -1252,36 +1253,45 @@ TEST_CASE(inconsistent_attr_shape) input); } -template -void test_softmax_variations() +void test_softmax_variations(const std::string& name) { { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, T{0}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, + migraphx::make_op(name, {{"axis", 0}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, T{1}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, + migraphx::make_op(name, {{"axis", 1}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, T{2}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, + migraphx::make_op(name, {{"axis", 2}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, T{3}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 5}}, + migraphx::make_op(name, {{"axis", 3}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; int axis = 4; - throws_shape(T{axis}, input); + throws_shape(migraphx::make_op(name, {{"axis", axis}}), input); } } -TEST_CASE(logsoftmax) { test_softmax_variations(); } +TEST_CASE(logsoftmax) { test_softmax_variations("logsoftmax"); } + +TEST_CASE(softmax) { test_softmax_variations("softmax"); } TEST_CASE(lstm) { @@ -2106,6 +2116,13 @@ TEST_CASE(pooling_shape3) input); } +TEST_CASE(pooling_shape4) +{ + migraphx::shape tiny_input{migraphx::shape::float_type, {4, 1}}; + throws_shape(migraphx::make_op("pooling", {{"mode", migraphx::op::pooling_mode::max}}), + tiny_input); +} + TEST_CASE(pooling_dyn_shape0) { migraphx::shape input{migraphx::shape::float_type, {{1, 4}, {3, 3, {3}}, {3, 3, {3}}, {3, 3}}}; @@ -2328,47 +2345,54 @@ TEST_CASE(dqlinear_mismatch_type) throws_shape(migraphx::make_op("dequantizelinear"), input, scales, zeros); } -template -void test_reduce_ops() +void test_reduce_ops(const std::string& name) { { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {1, 1, 1, 1}}, T{}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {1, 1, 1, 1}}, + migraphx::make_op(name), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape( - migraphx::shape{migraphx::shape::float_type, {1, 1, 1, 1}}, T{{0, 1, 2, 3}}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {1, 1, 1, 1}}, + migraphx::make_op(name, {{"axes", {0, 1, 2, 3}}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 1, 1}}, T{{2, 3}}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 1, 1}}, + migraphx::make_op(name, {{"axes", {2, 3}}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {1, 3, 4, 5}}, T{{0}}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {1, 3, 4, 5}}, + migraphx::make_op(name, {{"axes", {0}}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 1}}, T{{-1}}, input); + expect_shape(migraphx::shape{migraphx::shape::float_type, {2, 3, 4, 1}}, + migraphx::make_op(name, {{"axes", {-1}}}), + input); } { migraphx::shape input{migraphx::shape::float_type, {2, 3, 4, 5}}; - throws_shape(T{{4}}, input); + throws_shape(migraphx::make_op(name, {{"axes", {4}}}), input); } } // dynamic shape -template -void test_dyn_reduce_ops() +void test_dyn_reduce_ops(const std::string& name) { { migraphx::shape input{migraphx::shape::float_type, {{2, 3, {3}}, {2, 4, {4}}}}; expect_shape( migraphx::shape{migraphx::shape::float_type, std::vector({{2, 3, {3}}, {1, 1}})}, - T{{-1}}, + migraphx::make_op(name, {{"axes", {-1}}}), input); } { @@ -2376,7 +2400,7 @@ void test_dyn_reduce_ops() expect_shape( migraphx::shape{migraphx::shape::float_type, std::vector({{1, 1}, {2, 4, {4}}})}, - T{{0}}, + migraphx::make_op(name, {{"axes", {0}}}), input); } { @@ -2385,24 +2409,24 @@ void test_dyn_reduce_ops() expect_shape( migraphx::shape{migraphx::shape::float_type, std::vector({{1, 1}, {1, 1}})}, - T{{}}, + migraphx::make_op(name), input); } { migraphx::shape input{migraphx::shape::float_type, {{2, 3, {3}}, {2, 4, {4}}}}; - throws_shape(T{{4}}, input); + throws_shape(migraphx::make_op(name, {{"axes", {4}}}), input); } } -TEST_CASE(reduce_max) { test_reduce_ops(); } -TEST_CASE(reduce_mean) { test_reduce_ops(); } -TEST_CASE(reduce_prod) { test_reduce_ops(); } -TEST_CASE(reduce_sum) { test_reduce_ops(); } +TEST_CASE(reduce_max) { test_reduce_ops("reduce_max"); } +TEST_CASE(reduce_mean) { test_reduce_ops("reduce_mean"); } +TEST_CASE(reduce_prod) { test_reduce_ops("reduce_prod"); } +TEST_CASE(reduce_sum) { test_reduce_ops("reduce_sum"); } -TEST_CASE(reduce_max_dyn) { test_dyn_reduce_ops(); } -TEST_CASE(reduce_mean_dyn) { test_dyn_reduce_ops(); } -TEST_CASE(reduce_prod_dyn) { test_dyn_reduce_ops(); } -TEST_CASE(reduce_sum_dyn) { test_dyn_reduce_ops(); } +TEST_CASE(reduce_max_dyn) { test_dyn_reduce_ops("reduce_max"); } +TEST_CASE(reduce_mean_dyn) { test_dyn_reduce_ops("reduce_mean"); } +TEST_CASE(reduce_prod_dyn) { test_dyn_reduce_ops("reduce_prod"); } +TEST_CASE(reduce_sum_dyn) { test_dyn_reduce_ops("reduce_sum"); } TEST_CASE(reshape_shape) { @@ -2597,6 +2621,36 @@ TEST_CASE(reshape_non_fixed_not_matching_error) throws_shape(migraphx::make_op("reshape", {{"dims", new_shape}}), input); } +TEST_CASE(return_shape_tuple) +{ + using migraphx::shape; + auto op = migraphx::make_op("@return"); + shape s0{shape::bool_type, {1, 1}}; + shape s1{shape::float_type, {2, 3}}; + + std::vector s{s0, s1}; + auto s_out = op.compute_shape(s); + EXPECT(s_out.type() == shape::tuple_type); + EXPECT(s0 == s_out.sub_shapes()[0]); + EXPECT(s1 == s_out.sub_shapes()[1]); +} + +TEST_CASE(return_shape_half) +{ + using migraphx::shape; + auto op = migraphx::make_op("@return"); + std::vector s{{shape::half_type}}; + EXPECT(op.compute_shape(s) == shape{shape::half_type}); +} + +TEST_CASE(return_shape_empty) +{ + using migraphx::shape; + auto op = migraphx::make_op("@return"); + std::vector s; + EXPECT(op.compute_shape(s) == shape{}); +} + TEST_CASE(rnn) { { @@ -2792,7 +2846,7 @@ TEST_CASE(select_module_dyn) input); } -TEST_CASE(slice_shape) +TEST_CASE(slice_static_shape) { migraphx::shape input{migraphx::shape::int32_type, {2, 2, 3}}; expect_shape(migraphx::shape{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}, @@ -2810,6 +2864,67 @@ TEST_CASE(slice_shape) input); } +TEST_CASE(slice_var_inputs_static_shape0) +{ + migraphx::shape input{migraphx::shape::float_type, {3, 4, 4}}; + migraphx::shape starts{migraphx::shape::int64_type, {2}}; + migraphx::shape ends{migraphx::shape::int64_type, {2}}; + expect_shape(migraphx::shape{migraphx::shape::float_type, {{3, 3}, {0, 4}, {0, 4}}}, + migraphx::make_op("slice", {{"axes", {1, 2}}}), + input, + starts, + ends); +} + +TEST_CASE(slice_var_inputs_static_shape1) +{ + migraphx::shape input{migraphx::shape::float_type, {3, 4, 4}}; + migraphx::shape starts{migraphx::shape::int64_type, {2}}; + migraphx::shape ends{migraphx::shape::int64_type, {2}}; + migraphx::shape axes{migraphx::shape::int64_type, {2}}; + expect_shape(migraphx::shape{migraphx::shape::float_type, {{0, 3}, {0, 4}, {0, 4}}}, + migraphx::make_op("slice"), + input, + starts, + ends, + axes); +} + +TEST_CASE(slice_var_inputs_static_error0) +{ + migraphx::shape input{migraphx::shape::float_type, {3, 4, 4}}; + migraphx::shape starts{migraphx::shape::int64_type, {2}}; + migraphx::shape ends{migraphx::shape::int64_type, {2}}; + migraphx::shape axes{migraphx::shape::int64_type, {3}}; + throws_shape(migraphx::make_op("slice"), input, starts, ends, axes); +} + +TEST_CASE(slice_var_inputs_dyn_shape0) +{ + migraphx::shape input{migraphx::shape::float_type, {{3, 6}, {2, 4, {2, 4}}, {2, 4, {2, 4}}}}; + migraphx::shape starts{migraphx::shape::int64_type, {2}}; + migraphx::shape ends{migraphx::shape::int64_type, {2}}; + expect_shape(migraphx::shape{migraphx::shape::float_type, {{3, 6}, {0, 4}, {0, 4}}}, + migraphx::make_op("slice", {{"axes", {1, 2}}}), + input, + starts, + ends); +} + +TEST_CASE(slice_var_inputs_dyn_shape1) +{ + migraphx::shape input{migraphx::shape::float_type, {{3, 6}, {2, 4, {2, 4}}, {2, 4, {2, 4}}}}; + migraphx::shape starts{migraphx::shape::int64_type, {2}}; + migraphx::shape ends{migraphx::shape::int64_type, {2}}; + migraphx::shape axes{migraphx::shape::int64_type, {2}}; + expect_shape(migraphx::shape{migraphx::shape::float_type, {{0, 6}, {0, 4}, {0, 4}}}, + migraphx::make_op("slice"), + input, + starts, + ends, + axes); +} + TEST_CASE(slice_dyn_shape0) { migraphx::shape input{migraphx::shape::int32_type, {{2, 3}, {7, 7}, {2, 3}}}; @@ -2840,7 +2955,7 @@ TEST_CASE(slice_dyn_shape2) TEST_CASE(slice_dyn_shape3) { - // TODO: When variable dimension slicing is allowed, Slice to a size smaller than min. + // TODO: When non-fixed dimension slicing is allowed, Slice to a size smaller than min. // Until then, this action is an error. migraphx::shape input{migraphx::shape::int32_type, {{2, 3}, {7, 8}, {2, 3}}}; throws_shape(migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), @@ -2871,8 +2986,6 @@ TEST_CASE(slice_dyn_shape5) input); } -TEST_CASE(softmax) { test_softmax_variations(); } - TEST_CASE(softmax_dyn0) { migraphx::shape input{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}, {5, 5}}}; diff --git a/test/pad_calc_test.cpp b/test/pad_calc_test.cpp index 61554a41b26..7e21a9967f1 100644 --- a/test/pad_calc_test.cpp +++ b/test/pad_calc_test.cpp @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include -#include #include #include "test.hpp" diff --git a/test/py/CMakeLists.txt b/test/py/CMakeLists.txt index 54092d81061..634e6114520 100755 --- a/test/py/CMakeLists.txt +++ b/test/py/CMakeLists.txt @@ -27,7 +27,7 @@ include(PythonModules) function(add_py_test NAME SCRIPT) foreach(PYTHON_VERSION ${PYTHON_VERSIONS}) set (ENV_COMMAND ${CMAKE_COMMAND} -E env - "PYTHONPATH=$" + "PYTHONPATH=$" "PYTHONMALLOC=debug" "MALLOC_CHECK_=3" ) @@ -41,10 +41,8 @@ function(add_py_test NAME SCRIPT) endforeach() endfunction() -foreach(PYTHON_VERSION ${PYTHON_VERSIONS}) - add_dependencies(tests migraphx_py_${PYTHON_VERSION}) - add_dependencies(check migraphx_py_${PYTHON_VERSION}) -endforeach() +add_dependencies(tests migraphx_py) +add_dependencies(check migraphx_py) add_py_test(ref test_cpu.py WORKING_DIRECTORY ${TEST_ONNX_DIR}) add_py_test(save_load test_save_load.py WORKING_DIRECTORY ${TEST_ONNX_DIR}) diff --git a/test/quantization.cpp b/test/quantization.cpp index d9f94e32ee0..bb76152a6cb 100644 --- a/test/quantization.cpp +++ b/test/quantization.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/test/ref/CMakeLists.txt b/test/ref/CMakeLists.txt new file mode 100644 index 00000000000..0a3484ffae8 --- /dev/null +++ b/test/ref/CMakeLists.txt @@ -0,0 +1,30 @@ +##################################################################################### +# The MIT License (MIT) +# +# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +##################################################################################### + +file(GLOB REF CONFIGURE_DEPENDS *.cpp) + +add_test_executable(test_ref ${REF}) +target_include_directories(test_ref PUBLIC ../include) +rocm_clang_tidy_check(test_ref) + diff --git a/test/ref/abs.cpp b/test/ref/abs.cpp new file mode 100644 index 00000000000..104991a0bde --- /dev/null +++ b/test/ref/abs.cpp @@ -0,0 +1,66 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(abs_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + auto l = mm->add_literal(migraphx::literal{s, {-1, 2, -3, 4}}); + mm->add_instruction(migraphx::make_op("abs"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 2, 3, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(abs_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 8}, {2, 2}}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("abs"), input); + p.compile(migraphx::make_target("ref")); + + std::vector a = {-1, 2, -3, 4}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 2, 3, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/acos.cpp b/test/ref/acos.cpp new file mode 100644 index 00000000000..20488992f69 --- /dev/null +++ b/test/ref/acos.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(acos_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {3}}; + std::vector data{-0.8f, 0.0f, 1.0f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("acos"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acosf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(acos_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("acos"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-0.8f, 0.0f, 1.0f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acosf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/acosh.cpp b/test/ref/acosh.cpp new file mode 100644 index 00000000000..80651e1c7fc --- /dev/null +++ b/test/ref/acosh.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(acosh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {3}}; + std::vector data{1.1f, 1.2f, 2.0f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("acosh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acoshf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(acosh_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + std::vector input_data{1.1f, 1.2f, 2.0f}; + mm->add_instruction(migraphx::make_op("acosh"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acoshf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/add.cpp b/test/ref/add.cpp new file mode 100644 index 00000000000..a67663e7c0e --- /dev/null +++ b/test/ref/add.cpp @@ -0,0 +1,167 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(add_broadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3}}; + std::vector a_data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + migraphx::shape b_shape{migraphx::shape::float_type, {2, 2}}; + std::vector b_data{0, -1, -2, -3}; + uint64_t axis = 0; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + auto l3 = mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", axis}, {"out_lens", l1->get_shape().lens()}}), l2); + mm->add_instruction(migraphx::make_op("add"), l1, l3); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape().packed()); + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(add_multibroadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3}}; + std::vector a_data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + migraphx::shape b_shape{migraphx::shape::float_type, {2, 2, 1}}; + std::vector b_data{0, -1, -2, -3}; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + auto l3 = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3}}}), l1); + auto l4 = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3}}}), l2); + mm->add_instruction(migraphx::make_op("add"), l3, l4); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape().packed()); + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(add_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); + auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); + mm->add_instruction(migraphx::make_op("add"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 2, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(add_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + mm->add_instruction(migraphx::make_op("add"), x, y); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1, 0, 1}; + std::vector y_data{1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 2, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(fp16_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::half_type, {1}}; + migraphx::half a{1.5}; + migraphx::half b{2.5}; + migraphx::half c{4.0}; + auto l0 = mm->add_literal(migraphx::literal{s, {a}}); + auto l1 = mm->add_literal(migraphx::literal{s, {b}}); + mm->add_instruction(migraphx::make_op("add"), l0, l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(1); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{c}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(fp32_fp16_test) +{ + auto create_program = [] { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3}}; + std::vector data(2 * 3); + std::iota(data.begin(), data.end(), 1.0f); + auto l1 = mm->add_literal(migraphx::literal(s, data)); + auto l2 = mm->add_literal(migraphx::literal(s, data)); + mm->add_instruction(migraphx::make_op("add"), l1, l2); + return p; + }; + + auto test_case = [&](std::vector&& op_names) { + std::vector gold_res = {2.0, 4.0, 6.0, 8.0, 10.0, 12.0}; + auto p = create_program(); + migraphx::quantize_fp16(p, op_names); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res; + result.visit([&](auto output) { res.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res, gold_res)); + }; + + test_case({"all"}); + test_case({"add"}); +} diff --git a/test/ref/argmax.cpp b/test/ref/argmax.cpp new file mode 100644 index 00000000000..e98cb6ce2b8 --- /dev/null +++ b/test/ref/argmax.cpp @@ -0,0 +1,149 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(argmax_test_0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", 0}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmax_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {0, 0, 2, 1, 2, 0, 0, 2}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", 1}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmax_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {1, 3, 2, 2, 2, 3}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", 2}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmax_test_neg_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {0, 0, 2, 1, 2, 0, 0, 2}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", -2}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmax_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 2}, {3, 6}, {3, 6}}}; + auto dl = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", 0}}), dl); + p.compile(migraphx::make_target("ref")); + + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 3, 4}}; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + std::vector res_gold = {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1}; + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmax_test_nonstd_shape) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto dl = mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {2, 3, 4}})); + auto dl_trans = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), dl); + mm->add_instruction(migraphx::make_op("argmax", {{"axis", -3}}), dl_trans); + auto p_uncompiled = p; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto res_gold = p_uncompiled.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + std::vector res_gold_vec; + res_gold.visit([&](auto output) { res_gold_vec.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(result_vec, res_gold_vec)); +} diff --git a/test/ref/argmin.cpp b/test/ref/argmin.cpp new file mode 100644 index 00000000000..ad598bd8113 --- /dev/null +++ b/test/ref/argmin.cpp @@ -0,0 +1,127 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(argmin_test_0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmin", {{"axis", 0}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmin_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {2, 2, 0, 2, 0, 1, 2, 0}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmin", {{"axis", 1}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmin_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {2, 1, 0, 3, 3, 2}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmin", {{"axis", 2}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmin_test_neg_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, + -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, + 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; + std::vector res_gold = {2, 1, 0, 3, 3, 2}; + migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto dl = mm->add_literal(migraphx::literal{data_shape, data}); + mm->add_instruction(migraphx::make_op("argmin", {{"axis", -1}}), dl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); +} + +TEST_CASE(argmin_test_nonstd_shape) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto dl = mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {2, 3, 4}})); + auto dl_trans = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), dl); + mm->add_instruction(migraphx::make_op("argmin", {{"axis", -1}}), dl_trans); + auto p_uncompiled = p; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto res_gold = p_uncompiled.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + std::vector res_gold_vec; + res_gold.visit([&](auto output) { res_gold_vec.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(result_vec, res_gold_vec)); +} diff --git a/test/ref/asin.cpp b/test/ref/asin.cpp new file mode 100644 index 00000000000..bcedd61da0b --- /dev/null +++ b/test/ref/asin.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(asin_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data{-0.5f, 0.0f, 0.9f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("asin"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(asin_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("asin"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-0.5f, 0.0f, 0.9f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/asinh.cpp b/test/ref/asinh.cpp new file mode 100644 index 00000000000..788e4760f15 --- /dev/null +++ b/test/ref/asinh.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(asinh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data{-0.5f, 0.0f, 0.9f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("asinh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(asinh_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("asinh"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-0.5f, 0.0f, 0.9f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/atan.cpp b/test/ref/atan.cpp new file mode 100644 index 00000000000..3ab049ed46e --- /dev/null +++ b/test/ref/atan.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(atan_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {3}}; + std::vector data{-1.0f, 0.0f, 1.0f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("atan"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(atan_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("atan"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1.0f, 0.0f, 1.0f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/atanh.cpp b/test/ref/atanh.cpp new file mode 100644 index 00000000000..3c83792c259 --- /dev/null +++ b/test/ref/atanh.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(atanh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {3}}; + std::vector data{0.4435683f, 0.6223626f, 0.316958f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("atanh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(atanh_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("atanh"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{0.4435683f, 0.6223626f, 0.316958f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/broadcast.cpp b/test/ref/broadcast.cpp new file mode 100644 index 00000000000..7b8b62453d6 --- /dev/null +++ b/test/ref/broadcast.cpp @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(broadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; + std::vector a_data{0, 0, 0, 0}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + uint64_t axis = 0; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", axis}, {"out_lens", l1->get_shape().lens()}}), l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -2); + EXPECT(output(1, 0) == -3); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(broadcast_2in_static_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; + std::vector a_data{0, 0, 0, 0}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + uint64_t axis = 0; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction(migraphx::make_op("broadcast", {{"axis", axis}}), l2, l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -2); + EXPECT(output(1, 0) == -3); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(broadcast_2in_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 2}, {2, 4}}}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + uint64_t axis = 0; + auto pa = mm->add_parameter("a", a_shape); + auto lb = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction(migraphx::make_op("broadcast", {{"axis", axis}}), lb, pa); + p.compile(migraphx::make_target("ref")); + + std::vector a_data{0, 0, 0, 0}; + migraphx::shape input_fixed_shape0{migraphx::shape::int32_type, {2, 2}}; + migraphx::parameter_map params0; + params0["a"] = migraphx::argument(input_fixed_shape0, a_data.data()); + auto result = p.eval(params0).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -2); + EXPECT(output(1, 0) == -3); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(isnan_broadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s0{migraphx::shape::float_type, {3}}; + migraphx::shape s1{migraphx::shape::float_type, {3, 2}}; + auto nan_val = std::numeric_limits::quiet_NaN(); + std::vector data0 = {1.2, 5.2, nan_val}; + auto l0 = mm->add_literal(migraphx::literal{s0, data0}); + auto l1 = mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", 0}, {"out_lens", s1.lens()}}), l0); + mm->add_instruction(migraphx::make_op("isnan"), l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector correct = {0, 0, 0, 0, 1, 1}; + EXPECT(migraphx::verify::verify_range(results_vector, correct)); +} diff --git a/test/ref/ceil.cpp b/test/ref/ceil.cpp new file mode 100644 index 00000000000..169020ee32c --- /dev/null +++ b/test/ref/ceil.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(ceil_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + std::vector data = {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("ceil"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::ceil(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(ceil_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{4, 12}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("ceil"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::ceil(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/clip.cpp b/test/ref/clip.cpp new file mode 100644 index 00000000000..cfc249513b2 --- /dev/null +++ b/test/ref/clip.cpp @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(clip_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l = mm->add_literal(migraphx::literal{s, {-1.0, 0.0, 10.0}}); + auto min_val = mm->add_literal(0.0f); + auto max_val = mm->add_literal(6.0f); + min_val = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3}}}), min_val); + max_val = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3}}}), max_val); + mm->add_instruction(migraphx::make_op("clip"), l, min_val, max_val); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.0, 0.0, 6.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(clip_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dds = {{2, 8, {3}}}; + migraphx::shape s{migraphx::shape::float_type, dds}; + auto l = mm->add_parameter("X", s); + auto min_val = mm->add_literal(0.0f); + auto max_val = mm->add_literal(6.0f); + min_val = mm->add_instruction(migraphx::make_op("multibroadcast"), min_val, l); + max_val = mm->add_instruction(migraphx::make_op("multibroadcast"), max_val, l); + mm->add_instruction(migraphx::make_op("clip"), l, min_val, max_val); + p.compile(migraphx::make_target("ref")); + + migraphx::shape static_shape{migraphx::shape::float_type, {3}}; + migraphx::parameter_map params; + std::vector data = {-1.0, 0.0, 10.0}; + params["X"] = migraphx::argument(static_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.0, 0.0, 6.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/concat.cpp b/test/ref/concat.cpp new file mode 100644 index 00000000000..ba761da1fe3 --- /dev/null +++ b/test/ref/concat.cpp @@ -0,0 +1,175 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(concat_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + int axis = 1; + std::vector data0 = {0, 1, 5, 6}; + std::vector data1 = {2, 3, 4, 7, 8, 9}; + std::vector data2 = {10, 20}; + migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; + migraphx::shape s1{migraphx::shape::int32_type, {2, 3}}; + migraphx::shape s2{migraphx::shape::int32_type, {2, 1}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data0}); + auto l1 = mm->add_literal(migraphx::literal{s1, data1}); + auto l2 = mm->add_literal(migraphx::literal{s2, data2}); + mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector gold = {0, 1, 2, 3, 4, 10, 5, 6, 7, 8, 9, 20}; + std::vector results_vector(2 * 6); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), + std::vector({2, 6}))); + EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), + std::vector({6, 1}))); +} + +TEST_CASE(concat_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + int axis = -1; + std::vector data0 = {0, 1, 5, 6}; + std::vector data1 = {2, 3, 4, 7, 8, 9}; + std::vector data2 = {10, 20}; + migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; + migraphx::shape s1{migraphx::shape::int32_type, {2, 3}}; + migraphx::shape s2{migraphx::shape::int32_type, {2, 1}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data0}); + auto l1 = mm->add_literal(migraphx::literal{s1, data1}); + auto l2 = mm->add_literal(migraphx::literal{s2, data2}); + mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector gold = {0, 1, 2, 3, 4, 10, 5, 6, 7, 8, 9, 20}; + std::vector results_vector(2 * 6); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), + std::vector({2, 6}))); + EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), + std::vector({6, 1}))); +} + +TEST_CASE(concat_test_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + int axis = 0; + std::vector data0 = {0, 1, 2, 3}; + std::vector data1 = {4, 5, 6, 7, 8, 9}; + std::vector data2 = {10, 11}; + migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; + migraphx::shape s1{migraphx::shape::int32_type, {3, 2}}; + migraphx::shape s2{migraphx::shape::int32_type, {1, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data0}); + auto l1 = mm->add_literal(migraphx::literal{s1, data1}); + auto l2 = mm->add_literal(migraphx::literal{s2, data2}); + mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector results_vector(6 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), + std::vector({6, 2}))); + EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), + std::vector({2, 1}))); +} + +TEST_CASE(concat_test_4) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + int axis = -2; + std::vector data0 = {0, 1, 2, 3}; + std::vector data1 = {4, 5, 6, 7, 8, 9}; + std::vector data2 = {10, 11}; + migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; + migraphx::shape s1{migraphx::shape::int32_type, {3, 2}}; + migraphx::shape s2{migraphx::shape::int32_type, {1, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data0}); + auto l1 = mm->add_literal(migraphx::literal{s1, data1}); + auto l2 = mm->add_literal(migraphx::literal{s2, data2}); + mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector results_vector(6 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), + std::vector({6, 2}))); + EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), + std::vector({2, 1}))); +} + +TEST_CASE(concat_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + int axis = 0; + migraphx::shape s0{migraphx::shape::int32_type, {{2, 4, {2}}, {2, 3, {2}}}}; + migraphx::shape s1{migraphx::shape::int32_type, {{3, 4, {4}}, {2, 3, {2}}}}; + migraphx::shape s2{migraphx::shape::int32_type, {{1, 5, {3}}, {2, 3, {2}}}}; + + auto input0 = mm->add_parameter("X", s0); + auto input1 = mm->add_parameter("Y", s1); + auto input2 = mm->add_parameter("Z", s2); + mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), input0, input1, input2); + p.compile(migraphx::make_target("ref")); + + migraphx::shape static_shape0{migraphx::shape::int32_type, {2, 2}}; + migraphx::shape static_shape1{migraphx::shape::int32_type, {3, 2}}; + migraphx::shape static_shape2{migraphx::shape::int32_type, {1, 2}}; + std::vector data0 = {0, 1, 2, 3}; + std::vector data1 = {4, 5, 6, 7, 8, 9}; + std::vector data2 = {10, 11}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(static_shape0, data0.data()); + params["Y"] = migraphx::argument(static_shape1, data1.data()); + params["Z"] = migraphx::argument(static_shape2, data2.data()); + auto result = p.eval(params).back(); + + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), + std::vector({6, 2}))); +} diff --git a/test/ref/contiguous.cpp b/test/ref/contiguous.cpp new file mode 100644 index 00000000000..81a4ad1e195 --- /dev/null +++ b/test/ref/contiguous.cpp @@ -0,0 +1,104 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(contiguous_test) +{ + migraphx::shape a_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; + std::vector data(12); + std::iota(data.begin(), data.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + mm->add_instruction(migraphx::make_op("contiguous"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector new_strides = {12, 4, 2, 1}; + EXPECT(result.get_shape().strides() == new_strides); + + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(contiguous_param_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; + auto a = mm->add_parameter("X", a_shape); + mm->add_instruction(migraphx::make_op("contiguous"), a); + p.compile(migraphx::make_target("ref")); + + std::vector data(12); + std::iota(data.begin(), data.end(), 0); + migraphx::parameter_map params; + params["X"] = migraphx::argument(a_shape, data.data()); + auto result = p.eval(params).back(); + + std::vector new_strides = {12, 4, 2, 1}; + EXPECT(result.get_shape().strides() == new_strides); + + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(contiguous_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape dyn_shape{migraphx::shape::float_type, {{1, 1}, {2, 6}, {2, 2}, {2, 2}}}; + auto input = mm->add_parameter("X", dyn_shape); + mm->add_instruction(migraphx::make_op("contiguous"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::shape static_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; + std::vector data(12); + std::iota(data.begin(), data.end(), 0); + migraphx::parameter_map params; + params["X"] = migraphx::argument(static_shape, data.data()); + auto result = p.eval(params).back(); + + std::vector new_strides = {12, 4, 2, 1}; + EXPECT(result.get_shape().strides() == new_strides); + + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/convert.cpp b/test/ref/convert.cpp new file mode 100644 index 00000000000..cd666f0d833 --- /dev/null +++ b/test/ref/convert.cpp @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(convert_downcast_overflow_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data(4, 2 * std::numeric_limits::max()); + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), + l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of(results_vector.begin(), results_vector.end(), [](const auto& x) { + return x == std::numeric_limits::max(); + })); +} + +TEST_CASE(convert_downcast_underflow_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data(4, 2 * std::numeric_limits::lowest()); + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), + l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of(results_vector.begin(), results_vector.end(), [](const auto& x) { + return x == std::numeric_limits::lowest(); + })); +} + +TEST_CASE(convert_nan_upcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::half_type, {2, 2}}; + std::vector data(4, std::numeric_limits::quiet_NaN()); + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4, -1); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of( + results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); +} + +TEST_CASE(convert_nan_downcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {2, 2}}; + std::vector data(4, std::numeric_limits::quiet_NaN()); + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4, -1); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of( + results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); +} + +TEST_CASE(convert_nan_double_convert_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {2, 2}}; + std::vector data(4, std::numeric_limits::quiet_NaN()); + auto l = mm->add_literal(migraphx::literal{s, data}); + auto f_l = mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); + mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), + f_l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of( + results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); +} + +TEST_CASE(convert_nan_convert_updown_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data(4, std::numeric_limits::quiet_NaN()); + auto l = mm->add_literal(migraphx::literal{s, data}); + auto f_l = mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); + auto h_l = mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), f_l); + mm->add_instruction( + migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), h_l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::all_of( + results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); +} diff --git a/test/ref/convolution.cpp b/test/ref/convolution.cpp new file mode 100644 index 00000000000..25c39654610 --- /dev/null +++ b/test/ref/convolution.cpp @@ -0,0 +1,742 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(conv_dyn_batch_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_dyn_shape{migraphx::shape::float_type, + {{1, 100}, {3, 3}, {4, 4}, {4, 4}}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + + auto input = mm->add_parameter("X", input_dyn_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction(migraphx::make_op("convolution", + { + {"padding", {1, 1}}, + {"stride", {2, 2}}, + }), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = { + 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, + -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, + 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, + 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, + -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, + 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, + 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, + 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, + 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, + 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, + 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, + -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, + 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, + -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; + + std::vector c = { + -0.14601797, -0.13000923, 0.06521662, 0.06178288, -0.11083675, 0.10154136, 0.09990512, + 0.06030385, -0.11374587, -0.17523311, -0.14344215, 0.17802463, 0.06300922, -0.15325832, + 0.07066704, 0.05166031, 0.00615084, -0.02606523, 0.08083995, -0.17913306, 0.0624622, + 0.0735731, -0.04198661, -0.0164391, -0.06374192, 0.16569914, 0.10681538, 0.07370754, + 0.02802075, 0.00282027, 0.15104802, -0.11084409, -0.00197773, 0.07924436, 0.03528272, + 0.04765259, -0.15896152, 0.07917164, 0.12125669, -0.1154705, -0.11999125, 0.12749968, + -0.06269585, 0.18658121, -0.03944227, 0.0111798, -0.17731084, 0.11789055, -0.09982193, + 0.08142821, 0.0729029, 0.11303909, 0.12735154, 0.03885292}; + + std::vector sol = {-0.20817225, + 0.87965256, + 0.14958936, + -1.24887264, + -0.06540672, + 0.20778663, + 0.40456355, + -0.99900877, + 0.4917807, + 0.1994698, + 0.64205718, + 0.37798831, + -0.25315839, + 0.44276932, + -0.16138598, + 0.79344082}; + + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 4, 4}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + params0["W"] = migraphx::argument(weights_shape, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(64); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv_dyn_img_shape_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_dyn_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {4, 6}, {4, 6}}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {1, 3, 3, 3}}; + + auto input = mm->add_parameter("X", input_dyn_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction(migraphx::make_op("convolution", {{"padding", {0, 0}}, {"stride", {1, 1}}}), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = {0.28007596, 0.46114671, 0.12171969, 0.52260835, 0.40916841, 0.07163955, + 0.09896668, 0.98628836, 0.69406788, 0.44868846, 0.64017681, 0.27048886, + 0.30187397, 0.07334207, 0.05258557, 0.80747513, 0.81330534, 0.00497161, + 0.33005534, 0.08908686, 0.46794691, 0.61768946, 0.55104806, 0.13406187, + 0.70244284, 0.61296941, 0.46742536, 0.29712714, 0.91839388, 0.0834397, + 0.14476327, 0.37857075, 0.25922384, 0.61620963, 0.69455439, 0.70389431, + 0.77388606, 0.1752363, 0.74631394, 0.24604889, 0.53600244, 0.22116457, + 0.81217463, 0.10789447, 0.43083784, 0.63371852, 0.69742316, 0.09536905}; + + std::vector c = {0.98411968, 0.2899219, 0.44638833, 0.30390816, 0.03989896, 0.2445332, + 0.32700131, 0.57517075, 0.06956476, 0.93079306, 0.19882314, 0.52940601, + 0.35624753, 0.35938406, 0.9111428, 0.88923574, 0.61040283, 0.2797513, + 0.15479768, 0.46534674, 0.16970931, 0.49704618, 0.07062198, 0.01678321, + 0.53150934, 0.39244495, 0.9963813}; + + std::vector sol = {6.1329393, 4.3199925, 5.448438, 3.8497565}; + + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 3, 4, 4}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + params0["W"] = migraphx::argument(weights_shape, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(72); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, sol)); + + a = {0.95600171, 0.20768181, 0.82844489, 0.14928212, 0.51280462, 0.1359196, 0.68903648, + 0.84174772, 0.425509, 0.956926, 0.82533291, 0.33821531, 0.57576055, 0.75330186, + 0.82710394, 0.93343847, 0.14499469, 0.74558021, 0.13935139, 0.90652876, 0.22611443, + 0.85323975, 0.30631787, 0.96983037, 0.51783421, 0.32247456, 0.28243352, 0.605865, + 0.33376446, 0.67864877, 0.15442507, 0.24977552, 0.86989425, 0.60036782, 0.26198306, + 0.1494149, 0.13678915, 0.24892094, 0.38282467, 0.64907906, 0.83756376, 0.77603195, + 0.33951558, 0.14856874, 0.45701939, 0.43786436, 0.57421759, 0.37326922, 0.63382506, + 0.11464436, 0.23309047, 0.76724102, 0.98712427, 0.80800108, 0.84296564, 0.79568268, + 0.45684131, 0.73867068, 0.57845499, 0.45073557, 0.27102442, 0.86460315, 0.06865567, + 0.81673446, 0.881835, 0.42351639, 0.83322931, 0.34101671, 0.51979151, 0.54920645, + 0.19287718, 0.33321689, 0.27752456, 0.45755893, 0.67484562, 0.68383122, 0.52361312, + 0.46437257, 0.50862936, 0.32460429, 0.1726007, 0.29933345, 0.64856728, 0.06471591, + 0.63370843, 0.27900152, 0.18595992, 0.48904812, 0.35368508, 0.09620202}; + + c = {0.709561, 0.7916206, 0.0443115, 0.62592275, 0.2498623, 0.42725624, 0.7905135, + 0.53160169, 0.01303743, 0.01987505, 0.39041803, 0.89530203, 0.23155373, 0.44435213, + 0.14407301, 0.80968594, 0.38216188, 0.35692557, 0.2568538, 0.83587388, 0.43654904, + 0.04974508, 0.80375029, 0.25350374, 0.1820275, 0.23369029, 0.54358755}; + + sol = {6.305986, + 5.564665, + 6.122996, + 5.7262855, + 5.5546584, + 5.779489, + 5.798161, + 5.160476, + 6.702436, + 5.4851074, + 6.227567, + 5.2016754}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 3, 6, 5}}; + + migraphx::parameter_map params1; + params1["X"] = migraphx::argument(input_fixed_shape1, a.data()); + params1["W"] = migraphx::argument(weights_shape, c.data()); + + result = p.eval(params1).back(); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv_dyn_weights_shape_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; + + auto input = mm->add_parameter("X", input_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction(migraphx::make_op("convolution", {{"padding", {0, 0}}, {"stride", {1, 1}}}), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = {0.28007596, 0.46114671, 0.12171969, 0.52260835, 0.40916841, 0.07163955, + 0.09896668, 0.98628836, 0.69406788, 0.44868846, 0.64017681, 0.27048886, + 0.30187397, 0.07334207, 0.05258557, 0.80747513, 0.81330534, 0.00497161, + 0.33005534, 0.08908686, 0.46794691, 0.61768946, 0.55104806, 0.13406187, + 0.70244284, 0.61296941, 0.46742536, 0.29712714, 0.91839388, 0.0834397, + 0.14476327, 0.37857075, 0.25922384, 0.61620963, 0.69455439, 0.70389431, + 0.77388606, 0.1752363, 0.74631394, 0.24604889, 0.53600244, 0.22116457, + 0.81217463, 0.10789447, 0.43083784, 0.63371852, 0.69742316, 0.09536905}; + + std::vector c = {0.98411968, + 0.2899219, + 0.44638833, + 0.30390816, + 0.03989896, + 0.2445332, + 0.32700131, + 0.57517075, + 0.06956476, + 0.93079306, + 0.19882314, + 0.52940601}; + std::vector sol = {1.9939406, + 2.2703054, + 1.8896171, + 2.062202, + 2.3035214, + 1.629366, + 2.1606991, + 2.1917608, + 1.6797699}; + + migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_shape, a.data()); + params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(72); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, sol)); + + c = {0.98411968, 0.2899219, 0.44638833, 0.30390816, 0.03989896, 0.2445332, 0.32700131, + 0.57517075, 0.06956476, 0.93079306, 0.19882314, 0.52940601, 0.35624753, 0.35938406, + 0.9111428, 0.88923574, 0.61040283, 0.2797513, 0.15479768, 0.46534674, 0.16970931, + 0.49704618, 0.07062198, 0.01678321, 0.53150934, 0.39244495, 0.9963813}; + sol = {6.1329393, 4.3199925, 5.448438, 3.8497565}; + migraphx::shape weights_fixed_shape1{migraphx::shape::float_type, {1, 3, 3, 3}}; + + migraphx::parameter_map params1; + params1["X"] = migraphx::argument(input_shape, a.data()); + params1["W"] = migraphx::argument(weights_fixed_shape1, c.data()); + + result = p.eval(params1).back(); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv_dyn_img_same_upper_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_dyn_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {4, 6}, {4, 6}}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {1, 3, 3, 3}}; + + auto input = mm->add_parameter("X", input_dyn_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction( + migraphx::make_op( + "convolution", + {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_upper}}), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, + 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, + 0.24401724, 0.8815178, 0.4222333, 0.27191755, + + 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, + 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, + 0.80087787, 0.12776066, 0.26566318, 0.46569306, + + 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, + 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, + 0.6870904, 0.30701008, 0.314684, 0.91075855}; + + std::vector c = { + 2.8150102e-01, 3.3198616e-01, 9.5149356e-01, 7.4039467e-02, 9.6555042e-01, + 2.8815505e-01, 2.5100240e-01, 5.2186239e-01, 2.3850012e-01, + + 8.2963020e-01, 3.0763101e-04, 6.7026985e-01, 1.4260857e-01, 9.7517288e-01, + 3.6847427e-02, 8.5804445e-01, 7.3440993e-01, 6.7948365e-01, + + 7.9253986e-02, 7.3943835e-01, 1.7813577e-01, 1.0780835e-01, 4.2304707e-01, + 4.0084350e-01, 1.1114500e-01, 4.4846520e-01, 5.0109702e-01}; + + std::vector sol = {3.013387, + 3.7111127, + 4.2946506, + 3.579301, + 4.5306826, + 6.1262493, + 6.332169, + 4.495293, + 4.46013, + 6.0938954, + 5.848162, + 4.514299, + 2.9587686, + 4.117671, + 3.5187216, + 2.3236327}; + + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 3, 4, 4}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + params0["W"] = migraphx::argument(weights_shape, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv_dyn_kernel_same_upper_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; + + auto input = mm->add_parameter("X", input_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction( + migraphx::make_op( + "convolution", + {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_upper}}), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, + 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, + 0.24401724, 0.8815178, 0.4222333, 0.27191755, + + 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, + 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, + 0.80087787, 0.12776066, 0.26566318, 0.46569306, + + 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, + 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, + 0.6870904, 0.30701008, 0.314684, 0.91075855}; + std::vector c = {2.8150102e-01, + 3.3198616e-01, + 9.5149356e-01, + 7.4039467e-02, + + 9.6555042e-01, + 2.8815505e-01, + 2.5100240e-01, + 5.2186239e-01, + + 2.3850012e-01, + 8.2963020e-01, + 3.0763101e-04, + 6.7026985e-01}; + std::vector sol = {2.453681, + 2.536207, + 3.0187201, + 1.7912633, + 2.1738236, + 2.9695358, + 3.2319589, + 1.859269, + 2.5953722, + 2.50734, + 2.7736917, + 1.2229807, + 1.5900216, + 0.9225286, + 1.43048, + 0.74341124}; + + migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_shape, a.data()); + params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv_dyn_kernel_same_lower_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; + migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; + + auto input = mm->add_parameter("X", input_shape); + auto weights = mm->add_parameter("W", weights_shape); + mm->add_instruction( + migraphx::make_op( + "convolution", + {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_lower}}), + input, + weights); + + p.compile(migraphx::make_target("ref")); + + std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, + 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, + 0.24401724, 0.8815178, 0.4222333, 0.27191755, + + 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, + 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, + 0.80087787, 0.12776066, 0.26566318, 0.46569306, + + 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, + 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, + 0.6870904, 0.30701008, 0.314684, 0.91075855}; + std::vector c = {2.8150102e-01, + 3.3198616e-01, + 9.5149356e-01, + 7.4039467e-02, + + 9.6555042e-01, + 2.8815505e-01, + 2.5100240e-01, + 5.2186239e-01, + + 2.3850012e-01, + 8.2963020e-01, + 3.0763101e-04, + 6.7026985e-01}; + std::vector sol = {0.91231215, + 1.1416453, + 1.00216, + 1.6813052, + 1.7131033, + 2.453681, + 2.536207, + 3.0187201, + 1.3293691, + 2.1738236, + 2.9695358, + 3.2319589, + 1.3228729, + 2.5953722, + 2.50734, + 2.7736917}; + + migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; + + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_shape, a.data()); + params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, sol)); +} + +TEST_CASE(conv2d_padding_stride_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, + -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, + 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, + 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, + -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, + 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, + 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, + 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, + 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, + 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, + 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, + -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, + 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, + -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; + + std::vector c = { + -0.14601797, -0.13000923, 0.06521662, 0.06178288, -0.11083675, 0.10154136, 0.09990512, + 0.06030385, -0.11374587, -0.17523311, -0.14344215, 0.17802463, 0.06300922, -0.15325832, + 0.07066704, 0.05166031, 0.00615084, -0.02606523, 0.08083995, -0.17913306, 0.0624622, + 0.0735731, -0.04198661, -0.0164391, -0.06374192, 0.16569914, 0.10681538, 0.07370754, + 0.02802075, 0.00282027, 0.15104802, -0.11084409, -0.00197773, 0.07924436, 0.03528272, + 0.04765259, -0.15896152, 0.07917164, 0.12125669, -0.1154705, -0.11999125, 0.12749968, + -0.06269585, 0.18658121, -0.03944227, 0.0111798, -0.17731084, 0.11789055, -0.09982193, + 0.08142821, 0.0729029, 0.11303909, 0.12735154, 0.03885292}; + + std::vector s = {-0.20817225, + 0.87965256, + 0.14958936, + -1.24887264, + -0.06540672, + 0.20778663, + 0.40456355, + -0.99900877, + 0.4917807, + 0.1994698, + 0.64205718, + 0.37798831, + -0.25315839, + 0.44276932, + -0.16138598, + 0.79344082}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + + migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + + mm->add_instruction( + migraphx::make_op("convolution", {{"padding", {1, 1}}, {"stride", {2, 2}}}), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(conv2d_padding_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, + -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, + 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, + 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, + -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, + 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, + 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, + 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, + 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, + 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, + 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, + -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, + 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, + -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; + + std::vector c = { + -0.16115488, -0.09800646, -0.05412646, 0.10475694, 0.00555485, -0.12667653, 0.0458357, + -0.02656217, -0.16338061, 0.15037455, 0.0102711, 0.01303349, 0.05242859, 0.02034754, + 0.04751867, -0.17038961, -0.1434752, -0.10770349, 0.05676742, -0.15838449, 0.10128359, + -0.18958683, 0.11954515, 0.10758857, -0.01058291, -0.12797487, 0.08971019, 0.18793164, + -0.00881396, -0.06588994, -0.13321903, -0.03300409, 0.01439607, 0.07618178, -0.11556662, + 0.00764295, 0.12956454, -0.08937147, -0.12763587, 0.04674943, 0.05765297, 0.11336918, + 0.14747436, -0.06199479, -0.01166052, -0.12432006, -0.04494537, -0.17581205, 0.09475745, + 0.1149437, -0.1014564, 0.0274073, -0.01323579, -0.11092556}; + + std::vector s = { + -0.0201216, 0.40407312, -0.39005592, -0.0631946, 0.37963012, -0.64611685, 0.1349397, + -0.54113752, 0.28533003, 0.27667275, -0.16442731, -0.181494, 0.30564839, 0.58744538, + 0.32015014, 0.24969585, -0.27367792, -0.53308117, 0.41236052, 0.26136363, -0.01489828, + 0.57652152, -0.38506854, 0.119615, 0.0437076, 0.04779706, 0.57887721, 0.23126155, + 0.05695833, -0.68200272, 0.02063358, -0.10267162, 0.8062973, -0.38149622, -0.40134856, + -0.03353126, 0.38991132, -0.3478111, 0.03661491, 0.25783631, 0.62772679, -0.1961118, + 0.76423508, -0.36241418, -0.20994355, -0.12368261, -0.9406727, 0.02340185, -0.08793129, + -0.02471633, -0.58163726, -0.02211772, -0.42014724, 0.77525634, 0.504951, -0.20537445, + -0.20369984, -0.83037728, -1.40423918, -0.46160448, -0.22944322, 0.36074194, 0.49579027, + 0.46527559}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + + migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + + mm->add_instruction( + migraphx::make_op("convolution", {{"padding", {1, 1}}, {"stride", {1, 1}}}), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(64); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(conv2d_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, + -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, + 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, + 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, + -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, + 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, + 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, + 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, + 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, + 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, + 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, + -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, + 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, + -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; + + std::vector c = { + 2.82721668e-02, 6.44195229e-02, 1.53499246e-02, 1.72468081e-01, -6.33238107e-02, + 9.49496776e-02, 1.40258059e-01, -7.92879611e-02, -1.29301161e-01, 3.11307609e-03, + -1.90624535e-01, 1.13238767e-01, -2.80647576e-02, 3.12882811e-02, -3.52091640e-02, + 3.33581865e-02, 6.43158704e-02, 7.40238279e-02, -1.00106120e-01, -9.56912562e-02, + 1.44342467e-01, 9.40258950e-02, 6.36333972e-02, 1.66158378e-03, -8.91554281e-02, + 2.58734226e-02, 1.70919895e-02, 1.78214177e-01, 8.84564668e-02, 8.98126513e-02, + -1.63809001e-01, 1.37802169e-01, 1.66439757e-01, -1.45631135e-02, 1.88469887e-04, + 4.76950556e-02, -1.91969007e-01, -1.76233292e-01, -7.70473927e-02, 1.14828631e-01, + 1.76608220e-01, -1.50728196e-01, 1.99946314e-02, -5.88052124e-02, 1.31612435e-01, + 1.61106288e-02, -1.35080189e-01, 1.49512306e-01, 3.86456847e-02, 1.29330024e-01, + -3.22975963e-02, -5.60784787e-02, -5.41997552e-02, 4.78562862e-02}; + + std::vector s = {0.27039781, + 0.19105849, + -0.06339942, + -0.65087199, + 0.40867025, + 0.05063812, + -0.14907975, + 0.49018705, + -0.49197209, + 0.33236548, + -0.39374301, + 0.16012701, + 0.06574871, + 0.71606487, + -0.55201721, + -0.46427044}; + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + + migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + + mm->add_instruction(migraphx::make_op("convolution"), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(conv3d_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, + -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, + 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, + 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, + -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, + 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, + 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, + 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, + 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, + 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, + 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, + -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, + 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, + -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; + + std::vector c = { + 2.82721668e-02, 6.44195229e-02, 1.53499246e-02, 1.72468081e-01, -6.33238107e-02, + 9.49496776e-02, 1.40258059e-01, -7.92879611e-02, -1.29301161e-01, 3.11307609e-03, + -1.90624535e-01, 1.13238767e-01, -2.80647576e-02, 3.12882811e-02, -3.52091640e-02, + 3.33581865e-02, 6.43158704e-02, 7.40238279e-02, -1.00106120e-01, -9.56912562e-02, + 1.44342467e-01, 9.40258950e-02, 6.36333972e-02, 1.66158378e-03, -8.91554281e-02, + 2.58734226e-02, 1.70919895e-02, 1.78214177e-01, 8.84564668e-02, 8.98126513e-02, + -1.63809001e-01, 1.37802169e-01, 1.66439757e-01, -1.45631135e-02, 1.88469887e-04, + 4.76950556e-02, -1.91969007e-01, -1.76233292e-01, -7.70473927e-02, 1.14828631e-01, + 1.76608220e-01, -1.50728196e-01, 1.99946314e-02, -5.88052124e-02, 1.31612435e-01, + 1.61106288e-02, -1.35080189e-01, 1.49512306e-01, 3.86456847e-02, 1.29330024e-01, + -3.22975963e-02, -5.60784787e-02, -5.41997552e-02, 4.78562862e-02}; + + std::vector s = {0.27039781, + 0.19105849, + -0.06339942, + -0.65087199, + 0.40867025, + 0.05063812, + -0.14907975, + 0.49018705, + -0.49197209, + 0.33236548, + -0.39374301, + 0.16012701, + 0.06574871, + 0.71606487, + -0.55201721, + -0.46427044}; + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4, 1}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + + migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3, 1}}; + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + + mm->add_instruction( + migraphx::make_op("convolution", + {{"padding", {0, 0, 0}}, {"stride", {1, 1, 1}}, {"dilation", {1, 1, 1}}}), + al, + cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} diff --git a/test/ref/convolution_backwards.cpp b/test/ref/convolution_backwards.cpp new file mode 100644 index 00000000000..4c4a9d61a2c --- /dev/null +++ b/test/ref/convolution_backwards.cpp @@ -0,0 +1,292 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(convolution_backwards_1d) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3}}; + std::vector x_data{0, 0.5, 1}; + std::vector w_data{0.5, 0.5, 0.5}; + + std::vector gold{0, 0.25, 0.75, 0.75, 0.5}; + + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction(migraphx::make_op("convolution_backwards", + {{"padding", {0}}, {"stride", {1}}, {"dilation", {1}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_2d) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + + std::vector gold{0, 1, 3, 3, 2, 3, 8, 15, 12, 7, 9, 21, 36, + 27, 15, 9, 20, 33, 24, 13, 6, 13, 21, 15, 8}; + + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction(migraphx::make_op("convolution_backwards"), x, w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_3d) +{ + migraphx::shape s_1{migraphx::shape::float_type, {1, 1, 1, 2, 3}}; + migraphx::shape s_2{migraphx::shape::float_type, {1, 1, 3, 2, 3}}; + + // clang-format off + std::vector x_data{0.8471, -0.4195, -2.2749, 1.2491, 0.1722, 0.3246}; + std::vector w_data{ + 0.6478, -0.1985, 0.0633, -0.3479, 2.7056, -0.1440, + -1.1229, -0.7507, -1.3151, 0.8884, -0.1859, -0.3407, + -1.1544, -1.5893, 1.6265, -1.4624, 0.3812, -1.5378 + }; + std::vector gold{0.5488, -0.4399, -1.3369, 0.4251, -0.1439, 0.5145, 2.3015, -0.2104, + -6.1482, 0.3482, -0.4346, 3.3197, 0.1731, 0.8533, -0.0467, -0.9512, + -0.1649, 1.7553, 2.2594, 2.9917, -0.6500, -1.6612, -4.3680, 0.0957, + 0.3482, 1.1097, -0.0792, -0.1692, -0.1190, -0.1106, -0.9779, -0.8621, + 4.6707, 2.9332, -3.7001, -2.6808, -1.2476, 3.2475, -0.4578, 4.0263, + -1.8267, 0.2243, -2.3299, -0.1411, -0.4991}; + // clang-format on + + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s_1, x_data}); + auto w = mm->add_literal(migraphx::literal{s_2, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {0, 0, 0}}, {"stride", {1, 1, 1}}, {"dilation", {1, 1, 1}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_padding1) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + + std::vector gold{8, 15, 12, 21, 36, 27, 20, 33, 24}; + + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {1, 1}}, {"stride", {1, 1}}, {"dilation", {1, 1}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_padding2) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + + std::vector gold{3., 8., 15., 12., 7., 9., 21., 36., 27., 15., 9., 20., 33., 24., 13.}; + + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {1, 0}}, {"stride", {1, 1}}, {"dilation", {1, 1}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_2stride) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + std::vector gold{0., 0., 1., 1., 3., 2., 2., 0., 0., 1., 1., 3., 2., + 2., 3., 3., 8., 5., 12., 7., 7., 3., 3., 7., 4., 9., + 5., 5., 9., 9., 20., 11., 24., 13., 13., 6., 6., 13., 7., + 15., 8., 8., 6., 6., 13., 7., 15., 8., 8.}; + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {0, 0}}, {"stride", {2, 2}}, {"dilation", {1, 1}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_2dilation) +{ + migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + std::vector gold{0., 1., 2., 1., 2., 1., 2., 3., 4., 8., 4., 8., 4., + 5., 6., 8., 16., 8., 16., 8., 10., 3., 4., 8., 4., 8., + 4., 5., 6., 8., 16., 8., 16., 8., 10., 3., 4., 8., 4., + 8., 4., 5., 6., 7., 14., 7., 14., 7., 8.}; + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(migraphx::literal{s, x_data}); + auto w = mm->add_literal(migraphx::literal{s, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {0, 0}}, {"stride", {1, 1}}, {"dilation", {2, 2}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_dyn_batch1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + // clang-format off + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {1, 1}, {3, 3}, {3, 3}}}; + // clang-format on + auto x = mm->add_parameter("x", s); + auto w = mm->add_parameter("w", s); + + mm->add_instruction(migraphx::make_op("convolution_backwards"), x, w); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 3, 3}}; + params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); + params["w"] = migraphx::argument(input_fixed_shape, w_data.data()); + auto result = p.eval(params).back(); + + std::vector gold{0, 1, 3, 3, 2, 3, 8, 15, 12, 7, 9, 21, 36, + 27, 15, 9, 20, 33, 24, 13, 6, 13, 21, 15, 8}; + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(convolution_backwards_dyn_batch2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + // clang-format off + migraphx::shape x_shape{migraphx::shape::float_type, + {{1, 4}, {1, 1}, {5, 5}, {5, 5}}}; + // clang-format on + auto x = mm->add_parameter("x", x_shape); + migraphx::shape w_shape{migraphx::shape::float_type, {1, 1, 3, 3}}; + std::vector w_data(9, 1.); + auto w = mm->add_literal(migraphx::literal{w_shape, w_data}); + + mm->add_instruction( + migraphx::make_op("convolution_backwards", + {{"padding", {2, 2}}, {"stride", {2, 2}}, {"dilation", {2, 2}}}), + x, + w); + p.compile(migraphx::make_target("ref")); + + std::vector x_data(25); + std::iota(x_data.begin(), x_data.end(), 0.); + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 5, 5}}; + params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); + auto result = p.eval(params).back(); + + //clang-format off + std::vector gold{12., 0., 21., 0., 27., 0., 33., 0., 24., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 33., 0., 54., 0., 63., 0., 72., 0., 51., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 63., 0., 99., 0., 108., 0., + 117., 0., 81., 0., 0., 0., 0., 0., 0., 0., 0., 0., 93., 0., + 144., 0., 153., 0., 162., 0., 111., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 72., 0., 111., 0., 117., 0., 123., 0., 84.}; + //clang-format on + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/cos.cpp b/test/ref/cos.cpp new file mode 100644 index 00000000000..6c296bae667 --- /dev/null +++ b/test/ref/cos.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(cos_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data{-1, 0, 1}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("cos"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return cosf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(cos_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("cos"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1, 0, 1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return cosf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/cosh.cpp b/test/ref/cosh.cpp new file mode 100644 index 00000000000..0cf219d86b9 --- /dev/null +++ b/test/ref/cosh.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(cosh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data = {-1.0, 2.0, -3.0, 4.0}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("cosh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return coshf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(cosh_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("cosh"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {-1.0, 2.0, -3.0, 4.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return coshf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/dequantizelinear.cpp b/test/ref/dequantizelinear.cpp new file mode 100644 index 00000000000..12aec62145a --- /dev/null +++ b/test/ref/dequantizelinear.cpp @@ -0,0 +1,83 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(dequantizelinear_unsigned_int8) + +{ /*uint8*/ + migraphx::shape xs{migraphx::shape::uint8_type, {1, 3, 3}}; + std::vector xv = {0, 1, 2, 5, 10, 50, 100, 150, 250}; + migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}}; + std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2}; + migraphx::shape zs{migraphx::shape::uint8_type, {1, 3, 3}}; + std::vector zv = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + auto create_program = [&]() { + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(xs, xv); + auto s = mm->add_literal(ss, sv); + auto z = mm->add_literal(zs, zv); + mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s, z); + return p; + }; + + migraphx::program p1 = create_program(); + p1.compile(migraphx::make_target("ref")); + auto result = p1.eval({}).back(); + std::vector results_vector(9); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 2, 4, 10, 20, 100, 200, 300, 500}; + EXPECT(results_vector == gold); +} + +TEST_CASE(dequantizelinear_signed_int8) +{ /*int8*/ + migraphx::shape xs{migraphx::shape::int8_type, {1, 3, 3}}; + std::vector xv = {-128, -100, -50, -1, 0, 1, 50, 100, 127}; + migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}}; + std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2}; + auto create_program = [&]() { + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(xs, xv); + auto s = mm->add_literal(ss, sv); + mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s); + return p; + }; + + migraphx::program p1 = create_program(); + p1.compile(migraphx::make_target("ref")); + auto result = p1.eval({}).back(); + std::vector results_vector(9); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-256, -200, -100, -2, 0, 2, 100, 200, 254}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/dimensions_of.cpp b/test/ref/dimensions_of.cpp new file mode 100644 index 00000000000..272f5498538 --- /dev/null +++ b/test/ref/dimensions_of.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(dimensions_of_test0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4, {2, 4}}, {3, 3}, {4, 4}}}; + auto p1 = mm->add_parameter("x", s); + mm->add_instruction(migraphx::make_op("dimensions_of", {{"end", 3}}), p1); + p.compile(migraphx::make_target("ref")); + + std::vector x_data(24, 1.0); + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 3, 4}}; + migraphx::parameter_map params; + params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {2, 3, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(dimensions_of_test1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {3, 3}, {3, 8}, {3, 8}}}; + auto p1 = mm->add_parameter("x", s); + mm->add_instruction(migraphx::make_op("dimensions_of", {{"start", 2}, {"end", 4}}), p1); + p.compile(migraphx::make_target("ref")); + + std::vector x_data(48, 1.0); + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; + migraphx::parameter_map params; + params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {4, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/div.cpp b/test/ref/div.cpp new file mode 100644 index 00000000000..8be1c1d3be9 --- /dev/null +++ b/test/ref/div.cpp @@ -0,0 +1,76 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(div_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data1 = {-1.0f, 0.5f, 1.0f}; + std::vector data2 = {1.0f, 2.0f, 4.0f}; + auto l1 = mm->add_literal(migraphx::literal{s, data1}); + auto l2 = mm->add_literal(migraphx::literal{s, data2}); + mm->add_instruction(migraphx::make_op("div"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data1.size()); + std::transform(data1.begin(), data1.end(), data2.begin(), gold.begin(), std::divides()); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(div_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6, {3}}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + mm->add_instruction(migraphx::make_op("div"), x, y); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1.0f, 0.5f, 1.0f}; + std::vector y_data{1.0f, 2.0f, 4.0f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(x_data.size()); + std::transform( + x_data.begin(), x_data.end(), y_data.begin(), gold.begin(), std::divides()); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/dot_op.cpp b/test/ref/dot_op.cpp new file mode 100644 index 00000000000..8230c2ff28e --- /dev/null +++ b/test/ref/dot_op.cpp @@ -0,0 +1,1720 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.hpp" +#include + +template +void dot_2d_test() +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, + 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, + -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, + -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; + std::vector b = {6.09568541e-01, + -6.10527007e-01, + 3.66646462e-01, + 1.18951101e-01, + 5.58777432e-01, + -3.21296298e-01, + -5.95997198e-01, + -5.01425721e-01, + -2.84606807e-01, + -5.73673557e-01, + -8.99430260e-01, + -4.25103093e-01, + 1.53027987e+00, + -3.81407415e-04, + -3.29650255e-01}; + std::vector c = {-1.56327541e+00, + -7.09570140e-01, + -5.37424982e-01, + -2.22994831e-01, + -2.15586437e+00, + 2.09177941e-03, + -1.47279677e+00, + 2.02627040e-01, + -6.04527691e-01, + -1.29885596e+00, + 2.16294914e+00, + -1.48101497e-01}; + migraphx::shape a_shape{migraphx::shape::get_type{}, {4, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::get_type{}, {5, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), al, bl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(c, results_vector)); +} +TEST_CASE_REGISTER(dot_2d_test) +TEST_CASE_REGISTER(dot_2d_test) + +template +void dot_4d_test() +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, + 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, + -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, + -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; + std::vector b = {6.09568541e-01, + -6.10527007e-01, + 3.66646462e-01, + 1.18951101e-01, + 5.58777432e-01, + -3.21296298e-01, + -5.95997198e-01, + -5.01425721e-01, + -2.84606807e-01, + -5.73673557e-01, + -8.99430260e-01, + -4.25103093e-01, + 1.53027987e+00, + -3.81407415e-04, + -3.29650255e-01}; + std::vector c = {-1.56327541e+00, + -7.09570140e-01, + -5.37424982e-01, + -2.22994831e-01, + -2.15586437e+00, + 2.09177941e-03, + -1.47279677e+00, + 2.02627040e-01, + -6.04527691e-01, + -1.29885596e+00, + 2.16294914e+00, + -1.48101497e-01}; + migraphx::shape a_shape{migraphx::shape::get_type{}, {1, 1, 4, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::get_type{}, {1, 1, 5, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), al, bl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(c, results_vector)); +} +TEST_CASE_REGISTER(dot_4d_test) +TEST_CASE_REGISTER(dot_4d_test) + +TEST_CASE(dot_3D_test) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = {-0.76234141, + 0.01368910, + -0.86343423, + -0.99465282, + 0.76133268, + 0.96507140, + -0.55893585, + 0.02625652, + 0.75171776, + 0.23112578, + 0.25624787, + -1.50442161}; + migraphx::shape m1_shape{migraphx::shape::float_type, {2, 2, 3}}; + std::vector m2 = {-0.15933632, -0.69594712, -0.06198966, -1.23905184, -0.83672704, + -1.06971832, -0.12272917, 1.07094116, -0.08346820, 1.16820693, + -0.95700874, 0.24059691, 0.43326023, 0.78305235, -0.53506601, + -0.69359678, -0.26334436, 1.56292796, -0.33629175, -1.72693469, + 0.41435494, 1.52136843, -0.40699791, -1.59839430}; + migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 4}}; + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + + mm->add_instruction(migraphx::make_op("dot"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {0.18208394, + -0.49276402, + 0.87189133, + 0.75150114, + -0.55909610, + 1.00521735, + -0.95536130, + 2.27996211, + 0.06239879, + 0.74700068, + -0.01570983, + -0.85920856, + -0.59070835, + -1.70729902, + 0.40245487, + 1.80182751}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_3D_C_test0) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = {-0.76234141, + 0.01368910, + -0.86343423, + -0.99465282, + 0.76133268, + 0.96507140, + -0.55893585, + 0.02625652, + 0.75171776, + 0.23112578, + 0.25624787, + -1.50442161}; + migraphx::shape m1_shape{migraphx::shape::float_type, {2, 2, 3}}; + std::vector m2 = {-0.15933632, -0.69594712, -0.06198966, -1.23905184, -0.83672704, + -1.06971832, -0.12272917, 1.07094116, -0.08346820, 1.16820693, + -0.95700874, 0.24059691, 0.43326023, 0.78305235, -0.53506601, + -0.69359678, -0.26334436, 1.56292796, -0.33629175, -1.72693469, + 0.41435494, 1.52136843, -0.40699791, -1.59839430}; + migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 4}}; + std::vector m3 = {0.18208394, + -0.49276402, + 0.87189133, + 0.75150114, + -0.55909610, + 1.00521735, + -0.95536130, + 2.27996211, + 0.06239879, + 0.74700068, + -0.01570983, + -0.85920856, + -0.59070835, + -1.70729902, + 0.40245487, + 1.80182751}; + migraphx::shape m3_shape{migraphx::shape::float_type, {2, 2, 4}}; + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); + float alpha = 1.0f; + float beta = 0.0f; + migraphx::add_apply_alpha_beta(*mm, + std::vector{l1, l2, l3}, + migraphx::make_op("dot"), + alpha, + beta); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {0.18208394, + -0.49276402, + 0.87189133, + 0.75150114, + -0.55909610, + 1.00521735, + -0.95536130, + 2.27996211, + 0.06239879, + 0.74700068, + -0.01570983, + -0.85920856, + -0.59070835, + -1.70729902, + 0.40245487, + 1.80182751}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_3D_C_test1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = { + -0.76234141, 0.01368910, -0.86343423, -0.99465282, 0.76133268, 0.96507140}; + migraphx::shape m1_shape{migraphx::shape::float_type, {1, 2, 3}}; + std::vector m2 = {-0.15933632, + -0.69594712, + -0.06198966, + -1.23905184, + -0.83672704, + -1.06971832, + -0.12272917, + 1.07094116, + -0.08346820, + 1.16820693, + -0.95700874, + 0.24059691}; + migraphx::shape m2_shape{migraphx::shape::float_type, {1, 3, 4}}; + + migraphx::shape m3_shape{migraphx::shape::float_type, {1, 2, 4}}; + std::vector m3 = {0.18208394, + -0.49276402, + 0.87189133, + 0.75150114, + -0.55909610, + 1.00521735, + -0.95536130, + 2.27996211}; + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); + + float alpha = 1.0f; + float beta = 0.0f; + migraphx::add_apply_alpha_beta(*mm, + std::vector{l1, l2, l3}, + migraphx::make_op("dot"), + alpha, + beta); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {0.18208394, + -0.49276402, + 0.87189133, + 0.75150114, + -0.55909610, + 1.00521735, + -0.95536130, + 2.27996211}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_4D_test1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = { + -1.93300070, 0.33902698, -0.45173527, -0.72283069, -0.17177134, 1.62199882, + 0.87052847, 0.14989811, -0.88969184, -0.18131398, 0.72654339, -0.57123693, + 0.03852506, -0.72332085, -1.81844083, -0.33465167, -0.71400352, 0.36883161, + 0.08698452, 0.94974586, 0.40087323, -0.05448534, 0.03220677, -1.22494296, + 0.97938472, -1.43714454, -0.80430904, -0.08098728, 0.31520301, 0.49642169, + -1.63471091, 0.34390096, 2.81292176, -0.22666528, 1.54559556, -1.51075762}; + migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; + std::vector m2 = { + -0.33170529, 2.26325120, -0.50639461, 0.64802947, 0.44748888, 0.33768068, + -0.53621075, 0.34341460, 0.58742520, -1.13995790, -0.99322535, 0.35447353, + 0.01977110, -0.10155016, -1.02288245, -0.16575791, -1.47870374, 0.29300008, + -0.39112198, 1.42303608, -0.02853060, 1.52610164, 0.53540909, 0.75618998, + -0.26877787, -1.90886366, 0.30622790, 0.59794535, 1.29795331, -0.37805803, + -1.58167176, -1.26966832, 0.27435891, 0.89430347, 0.22854926, -0.50317658}; + migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + + mm->add_instruction(migraphx::make_op("dot"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {0.26735861, -4.30770895, 1.05257728, -1.19954265, 0.50493170, + -0.18729756, 1.09137941, -1.09298312, 3.42956915, -0.41681939, + 0.17833257, 0.26040336, 0.15351280, 1.87632715, -0.63545406, + -0.95467340, -1.74728628, -2.42477030, 0.76262372, 0.15539164, + 3.32281958, 0.96769613, 0.43727545, 2.43019906}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_4D_alpha_beta_test) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = { + 1.23636469, -0.47041261, -0.14375651, -0.48371852, 1.16479301, -0.89361055, + -0.18569086, 1.10700457, -1.02632638, 0.82277012, 0.33525769, 0.52825145, + -1.00141689, 0.45510090, -0.02675039, -0.60454439, 0.38551153, -0.01658514, + 0.93059292, -0.54595188, -0.04911005, -0.91397221, -0.83127477, -1.57685603, + -1.36200452, 2.25822236, -1.23416970, 0.12312496, 0.76232760, -0.83594234, + 1.67418145, -0.19412936, 1.05261378, 0.66246074, -1.15233398, 0.16429736}; + migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; + std::vector m2 = { + -0.87300530, -0.07112838, 0.19196860, -1.04986840, 1.20348200, 0.31966893, + 1.04805440, -2.04777729, -0.67906052, -1.17250760, 0.34305044, -1.01957785, + -1.12694862, 0.18431338, -1.63712290, 0.27566931, -1.11282021, 1.41738919, + 0.47871283, -1.01980420, 1.00212436, -0.78740444, -1.65636133, 1.51466547, + -0.12470397, 0.70404393, -0.15244797, 0.74288871, 0.07339926, -1.45811623, + 0.27185845, 0.08804596, 0.99061977, -1.61752428, 0.29191159, 0.87271953}; + migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; + std::vector m3 = {-1.07692443, 0.85223457, -0.37266530, 2.31511577, 0.04227017, + 1.13229428, -0.52769242, 0.27307182, -0.47779843, -0.08023168, + -0.22862823, 0.81489871, 1.13139581, 1.13860467, 0.24309065, + 0.26533729, 0.49106772, -1.18860493, 0.27842449, 1.03568141, + 0.49759611, 0.10021662, 0.00592602, 0.90862000}; + migraphx::shape m3_shape{migraphx::shape::float_type, {2, 3, 2, 2}}; + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); + float alpha = 0.35; + float beta = 0.41; + auto m12_alpha = migraphx::add_apply_alpha_beta( + *mm, std::vector{l1, l2}, migraphx::make_op("dot"), alpha); + auto l_beta = mm->add_literal(beta); + auto b_beta = mm->add_instruction( + migraphx::make_op("scalar", {{"scalar_bcst_dims", m12_alpha->get_shape().lens()}}), l_beta); + auto m3_beta = mm->add_instruction(migraphx::make_op("mul"), b_beta, l3); + mm->add_instruction(migraphx::make_op("add"), m3_beta, m12_alpha); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {-0.91147203, 0.47540785, -0.30313587, 0.43325099, -0.43711586, + 0.50928632, 0.06919868, -0.80382802, -0.05125718, -0.06685650, + -0.06972163, 0.32407764, 0.45677396, 0.25909489, 0.56911252, + -0.17183724, 0.10858734, 0.39406289, 0.04662959, 1.07979824, + 0.40355016, 0.52410648, -0.31728447, 1.09550845}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_4D_alpha_beta_C_test) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector m1 = { + 1.23636469, -0.47041261, -0.14375651, -0.48371852, 1.16479301, -0.89361055, + -0.18569086, 1.10700457, -1.02632638, 0.82277012, 0.33525769, 0.52825145, + -1.00141689, 0.45510090, -0.02675039, -0.60454439, 0.38551153, -0.01658514, + 0.93059292, -0.54595188, -0.04911005, -0.91397221, -0.83127477, -1.57685603, + -1.36200452, 2.25822236, -1.23416970, 0.12312496, 0.76232760, -0.83594234, + 1.67418145, -0.19412936, 1.05261378, 0.66246074, -1.15233398, 0.16429736}; + migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; + std::vector m2 = { + -0.87300530, -0.07112838, 0.19196860, -1.04986840, 1.20348200, 0.31966893, + 1.04805440, -2.04777729, -0.67906052, -1.17250760, 0.34305044, -1.01957785, + -1.12694862, 0.18431338, -1.63712290, 0.27566931, -1.11282021, 1.41738919, + 0.47871283, -1.01980420, 1.00212436, -0.78740444, -1.65636133, 1.51466547, + -0.12470397, 0.70404393, -0.15244797, 0.74288871, 0.07339926, -1.45811623, + 0.27185845, 0.08804596, 0.99061977, -1.61752428, 0.29191159, 0.87271953}; + migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; + std::vector m3 = {-1.07692443, 0.85223457, -0.37266530, 2.31511577, 0.04227017, + 1.13229428, -0.52769242, 0.27307182, -0.47779843, -0.08023168, + -0.22862823, 0.81489871, 1.13139581, 1.13860467, 0.24309065, + 0.26533729, 0.49106772, -1.18860493, 0.27842449, 1.03568141, + 0.49759611, 0.10021662, 0.00592602, 0.90862000}; + migraphx::shape m3_shape{migraphx::shape::float_type, {2, 3, 2, 2}}; + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); + float alpha = 0.35; + float beta = 0.41; + migraphx::add_apply_alpha_beta(*mm, + std::vector{l1, l2, l3}, + migraphx::make_op("dot"), + alpha, + beta); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + + std::vector m_res = {-0.91147203, 0.47540785, -0.30313587, 0.43325099, -0.43711586, + 0.50928632, 0.06919868, -0.80382802, -0.05125718, -0.06685650, + -0.06972163, 0.32407764, 0.45677396, 0.25909489, 0.56911252, + -0.17183724, 0.10858734, 0.39406289, 0.04662959, 1.07979824, + 0.40355016, 0.52410648, -0.31728447, 1.09550845}; + + EXPECT(migraphx::verify::verify_range(m, m_res)); +} + +TEST_CASE(dot_2D_C_test0) +{ + + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-0.86217194, + -1.04129542, + -0.64850364, + -0.97078327, + -0.40516386, + 0.83136927, + 0.37717502, + 0.42271939, + 1.10062165, + -0.92239359, + 0.40403076, + -0.43935377}; + std::vector b = {0.76084386, + 1.89201125, + 1.73218067, + 0.7148568, + -0.55578914, + 0.05799101, + -1.24090721, + -0.51151978, + 1.13255803, + 0.21540723, + -1.10459009, + 0.45580331}; + std::vector c = {-0.80473623, + 0.35154171, + -2.73077756, + -0.09093885, + -1.88850472, + -0.03375556, + -0.41798276, + 2.87368099, + 2.11031439}; + + migraphx::shape a_shape{migraphx::shape::float_type, {3, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {4, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + migraphx::shape c_shape{migraphx::shape::float_type, {3, 3}}; + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + migraphx::add_apply_alpha_beta(*mm, {al, bl, cl}, migraphx::make_op("dot"), 1.0f, 1.0f); + std::vector gold = { + -1.60947, 0.703083, -5.46156, -0.181878, -3.77701, -0.0675112, -0.835966, 5.74736, 4.22063}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vv_inner_product_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {0.7481789, + 0.02906279, + 1.01193836, + 1.60222907, + 1.89135978, + 0.30054158, + -0.4892588, + -0.27027533}; + std::vector b = {-0.25829116, + 0.27908929, + -1.27888957, + 0.21152361, + 0.08593658, + 0.52163899, + 1.38343824, + -0.2342857}; + migraphx::shape a_shape{migraphx::shape::float_type, {8}}; + migraphx::shape b_shape{migraphx::shape::float_type, {8}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); + mm->add_instruction(migraphx::make_op("dot"), ual, ubl); + std::vector gold = {-1.43461}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vv_inner_product_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {0.7481789, + 0.02906279, + 1.01193836, + 1.60222907, + 1.89135978, + 0.30054158, + -0.4892588, + -0.27027533}; + std::vector b = {-0.25829116, + 0.27908929, + -1.27888957, + 0.21152361, + 0.08593658, + 0.52163899, + 1.38343824, + -0.2342857}; + migraphx::shape a_shape{migraphx::shape::float_type, {8}}; + migraphx::shape b_shape{migraphx::shape::float_type, {8}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); + float alpha = 0.32f; + migraphx::add_apply_alpha_beta( + *mm, std::vector{ual, ubl}, migraphx::make_op("dot"), alpha); + std::vector gold = {-0.4590752}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vm_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {1.49530002, + -0.07181969, + 0.44593846, + -0.8645019, + 0.52992304, + -0.4910338, + -2.12179422, + -0.45962977}; + std::vector b = { + -0.06210242, 0.0187149, 1.47482984, -1.19590602, -0.45601701, 0.36934488, -0.83913193, + 0.75350964, 0.80707019, 0.35923582, -2.18480722, -0.85608682, 0.75849199, 0.49103473, + -0.91329477, -0.36364322, -0.69688937, 0.07165814, -0.15505523, 0.52221663, -0.98631192, + -0.37353654, -1.89818706, -0.87209739, -0.33942003, 0.11390353, 0.78181162, -0.18395337, + -0.34743419, -0.08091231, 1.21119765, 1.23869861, 1.42169414, 0.86412382, 1.05898002, + -0.31918307, 1.08546695, 1.50682711, -0.66083538, -0.32683929}; + migraphx::shape a_shape{migraphx::shape::float_type, {8}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + migraphx::shape b_shape{migraphx::shape::float_type, {8, 5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), ual, bl); + std::vector gold = {-3.78111, -3.40007, -2.1972, -3.31448, -3.80326}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vm_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {1.49530002, + -0.07181969, + 0.44593846, + -0.8645019, + 0.52992304, + -0.4910338, + -2.12179422, + -0.45962977}; + std::vector b = { + -0.06210242, 0.0187149, 1.47482984, -1.19590602, -0.45601701, 0.36934488, -0.83913193, + 0.75350964, 0.80707019, 0.35923582, -2.18480722, -0.85608682, 0.75849199, 0.49103473, + -0.91329477, -0.36364322, -0.69688937, 0.07165814, -0.15505523, 0.52221663, -0.98631192, + -0.37353654, -1.89818706, -0.87209739, -0.33942003, 0.11390353, 0.78181162, -0.18395337, + -0.34743419, -0.08091231, 1.21119765, 1.23869861, 1.42169414, 0.86412382, 1.05898002, + -0.31918307, 1.08546695, 1.50682711, -0.66083538, -0.32683929}; + migraphx::shape a_shape{migraphx::shape::float_type, {8}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + migraphx::shape b_shape{migraphx::shape::float_type, {8, 5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + float alpha = 0.5f; + migraphx::add_apply_alpha_beta( + *mm, std::vector{ual, bl}, migraphx::make_op("dot"), alpha); + std::vector gold = {-1.89056, -1.70003, -1.0986, -1.65724, -1.90163}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vm_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-1.7468318, -0.38900251, 1.00183915, 0.06016438, 0.08295905, 1.5830535}; + std::vector b = { + 1.2459538, 0.39586199, -0.77035574, 0.22689828, 0.3289835, 1.02804361, -0.22941113, + -0.33940324, 0.80078249, 1.0319152, 0.80034948, -0.11631159, 0.36899208, -0.28506697, + -1.2211584, -0.55678377, -0.3618498, 0.34857264, -0.38700147, -0.43434611, 1.73029783, + -0.71578372, 0.09777723, 0.06616614, -1.66721186, -0.16046032, -1.64581663, 1.09373609, + -0.14127692, -0.01938473, -0.67310303, -1.56154787, -1.0665462, 0.68538535, -1.53920085, + -0.35710272, 0.06887234, 0.17474616, 1.08194804, -0.19990148, -0.91149488, 0.95303646, + 0.95448717, -0.49332393, -1.762213, -0.56571194, -1.69704968, -0.82798066, 0.65531872, + 1.5007798, 0.99877355, 0.53386114, -0.88150609, -1.0756985, 0.50962511, -0.68019002, + 0.1583068, 2.83988407, -1.10292457, 0.02126969, 0.21129951, 0.25690146, -1.6490316, + 0.55261771, -1.70504303, -0.02870394, -0.18205627, 0.29446203, -1.91360924, 0.46102174, + 0.44977568, -0.48113321}; + + migraphx::shape a_shape{migraphx::shape::float_type, {6}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + auto bual = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 1, 6}}}), ual); + migraphx::shape b_shape{migraphx::shape::float_type, {3, 6, 4}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), bual, bl); + std::vector gold = {1.22914, + -1.17896, + 2.28596, + -0.345637, + -0.962362, + 0.168508, + -0.947471, + -3.02458, + -3.80131, + 1.38484, + -2.45019, + -1.35064}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_vm_4) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-1.7468318, -0.38900251, 1.00183915, 0.06016438, 0.08295905, 1.5830535}; + std::vector b = { + 1.2459538, 0.39586199, -0.77035574, 0.22689828, 0.3289835, 1.02804361, -0.22941113, + -0.33940324, 0.80078249, 1.0319152, 0.80034948, -0.11631159, 0.36899208, -0.28506697, + -1.2211584, -0.55678377, -0.3618498, 0.34857264, -0.38700147, -0.43434611, 1.73029783, + -0.71578372, 0.09777723, 0.06616614, -1.66721186, -0.16046032, -1.64581663, 1.09373609, + -0.14127692, -0.01938473, -0.67310303, -1.56154787, -1.0665462, 0.68538535, -1.53920085, + -0.35710272, 0.06887234, 0.17474616, 1.08194804, -0.19990148, -0.91149488, 0.95303646, + 0.95448717, -0.49332393, -1.762213, -0.56571194, -1.69704968, -0.82798066, 0.65531872, + 1.5007798, 0.99877355, 0.53386114, -0.88150609, -1.0756985, 0.50962511, -0.68019002, + 0.1583068, 2.83988407, -1.10292457, 0.02126969, 0.21129951, 0.25690146, -1.6490316, + 0.55261771, -1.70504303, -0.02870394, -0.18205627, 0.29446203, -1.91360924, 0.46102174, + 0.44977568, -0.48113321}; + + migraphx::shape a_shape{migraphx::shape::float_type, {6}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); + auto bual = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 1, 6}}}), ual); + migraphx::shape b_shape{migraphx::shape::float_type, {3, 6, 4}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + migraphx::add_apply_alpha_beta( + *mm, std::vector{bual, bl}, migraphx::make_op("dot"), 0.21f); + std::vector gold = {0.25812, + -0.247582, + 0.480051, + -0.0725837, + -0.202096, + 0.0353867, + -0.198969, + -0.635161, + -0.798275, + 0.290817, + -0.514539, + -0.283635}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mv_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {0.1612524, + 0.61266466, + -0.19212896, + 1.34228825, + -1.09746949, + 0.4680955, + -0.431748, + -0.89791241, + -2.19078702, + -0.13767058, + -1.66105228, + -0.91834613, + 0.59199744, + 1.41967261, + 0.76237423}; + + std::vector b = {0.14365572, 0.23401411, -0.8970094, -0.12526676, -1.04703286}; + + migraphx::shape a_shape{migraphx::shape::float_type, {3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); + mm->add_instruction(migraphx::make_op("dot"), al, ubl); + std::vector gold = {1.31982, 1.19022, -1.96062}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mv_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {0.1612524, + 0.61266466, + -0.19212896, + 1.34228825, + -1.09746949, + 0.4680955, + -0.431748, + -0.89791241, + -2.19078702, + -0.13767058, + -1.66105228, + -0.91834613, + 0.59199744, + 1.41967261, + 0.76237423}; + + std::vector b = {0.14365572, 0.23401411, -0.8970094, -0.12526676, -1.04703286}; + + migraphx::shape a_shape{migraphx::shape::float_type, {3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); + float alpha = 0.3f; + migraphx::add_apply_alpha_beta( + *mm, std::vector{al, ubl}, migraphx::make_op("dot"), alpha); + std::vector gold = {0.395946, 0.357067, -0.588187}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mv_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = { + 1.24593227, -0.84351316, 0.27882229, -0.42518484, -1.11391528, 0.59141834, 1.34198714, + 2.25884063, -1.32093452, 0.44766336, -0.09306479, 0.47526699, 0.25858488, 1.30820392, + 1.17186787, 0.31530864, -1.19159424, -0.24100903, -1.03857886, 1.54453427, 0.05041654, + 1.67108177, 0.965805, 0.52958924, -1.61243992, 0.02941846, 0.77523836, 1.97963853, + -2.51093596, 0.21882645, -2.60193574, 1.1899952, 1.70883519, 0.94586745, 2.65002512, + -1.42427102, 1.0143951, -1.34115312, 1.63833732, -1.46477355, 0.44014877, 0.58032696, + -1.63874372, -0.82834423, 1.81131778, -0.52393379, 1.16721943, 0.39488835, 0.23947128, + -0.15733194, 0.19451158, 1.21315445, 0.44594897, 0.40809135, -0.64252994, 0.7541716, + -0.97203195, 0.69208485, 0.34350988, 0.9836842}; + std::vector b = {0.05013914, 1.39932885, 2.56616476, 1.02225623, -0.03977829}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); + auto bubl = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 1}}}), ubl); + mm->add_instruction(migraphx::make_op("dot"), al, bubl); + std::vector gold = {-0.792717, + 6.33595, + 2.61466, + -3.39322, + 5.42485, + 3.59084, + 6.78139, + -0.360492, + -4.28998, + 2.87146, + 3.29447, + 0.765651}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm1_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = { + -0.49450006, -1.07431991, -0.02796692, -0.99631927, 0.20040449, -1.39709437, -0.15695328, + 0.08208373, -0.09746386, 0.77923021, -0.1849151, 0.14419043, -0.25798175, -0.2504807, + -1.11134383, -0.71030613, -0.20234025, 0.90229168, 0.62643053, -0.83512638, 1.66051254, + 0.05941673, 0.73081559, 0.27111867, 0.55060745, 0.34999583, 1.02236619, 0.60178395, + 1.49646162, 1.93255155, -3.65357913, -1.38059906, -0.46302398, 0.19847152, 0.39785875, + 1.47004861, -1.24482133, -0.01954702, 0.36073898, 1.56055978, -0.10344603, -0.34283135, + -0.56482649, 1.80861249, -0.92268202, 0.94371182, -0.02373232, -0.75441145, 0.43325034, + 0.4057425, -0.48844822, -0.36390512, 0.74110406, 1.25158366, 0.52196654, 1.43461691, + -0.57530864, -0.66716206, -1.76516289, 0.96582849}; + std::vector b = {0.49899375, + -2.20168661, + 1.08895066, + -0.01135643, + 0.90570669, + -1.43550963, + -1.73033377, + 0.21338776, + 0.96962508, + 0.38913968, + -0.32822861, + 0.88222863, + 0.93330718, + -1.24265228, + -1.62587164}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {5, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto bbl = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); + mm->add_instruction(migraphx::make_op("dot"), al, bbl); + std::vector gold = {-0.386828, 0.187735, -0.22822, -0.148057, 2.015, -2.56938, + -0.782212, 1.9459, 0.927426, -2.44907, 2.40531, 2.30232, + 0.182745, -4.21937, 1.77551, 1.50775, -2.60888, -2.32484, + -0.557691, 6.13527, -2.91743, 2.37836, -6.42584, 1.14979, + 0.77227, 0.349659, 2.92759, 2.32384, -2.90664, 0.0527679, + -0.547761, -0.155467, 0.964619, 2.09133, -4.44281, -1.3864}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm1_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-0.0309568, + -1.57294749, + -0.00768606, + 1.5786921, + 0.50519718, + 0.10530702, + -0.05302112, + -0.06503757, + 0.4079716, + 0.0799132, + -0.82624962, + 0.49341502}; + + std::vector b = { + 0.3664867, 0.24649534, 1.14728076, 1.09911548, -1.23711247, -0.49436419, -0.67557879, + -0.84180575, -1.09754376, 0.07807351, 0.74349043, -0.92084701, 0.50267885, 0.78709401, + 0.80598159, -0.51269589, -0.40337193, 0.29457878, 1.25447301, -1.66251457, -1.54652239, + -0.35067765, -0.5214464, -0.7866878, 1.11128573, 0.26927291, -0.0929818, 0.07523954, + 0.3256776, -1.08617826, 0.89294253, -0.91007619, -2.42825765, -1.76805581, 1.08136334, + -0.14521253, -1.32061148, 0.60663124, -1.19835255, -0.98803563, -1.06927896, -0.51967419, + -0.98974639, 1.01287011, 1.34910394, 0.1203349, 0.67387452, -0.32447465, 1.15187449, + -0.82253807, 0.22302433, 0.46434695, 0.319647, 1.56459445, 0.15664012, 0.03998102, + 0.62981041, 0.11831296, 0.47824434, -0.93941882, -0.34674036, 1.17071104, 0.59203806, + 2.75817738, -0.69300013, 1.30971899, -0.14231862, -1.90915568, -0.06895489, 0.20160375, + 0.01945916, 0.03586956}; + + migraphx::shape a_shape{migraphx::shape::float_type, {3, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto bal = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 3, 3, 4}}}), al); + migraphx::shape b_shape{migraphx::shape::float_type, {2, 3, 4, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), bal, bl); + std::vector gold = { + -1.61175, 3.11849, -0.703205, 0.331635, -0.00946922, 0.645626, 0.834069, 1.06409, + 0.881037, 0.227628, -0.200308, -1.71836, 0.156255, 0.477222, 0.571363, -1.04543, + 1.40524, 1.24201, -2.95083, 1.19352, 1.5008, 0.636987, 0.148256, -0.0231631, + -1.15079, 1.42139, 1.80996, 1.79259, 2.7192, 0.331902, -0.726565, 0.0963351, + -0.710558, 0.259424, -0.342345, -1.80522, -0.580476, 0.277368, -3.95582, 0.614823, + -0.415107, 0.305138, 0.435993, -0.107089, -0.767885, -4.00837, 1.09921, -2.02129, + 0.109717, 0.618422, 0.438342, 0.29602, 2.00928, 0.420871}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm2_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = { + -0.49450006, -1.07431991, -0.02796692, -0.99631927, 0.20040449, -1.39709437, -0.15695328, + 0.08208373, -0.09746386, 0.77923021, -0.1849151, 0.14419043, -0.25798175, -0.2504807, + -1.11134383, -0.71030613, -0.20234025, 0.90229168, 0.62643053, -0.83512638, 1.66051254, + 0.05941673, 0.73081559, 0.27111867, 0.55060745, 0.34999583, 1.02236619, 0.60178395, + 1.49646162, 1.93255155, -3.65357913, -1.38059906, -0.46302398, 0.19847152, 0.39785875, + 1.47004861, -1.24482133, -0.01954702, 0.36073898, 1.56055978, -0.10344603, -0.34283135, + -0.56482649, 1.80861249, -0.92268202, 0.94371182, -0.02373232, -0.75441145, 0.43325034, + 0.4057425, -0.48844822, -0.36390512, 0.74110406, 1.25158366, 0.52196654, 1.43461691, + -0.57530864, -0.66716206, -1.76516289, 0.96582849}; + std::vector b = {-1.12211357, 1.74720423, 0.60382572, -0.61090125, -0.3315936, + 0.30924675, -0.28906435, 0.64039247, -1.2822253, 0.55899286, + 2.14013013, 1.00944809, 0.21660017, -0.75465098, 0.12097934, + -1.64006315, 0.43582108, -0.64348541, 0.43101069, 1.30191386, + 1.7746011, 0.24935804, 0.42830791, -0.13593643, 0.38749427, + 1.39776254, -0.42911717, -1.3537624, -0.81999648, -0.1754485}; + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {2, 1, 5, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto bbl = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); + std::vector gold = { + 0.70574512, -2.80915314, -1.57644969, 1.75415381, -3.13303087, -1.00150259, + -0.18675123, -0.23349122, -0.12357225, 0.82911538, 1.37473744, -1.11709934, + -1.84001907, 3.51427391, 0.42425673, 0.0638482, 2.40210271, 1.50027643, + 4.81988916, -3.63687142, -0.19101717, -4.92522092, -1.76377022, -3.58095615, + 1.83096922, 2.5512663, -1.07926588, -2.12749134, 0.33014536, -0.80393025, + 0.60740202, 0.95217761, -1.06087445, -4.75868152, -3.6687713, -1.26539821}; + mm->add_instruction(migraphx::make_op("dot"), al, bbl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm2_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = {-0.19276159, -1.2568421, -0.321242, 1.21471077, -0.4927751, + 0.69446894, -0.1786371, -1.00763473, -0.10279314, 3.02931355, + 1.08359235, -0.35190132, -0.00639111, 0.78989113, 1.23538029, + 0.4590747, 0.17304142, 0.42512412, 0.21076913, -0.01724556, + -0.17763898, 0.12852236, -0.00459301, 1.34498824, 0.02907823, + 0.1784464, -0.20790355, -0.52336699, 0.45804085, 1.06025801}; + + std::vector b = {-1.12211357, 1.74720423, 0.60382572, -0.61090125, -0.3315936, + 0.30924675, -0.28906435, 0.64039247, -1.2822253, 0.55899286, + 2.14013013, 1.00944809, 0.21660017, -0.75465098, 0.12097934, + -1.64006315, 0.43582108, -0.64348541, 0.43101069, 1.30191386, + 1.7746011, 0.24935804, 0.42830791, -0.13593643, 0.38749427, + 1.39776254, -0.42911717, -1.3537624, -0.81999648, -0.1754485}; + migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 3, 5}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + auto bal = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3, 5}}}), al); + migraphx::shape b_shape{migraphx::shape::float_type, {2, 1, 5, 3}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto bbl = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); + mm->add_instruction(migraphx::make_op("dot"), bal, bbl); + std::vector gold = {1.64924590e+00, 2.84575831e+00, 1.07340773e+00, 2.19817080e-01, + -1.87873283e+00, 1.91883003e+00, -2.89962196e-01, 2.76404142e+00, + 1.50048102e+00, -6.29650347e-01, 1.48105185e+00, -3.71716505e-03, + 8.80281500e-01, 2.50057585e+00, 1.29958508e+00, 5.63751779e-01, + 2.25703781e-01, 1.30516919e+00, 8.32118386e-01, 2.44050864e-01, + -2.49748221e+00, -5.60803176e+00, -2.98919069e+00, -1.11429417e+00, + -3.29675989e+00, 1.02442564e-01, -1.87659303e+00, -4.67302454e-01, + 9.16189968e-01, -1.33537175e-01, 8.27398578e-01, 1.94406914e+00, + -2.39250915e-01, -1.77062701e+00, -6.46239534e-01, -7.95202750e-01}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm2_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = { + -0.55248691, 0.70275958, 0.56967633, 0.88206033, -0.85088547, 0.05689149, -0.20084703, + 0.18024434, 1.0730491, 0.15913531, 0.93621628, 0.35072771, 1.28616952, 1.55384379, + 0.30376261, -1.12356544, -0.64271552, -2.50703079, -0.23994372, 0.8166084, 0.06542249, + -0.17472336, -0.37665211, 0.16342699, 0.07645941, 0.65024333, -1.19883423, -0.40536776, + -0.31132765, 0.78113691, -0.16887638, 2.30797418, -0.36241233, 0.33552153, -1.05343996, + -0.16909699, -1.22608815, 1.64165613, 0.96260828, -0.16733976, 0.84211199, 1.31243813, + 0.89258549, -0.48250384, -1.06005206, 1.37021342, -0.35658565, 0.26879188}; + + std::vector b = { + 0.17111129, -0.82134741, -1.58001178, -1.46759447, 0.31522514, -0.11567352, -0.038978, + -0.3601414, -0.84379876, 0.24848939, -0.37080544, 0.00838631, 1.51316241, 0.42385344, + 2.06043846, 1.82348849, 1.07180434, 0.6567393, 1.41164561, 0.73091185, -0.33541302, + -0.98082287, -0.06605479, 0.82219717, -1.41619634, 0.51326658, 0.26916313, 0.79819769, + 0.85583702, 0.07876046, -0.42375545, -0.7758751, 1.14334296, -0.14211708, -1.54520411, + -0.55244869, -0.48478899, 0.10782164, -0.20879552, -0.99019754, 1.78783102, -1.31610052, + 1.73510175, -0.48360172, 0.62367417, -1.34180545, -0.37512931, -1.50521357, 0.08383314, + 0.76165608, -0.4961646, 0.95821311, -0.68407191, 0.48299435, -0.24323988, 0.34793412, + 0.37908669, 1.19083454, 1.30218795, -0.26731035, -0.34544132, -0.09595373, 0.50951334, + 0.48896956, 0.38753818, -0.4939919, 0.02352126, 0.42013764, 0.07027765, 0.21169851, + -0.24411376, -1.77793736, -0.88370924, 0.95294025, -0.08208804, -0.95943892, 0.30280474, + 1.1967013, -1.17700948, 0.29533973}; + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {2, 2, 4, 5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + mm->add_instruction(migraphx::make_op("dot"), al, bl); + std::vector gold = { + 1.22136035, 1.3765651, 2.0611395, 1.70445494, 1.8189619, 0.2509717, 0.88815736, + 1.13837946, 1.37006127, -0.53617378, 0.45759693, -0.503786, -0.10575749, -0.81715738, + 2.56316255, 0.85812927, -0.53425671, 1.38147704, 2.57874755, -1.05591061, -1.42065674, + -0.25412658, -2.14494165, -2.81045272, 0.27491485, -0.04229986, 0.10181043, -0.55680682, + -0.07633866, 0.313767, -0.28202571, -1.64696179, -0.50872733, -1.08935912, 0.94291084, + -0.71792156, 0.82981387, 1.14797592, 3.13989358, -0.17507726, -0.63429162, -0.72241531, + -0.61459168, -0.52561056, 0.3309648, -0.46185697, -1.60586695, -0.98590829, 0.63012062, + -0.25606052, -0.69419352, -1.78299913, -0.38572706, 1.92249442, 0.3884186, -0.48153048, + 0.84932351, 0.67234919, -1.07821322, -0.01208216}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_mm2_4) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + std::vector a = { + -0.55248691, 0.70275958, 0.56967633, 0.88206033, -0.85088547, 0.05689149, -0.20084703, + 0.18024434, 1.0730491, 0.15913531, 0.93621628, 0.35072771, 1.28616952, 1.55384379, + 0.30376261, -1.12356544, -0.64271552, -2.50703079, -0.23994372, 0.8166084, 0.06542249, + -0.17472336, -0.37665211, 0.16342699, 0.07645941, 0.65024333, -1.19883423, -0.40536776, + -0.31132765, 0.78113691, -0.16887638, 2.30797418, -0.36241233, 0.33552153, -1.05343996, + -0.16909699, -1.22608815, 1.64165613, 0.96260828, -0.16733976, 0.84211199, 1.31243813, + 0.89258549, -0.48250384, -1.06005206, 1.37021342, -0.35658565, 0.26879188}; + + std::vector b = { + -0.33734601, 0.66386073, 0.41425048, 0.40190389, -0.99645073, -0.10017067, -0.58542118, + 0.48636962, 0.06301405, 1.14669128, -0.06526677, 0.23172741, -1.49693143, -0.44464233, + -0.12775566, -1.32038007, 1.1812471, 1.22362746, -0.49013843, 0.25339836, 1.31698705, + 1.54256669, 0.11211132, -0.18005487, 0.36730145, 0.97705953, -0.18909084, 0.544932, + 0.32891878, 0.64250015, -0.41381398, 0.47402562, 1.22286761, 1.07573211, -0.92988077, + -0.36340925, -1.76152377, -0.96642674, -0.79231929, 0.11517073}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 4}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape b_shape{migraphx::shape::float_type, {2, 4, 5}}; + auto bl = mm->add_literal(migraphx::literal{b_shape, b}); + auto bbl = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 4, 5}}}), bl); + mm->add_instruction(migraphx::make_op("dot"), al, bbl); + std::vector gold = { + -1.08585245, 0.39575611, 0.33947977, -0.86339678, 1.50710753, 0.05646156, -0.43180359, + 0.19639674, -0.33742881, 0.98443538, -0.9021272, 1.25043704, -0.45038184, -0.14689614, + -0.91749459, 3.49467934, 3.81336312, 2.4482385, 1.49649707, 1.05889193, -3.49343731, + -2.06958956, -2.52082858, -1.61401519, -1.52966956, 0.01191848, -0.33246613, -0.70641362, + -0.60391255, 0.28083355, 0.52255496, -1.08655006, 1.64648546, 0.80344255, 0.71987865, + -3.00960296, 2.02318221, 3.32785057, -1.13203844, 1.81235734, 0.38067585, -0.88086897, + 1.38307367, 0.42677257, 0.83759966, -0.34827442, -1.45067092, 2.09599671, 1.92882983, + -0.30996324, 2.19736278, 2.32389426, 2.36741832, 1.62253915, 0.26698225, -0.00741609, + -2.53680983, -0.0679954, 0.04499683, 0.85354276}; + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(dot_dyn_2D_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, {{1, 4}, {5, 5}}}; + auto ap = mm->add_parameter("a", a_shape); + migraphx::shape b_shape{migraphx::shape::float_type, {5, 3}}; + auto bp = mm->add_parameter("b", b_shape); + mm->add_instruction(migraphx::make_op("dot"), ap, bp); + p.compile(migraphx::make_target("ref")); + + std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, + 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, + -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, + -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; + std::vector b = {6.09568541e-01, + -6.10527007e-01, + 3.66646462e-01, + 1.18951101e-01, + 5.58777432e-01, + -3.21296298e-01, + -5.95997198e-01, + -5.01425721e-01, + -2.84606807e-01, + -5.73673557e-01, + -8.99430260e-01, + -4.25103093e-01, + 1.53027987e+00, + -3.81407415e-04, + -3.29650255e-01}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {4, 5}}; + migraphx::parameter_map params; + params["a"] = migraphx::argument(input_fixed_shape, a.data()); + params["b"] = migraphx::argument(b_shape, b.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector c = {-1.56327541e+00, + -7.09570140e-01, + -5.37424982e-01, + -2.22994831e-01, + -2.15586437e+00, + 2.09177941e-03, + -1.47279677e+00, + 2.02627040e-01, + -6.04527691e-01, + -1.29885596e+00, + 2.16294914e+00, + -1.48101497e-01}; + EXPECT(migraphx::verify::verify_range(c, results_vector)); +} + +TEST_CASE(dot_dyn_4D_test) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, {{1, 1}, {1, 1}, {4, 6, {4}}, {5, 5}}}; + auto al = mm->add_parameter("a", a_shape); + migraphx::shape b_shape{migraphx::shape::float_type, {1, 1, 5, 3}}; + auto bl = mm->add_parameter("b", b_shape); + mm->add_instruction(migraphx::make_op("dot"), al, bl); + p.compile(migraphx::make_target("ref")); + + std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, + 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, + -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, + -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; + std::vector b = {6.09568541e-01, + -6.10527007e-01, + 3.66646462e-01, + 1.18951101e-01, + 5.58777432e-01, + -3.21296298e-01, + -5.95997198e-01, + -5.01425721e-01, + -2.84606807e-01, + -5.73673557e-01, + -8.99430260e-01, + -4.25103093e-01, + 1.53027987e+00, + -3.81407415e-04, + -3.29650255e-01}; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 1, 4, 5}}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 1, 5, 3}}; + migraphx::parameter_map params; + params["a"] = migraphx::argument(input_fixed_shape0, a.data()); + params["b"] = migraphx::argument(input_fixed_shape1, b.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector c = {-1.56327541e+00, + -7.09570140e-01, + -5.37424982e-01, + -2.22994831e-01, + -2.15586437e+00, + 2.09177941e-03, + -1.47279677e+00, + 2.02627040e-01, + -6.04527691e-01, + -1.29885596e+00, + 2.16294914e+00, + -1.48101497e-01}; + EXPECT(migraphx::verify::verify_range(c, results_vector)); +} + +TEST_CASE(quant_dot_2args_multi4_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 8}}; + std::vector data1(4 * 4); + std::vector data2(4 * 8); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); + + std::vector gold = {112, 118, 124, 130, 136, 142, 148, 154, 304, 326, 348, + 370, 392, 414, 436, 458, 496, 534, 572, 610, 648, 686, + 724, 762, 688, 742, 796, 850, 904, 958, 1012, 1066}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_multi4_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 8}}; + std::vector data1(4 * 4); + std::vector data2(4 * 8); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + mm->add_instruction(migraphx::make_op("quant_dot"), tl1, l2); + + std::vector gold = {448, 472, 496, 520, 544, 568, 592, 616, 496, 524, 552, + 580, 608, 636, 664, 692, 544, 576, 608, 640, 672, 704, + 736, 768, 592, 628, 664, 700, 736, 772, 808, 844}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_multi4_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 4}}; + std::vector data1(4 * 4); + std::vector data2(4 * 8); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + mm->add_instruction(migraphx::make_op("quant_dot"), l1, tl2); + + std::vector gold = {14, 38, 62, 86, 110, 134, 158, 182, 38, 126, 214, + 302, 390, 478, 566, 654, 62, 214, 366, 518, 670, 822, + 974, 1126, 86, 302, 518, 734, 950, 1166, 1382, 1598}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_multi4_4) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 4}}; + std::vector data1(4 * 4); + std::vector data2(4 * 8); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + mm->add_instruction(migraphx::make_op("quant_dot"), tl1, tl2); + + std::vector gold = {56, 152, 248, 344, 440, 536, 632, 728, 62, 174, 286, + 398, 510, 622, 734, 846, 68, 196, 324, 452, 580, 708, + 836, 964, 74, 218, 362, 506, 650, 794, 938, 1082}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_general_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; + std::vector data1(3 * 4); + std::vector data2(4 * 5); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); + + std::vector gold = {70, 76, 82, 88, 94, 190, 212, 234, 256, 278, 310, 348, 386, 424, 462}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_general_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 3}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; + std::vector data1(4 * 3); + std::vector data2(4 * 5); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + mm->add_instruction(migraphx::make_op("quant_dot"), tl1, l2); + + std::vector gold = { + 210, 228, 246, 264, 282, 240, 262, 284, 306, 328, 270, 296, 322, 348, 374}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_general_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {5, 4}}; + std::vector data1(3 * 4); + std::vector data2(4 * 5); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + + migraphx::add_apply_alpha_beta(*mm, {l1, tl2}, migraphx::make_op("quant_dot"), 2); + + std::vector gold = { + 28, 76, 124, 172, 220, 76, 252, 428, 604, 780, 124, 428, 732, 1036, 1340}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_2args_general_4) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 3}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {5, 4}}; + std::vector data1(4 * 3); + std::vector data2(4 * 5); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + migraphx::add_apply_alpha_beta(*mm, {tl1, tl2}, migraphx::make_op("quant_dot"), 3); + + std::vector gold = { + 126, 342, 558, 774, 990, 144, 408, 672, 936, 1200, 162, 474, 786, 1098, 1410}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_general_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 8}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 7}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; + std::vector data1(2 * 8); + std::vector data2(8 * 7); + std::vector data3(2 * 7); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {l1, l2, l3}, migraphx::make_op("quant_dot"), 1, 1); + + std::vector gold = { + 982, 1011, 1040, 1069, 1098, 1127, 1156, 2557, 2650, 2743, 2836, 2929, 3022, 3115}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_general_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {3, 5}}; + std::vector data1(3 * 4); + std::vector data2(4 * 5); + std::vector data3(3 * 5); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 0); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); + + std::vector gold = {70, 76, 82, 88, 94, 190, 212, 234, 256, 278, 310, 348, 386, 424, 462}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_general_3) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {8, 2}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 7}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; + std::vector data1(2 * 8); + std::vector data2(8 * 7); + std::vector data3(2 * 7); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {tl1, l2, l3}, migraphx::make_op("quant_dot"), 1, 3); + + std::vector gold = { + 1966, 2025, 2084, 2143, 2202, 2261, 2320, 2183, 2250, 2317, 2384, 2451, 2518, 2585}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_general_4) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 8}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; + std::vector data1(2 * 8); + std::vector data2(8 * 7); + std::vector data3(2 * 7); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {l1, tl2, l3}, migraphx::make_op("quant_dot"), 2, 3); + + std::vector gold = { + 286, 737, 1188, 1639, 2090, 2541, 2992, 755, 2230, 3705, 5180, 6655, 8130, 9605}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_general_5) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {8, 2}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; + std::vector data1(2 * 8); + std::vector data2(8 * 7); + std::vector data3(2 * 7); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {tl1, tl2, l3}, migraphx::make_op("quant_dot"), 3, 2); + + std::vector gold = { + 844, 2190, 3536, 4882, 6228, 7574, 8920, 942, 2480, 4018, 5556, 7094, 8632, 10170}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_batch_1) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 2, 2, 4}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {2, 2, 4, 7}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 2, 2, 7}}; + std::vector data1(4 * 2 * 4); + std::vector data2(4 * 4 * 7); + std::vector data3(4 * 2 * 7); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {l1, l2, l3}, migraphx::make_op("quant_dot"), 1, 2); + + std::vector gold = {102, 110, 118, 126, 134, 142, 150, 284, 308, 332, + 356, 380, 404, 428, 1530, 1570, 1610, 1650, 1690, 1730, + 1770, 2160, 2216, 2272, 2328, 2384, 2440, 2496, 4750, 4822, + 4894, 4966, 5038, 5110, 5182, 5828, 5916, 6004, 6092, 6180, + 6268, 6356, 9762, 9866, 9970, 10074, 10178, 10282, 10386, 11288, + 11408, 11528, 11648, 11768, 11888, 12008}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} + +TEST_CASE(quant_dot_3args_batch_2) +{ + migraphx::program p; + + auto* mm = p.get_main_module(); + migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 2, 4, 3}}; + migraphx::shape m2_shape{migraphx::shape::int8_type, {2, 2, 6, 4}}; + migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 2, 3, 6}}; + std::vector data1(48); + std::vector data2(96); + std::vector data3(72); + std::iota(data1.begin(), data1.end(), 0); + std::iota(data2.begin(), data2.end(), 0); + std::iota(data3.begin(), data3.end(), 2); + + auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); + auto tl1 = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1); + auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); + auto tl2 = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2); + auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); + migraphx::add_apply_alpha_beta(*mm, {tl1, tl2, l3}, migraphx::make_op("quant_dot"), 2, 3); + + std::vector gold = { + 90, 237, 384, 531, 678, 825, 120, 299, 478, 657, 836, 1015, + 150, 361, 572, 783, 994, 1205, 3456, 3987, 4518, 5049, 5580, 6111, + 3678, 4241, 4804, 5367, 5930, 6493, 3900, 4495, 5090, 5685, 6280, 6875, + 11430, 12345, 13260, 14175, 15090, 16005, 11844, 12791, 13738, 14685, 15632, 16579, + 12258, 13237, 14216, 15195, 16174, 17153, 24012, 25311, 26610, 27909, 29208, 30507, + 24618, 25949, 27280, 28611, 29942, 31273, 25224, 26587, 27950, 29313, 30676, 32039}; + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector m; + result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(m, gold)); +} diff --git a/test/ref/elu.cpp b/test/ref/elu.cpp new file mode 100644 index 00000000000..48475e73d88 --- /dev/null +++ b/test/ref/elu.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +float elu(float a, float x) { return x > 0 ? x : a * std::expm1(x); } + +TEST_CASE(elu_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + auto l = mm->add_literal(migraphx::literal{s, {-1.0, 2.0, -3.0, 4.0}}); + float alpha = 0.5; + mm->add_instruction(migraphx::make_op("elu", {{"alpha", alpha}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{elu(alpha, -1), elu(alpha, 2), elu(alpha, -3), elu(alpha, 4)}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(elu_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + float alpha = 0.5; + mm->add_instruction(migraphx::make_op("elu", {{"alpha", alpha}}), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1.0, 2.0, -3.0, 4.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{elu(alpha, -1), elu(alpha, 2), elu(alpha, -3), elu(alpha, 4)}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/equal.cpp b/test/ref/equal.cpp new file mode 100644 index 00000000000..1caa1ffbdf5 --- /dev/null +++ b/test/ref/equal.cpp @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(equal_brcst_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; + auto l0 = + mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); + migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; + auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); + auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); + auto eq = mm->add_instruction(migraphx::make_op("equal"), l0, bl1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + eq); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {true, false, false, false, true, false, true, false, false}; + EXPECT(results_vector == gold); +} + +TEST_CASE(equal_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + auto l0 = + mm->add_literal(migraphx::literal{s, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); + auto l1 = + mm->add_literal(migraphx::literal{s, {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}}); + auto eq = mm->add_instruction(migraphx::make_op("equal"), l0, l1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + eq); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {true, false, false, false, true, false, true, false, false}; + EXPECT(results_vector == gold); +} + +TEST_CASE(equal_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{6, 12, {9}}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto p0 = mm->add_parameter("l", s); + auto p1 = mm->add_parameter("r", s); + auto eq = mm->add_instruction(migraphx::make_op("equal"), p0, p1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + eq); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + + std::vector l_data{1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + std::vector r_data{1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["l"] = migraphx::argument(input_fixed_shape0, l_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, r_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {true, false, false, false, true, false, true, false, false}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/erf.cpp b/test/ref/erf.cpp new file mode 100644 index 00000000000..3cca339fe61 --- /dev/null +++ b/test/ref/erf.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(erf_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {4}}; + std::vector data = {0.73785057, 1.58165966, -0.43597795, -0.01677432}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("erf"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return erff(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(erf_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("erf"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {0.73785057, 1.58165966, -0.43597795, -0.01677432}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return erff(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/exp.cpp b/test/ref/exp.cpp new file mode 100644 index 00000000000..d7fee9f3a29 --- /dev/null +++ b/test/ref/exp.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(exp_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data{-1, 0, 1}; + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("exp"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return expf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(exp_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("exp"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1, 0, 1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return expf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/floor.cpp b/test/ref/floor.cpp new file mode 100644 index 00000000000..7d16ec4adff --- /dev/null +++ b/test/ref/floor.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(floor_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + std::vector data = {1.1, 1.5, 0.6, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("floor"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return floor(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(floor_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{5, 12}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("floor"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {1.1, 1.5, 0.6, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return floor(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/fmod.cpp b/test/ref/fmod.cpp new file mode 100644 index 00000000000..ba5e0b3f6a0 --- /dev/null +++ b/test/ref/fmod.cpp @@ -0,0 +1,96 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(fmod_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {-7, 8, -3}}); + auto l1 = mm->add_literal(migraphx::literal{s, {2, 4, 6}}); + auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); + auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), l0, l1); + mm->add_instruction(migraphx::make_op("fmod"), curr_mod, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-1, 0, -3}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(fmod_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + auto z = mm->add_parameter("z", s); + auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), x, y); + mm->add_instruction(migraphx::make_op("fmod"), curr_mod, z); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-7, 8, -3}; + std::vector y_data{2, 4, 6}; + std::vector z_data{7, 5, 9}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-1, 0, -3}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(fmod_float_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {-7.2f, 8.5f, -3.3f}}); + auto l1 = mm->add_literal(migraphx::literal{s, {2.0f, 4.0f, 6.0f}}); + auto l2 = mm->add_literal(migraphx::literal{s, {7.0f, 5.0f, 9.0f}}); + auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), l0, l1); + mm->add_instruction(migraphx::make_op("fmod"), curr_mod, l2); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-1.2f, 0.5f, -3.3f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/gather.cpp b/test/ref/gather.cpp new file mode 100644 index 00000000000..e44e76f7a51 --- /dev/null +++ b/test/ref/gather.cpp @@ -0,0 +1,286 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(gather_non_std_test) +{ + { + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data = {0.5f, 3.5f, 6.5f, 1.5f, 4.5f, 7.5f, 2.5f, 2.5f, 8.5f}; + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto d = mm->add_literal(migraphx::literal{s, data}); + migraphx::shape s_indices{migraphx::shape::int32_type, {2, 2}}; + std::vector indices{-3, -3, -1, -1}; + auto ind = mm->add_literal(migraphx::literal{s_indices, indices}); + auto td = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), d); + auto tind = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), ind); + + mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), td, tind); + auto result = p.eval({}).back(); + std::vector golden = { + 0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f, 0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; + std::vector res_data; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); + } +} + +TEST_CASE(gather_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; + std::vector indices{0, 2}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = 0; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data(4 * 5); + std::vector golden = {0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; + std::vector indices{-3, -1}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = 0; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data(4 * 5); + std::vector golden = {0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; + std::vector indices{0, 2}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = 1; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data(4 * 5); + std::vector golden = {0.5f, 2.5f, 3.5f, 5.5f, 6.5f, 8.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_4) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; + std::vector indices{0, 2}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = -1; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data(4 * 5); + std::vector golden = {0.5f, 2.5f, 3.5f, 5.5f, 6.5f, 8.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_5) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + // scalar index + migraphx::shape s_indices{migraphx::shape::int32_type}; + std::vector indices{0}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = -1; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector golden = {0.5f, 3.5f, 6.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_6) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3 * 3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + // scalar index + migraphx::shape s_indices{migraphx::shape::int32_type}; + std::vector indices{-3}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = -1; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector golden = {0.5f, 3.5f, 6.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_test_7) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + std::vector data(3); + std::iota(data.begin(), data.end(), 0.5); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto a0 = mm->add_literal(migraphx::literal{s, data}); + // scalar index + migraphx::shape s_indices{migraphx::shape::int32_type}; + std::vector indices{0}; + auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); + int axis = -1; + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector golden = {0.5f}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, golden)); +} + +TEST_CASE(gather_dyn_test0) +{ + // Dynamic data, static indices + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {{2, 5}, {3, 3}}}; + + auto x = mm->add_parameter("x", s); + std::vector indices{1, 2}; + + migraphx::shape s_ind{migraphx::shape::int32_type, {1, 2}}; + auto ind = mm->add_parameter("indices", s_ind); + mm->add_instruction(migraphx::make_op("gather", {{"axis", 1}}), x, ind); + + migraphx::shape sresult{migraphx::shape::int32_type, {{2, 5}, {1, 1}, {2, 2}}}; + EXPECT(p.get_output_shapes().back() == sresult); + p.compile(migraphx::make_target("ref")); + + migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 3}}; + migraphx::shape input_indices{migraphx::shape::int32_type, {1, 2}}; + migraphx::parameter_map params; + std::vector data(2 * 3); + std::iota(data.begin(), data.end(), 0); + params["x"] = migraphx::argument(input_fixed_shape, data.data()); + params["indices"] = migraphx::argument(input_indices, indices.data()); + auto result = p.eval(params).back(); + + std::vector gold = {1, 2, 4, 5}; + std::vector results_vector(2 * 1 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + migraphx::shape sfinal{migraphx::shape::int32_type, {2, 1, 2}}; + EXPECT(result.get_shape() == sfinal); +} + +TEST_CASE(gather_dyn_test1) +{ + // Dynamic data, dynamic indices + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {{2, 5}, {4, 4}}}; + + auto x = mm->add_parameter("x", s); + + migraphx::shape s_ind{migraphx::shape::int32_type, {{1, 8, {7}}, {2, 3, {3}}}}; + auto ind = mm->add_parameter("indices", s_ind); + mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), x, ind); + + migraphx::shape sresult{migraphx::shape::int32_type, {{1, 8, {7}}, {2, 3, {3}}, {4, 4}}}; + EXPECT(p.get_output_shapes().back() == sresult); + p.compile(migraphx::make_target("ref")); + + migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {3, 4}}; + migraphx::shape input_indices_shape{migraphx::shape::int32_type, {1, 2}}; + std::vector indices{2, 0}; + migraphx::parameter_map params; + + std::vector data(3 * 4); + std::iota(data.begin(), data.end(), 0); + params["x"] = migraphx::argument(input_fixed_shape, data.data()); + params["indices"] = migraphx::argument(input_indices_shape, indices.data()); + auto result = p.eval(params).back(); + + std::vector gold = {8, 9, 10, 11, 0, 1, 2, 3}; + std::vector results_vector(1 * 2 * 4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + migraphx::shape sfinal{migraphx::shape::int32_type, {1, 2, 4}}; + EXPECT(result.get_shape() == sfinal); +} diff --git a/test/ref/gathernd.cpp b/test/ref/gathernd.cpp new file mode 100644 index 00000000000..2599df94483 --- /dev/null +++ b/test/ref/gathernd.cpp @@ -0,0 +1,408 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(gathernd_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 2}}; + + std::vector data_vec(2 * 2); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{0, 0, 1, 1}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd"), data, indices); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{0, 3}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 1}}; + + std::vector data_vec(2 * 2); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd"), data, indices); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{2, 3, 0, 1}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_test_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; + + std::vector data_vec(2 * 3 * 1); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0, 0, 1}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd"), data, indices); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_test_4) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 3, 2, 3}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 2, 2}}; + + std::vector data_vec(2 * 3 * 2 * 3); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{0, 0, 0, 1, 0, 0, 0, 1}; + const int batch_dims = 1; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{0, 1, 2, 3, 4, 5, 18, 19, 20, 21, 22, 23}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_test_5) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1, 3}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 3, 2}}; + + std::vector data_vec(2 * 3 * 1 * 3); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{0, 0, 0, 1, 0, 2, 0, 2, 0, 1, 0, 0}; + const int batch_dims = 2; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{0, 4, 8, 11, 13, 15}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_test_6) +{ + // k > r - batch_dims + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1, 3}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 3, 3}}; + + std::vector data_vec(2 * 3 * 1 * 3); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec(2 * 3 * 3, 0); + const int batch_dims = 2; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + EXPECT(test::throws([&] { + mm->add_instruction( + migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); + })); +} + +TEST_CASE(gathernd_dynamic0) +{ + // dynamic data, all dimensions fixed + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {{2, 2, {2}}, {3, 3}, {1, 1}}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + + auto gathernd_op = migraphx::make_op("gathernd"); + auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); + + mm->add_return({gathernd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data + migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index + + std::vector data_vec(2 * 3 * 1); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0, 0, 1}; + + params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); + params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); + + auto result = p.eval(params).back(); + std::vector res_data{}; + std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_dynamic1) +{ + // dynamic data, dims not fixed + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {{2, 5, {2}}, {1, 5}, {1, 5}}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + + auto gathernd_op = migraphx::make_op("gathernd"); + auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); + + mm->add_return({gathernd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data + migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index + + std::vector data_vec(2 * 3 * 1); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0, 0, 1}; + params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); + params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); + + auto result = p.eval(params).back(); + std::vector res_data{}; + std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_dynamic2) +{ + // dynamic both index and data + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {{2, 5, {2}}, {1, 5}, {1, 5}}}; + migraphx::shape is{migraphx::shape::int64_type, {{2, 5, {3}}, {2, 3, {3}}, {1, 1}}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + + auto gathernd_op = migraphx::make_op("gathernd"); + auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); + + mm->add_return({gathernd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data + migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index + + std::vector data_vec(2 * 3 * 1); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0, 0, 1}; + params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); + params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); + + auto result = p.eval(params).back(); + std::vector res_data{}; + std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_dynamic3) +{ + // dynamic index, static data and a batch_dims input + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1}}; + migraphx::shape is{migraphx::shape::int64_type, {{2, 5, {3}}, {2, 3, {3}}, {1, 1}}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + + int batch_dims{1}; + auto gathernd_op = migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}); + auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); + + mm->add_return({gathernd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data + migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index + + std::vector data_vec(2 * 3 * 1); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{1, 0, 0, 1}; + params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); + params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); + + auto result = p.eval(params).back(); + std::vector res_data{}; + std::vector gold{1, 0, 3, 4}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_dynamic4) +{ + // int(q) + r - k - batch_dims - 1 = 0 => returns a scalar + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {migraphx::shape::dynamic_dimension({2, 2})}}; + migraphx::shape is{migraphx::shape::int64_type, {1}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + + auto gathernd_op = migraphx::make_op("gathernd"); + auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); + + mm->add_return({gathernd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2}}; // data + migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {1}}; // index + + std::vector data_vec(2); + std::iota(data_vec.begin(), data_vec.end(), 4); + std::vector indices_vec{1}; + params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); + params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); + + auto result = p.eval(params).back(); + std::vector res_data{}; + std::vector gold{5}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_negative_index_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 1, 1}}; + + std::vector data_vec(2 * 2); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{-1, 0}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd"), data, indices); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector res_data{}; + std::vector gold{2, 3, 0, 1}; + result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(res_data, gold)); +} + +TEST_CASE(gathernd_negative_index_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; + migraphx::shape is{migraphx::shape::int64_type, {2, 1, 1}}; + + std::vector data_vec(2 * 2); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector indices_vec{-3, 0}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); + + mm->add_instruction(migraphx::make_op("gathernd"), data, indices); + p.compile(migraphx::make_target("ref")); + + EXPECT(test::throws([&] { p.eval({}); })); +} diff --git a/test/ref/greater.cpp b/test/ref/greater.cpp new file mode 100644 index 00000000000..b666ff9c9c8 --- /dev/null +++ b/test/ref/greater.cpp @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(greater_brcst_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; + auto l0 = + mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); + migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; + auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); + auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); + auto gr = mm->add_instruction(migraphx::make_op("greater"), l0, bl1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + gr); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, true, false, true, false, true, false, true, false}; + EXPECT(results_vector == gold); +} + +TEST_CASE(greater_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + auto l0 = + mm->add_literal(migraphx::literal{s, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); + auto l1 = + mm->add_literal(migraphx::literal{s, {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}}); + auto gr = mm->add_instruction(migraphx::make_op("greater"), l0, l1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + gr); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, false, true, true, false, true, false, false, true}; + EXPECT(results_vector == gold); +} + +TEST_CASE(greater_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{8, 10, {9}}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto left = mm->add_parameter("l", s); + auto right = mm->add_parameter("r", s); + auto gr = mm->add_instruction(migraphx::make_op("greater"), left, right); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + gr); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + + std::vector left_data{1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + std::vector right_data{1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, false, true, true, false, true, false, false, true}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/identity.cpp b/test/ref/identity.cpp new file mode 100644 index 00000000000..a052b3a23e1 --- /dev/null +++ b/test/ref/identity.cpp @@ -0,0 +1,65 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(identity_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data{1, 2, 3, 4}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("identity"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::equal(data.begin(), data.end(), results_vector.begin())); +} + +TEST_CASE(identity_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 4}}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("identity"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{1, 2, 3, 4}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::int32_type, {2, 2}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(std::equal(input_data.begin(), input_data.end(), results_vector.begin())); +} diff --git a/test/ref/if.cpp b/test/ref/if.cpp new file mode 100644 index 00000000000..e689bcfebf0 --- /dev/null +++ b/test/ref/if.cpp @@ -0,0 +1,219 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(if_literal_test) +{ + auto create_program = [] { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape cond_s{migraphx::shape::bool_type}; + auto cond = mm->add_parameter("cond", cond_s); + + migraphx::shape s{migraphx::shape::float_type, {5}}; + + auto* then_mod = p.create_module("If_0_if"); + std::vector data1 = {1, 2, 3, 4, 5}; + auto l1 = then_mod->add_literal(migraphx::literal(s, data1)); + then_mod->add_return({l1}); + + auto* else_mod = p.create_module("If_0_else"); + std::vector data2 = {5, 4, 3, 2, 1}; + auto l2 = else_mod->add_literal(migraphx::literal(s, data2)); + else_mod->add_return({l2}); + + auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod}); + auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); + mm->add_return({r}); + + return p; + }; + + auto run_prog = [&](bool cond) { + auto p = create_program(); + p.compile(migraphx::make_target("ref")); + std::vector c_data = {static_cast(cond)}; + migraphx::shape cs{migraphx::shape::bool_type}; + migraphx::parameter_map m; + m["cond"] = migraphx::argument(cs, c_data.data()); + + auto res = p.eval(m).back(); + std::vector ret; + res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); + + return ret; + }; + + // then branch + { + std::vector gold_ret = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + auto ret = run_prog(true); + EXPECT(gold_ret == ret); + } + + // else branch + { + std::vector gold_ret = {5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + auto ret = run_prog(false); + EXPECT(gold_ret == ret); + } +} + +TEST_CASE(if_param_test) +{ + auto create_program = [] { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape cond_s{migraphx::shape::bool_type}; + auto cond = mm->add_parameter("cond", cond_s); + migraphx::shape ds{migraphx::shape::float_type, {2, 3}}; + auto x = mm->add_parameter("x", ds); + auto y = mm->add_parameter("y", ds); + std::vector data2 = {-0.258047, 0.360394, 0.536804, -0.577762, 1.0217, 1.02442}; + auto l2 = mm->add_literal(migraphx::literal(ds, data2)); + auto sum = mm->add_instruction(migraphx::make_op("add"), x, l2); + + auto* then_mod = p.create_module("If_0_if"); + std::vector data1 = {0.384804, -1.77948, -0.453775, 0.477438, -1.06333, -1.12893}; + auto l1 = then_mod->add_literal(migraphx::literal(ds, data1)); + auto tx = then_mod->add_parameter("x", ds); + auto a1 = then_mod->add_instruction(migraphx::make_op("add"), tx, l1); + then_mod->add_return({a1}); + + auto* else_mod = p.create_module("If_0_else"); + auto ey = else_mod->add_parameter("y", ds); + auto a2 = else_mod->add_instruction(migraphx::make_op("mul"), ey, sum); + else_mod->add_return({a2}); + + auto ret = mm->add_instruction(migraphx::make_op("if"), {cond, x, y}, {then_mod, else_mod}); + auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); + mm->add_return({r}); + + return p; + }; + + auto run_prog = [&](bool cond) { + auto p = create_program(); + p.compile(migraphx::make_target("ref")); + std::vector c_data = {static_cast(cond)}; + migraphx::shape cs{migraphx::shape::bool_type}; + migraphx::parameter_map m; + m["cond"] = migraphx::argument(cs, c_data.data()); + migraphx::shape ds{migraphx::shape::float_type, {2, 3}}; + std::vector data_x(ds.elements(), 1); + m["x"] = migraphx::argument(ds, data_x.data()); + std::vector data_y(ds.elements(), 2); + m["y"] = migraphx::argument(ds, data_y.data()); + + auto res = p.eval(m).back(); + std::vector ret; + res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); + return ret; + }; + + // then branch + { + std::vector gold_ret = { + 1.384804, -0.77947998, 0.54622501, 1.477438, -0.063330054, -0.12892997}; + auto ret = run_prog(true); + EXPECT(gold_ret == ret); + } + + // else branch + { + std::vector gold_ret = { + 1.483906, 2.720788, 3.0736079, 0.84447598, 4.0433998, 4.04884}; + auto ret = run_prog(false); + EXPECT(gold_ret == ret); + } +} + +TEST_CASE(if_pl_test) +{ + auto create_program = [] { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape cond_s{migraphx::shape::bool_type}; + migraphx::shape s{migraphx::shape::float_type, {5}}; + auto cond = mm->add_parameter("cond", cond_s); + auto x = mm->add_parameter("x", s); + + auto* then_mod = p.create_module("If_0_if"); + std::vector data1 = {1, 2, 3, 4, 5}; + auto l1 = then_mod->add_literal(migraphx::literal(s, data1)); + then_mod->add_return({l1, x}); + + auto* else_mod = p.create_module("If_0_else"); + std::vector data2 = {5, 4, 3, 2, 1}; + auto l2 = else_mod->add_literal(migraphx::literal(s, data2)); + auto s2 = else_mod->add_instruction(migraphx::make_op("add"), x, l2); + else_mod->add_return({s2, l2}); + + auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod}); + auto outline = mm->add_outline(s); + auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); + mm->add_return({outline, r}); + + return p; + }; + + auto run_prog = [&](bool cond) { + auto p = create_program(); + p.compile(migraphx::make_target("ref")); + std::vector c_data = {static_cast(cond)}; + migraphx::shape cs{migraphx::shape::bool_type}; + migraphx::parameter_map m; + m["cond"] = migraphx::argument(cs, c_data.data()); + migraphx::shape ds{migraphx::shape::float_type, {5}}; + std::vector data(ds.elements(), 1); + m["x"] = migraphx::argument(ds, data.data()); + + auto res = p.eval(m).back(); + std::vector ret; + res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); + + return ret; + }; + + // then branch + { + std::vector gold_ret = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + auto ret = run_prog(true); + EXPECT(gold_ret == ret); + } + + // else branch + { + std::vector gold_ret = {6.0f, 5.0f, 4.0f, 3.0f, 2.0f}; + auto ret = run_prog(false); + EXPECT(gold_ret == ret); + } +} diff --git a/test/ref/im2col.cpp b/test/ref/im2col.cpp new file mode 100644 index 00000000000..a26aa4d4847 --- /dev/null +++ b/test/ref/im2col.cpp @@ -0,0 +1,211 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(im2col_3x3_no_pad_identity_test) +{ + std::size_t f[2] = {3, 3}; + std::size_t size[2] = {3, 3}; + std::vector padding{0, 0}; + std::vector stride{1, 1}; + std::vector dilation{1, 1}; + std::size_t channels = 1; + + std::vector weights(channels * f[0] * f[1]); + std::vector input(channels * size[0] * size[1]); + std::iota(input.begin(), input.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; + migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; + auto l_image = mm->add_literal(migraphx::literal{s_image, input}); + auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); + mm->add_instruction( + migraphx::make_op("im2col", + {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), + l_image, + l_weights); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; + std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; + std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, input)); +} + +TEST_CASE(im2col_3x3_no_pad_test) +{ + std::size_t f[2] = {3, 3}; + std::size_t size[2] = {4, 4}; + std::vector padding{0, 0}; + std::vector stride{1, 1}; + std::vector dilation{1, 1}; + std::size_t channels = 1; + + std::vector weights(channels * f[0] * f[1]); + std::vector input(channels * size[0] * size[1]); + std::iota(input.begin(), input.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; + migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; + auto l_image = mm->add_literal(migraphx::literal{s_image, input}); + auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); + mm->add_instruction( + migraphx::make_op("im2col", + {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), + l_image, + l_weights); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector correct = {0, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 3, 5, 6, 7, 9, 10, 11, + 4, 5, 6, 8, 9, 10, 12, 13, 14, 5, 6, 7, 9, 10, 11, 13, 14, 15}; + + std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; + std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; + std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, correct)); +} + +TEST_CASE(im2col_3x3_stride_2_no_pad_test) +{ + std::size_t f[2] = {3, 3}; + std::size_t size[2] = {6, 6}; + std::vector padding{0, 0}; + std::vector stride{2, 2}; + std::vector dilation{1, 1}; + std::size_t channels = 1; + + std::vector weights(channels * f[0] * f[1]); + std::vector input(channels * size[0] * size[1]); + std::iota(input.begin(), input.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; + migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; + auto l_image = mm->add_literal(migraphx::literal{s_image, input}); + auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); + mm->add_instruction( + migraphx::make_op("im2col", + {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), + l_image, + l_weights); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector correct = {0, 1, 2, 6, 7, 8, 12, 13, 14, 2, 3, 4, + 8, 9, 10, 14, 15, 16, 12, 13, 14, 18, 19, 20, + 24, 25, 26, 14, 15, 16, 20, 21, 22, 26, 27, 28}; + + std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; + std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; + std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, correct)); +} + +TEST_CASE(im2col_3x3_with_channels_identity_test) +{ + std::size_t f[2] = {3, 3}; + std::size_t size[2] = {3, 3}; + std::vector padding{0, 0}; + std::vector stride{1, 1}; + std::vector dilation{1, 1}; + std::size_t channels = 2; + + std::vector weights(channels * f[0] * f[1]); + std::vector input(channels * size[0] * size[1]); + std::iota(input.begin(), input.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; + migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; + auto l_image = mm->add_literal(migraphx::literal{s_image, input}); + auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); + mm->add_instruction( + migraphx::make_op("im2col", + {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), + l_image, + l_weights); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; + std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; + std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, input)); +} + +TEST_CASE(im2col_3x3_with_padding_test) +{ + std::size_t f[2] = {3, 3}; + std::size_t size[2] = {2, 2}; + std::vector padding{1, 1}; + std::vector stride{1, 1}; + std::vector dilation{1, 1}; + std::size_t channels = 1; + + std::vector weights(channels * f[0] * f[1]); + std::vector input(channels * size[0] * size[1]); + std::iota(input.begin(), input.end(), 0); + + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; + migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; + auto l_image = mm->add_literal(migraphx::literal{s_image, input}); + auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); + mm->add_instruction( + migraphx::make_op("im2col", + {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), + l_image, + l_weights); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector correct = {0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, + 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0}; + + std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; + std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; + std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, correct)); +} diff --git a/test/ref/isnan.cpp b/test/ref/isnan.cpp new file mode 100644 index 00000000000..bfcbe595c74 --- /dev/null +++ b/test/ref/isnan.cpp @@ -0,0 +1,91 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(isnan_test) +{ + // float test + { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3}}; + auto nan_val = std::numeric_limits::quiet_NaN(); + std::vector data0 = {1.2, 5.2, nan_val, nan_val, 0., 100.}; + auto l1 = mm->add_literal(migraphx::literal{s, data0}); + mm->add_instruction(migraphx::make_op("isnan"), l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector correct = {0, 0, 1, 1, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, correct)); + } + + // half test + { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::half_type, {2, 3}}; + auto nan_val = std::numeric_limits::quiet_NaN(); + migraphx::half a{1.2}; + migraphx::half b{5.2}; + std::vector data0 = {a, b, nan_val, nan_val, b, a}; + auto l1 = mm->add_literal(migraphx::literal{s, data0}); + mm->add_instruction(migraphx::make_op("isnan"), l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector correct = {0, 0, 1, 1, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, correct)); + } +} + +TEST_CASE(isnan_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 2}, {3, 8}}}; + auto input = mm->add_parameter("X", s); + auto nan_val = std::numeric_limits::quiet_NaN(); + mm->add_instruction(migraphx::make_op("isnan"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {1.2, 5.2, nan_val, nan_val, 0., 100.}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector correct = {0, 0, 1, 1, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, correct)); +} diff --git a/test/ref/leaky_relu.cpp b/test/ref/leaky_relu.cpp new file mode 100644 index 00000000000..da4a838da5a --- /dev/null +++ b/test/ref/leaky_relu.cpp @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(leaky_relu_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l = mm->add_literal(migraphx::literal{s, {-1.f, 0.f, 1.f}}); + mm->add_instruction(migraphx::make_op("leaky_relu", {{"alpha", 0.01}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-0.01f, 0.f, 1.f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/less.cpp b/test/ref/less.cpp new file mode 100644 index 00000000000..12fe32a5834 --- /dev/null +++ b/test/ref/less.cpp @@ -0,0 +1,118 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(less_brcst_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; + auto l0 = + mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); + migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; + auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); + auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); + auto le = mm->add_instruction(migraphx::make_op("less"), l0, bl1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + le); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, false, true, false, false, false, false, false, true}; + EXPECT(results_vector == gold); +} + +TEST_CASE(less_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + std::vector data1 = {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + std::vector data2 = {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; + auto l0 = mm->add_literal(migraphx::literal{s, data1}); + auto l1 = mm->add_literal(migraphx::literal{s, data2}); + auto le = mm->add_instruction(migraphx::make_op("less"), l0, l1); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + le); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data1.size()); + std::transform( + data1.begin(), data1.end(), data2.begin(), gold.begin(), [](float n1, float n2) -> bool { + return n1 < n2; + }); + EXPECT(results_vector == gold); +} + +TEST_CASE(less_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{8, 10, {9}}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto left = mm->add_parameter("l", s); + auto right = mm->add_parameter("r", s); + auto le = mm->add_instruction(migraphx::make_op("less"), left, right); + auto r = mm->add_instruction( + migraphx::make_op("convert", + {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), + le); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + + std::vector left_data = {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; + std::vector right_data = {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(left_data.size()); + std::transform(left_data.begin(), + left_data.end(), + right_data.begin(), + gold.begin(), + [](float n1, float n2) -> bool { return n1 < n2; }); + EXPECT(results_vector == gold); +} diff --git a/test/ref/log.cpp b/test/ref/log.cpp new file mode 100644 index 00000000000..0a48721eea8 --- /dev/null +++ b/test/ref/log.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(log_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data = {1, 2, 3}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("log"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return logf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(log_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("log"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return logf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/logical_and.cpp b/test/ref/logical_and.cpp new file mode 100644 index 00000000000..3258a174751 --- /dev/null +++ b/test/ref/logical_and.cpp @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(logical_and_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::bool_type, {4}}; + std::vector data1{true, false, true, false}; + std::vector data2{true, true, false, false}; + auto l1 = mm->add_literal(migraphx::literal{s, data1}); + auto l2 = mm->add_literal(migraphx::literal{s, data2}); + mm->add_instruction(migraphx::make_op("logical_and"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data2.size()); + std::transform( + data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { + return n1 and n2; + }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(logical_and_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6, {4}}}; + migraphx::shape s{migraphx::shape::bool_type, dd}; + auto left = mm->add_parameter("l", s); + auto right = mm->add_parameter("r", s); + mm->add_instruction(migraphx::make_op("logical_and"), left, right); + p.compile(migraphx::make_target("ref")); + + std::vector left_data{1, 0, 1, 0}; + std::vector right_data{1, 1, 0, 0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; + params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(left_data.size()); + std::transform(left_data.begin(), + left_data.end(), + right_data.begin(), + gold.begin(), + [](bool n1, bool n2) -> bool { return n1 and n2; }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/logical_or.cpp b/test/ref/logical_or.cpp new file mode 100644 index 00000000000..1517b138458 --- /dev/null +++ b/test/ref/logical_or.cpp @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(logical_or_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::bool_type, {4}}; + std::vector data1{true, false, true, false}; + std::vector data2{true, true, false, false}; + auto l1 = mm->add_literal(migraphx::literal{s, data1}); + auto l2 = mm->add_literal(migraphx::literal{s, data2}); + mm->add_instruction(migraphx::make_op("logical_or"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data1.size()); + std::transform( + data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { + return n1 or n2; + }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(logical_or_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6, {4}}}; + migraphx::shape s{migraphx::shape::bool_type, dd}; + auto left = mm->add_parameter("l", s); + auto right = mm->add_parameter("r", s); + mm->add_instruction(migraphx::make_op("logical_or"), left, right); + p.compile(migraphx::make_target("ref")); + + std::vector left_data{1, 0, 1, 0}; + std::vector right_data{1, 1, 0, 0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; + params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(left_data.size()); + std::transform(left_data.begin(), + left_data.end(), + right_data.begin(), + gold.begin(), + [](bool n1, bool n2) -> bool { return n1 or n2; }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/logical_xor.cpp b/test/ref/logical_xor.cpp new file mode 100644 index 00000000000..b9e14d10894 --- /dev/null +++ b/test/ref/logical_xor.cpp @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(logical_xor_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::bool_type, {4}}; + std::vector data1{true, false, true, false}; + std::vector data2{true, true, false, false}; + auto l1 = mm->add_literal(migraphx::literal{s, data1}); + auto l2 = mm->add_literal(migraphx::literal{s, data2}); + mm->add_instruction(migraphx::make_op("logical_xor"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, true, true, false}; + std::transform( + data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { + return n1 ^ n2; + }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(logical_xor_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6, {4}}}; + migraphx::shape s{migraphx::shape::bool_type, dd}; + auto left = mm->add_parameter("l", s); + auto right = mm->add_parameter("r", s); + mm->add_instruction(migraphx::make_op("logical_xor"), left, right); + p.compile(migraphx::make_target("ref")); + + std::vector left_data{1, 0, 1, 0}; + std::vector right_data{1, 1, 0, 0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; + params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); + params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {false, true, true, false}; + std::transform(left_data.begin(), + left_data.end(), + right_data.begin(), + gold.begin(), + [](bool n1, bool n2) -> bool { return n1 ^ n2; }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/logsoftmax.cpp b/test/ref/logsoftmax.cpp new file mode 100644 index 00000000000..4d5c9c0728e --- /dev/null +++ b/test/ref/logsoftmax.cpp @@ -0,0 +1,167 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(logsoftmax_test_axis_0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, + -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, + -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, + -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, + 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, + -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, + -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, + -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; + + std::vector s = { + -0.135261, -2.843968, -0.659995, -0.488413, -1.051857, -2.812936, -0.250956, -0.353985, + -1.155980, -0.603651, -0.211969, -0.175371, -1.336552, -3.885010, -1.871544, -0.837083, + -0.887745, -0.433338, -1.158864, -4.911197, -1.147972, -0.666711, -0.996874, -0.981418, + -0.851145, -0.853988, -0.858112, -2.067420, -0.059956, -0.727436, -0.950881, -0.429689, + -0.061906, -1.505332, -1.210277, -0.377970, -0.791448, -1.655428, -1.827253, -0.304828, + -0.020762, -0.167101, -0.567346, -0.530319, -1.045094, -0.376648, -0.007391, -0.381670, + -0.720302, -0.460499, -0.469651, -0.556740, -0.554628, -0.551582}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + int axis = 0; + mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(logsoftmax_test_axis_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, + -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, + -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, + -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, + 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, + -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, + -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, + -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; + + std::vector s = { + -0.550468, -2.132973, -1.549746, -0.650533, -1.051529, -2.248570, -0.141017, -2.028357, + -1.947730, -1.511324, -0.166597, -0.379726, -1.965689, -1.172109, -1.475721, -2.700831, + -1.537011, -0.658754, -1.596017, -3.353137, -2.266743, -1.084197, -1.076214, -0.406712, + -2.743019, -0.425526, -1.079083, -2.139486, -1.270584, -1.024088, -1.154231, -3.201762, + -0.888957, -0.532855, -3.103583, -1.221339, -1.355980, -3.531678, -1.438510, -0.975194, + -0.080261, -1.162697, -1.568557, -1.398519, -1.322129, -0.470660, -0.370953, -0.907343, + -1.179017, -3.312239, -1.286363, -1.586076, -0.345100, -0.824173}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + int axis = 1; + mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(logsoftmax_test_axis_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, + -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, + -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, + -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, + 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, + -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, + -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, + -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; + + std::vector s = { + -0.495957, -1.031212, -0.245531, -2.013726, -1.339125, -2.465619, -1.356652, -0.964037, + -2.019250, -0.214522, -0.289569, -0.234392, -2.086591, -2.684439, -2.851651, -2.674176, + -1.697424, -1.889155, -0.401029, -3.064586, -1.173030, -1.306912, -2.177020, -0.834262, + -2.818177, -0.174415, -1.361105, -1.024571, -0.106766, -1.167645, -1.072650, -2.576522, + -0.569261, -1.207483, -3.679894, -2.095913, -0.504264, -3.039291, -1.290559, -1.156812, + -0.126453, -0.551493, -2.506384, -2.646261, -1.905195, -0.206994, -0.191369, -0.959754, + -1.948685, -3.671233, -0.875521, -3.111952, -1.905644, -1.6076011}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + int axis = 2; + mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(logsoftmax_test_axis_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, + -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, + -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, + -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, + 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, + -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, + -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, + -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; + + std::vector s = { + -0.336904, -3.475825, -1.366154, -0.279366, -2.208430, -2.010934, -0.225511, -2.436562, + -2.167785, -1.572415, -1.784104, -0.470789, -1.067459, -1.801948, -0.711023, -2.307197, + -1.467087, -0.400681, -0.426983, -3.740518, -1.127681, -1.078919, -2.599005, -0.534965, + -2.561400, -0.567617, -1.033025, -2.097713, -0.520463, -1.262245, -1.763230, -2.607658, + -0.281299, -0.814243, -2.627210, -0.724131, -0.655704, -2.123055, -1.018163, -2.480634, + -0.382599, -1.451479, -1.843102, -0.915303, -0.818078, -1.316929, -0.508875, -2.033541, + -1.487672, -2.417791, -0.378360, -2.568531, -0.569794, -1.028032}; + + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + int axis = 3; + mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} diff --git a/test/ref_loop_test.cpp b/test/ref/loop.cpp similarity index 98% rename from test/ref_loop_test.cpp rename to test/ref/loop.cpp index 264ced9b3e7..e0288d12d12 100644 --- a/test/ref_loop_test.cpp +++ b/test/ref/loop.cpp @@ -125,5 +125,3 @@ TEST_CASE(loop_test4) std::vector gold_concat = {5, 9, 14, 20, 0, 0, 0, 0, 0, 0}; EXPECT(ress.back() == gold_concat); } - -int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/ref/lrn.cpp b/test/ref/lrn.cpp new file mode 100644 index 00000000000..ebe08d72f04 --- /dev/null +++ b/test/ref/lrn.cpp @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(lrn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {1, 5, 1, 1}}; + auto l = mm->add_literal(migraphx::literal{s, {-2.0f, 1.0f, 0.f, 1.0f, 2.0f}}); + mm->add_instruction( + migraphx::make_op("lrn", {{"alpha", 0.0001}, {"beta", 0.75}, {"bias", 1}, {"size", 5}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(5); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2 / 1.000075, 1 / 1.00009, 0 / 1.000145, 1 / 1.00009, 2 / 1.000075}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/main.cpp b/test/ref/main.cpp new file mode 100644 index 00000000000..5ad4d5ec1ef --- /dev/null +++ b/test/ref/main.cpp @@ -0,0 +1,26 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include + +int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/ref/max.cpp b/test/ref/max.cpp new file mode 100644 index 00000000000..1a17db6676a --- /dev/null +++ b/test/ref/max.cpp @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(max_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 4, 3}}); + auto l1 = mm->add_literal(migraphx::literal{s, {2, 8, 6}}); + auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); + auto curr_max = mm->add_instruction(migraphx::make_op("max"), l0, l1); + mm->add_instruction(migraphx::make_op("max"), curr_max, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{7, 8, 9}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(max_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + auto z = mm->add_parameter("z", s); + auto curr_max = mm->add_instruction(migraphx::make_op("max"), x, y); + mm->add_instruction(migraphx::make_op("max"), curr_max, z); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{1, 4, 3}; + std::vector y_data{2, 8, 6}; + std::vector z_data{7, 5, 9}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{7, 8, 9}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/min.cpp b/test/ref/min.cpp new file mode 100644 index 00000000000..f88882df038 --- /dev/null +++ b/test/ref/min.cpp @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(min_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 4, 3}}); + auto l1 = mm->add_literal(migraphx::literal{s, {2, 8, 6}}); + auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); + auto curr_min = mm->add_instruction(migraphx::make_op("min"), l0, l1); + mm->add_instruction(migraphx::make_op("min"), curr_min, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 4, 3}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(min_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + auto z = mm->add_parameter("z", s); + auto curr_min = mm->add_instruction(migraphx::make_op("min"), x, y); + mm->add_instruction(migraphx::make_op("min"), curr_min, z); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{1, 4, 3}; + std::vector y_data{2, 8, 6}; + std::vector z_data{7, 5, 9}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 4, 3}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/mod.cpp b/test/ref/mod.cpp new file mode 100644 index 00000000000..c0eaec19a3b --- /dev/null +++ b/test/ref/mod.cpp @@ -0,0 +1,96 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(mod_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {-3, 8, -7}}); + auto l1 = mm->add_literal(migraphx::literal{s, {3, 3, 3}}); + auto l2 = mm->add_literal(migraphx::literal{s, {10, 2, 9}}); + auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), l0, l1); + mm->add_instruction(migraphx::make_op("mod"), curr_mod, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 0, 2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(mod_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + auto z = mm->add_parameter("z", s); + auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), x, y); + mm->add_instruction(migraphx::make_op("mod"), curr_mod, z); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-3, 8, -7}; + std::vector y_data{3, 3, 3}; + std::vector z_data{10, 2, 9}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 0, 2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(mod_float_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l0 = mm->add_literal(migraphx::literal{s, {-3.0f, 8.5f, -7.0f}}); + auto l1 = mm->add_literal(migraphx::literal{s, {2.0f, 3.0f, 3.0f}}); + auto l2 = mm->add_literal(migraphx::literal{s, {3.0f, 3.0f, 4.0f}}); + auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), l0, l1); + mm->add_instruction(migraphx::make_op("mod"), curr_mod, l2); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.0f, 2.5f, 2.0f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/mul.cpp b/test/ref/mul.cpp new file mode 100644 index 00000000000..dd6fd47cf09 --- /dev/null +++ b/test/ref/mul.cpp @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(mul_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data1{-1, 0, 1}; + std::vector data2{1, 2, 3}; + auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); + auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); + mm->add_instruction(migraphx::make_op("mul"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data1.size()); + std::transform( + data1.begin(), data1.end(), data2.begin(), gold.begin(), [](float n1, float n2) -> float { + return n1 * n2; + }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(mul_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + mm->add_instruction(migraphx::make_op("mul"), x, y); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1, 0, 1}; + std::vector y_data{1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(x_data.size()); + std::transform(x_data.begin(), + x_data.end(), + y_data.begin(), + gold.begin(), + [](float n1, float n2) -> float { return n1 * n2; }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/multibroadcast.cpp b/test/ref/multibroadcast.cpp new file mode 100644 index 00000000000..573a8c7ed64 --- /dev/null +++ b/test/ref/multibroadcast.cpp @@ -0,0 +1,129 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(multibroadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; + std::vector a_data{0, 0, 0, 0}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", l1->get_shape().lens()}}), + l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -3); + EXPECT(output(1, 0) == -2); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(multibroadcast_2in_static_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; + std::vector a_data{0, 0, 0, 0}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -3); + EXPECT(output(1, 0) == -2); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(multibroadcast_2in_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 4}, {2, 2}}}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + std::vector b_data{-2, -3}; + auto l1 = mm->add_parameter("a", a_shape); + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1); + p.compile(migraphx::make_target("ref")); + + std::vector a_data{0, 0, 0, 0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; + params0["a"] = migraphx::argument(input_fixed_shape0, a_data.data()); + auto result = p.eval(params0).back(); + auto output = result.get(); + EXPECT(output(0, 0) == -2); + EXPECT(output(0, 1) == -3); + EXPECT(output(1, 0) == -2); + EXPECT(output(1, 1) == -3); +} + +TEST_CASE(multibroadcast_3in_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 4}, {2, 2}}}; + migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; + migraphx::shape c_shape{migraphx::shape::int32_type, {{1, 4, {2, 4}}, {2, 4}, {2, 2}}}; + auto l1 = mm->add_parameter("a", a_shape); + std::vector b_data{-2, -3}; + auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); + auto l3 = mm->add_parameter("c", c_shape); + mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1, l3); + p.compile(migraphx::make_target("ref")); + + std::vector a_data(4, 0); + std::vector c_data(8, 0); + migraphx::parameter_map params; + migraphx::shape input_fixed_shape_a{migraphx::shape::float_type, {2, 2}}; + migraphx::shape input_fixed_shape_c{migraphx::shape::float_type, {2, 2, 2}}; + params["a"] = migraphx::argument(input_fixed_shape_a, a_data.data()); + params["c"] = migraphx::argument(input_fixed_shape_c, c_data.data()); + auto result = p.eval(params).back(); + auto output = result.get(); + EXPECT(output(0, 0, 0) == -2); + EXPECT(output(0, 0, 1) == -3); + EXPECT(output(0, 1, 0) == -2); + EXPECT(output(0, 1, 1) == -3); + EXPECT(output(1, 0, 0) == -2); + EXPECT(output(1, 0, 1) == -3); + EXPECT(output(1, 1, 0) == -2); + EXPECT(output(1, 1, 1) == -3); +} diff --git a/test/ref/multinomial.cpp b/test/ref/multinomial.cpp new file mode 100644 index 00000000000..f1e61b954a2 --- /dev/null +++ b/test/ref/multinomial.cpp @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(multinomial_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + size_t sample_size = 100000; + float seed = 0.0f; + std::mt19937 gen(seed); + std::uniform_real_distribution<> dis(0.0, 1.0); + std::vector rand_samples(sample_size); + std::generate(rand_samples.begin(), rand_samples.end(), [&]() { return dis(gen); }); + migraphx::shape rs{migraphx::shape::float_type, {1, sample_size}}; + auto rs_lit = mm->add_literal(migraphx::literal{rs, rand_samples}); + + migraphx::shape s{migraphx::shape::float_type, {1, 5}}; + std::vector dist{15, 25, 15, 25, 20}; + std::vector data(5); + std::transform(dist.begin(), dist.end(), data.begin(), [&](auto d) { return std::log(d); }); + auto input = mm->add_literal(migraphx::literal(s, data)); + + auto maxes = mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {1}}}), input); + auto mb_maxes = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {1, 5}}}), maxes); + auto cdf = mm->add_instruction(migraphx::make_op("sub"), input, mb_maxes); + cdf = mm->add_instruction(migraphx::make_op("exp"), cdf); + cdf = mm->add_instruction( + migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), cdf); + + mm->add_instruction(migraphx::make_op("multinomial"), cdf, rs_lit); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec(sample_size); + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + + std::vector res_dist(5, 0); + for(const auto& r : result_vec) + res_dist[r]++; + auto dist_sum = std::accumulate(dist.begin(), dist.end(), 0); + auto res_dist_sum = std::accumulate(res_dist.begin(), res_dist.end(), 0); + std::vector norm(5); + std::vector res_norm(5); + std::transform(dist.begin(), dist.end(), norm.begin(), [&](auto n) { + return static_cast(n) / dist_sum; + }); + std::transform(res_dist.begin(), res_dist.end(), res_norm.begin(), [&](auto n) { + return static_cast(n) / res_dist_sum; + }); + EXPECT(migraphx::verify::verify_range(norm, res_norm, 100000)); +} diff --git a/test/ref/neg.cpp b/test/ref/neg.cpp new file mode 100644 index 00000000000..8b7749ca7ac --- /dev/null +++ b/test/ref/neg.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(neg_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3}}; + std::vector data = {1.0f, 1.3f, -1.2f, 0.0f, -100.f, 200.f}; + auto input = mm->add_literal(migraphx::literal(s, data)); + auto ret = mm->add_instruction(migraphx::make_op("neg"), input); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform(gold.begin(), gold.end(), gold.begin(), std::negate()); + EXPECT(migraphx::verify::verify_range(result_vector, gold)); +} + +TEST_CASE(neg_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {3, 3}}}; + auto input = mm->add_parameter("X", s); + auto ret = mm->add_instruction(migraphx::make_op("neg"), input); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + + std::vector a = {1.0f, 1.3f, -1.2f, 0.0f, -100.f, 200.f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + auto result = p.eval(params0).back(); + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + std::vector gold = a; + std::transform(gold.begin(), gold.end(), gold.begin(), std::negate()); + EXPECT(migraphx::verify::verify_range(result_vector, gold)); +} diff --git a/test/ref/nonmaxsuppression.cpp b/test/ref/nonmaxsuppression.cpp new file mode 100644 index 00000000000..92ea5decb38 --- /dev/null +++ b/test/ref/nonmaxsuppression.cpp @@ -0,0 +1,345 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(nms_dyn_out_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; + std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, + 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; + + migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); + auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto r = mm->add_instruction( + migraphx::make_op("nonmaxsuppression", + {{"center_point_box", true}, {"use_dyn_output", true}}), + boxes_l, + scores_l, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto output = p.eval({}).back(); + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_dyn_batch_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 3}, {6, 6}, {4, 4}}}; + + migraphx::shape scores_s{migraphx::shape::float_type, {{1, 3}, {1, 1}, {6, 6}}}; + + auto boxes_p = mm->add_parameter("boxes", boxes_s); + auto scores_p = mm->add_parameter("scores", scores_s); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto r = mm->add_instruction( + migraphx::make_op("nonmaxsuppression", + {{"center_point_box", true}, {"use_dyn_output", true}}), + boxes_p, + scores_p, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + + std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, + 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0, + 0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, + 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; + std::vector scores_vec = { + 0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 6, 4}}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {2, 1, 6}}; + migraphx::parameter_map params0; + params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); + params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); + auto output = p.eval(params0).back(); + + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 1, 0, 3, 1, 0, 0, 1, 0, 5}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_dyn_boxes_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 1}, {4, 20}, {4, 4}}}; + + migraphx::shape scores_s{migraphx::shape::float_type, {{1, 1}, {1, 1}, {4, 20}}}; + + auto boxes_p = mm->add_parameter("boxes", boxes_s); + auto scores_p = mm->add_parameter("scores", scores_s); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto r = mm->add_instruction( + migraphx::make_op("nonmaxsuppression", + {{"center_point_box", true}, {"use_dyn_output", true}}), + boxes_p, + scores_p, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + + std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, + 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 6, 4}}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 1, 6}}; + migraphx::parameter_map params0; + params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); + params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); + auto output = p.eval(params0).back(); + + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_dyn_classes_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 1}, {6, 6}, {4, 4}}}; + + migraphx::shape scores_s{migraphx::shape::float_type, {{1, 1}, {1, 3}, {6, 6}}}; + + auto boxes_p = mm->add_parameter("boxes", boxes_s); + auto scores_p = mm->add_parameter("scores", scores_s); + auto max_out_l = mm->add_literal(int64_t{2}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto r = mm->add_instruction( + migraphx::make_op("nonmaxsuppression", + {{"center_point_box", true}, {"use_dyn_output", true}}), + boxes_p, + scores_p, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + + std::vector boxes_vec = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, + 0.0, -0.1, 1.0, 0.9, 0.0, 10.0, 1.0, 11.0, + 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; + std::vector scores_vec = { + 0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 6, 4}}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 2, 6}}; + migraphx::parameter_map params0; + params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); + params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); + auto output = p.eval(params0).back(); + + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 1, 3, 0, 1, 0}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_not_center_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; + std::vector boxes_vec = {1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, + 0.0, 0.9, 1.0, -0.1, 0.0, 10.0, 1.0, 11.0, + 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0}; + + migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); + auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + // set use_dyn_output back to false in operator map + auto r = + mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"use_dyn_output", false}}), + boxes_l, + scores_l, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto output = p.eval({}).back(); + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; + std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, + 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; + + migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); + auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto r = + mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), + boxes_l, + scores_l, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto output = p.eval({}).back(); + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_transpose1_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {1, 4, 6}}; + std::vector boxes_vec = { + 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6, 0.4, 10.5, 10.6, 100.5, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + }; + + migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + auto t_boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); + auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto transpose_boxes = mm->add_instruction( + migraphx::make_op("transpose", {{"permutation", {0, 2, 1}}}), t_boxes_l); + auto r = + mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), + transpose_boxes, + scores_l, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto output = p.eval({}).back(); + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} + +TEST_CASE(nms_transpose2_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape boxes_s{migraphx::shape::float_type, {4, 1, 6}}; + std::vector boxes_vec = { + 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6, 0.4, 10.5, 10.6, 100.5, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + }; + + migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; + std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; + + auto t_boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); + auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); + auto max_out_l = mm->add_literal(int64_t{4}); + auto iou_threshold = mm->add_literal(0.5f); + auto score_threshold = mm->add_literal(0.0f); + + auto transpose_boxes = mm->add_instruction( + migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), t_boxes_l); + auto r = + mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), + transpose_boxes, + scores_l, + max_out_l, + iou_threshold, + score_threshold); + mm->add_return({r}); + + p.compile(migraphx::make_target("ref")); + auto output = p.eval({}).back(); + std::vector result; + output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); + std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(result, gold)); +} diff --git a/test/ref/nonzero.cpp b/test/ref/nonzero.cpp new file mode 100644 index 00000000000..2bd2e022d37 --- /dev/null +++ b/test/ref/nonzero.cpp @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(nonzero_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2, 3}}; + std::vector data = { + 1.0f, 1.3f, 0.0f, -1.2f, 0.0f, -100.f, 200.f, 0.0f, 0.1f, 0.2f, 0.0f, 0.5f}; + auto input = mm->add_literal(migraphx::literal(s, data)); + auto ret = mm->add_instruction(migraphx::make_op("nonzero"), input); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(result_vector, gold)); +} diff --git a/test/ref/not.cpp b/test/ref/not.cpp new file mode 100644 index 00000000000..a04ef00c1ce --- /dev/null +++ b/test/ref/not.cpp @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(not_test_int32) +// int32 +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {4}}; + std::vector data{0, 8, 1, -32}; + auto l1 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("not"), l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(not_test_bool) +// bool +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::bool_type, {4}}; + std::vector data{false, false, true, true}; + auto l1 = mm->add_literal(migraphx::literal{s, {0, 0, 1, 1}}); + mm->add_instruction(migraphx::make_op("not"), l1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(data.size()); + std::transform(data.begin(), data.end(), gold.begin(), [](bool n) -> bool { return not n; }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(not_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("not"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{0, 8, 1, -32}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/pad.cpp b/test/ref/pad.cpp new file mode 100644 index 00000000000..026893c8b5d --- /dev/null +++ b/test/ref/pad.cpp @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(pad_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); + mm->add_instruction(migraphx::make_op("pad", {{"pads", {1, 1, 1, 1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(pad_test_asym) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); + mm->add_instruction(migraphx::make_op("pad", {{"pads", {0, 0, 1, 1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(9); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 2, 0, 3, 4, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(pad_test_highest_half) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::half_type, {2, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); + mm->add_instruction( + migraphx::make_op("pad", + {{"pads", {1, 1, 1, 1}}, {"value", std::numeric_limits::max()}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + const float x = std::numeric_limits::max(); + std::vector gold{x, x, x, x, x, 1, 2, x, x, 3, 4, x, x, x, x, x}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(pad_test_lowest_half) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::half_type, {2, 2}}; + auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); + mm->add_instruction( + migraphx::make_op( + "pad", {{"pads", {1, 1, 1, 1}}, {"value", std::numeric_limits::lowest()}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + const float x = std::numeric_limits::lowest(); + std::vector gold{x, x, x, x, x, 1, 2, x, x, 3, 4, x, x, x, x, x}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(pad_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4, {2}}, {2, 4, {2}}}}; + auto x = mm->add_parameter("x", s); + mm->add_instruction(migraphx::make_op("pad", {{"pads", {1, 1, 1, 1}}}), x); + p.compile(migraphx::make_target("ref")); + + std::vector data = {1, 2, 3, 4}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 2}}; + params["x"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(16); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/pointwise.cpp b/test/ref/pointwise.cpp new file mode 100644 index 00000000000..1be568b32ba --- /dev/null +++ b/test/ref/pointwise.cpp @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(pointwise_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); + auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); + auto* pm = p.create_module("pointwise"); + auto x1 = pm->add_parameter("x1", {migraphx::shape::float_type}); + auto x2 = pm->add_parameter("x2", {migraphx::shape::float_type}); + pm->add_instruction(migraphx::make_op("add"), x1, x2); + mm->add_instruction(migraphx::make_op("pointwise"), {l1, l2}, {pm}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 2, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/pooling.cpp b/test/ref/pooling.cpp new file mode 100644 index 00000000000..478a16f2d4d --- /dev/null +++ b/test/ref/pooling.cpp @@ -0,0 +1,756 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(avgpool_rank3_test) +{ + // 1D case 1, input is 3D + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {1}; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.25, 0.3, 0.25, 0.65, 0.7, 0.5, 0.4, 0.4, 0.35}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_dyn_test) +{ + // Dynamic input, no padding + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::average}, + {"lengths", {2}}, + {"padding", {0}}, + {"stride", {1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.25, 0.3, 0.25, 0.65, 0.7, 0.5, 0.4, 0.4, 0.35}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_dyn_pad_test) +{ + // Dynamic input with explicit padding/ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 3}, {3, 3}, {4, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::average}, + {"lengths", {2}}, + {"padding", {1}}, + {"stride", {1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + std::vector gold{ + 0.3, 0.25, 0.3, 0.25, 0.1, 0.8, 0.65, 0.7, 0.5, 0.1, 0.1, 0.4, 0.4, 0.35, 0.6}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_dyn_auto_pad_test) +{ + // Pooling with dynamic input, multidimensional kernel and auto-padding + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = + migraphx::shape{migraphx::shape::float_type, {{1, 1}, {1, 3}, {2, 6, {2}}, {2, 6, {2}}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction( + migraphx::make_op("pooling", + { + {"mode", migraphx::op::pooling_mode::average}, + {"dyn_global", false}, + // non-default auto padding + {"padding_mode", migraphx::op::padding_mode_t::same_upper}, + {"lengths", {2, 3}}, + }), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{1, 2, 3, 4}; + + // * 1 2 * auto padding should look like this + // * 3 4 * + // * * * * + + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 2, 2}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2.5, 2.5, 3.5, 3.5}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_dyn_auto_pad_1d_test) +{ + // Dynamic input with auto padding (== padding_mode specified) + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 3}, {3, 3}, {4, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction( + migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::average}, + {"lengths", {2}}, + // padding added will be {1, 0} to make output + // the same size as input + {"padding_mode", migraphx::op::padding_mode_t::same_lower}, + {"stride", {1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + // clang-format off + std::vector gold{0.3, 0.25, 0.3, 0.25, + 0.8, 0.65, 0.7, 0.5, + 0.1, 0.4, 0.4, 0.35}; + // clang-format on + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_dyn_pad_ceil_test) +{ + // pooling with dynamic input and padding + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {1, 3}, {2, 4}, {2, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::average}, + {"lengths", {2, 3}}, + {"padding", {1, 2}}, + {"ceil_mode", true}, + {"stride", {1, 1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{1, 2, 3, 4}; + + // * * * * * * + // * * 1 2 * * padded input will look like this + // * * 3 4 * * but the * are ignored in averaging + // * * * * * * + + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 2, 2}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + // clang-format off + std::vector gold{1.0, 1.5, 1.5, 2.0, + 2.0, 2.5, 2.5, 3.0, + 3.0, 3.5, 3.5, 4.0}; + // clang-format on + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_rank3_stride2_test) +{ + // 1D case 2, stride 2 + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 4}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; + op.lengths = {2}; + op.padding = {1}; + op.stride = {2}; + + // clang-format off + std::vector data{1.6321, -2.4186, 0.2239, -1.4232, + 0.8158, 0.4103, -0.3149, -0.1361, + -0.3442, 2.007, 0.4331, 1.5295, + 0.9965, 0.4766, 1.0942, -0.2915}; + // clang-format on + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + // clang-format off + std::vector gold{1.6321, -1.09735, -1.4232, + 0.8158, 0.0477, -0.1361, + -0.3442, 1.22005, 1.5295, + 0.9965, 0.7854, -0.2915}; + // clang-format on + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(avgpool_rank5_test) +{ + // 3D, input is 5D + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 3, 3, 3}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; + op.lengths = {2, 2, 2}; + op.padding = {0, 0, 0}; + op.stride = {1, 1, 1}; + + std::vector data{ + -0.179, -1.756, 0.651, 1.955, 1.87, -0.604, 0.247, 0.449, -0.137, 1.187, 1.593, + 0.424, 2.698, -0.104, -0.069, -1.293, 0.538, 1.291, 0.974, 1.096, 0.74, -0.669, + -1.08, -1.041, -1.407, 1.43, -0.211, -0.017, 0.532, 1.276, 0.627, 0.236, -0.396, + -0.204, 0.501, -0.599, -1.414, -0.615, -0.274, 0.168, -0.144, 0.5, 1.42, 1.082, + -0.952, -0.846, -1.244, 1.475, 1.246, 1.344, -1.722, -1.24, -0.851, 0.06, 0.507, + 0.762, -0.007, -1.484, 1.028, 0.317, 1.077, -1.289, 0.875, -0.417, -0.673, 1.715, + -0.307, 0.264, -0.973, 1.412, 2.561, -0.515, -0.201, 0.827, -1.231, 1.958, -0.552, + 0.036, -0.993, -0.859, -1.458, -0.575, 0.048, -0.779, -1.025, -1.135, 1.166, -0.131, + 0.726, 0.52, 0.467, -0.494, 0.675, 0.203, -0.63, -0.918, -0.5, -1.395, 1.39, + 1.705, 0.444, -0.835, -0.506, 0.101, 0.602, 0.543, 0.357, 1.042}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 0.908, 0.250625, 0.795, 0.40425, 0.711875, 0.194875, 0.014125, 0.09425, + -0.078375, 0.139375, 0.46075, 0.0285, -0.188125, -0.085, 0.378125, -0.085375, + -0.04, 0.304125, 0.40775, 0.2835, 0.112375, -0.073375, 0.4355, -0.187, + -0.392625, -0.258375, -0.485875, -0.0345, 0.16125, -0.131875, -0.228375, 0.068625}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globalavgpool_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; + auto lens = s.lens(); + op.lengths = {lens[2], lens[3]}; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.25, 0.575, 0.375}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globalavgpool_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6}, {2, 6, {2}}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction( + migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::average}, {"dyn_global", true}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.25, 0.575, 0.375}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globallppool_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; + auto lens = s.lens(); + op.lengths = {lens[2], lens[3]}; + op.lp_order = 2; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.5477225575051662, 1.307669683062202, 0.9327379053088815}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globallppool_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = + migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6, {2}}, {2, 6, {2}}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction( + migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::lpnorm}, {"dyn_global", true}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.5477225575051662, 1.307669683062202, 0.9327379053088815}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globalmaxpool_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; + auto lens = s.lens(); + op.lengths = {lens[2], lens[3]}; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.4, 0.9, 0.7}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(globalmaxpool_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = + migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6, {2}}, {2, 6, {2}}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction( + migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::max}, {"dyn_global", true}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.4, 0.9, 0.7}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(lppool_l1_norm_test) +{ + // L1 norm test + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {1}; + op.lp_order = 1; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.5, 0.6, 0.5, 1.3, 1.4, 1.0, 0.8, 0.8, 0.7}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +// TODO: this tests compliance with a oneDNN rule and a feature that's commented out +// in pooling.hpp +// TEST_CASE(lppool_l1_norm_err_test) +// { +// // padding too large for kernel size +// migraphx::program p; +// auto* mm = p.get_main_module(); +// auto s = migraphx::shape{migraphx::shape::float_type, {1, 2, 5}}; +// auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; +// op.lengths = {3}; +// op.padding = {2}; +// op.stride = {1}; +// op.lp_order = 1; + +// std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7}; +// auto l0 = mm->add_literal(migraphx::literal{s, data}); +// EXPECT(test::throws([&] { +// mm->add_instruction(op, l0); +// })); +// } + +TEST_CASE(lppool_l2_norm_test) +{ + // L2 norm test + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {1}; + op.lp_order = 2; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.36055512754639896, + 0.447213595499958, + 0.4123105625617661, + 0.9433981132056605, + 1.0295630140987, + 0.9055385138137417, + 0.7071067811865475, + 0.7071067811865475, + 0.6082762530298219}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(lppool_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::lpnorm}, + {"lengths", {2}}, + {"padding", {0}}, + {"stride", {1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.36055512754639896, + 0.447213595499958, + 0.4123105625617661, + 0.9433981132056605, + 1.0295630140987, + 0.9055385138137417, + 0.7071067811865475, + 0.7071067811865475, + 0.6082762530298219}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(maxpool_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + -2.1314404, -1.63041711, 1.54562736, 1.04625261, -1.42931843, -0.48703974, 0.4065806, + -0.1524526, 1.30775225, 0.45538983, -0.06631992, -1.75332725, 1.33493888, 0.47327688, + 0.36873096, 1.18358743, -0.34640595, 1.22098756, 0.01946825, -0.20238149, 0.43348005, + -0.67991608, -0.83041084, 0.93537551, 0.70241445, -0.5654031, -1.30899191, -0.26735824, + -0.52444768, 1.99097753, 1.86504853, -0.26506025, 0.26236168, 0.43763575, 0.95300823, + -1.02733946, -0.74655169, -0.5374338, -0.28901565, -0.59789604, 0.5310151, 0.99125904, + 0.40609556, -1.57175648, 0.22031412, 1.45862222, 0.53217483, 1.39087725, 1.00170159, + -0.87175864, -1.7204628, -1.72008383, -0.38656762, -0.01443311, 1.46645272, -1.39995027, + 0.22505587, -0.43461126, -0.05511411, -0.79950953, -0.01439556, 0.08795211, 1.18943918, + -0.84079367, -1.73383629, -0.55662078, -0.30626822, -0.67339015, 0.44179603, 0.54316711, + 0.40899998, -0.27831686, -1.11900508, -0.0881724, 0.35483059, 2.36277103, -0.04765317, + -0.36865309, 0.73814237, 1.47151589, 1.36546791, -0.32649881, -1.0517807, 2.24768877, + 0.68883753, 0.58646208, -0.91017133, -0.50462508, -0.4013325, -0.72348958, -0.47368807, + 0.35285577, -1.01817429, -0.5152272, 0.60321307, 0.43521205, -0.23733577, 0.66427642, + 0.82949388, 0.82443929, 0.71550399, 0.34561086, 0.68570769, -0.40718508, -1.20350206, + 0.15793853, -2.31013632, -0.07934658, -0.09348056, 0.36576006, 2.46601582, 0.11090943, + 0.9144392, 0.56759721, -0.22112127, -0.21955389, 0.72474903, -1.28448462, 1.53285873, + 0.37437943, 0.31409341, 1.95433736, 0.91620457, 0.86205518, 1.24365854, 0.19248386, + 0.22526583, 0.13462132, -0.27561715, -2.06446075, -0.02306402, -1.38278747, 1.1411345, + 1.31293464, -1.86041689, 1.06763375, -0.26541466, 1.4545635, 1.11430049, -0.66491818, + 0.87101674, 0.67768967, -1.02062869, -1.05031872, -2.2764678, -2.0200038, 0.37592548, + -0.26701379, -0.83388507, 0.19403623, 1.00968623, 0.11020003, 1.16736257, -1.1160326, + 0.47346735, 0.6126079, -0.19135755, 1.33624589, -0.29802522, -0.57873946, -1.06555879, + -0.20686582, 1.36892557, -0.19937795, 0.8649236, -1.40126073, 1.53441942, 0.34682792, + -1.31724346, -1.32898355, 2.40126371, 0.07845283, 1.35732043, -0.63678312, 0.39429256, + -1.36487007, -0.31026676, -0.44981545, -0.28994772, -0.14657612, -1.75206447, -0.70612341, + 1.20071781, -1.64647579, -0.7133292, 0.88494766, 0.52119428, -2.77387547, 2.07681108, + -0.90133125, 0.2847338, 0.6174528, -0.20616426, -0.64263535, -1.08496261, 0.54275119, + -0.88503587, 0.6629802, 1.47319221, -1.05829155, -0.97027361, -0.93187737, -1.39954746, + -0.52359426, -0.14743951, 1.51522756, 0.2078452, -1.28156149, -1.19363916, -0.78680223, + -0.89094824, 1.30212069, -0.77974445, -0.58411664, 0.48764706, -0.67132682}; + std::vector c = {1.33493888, 1.54562736, 1.22098756, 1.33493888, 1.18358743, 1.99097753, + 1.00170159, 1.45862222, 1.39087725, 1.46645272, 1.18943918, -0.01443311, + 1.47151589, 2.36277103, 2.24768877, 0.68883753, 0.82949388, 0.71550399, + 1.95433736, 2.46601582, 1.53285873, 1.95433736, 1.06763375, 1.4545635, + 1.33624589, 1.16736257, 0.6126079, 1.36892557, 2.40126371, 1.53441942, + 0.52119428, 2.07681108, 0.88494766, 1.51522756, 0.54275119, 0.6629802}; + migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 6, 6}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::max}, + {"padding", {0, 0}}, + {"stride", {2, 2}}, + {"lengths", {3, 2}}}), + al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(36); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, c)); +} + +TEST_CASE(maxpool_pad_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = {-6, -5, -4, -3, -5, -1, 0, 1, 2, 3, 4, 5}; + std::vector c = {-4, -3, -4, -1, 2, 3, 4, 5}; + migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 3, 2}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::max}, + {"padding", {1, 1}}, + {"stride", {2, 2}}, + {"lengths", {3, 2}}}), + al); + + // * * * * * * * * + // * -6 -5 * * 0 1 * + // * -4 -3 * padding will look like this * 2 3 * + // * -5 -1 * and this * 4 5 * + // * * * * The * values are actually -INF * * * * + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(8); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, c)); +} + +TEST_CASE(maxpool_rank3_test0) +{ + // 1D case 1, input is 3D + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {1}; + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.3, 0.4, 0.4, 0.8, 0.9, 0.9, 0.7, 0.7, 0.6}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(maxpool_rank3_test1) +{ + // 1D case 2, input is 3D + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 5}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {2}; + + std::vector data{0.4975, -0.1226, -0.0405, -0.2861, -0.1227, -0.6186, -0.9618, + 0.6022, -0.1912, 1.1925, 0.5493, 0.1692, -0.8039, -1.0281, + 0.9907, 0.477, 1.5001, -1.1603, -1.361, 1.2556}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.4975, -0.0405, -0.6186, 0.6022, 0.5493, -0.8039, 1.5001, -1.1603}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(maxpool_rank3_ceil_test) +{ + // 1D case 2, input is 3D, ceil mode + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 5}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; + op.lengths = {2}; + op.padding = {0}; + op.stride = {2}; + op.ceil_mode = true; + + // clang-format off + std::vector data{0.4975, -0.1226, -0.0405, -0.2861, -0.1227, + -0.6186, -0.9618, 0.6022, -0.1912, 1.1925, + 0.5493, 0.1692, -0.8039, -1.0281, 0.9907, + 0.477, 1.5001, -1.1603, -1.361, 1.2556}; + // clang-format on + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + // clang-format off + std::vector gold{0.4975, -0.0405, -0.1227, -0.6186, + 0.6022, 1.1925, 0.5493, -0.8039, + 0.9907, 1.5001, -1.1603, 1.2556}; + // clang-format on + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(maxpool_rank5_test) +{ + // 3D, input is 5D + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 3, 3, 3}}; + auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; + op.lengths = {2, 2, 2}; + op.padding = {0, 0, 0}; + op.stride = {2, 2, 2}; + + std::vector data{ + -2.8029, 0.5861, 0.7015, 0.1297, -1.44, -1.9472, 0.7812, 2.408, -0.3145, 0.3405, + -0.9146, 0.0624, 1.5064, -0.8345, 1.7977, 1.8949, 1.0073, -0.2102, -0.042, -0.7146, + 0.6227, -0.5263, -2.2598, 0.1713, 0.449, 0.5303, -0.8622, -0.5691, 0.907, -0.0569, + -1.5348, -0.4109, -0.1461, -0.5445, 0.4266, 0.2282, 1.3655, -2.1519, 0.6068, -0.2001, + -0.4702, 0.3864, 1.7083, 0.9096, 0.4286, -1.8866, 0.7034, 0.0293, 1.4587, 0.7672, + -2.8614, 0.8124, -0.053, 1.0449, 0.845, -0.0131, 0.1139, -0.859, -1.2681, -0.6337, + -0.4644, 0.1938, 0.2889, 0.9035, 0.7118, -0.5767, 0.4577, -0.0549, 0.2237, 0.5756, + 0.0677, -0.0223, -0.329, 0.2364, 2.7666, -0.7417, -1.3196, -0.2655, 0.1698, -0.1777, + -0.9427, 2.6859, -0.7501, 0.5175, 1.0029, -2.6436, -0.4388, -1.2348, -0.1539, -0.6229, + -0.4136, 0.5085, 0.4136, -0.6439, -1.1953, -0.406, -0.0195, 0.1869, -0.8664, 1.1364, + 0.5041, 0.0647, 0.1941, -1.0819, -0.4629, -0.5107, 0.3612, -0.3583}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(op, l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.5064, 1.3655, 0.9035, 2.6859}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(maxpool_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; + auto x = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("pooling", + {{"mode", migraphx::op::pooling_mode::max}, + {"lengths", {2}}, + {"padding", {0}}, + {"stride", {1}}}), + x); + p.compile(migraphx::make_target("ref")); + + std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; + migraphx::parameter_map params; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.3, 0.4, 0.4, 0.8, 0.9, 0.9, 0.7, 0.7, 0.6}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/pow.cpp b/test/ref/pow.cpp new file mode 100644 index 00000000000..41b839aac54 --- /dev/null +++ b/test/ref/pow.cpp @@ -0,0 +1,74 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(pow_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data = {1, 2, 3}; + auto b = mm->add_literal(migraphx::literal{s, data}); + auto e = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("pow"), b, e); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::pow(n, n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(pow_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto b = mm->add_parameter("b", s); + auto e = mm->add_parameter("e", s); + mm->add_instruction(migraphx::make_op("pow"), b, e); + p.compile(migraphx::make_target("ref")); + + std::vector data = {1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["b"] = migraphx::argument(input_fixed_shape0, data.data()); + params0["e"] = migraphx::argument(input_fixed_shape0, data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::pow(n, n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/prefix_scan_sum.cpp b/test/ref/prefix_scan_sum.cpp new file mode 100644 index 00000000000..815f77314ae --- /dev/null +++ b/test/ref/prefix_scan_sum.cpp @@ -0,0 +1,302 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(prefix_scan_sum_1d) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {6}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.0, 3.0, 6.0, 10.0, 15.0, 21.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_dyn_1d) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{5, 8}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), + input); + p.compile(migraphx::make_target("ref")); + + std::vector a = {1, 2, 3, 4, 5, 6}; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {6}}; + migraphx::parameter_map params0; + params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); + + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.0, 3.0, 6.0, 10.0, 15.0, 21.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_2d_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_2d_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_3d_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 2.0, 4.0, 6.0, 2.0, 4.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_3d_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_3d_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 2}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_exclusive_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {8}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", true}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0.0, 1.0, 3.0, 6.0, 10.0, 11.0, 13.0, 16.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_exclusive_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", true}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_exclusive_reverse) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {6}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6}}; + auto l0 = mm->add_literal(input); + mm->add_instruction( + migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", true}, {"reverse", true}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{20.0, 18.0, 15.0, 11.0, 6.0, 0.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_negative_axis_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", -3}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 2.0, 4.0, 6.0, 2.0, 4.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_negative_axis_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", -2}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0, 1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_negative_axis_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", -1}, {"exclusive", false}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_reverse_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {8}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", + {{"axis", 0}, {"exclusive", false}, {"reverse", true}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{20.0, 19.0, 17.0, 14.0, 10.0, 9.0, 7.0, 4.0}; + EXPECT(results_vector == gold); +} + +TEST_CASE(prefix_scan_sum_reverse_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("prefix_scan_sum", + {{"axis", 0}, {"exclusive", false}, {"reverse", true}}), + l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2.0, 4.0, 6.0, 8.0, 1.0, 2.0, 3.0, 4.0}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/prelu.cpp b/test/ref/prelu.cpp new file mode 100644 index 00000000000..89a1b66a6aa --- /dev/null +++ b/test/ref/prelu.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(prelu_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto x = mm->add_literal(migraphx::literal{s, {-1, 0, 2}}); + auto slope = mm->add_literal(migraphx::literal{s, {2, 1, 2}}); + mm->add_instruction(migraphx::make_op("prelu"), x, slope); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2.0f, 0.0f, 2.0f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(prelu_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto slope = mm->add_parameter("slope", s); + mm->add_instruction(migraphx::make_op("prelu"), x, slope); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1, 0, 2}; + std::vector slope_data{2, 1, 2}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["slope"] = migraphx::argument(input_fixed_shape0, slope_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2.0f, 0.0f, 2.0f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/quant_convolution.cpp b/test/ref/quant_convolution.cpp new file mode 100644 index 00000000000..64c0d7991af --- /dev/null +++ b/test/ref/quant_convolution.cpp @@ -0,0 +1,137 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(quant_conv2d_padding_stride_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; + std::vector a(2 * 3 * 4 * 4); + std::iota(a.begin(), a.end(), 0); + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; + std::vector c(2 * 3 * 3 * 3); + std::iota(c.begin(), c.end(), 0); + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + mm->add_instruction( + migraphx::make_op("quant_convolution", {{"padding", {1, 1}}, {"stride", {2, 2}}}), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector s = {4521, + 7014, + 7830, + 11952, + 10515, + 16734, + 19737, + 30906, + 13161, + 19542, + 19494, + 28800, + 34707, + 52590, + 54729, + 82746}; + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(quant_conv2d_padding_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; + std::vector a(2 * 3 * 4 * 4); + std::iota(a.begin(), a.end(), 0); + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; + std::vector c(2 * 3 * 3 * 3); + std::iota(c.begin(), c.end(), 0); + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + mm->add_instruction( + migraphx::make_op("quant_convolution", {{"padding", {1, 1}}, {"stride", {1, 1}}}), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector s = { + 4521, 6753, 7014, 4635, 6858, 10197, 10548, 6939, 7830, 11601, 11952, 7839, 5007, + 7383, 7590, 4953, 10515, 15987, 16734, 11277, 16821, 25506, 26586, 17874, 19737, 29826, + 30906, 20718, 13593, 20505, 21198, 14187, 13161, 19281, 19542, 12699, 18522, 27045, 27396, + 17739, 19494, 28449, 28800, 18639, 11919, 17319, 17526, 11289, 34707, 51843, 52590, 34893, + 51813, 77346, 78426, 52002, 54729, 81666, 82746, 54846, 36057, 53769, 54462, 36075}; + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(quant_conv2d_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; + std::vector a(2 * 3 * 4 * 4); + std::iota(a.begin(), a.end(), 0); + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + + migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; + std::vector c(2 * 3 * 3 * 3); + std::iota(c.begin(), c.end(), 0); + auto cl = mm->add_literal(migraphx::literal{c_shape, c}); + + mm->add_instruction(migraphx::make_op("quant_convolution"), al, cl); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + + std::vector s = {10197, + 10548, + 11601, + 11952, + 25506, + 26586, + 29826, + 30906, + 27045, + 27396, + 28449, + 28800, + 77346, + 78426, + 81666, + 82746}; + + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} diff --git a/test/ref/quantizelinear.cpp b/test/ref/quantizelinear.cpp new file mode 100644 index 00000000000..719e77e3c39 --- /dev/null +++ b/test/ref/quantizelinear.cpp @@ -0,0 +1,85 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(quantizelinear_1) +{ + migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}}; + std::vector xv = { + -300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550}; + migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}}; + std::vector sv = {2, 2, 2, 4, 4, 4, 6, 6, 6, 2, 2, 2, 4, 4, 4, 6, 6, 6}; + migraphx::shape zs{migraphx::shape::int8_type, {2, 3, 3}}; + std::vector zv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + auto create_program = [&]() { + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(xs, xv); + auto s = mm->add_literal(ss, sv); + auto z = mm->add_literal(zs, zv); + mm->add_instruction(migraphx::make_op("quantizelinear"), x, s, z); + return p; + }; + + migraphx::program p1 = create_program(); + p1.compile(migraphx::make_target("ref")); + auto result = p1.eval({}).back(); + std::vector results_vector(18); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{ + -128, 127, 65, -128, 1, 1, -1, 100, 92, -128, 127, 65, -128, 1, 1, -1, 100, 92}; + EXPECT(results_vector == gold); +} + +TEST_CASE(quantizelinear_2) +{ + migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}}; + std::vector xv = { + -300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550}; + migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}}; + std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + auto create_program = [&]() { + migraphx::program p; + auto* mm = p.get_main_module(); + auto x = mm->add_literal(xs, xv); + auto s = mm->add_literal(ss, sv); + mm->add_instruction(migraphx::make_op("quantizelinear"), x, s); + return p; + }; + + migraphx::program p1 = create_program(); + p1.compile(migraphx::make_target("ref")); + auto result = p1.eval({}).back(); + std::vector results_vector(18); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 255, 65, 0, 2, 2, 0, 255, 255, 0, 255, 65, 0, 2, 2, 0, 255, 255}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/recip.cpp b/test/ref/recip.cpp new file mode 100644 index 00000000000..6d9ef63acb9 --- /dev/null +++ b/test/ref/recip.cpp @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(recip_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::double_type, {3}}; + std::vector data{-0.5f, 0.1f, 0.5f}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("recip"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2.0f, 10.0f, 2.0f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(recip_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("recip"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-0.5f, 0.1f, 0.5f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2.0f, 10.0f, 2.0f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/reduce_max.cpp b/test/ref/reduce_max.cpp new file mode 100644 index 00000000000..df4fc87f25e --- /dev/null +++ b/test/ref/reduce_max.cpp @@ -0,0 +1,100 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reduce_max_axis0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{9, 10, 11, 12}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_max_dynamic_axis0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4, {2}}, {3, 5, {3}}}}; + auto input = mm->add_parameter("X", s); + auto reduce_max_op = migraphx::make_op("reduce_max", {{"axes", {0}}}); + mm->add_instruction(reduce_max_op, input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 5}}; + std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + params["X"] = migraphx::argument(input_fixed_shape, input_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {6, 7, 8, 9, 10}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(reduce_max_axis01) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0, 1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{11, 12}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_max_axis02) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{10, 12}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/reduce_mean.cpp b/test/ref/reduce_mean.cpp new file mode 100644 index 00000000000..cfa0be80a4e --- /dev/null +++ b/test/ref/reduce_mean.cpp @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reduce_mean_axis02) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {0, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{5.5, 7.5}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_mean_axis1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2, 3, 6, 7, 10, 11}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_mean_axis12) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2.5f, 6.5f, 10.5f}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_mean_axis2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1.5f, 3.5f, 5.5f, 7.5f, 9.5f, 11.5f}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_mean_int) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2, 6, 10}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/reduce_min.cpp b/test/ref/reduce_min.cpp new file mode 100644 index 00000000000..377e64adb37 --- /dev/null +++ b/test/ref/reduce_min.cpp @@ -0,0 +1,79 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reduce_min_axis02) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {0, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 3}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_min_axis1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 2, 5, 6, 9, 10}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_min_axis12) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {1, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 5, 9}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/reduce_prod.cpp b/test/ref/reduce_prod.cpp new file mode 100644 index 00000000000..5de50ec88dd --- /dev/null +++ b/test/ref/reduce_prod.cpp @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reduce_prod_axis0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {4, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 3, 2, 3}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_prod", {{"axes", {0}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{6, 18, 12, 18}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/reduce_sum.cpp b/test/ref/reduce_sum.cpp new file mode 100644 index 00000000000..ff596e9ad2e --- /dev/null +++ b/test/ref/reduce_sum.cpp @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reduce_sum_axis0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {0}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{15, 18, 21, 24}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_sum_axis02) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {0, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{33, 45}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_sum_axis1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{4, 6, 12, 14, 20, 22}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_sum_axis12) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1, 2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{10, 26, 42}; + EXPECT(results_vector == gold); +} + +TEST_CASE(reduce_sum_axis2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; + auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; + auto l0 = mm->add_literal(input); + mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{3, 7, 11, 15, 19, 23}; + EXPECT(results_vector == gold); +} diff --git a/test/ref/relu.cpp b/test/ref/relu.cpp new file mode 100644 index 00000000000..59af3449506 --- /dev/null +++ b/test/ref/relu.cpp @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(relu_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l = mm->add_literal(migraphx::literal{s, {-1.f, 0.f, 1.f}}); + mm->add_instruction(migraphx::make_op("relu"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.f, 0.f, 1.f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(relu_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("relu"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1.f, 0.f, 1.f}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.f, 0.f, 1.f}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/reshape.cpp b/test/ref/reshape.cpp new file mode 100644 index 00000000000..00d0db33291 --- /dev/null +++ b/test/ref/reshape.cpp @@ -0,0 +1,103 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reshape_test0) +{ + migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; + std::vector data(24); + std::iota(data.begin(), data.end(), -3); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + std::vector new_shape = {8, 3, 1, 1}; + mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector{}; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, data)); +} + +TEST_CASE(reshape_test1) +{ + migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; + std::vector data(24); + std::iota(data.begin(), data.end(), -3); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + std::vector new_shape = {1, 3, 4, 2}; + mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector{}; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, data)); +} + +TEST_CASE(reshape_test2) +{ + migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; + std::vector data(24); + std::iota(data.begin(), data.end(), -3); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + std::vector new_shape = {1, 2, 3, 4}; + mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector{}; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, data)); +} + +TEST_CASE(reshape_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {24, 24}, {1, 1}, {1, 1}}}; + std::vector new_shape = {0, 8, 3, 1}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), input); + p.compile(migraphx::make_target("ref")); + + std::vector data(48); + std::iota(data.begin(), data.end(), -3); + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 24, 1, 1}}; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + std::vector results_vector{}; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, data)); +} diff --git a/test/ref/reverse.cpp b/test/ref/reverse.cpp new file mode 100644 index 00000000000..0b5057eae53 --- /dev/null +++ b/test/ref/reverse.cpp @@ -0,0 +1,91 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(reverse_test_axis0) +{ + migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; + std::vector data(32); + std::iota(data.begin(), data.end(), 1); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{in_shape, data}); + std::vector axes = {0}; + mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector target_data = data; + std::swap_ranges(target_data.begin(), target_data.begin() + 16, target_data.begin() + 16); + EXPECT(migraphx::verify::verify_range(results_vector, target_data)); +} + +TEST_CASE(reverse_test_axis1) +{ + migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; + std::vector data(32); + std::iota(data.begin(), data.end(), 1); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{in_shape, data}); + std::vector axes = {1}; + mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector target_data = data; + std::reverse(target_data.begin(), target_data.begin() + 16); + std::reverse(target_data.end() - 16, target_data.end()); + EXPECT(migraphx::verify::verify_range(results_vector, target_data)); +} + +TEST_CASE(reverse_test_axis10) +{ + migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; + std::vector data(32); + std::iota(data.begin(), data.end(), 1); + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{in_shape, data}); + std::vector axes = {1, 0}; + mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector target_data = data; + std::reverse(target_data.begin(), target_data.begin() + 16); + std::reverse(target_data.end() - 16, target_data.end()); + std::swap_ranges(target_data.begin(), target_data.begin() + 16, target_data.begin() + 16); + EXPECT(migraphx::verify::verify_range(results_vector, target_data)); +} diff --git a/test/ref_rnn_ops_test.cpp b/test/ref/rnn_ops.cpp similarity index 98% rename from test/ref_rnn_ops_test.cpp rename to test/ref/rnn_ops.cpp index df0f7ae8437..23e287e545f 100644 --- a/test/ref_rnn_ops_test.cpp +++ b/test/ref/rnn_ops.cpp @@ -400,7 +400,6 @@ TEST_CASE(rnn_reverse) migraphx::shape ih_shape{migraphx::shape::float_type, {num_dirct, batch_size, hidden_size}}; // concatenation of hidden states as program output { - migraphx::program p; auto* mm = p.get_main_module(); auto seq = mm->add_literal(migraphx::literal{in_shape, input}); @@ -1736,12 +1735,12 @@ TEST_CASE(gru_reverse) migraphx::make_op( "gru", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, - {"clip", clip}, - {"linear_before_reset", 1}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, + {"clip", clip}, + {"linear_before_reset", 1}}), seq, w, r, @@ -2067,12 +2066,12 @@ TEST_CASE(gru_bidirectional) migraphx::make_op( "gru", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"linear_before_reset", 1}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"linear_before_reset", 1}}), seq, w, r, @@ -3769,13 +3768,13 @@ TEST_CASE(lstm_reverse) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -3811,10 +3810,10 @@ TEST_CASE(lstm_reverse) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", {}}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", {}}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::reverse)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -4187,13 +4186,13 @@ TEST_CASE(lstm_bidirectional) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r, @@ -4230,13 +4229,13 @@ TEST_CASE(lstm_bidirectional) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r, @@ -4714,12 +4713,12 @@ TEST_CASE(lstm_bidirectional_actv_func) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -4747,15 +4746,15 @@ TEST_CASE(lstm_bidirectional_actv_func) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value( + {"actv_func", + migraphx::to_value( std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh"), - migraphx::make_op("sigmoid")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + migraphx::make_op("tanh"), + migraphx::make_op("tanh"), + migraphx::make_op("sigmoid")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -4783,15 +4782,15 @@ TEST_CASE(lstm_bidirectional_actv_func) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh"), - migraphx::make_op("sigmoid"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh"), + migraphx::make_op("sigmoid"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -4819,16 +4818,16 @@ TEST_CASE(lstm_bidirectional_actv_func) migraphx::make_op( "lstm", {{"hidden_size", hidden_size}, - {"actv_func", - migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh"), - migraphx::make_op("sigmoid"), - migraphx::make_op("tanh"), - migraphx::make_op("tanh")})}, - {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, - {"clip", clip}, - {"input_forget", 0}}), + {"actv_func", + migraphx::to_value(std::vector{migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh"), + migraphx::make_op("sigmoid"), + migraphx::make_op("tanh"), + migraphx::make_op("tanh")})}, + {"direction", migraphx::to_value(migraphx::op::rnn_direction::bidirectional)}, + {"clip", clip}, + {"input_forget", 0}}), seq, w, r); @@ -4989,5 +4988,3 @@ TEST_CASE(lstm_fp16) 0.135643, -0.0566208, 0.142701, 0.0342236, -0.198664, 0.0702607}; EXPECT(migraphx::verify::verify_range(hs_data, hs_data_gold, 5e4)); } - -int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/ref/roialign.cpp b/test/ref/roialign.cpp new file mode 100644 index 00000000000..644b3cb43ca --- /dev/null +++ b/test/ref/roialign.cpp @@ -0,0 +1,197 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(roialign_out_of_bound_test) +{ + auto create_program = [](const std::string& trans_mode = "half_pixel") { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape x_s{migraphx::shape::float_type, {1, 1, 10, 10}}; + std::vector x_vec = { + 0.2764, 0.7150, 0.1958, 0.3416, 0.4638, 0.0259, 0.2963, 0.6518, 0.4856, 0.7250, + 0.9637, 0.0895, 0.2919, 0.6753, 0.0234, 0.6132, 0.8085, 0.5324, 0.8992, 0.4467, + 0.3265, 0.8479, 0.9698, 0.2471, 0.9336, 0.1878, 0.4766, 0.4308, 0.3400, 0.2162, + 0.0206, 0.1720, 0.2155, 0.4394, 0.0653, 0.3406, 0.7724, 0.3921, 0.2541, 0.5799, + 0.4062, 0.2194, 0.4473, 0.4687, 0.7109, 0.9327, 0.9815, 0.6320, 0.1728, 0.6119, + 0.3097, 0.1283, 0.4984, 0.5068, 0.4279, 0.0173, 0.4388, 0.0430, 0.4671, 0.7119, + 0.1011, 0.8477, 0.4726, 0.1777, 0.9923, 0.4042, 0.1869, 0.7795, 0.9946, 0.9689, + 0.1366, 0.3671, 0.7011, 0.6234, 0.9867, 0.5585, 0.6985, 0.5609, 0.8788, 0.9928, + 0.5697, 0.8511, 0.6711, 0.9406, 0.8751, 0.7496, 0.1650, 0.1049, 0.1559, 0.2514, + 0.7012, 0.4056, 0.7879, 0.3461, 0.0415, 0.2998, 0.5094, 0.3727, 0.5482, 0.0502}; + + migraphx::shape roi_s{migraphx::shape::float_type, {3, 4}}; + std::vector roi_vec = {0, 0, 9.99, 9.99, 0, 5, 4, 9, 5, 5, 9.9, 9.9}; + + migraphx::shape ind_s{migraphx::shape::int64_type, {3}}; + std::vector ind_vec = {0, 0, 0}; + + auto x = mm->add_literal(migraphx::literal(x_s, x_vec)); + auto roi = mm->add_literal(migraphx::literal(roi_s, roi_vec)); + auto ind = mm->add_literal(migraphx::literal(ind_s, ind_vec)); + auto r = + mm->add_instruction(migraphx::make_op("roialign", + {{"coordinate_transformation_mode", trans_mode}, + {"spatial_scale", 5.0}, + {"output_height", 1}, + {"output_width", 1}, + {"sampling_ratio", 1}}), + x, + roi, + ind); + mm->add_return({r}); + return p; + }; + + { + auto p = create_program("output_half_pixel"); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.0f, 0.0f, 0.0f}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} + +TEST_CASE(roialign_test) +{ + auto create_program = [](const std::string& trans_mode = "half_pixel", + const migraphx::op::pooling_mode pooling_mode = + migraphx::op::pooling_mode::average, + int64_t sampling_ratio = 2) { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape x_s{migraphx::shape::float_type, {1, 1, 10, 10}}; + std::vector x_vec = { + 0.2764, 0.7150, 0.1958, 0.3416, 0.4638, 0.0259, 0.2963, 0.6518, 0.4856, 0.7250, + 0.9637, 0.0895, 0.2919, 0.6753, 0.0234, 0.6132, 0.8085, 0.5324, 0.8992, 0.4467, + 0.3265, 0.8479, 0.9698, 0.2471, 0.9336, 0.1878, 0.4766, 0.4308, 0.3400, 0.2162, + 0.0206, 0.1720, 0.2155, 0.4394, 0.0653, 0.3406, 0.7724, 0.3921, 0.2541, 0.5799, + 0.4062, 0.2194, 0.4473, 0.4687, 0.7109, 0.9327, 0.9815, 0.6320, 0.1728, 0.6119, + 0.3097, 0.1283, 0.4984, 0.5068, 0.4279, 0.0173, 0.4388, 0.0430, 0.4671, 0.7119, + 0.1011, 0.8477, 0.4726, 0.1777, 0.9923, 0.4042, 0.1869, 0.7795, 0.9946, 0.9689, + 0.1366, 0.3671, 0.7011, 0.6234, 0.9867, 0.5585, 0.6985, 0.5609, 0.8788, 0.9928, + 0.5697, 0.8511, 0.6711, 0.9406, 0.8751, 0.7496, 0.1650, 0.1049, 0.1559, 0.2514, + 0.7012, 0.4056, 0.7879, 0.3461, 0.0415, 0.2998, 0.5094, 0.3727, 0.5482, 0.0502}; + + migraphx::shape roi_s{migraphx::shape::float_type, {3, 4}}; + std::vector roi_vec = {0, 0, 9, 9, 0, 5, 4, 9, 5, 5, 9, 9}; + + migraphx::shape ind_s{migraphx::shape::int64_type, {3}}; + std::vector ind_vec = {0, 0, 0}; + + auto x = mm->add_literal(migraphx::literal(x_s, x_vec)); + auto roi = mm->add_literal(migraphx::literal(roi_s, roi_vec)); + auto ind = mm->add_literal(migraphx::literal(ind_s, ind_vec)); + auto r = + mm->add_instruction(migraphx::make_op("roialign", + {{"coordinate_transformation_mode", trans_mode}, + {"spatial_scale", 1.0}, + {"output_height", 5}, + {"output_width", 5}, + {"sampling_ratio", sampling_ratio}, + {"mode", pooling_mode}}), + x, + roi, + ind); + mm->add_return({r}); + return p; + }; + + { + auto p = create_program(); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = { + 0.466421425, 0.446552634, 0.340521216, 0.568848491, 0.606780827, 0.371379346, + 0.429571986, 0.383519977, 0.556241512, 0.351050019, 0.27680251, 0.488286227, + 0.522200167, 0.552770197, 0.417057365, 0.471240699, 0.4844096, 0.690457463, + 0.492039412, 0.877398551, 0.623889625, 0.712461948, 0.628926516, 0.335504025, + 0.349469036, 0.302179992, 0.43046391, 0.469585985, 0.39774403, 0.542259991, + 0.365552008, 0.704923987, 0.516481996, 0.317131996, 0.701444089, 0.291239977, + 0.505897999, 0.647610962, 0.623489916, 0.829879999, 0.591567993, 0.738860011, + 0.704825997, 0.837148011, 0.889315963, 0.622680008, 0.615276039, 0.709713995, + 0.615356028, 0.458524048, 0.238451958, 0.337952018, 0.371693879, 0.609999895, + 0.760059953, 0.376724035, 0.378532052, 0.71468991, 0.924308002, 0.972783983, + 0.574903965, 0.582623959, 0.570936024, 0.761904061, 0.876998067, 0.535508037, + 0.256580025, 0.214098021, 0.279604018, 0.360000014, 0.436488032, 0.350427985, + 0.288755983, 0.366139978, 0.234920025}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } + + { + auto p = create_program("output_half_pixel"); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = { + 0.517783, 0.343411, 0.322905, 0.447362, 0.634375, 0.40308, 0.536647, 0.442791, + 0.486144, 0.402313, 0.251194, 0.400154, 0.515524, 0.695369, 0.346537, 0.33504, + 0.460099, 0.588069, 0.343863, 0.684932, 0.49319, 0.714058, 0.821744, 0.471935, + 0.403946, 0.306955, 0.218678, 0.33369, 0.488001, 0.486962, 0.18709, 0.49142, + 0.55611, 0.419167, 0.368608, 0.143278, 0.460835, 0.597125, 0.53096, 0.498207, + 0.278818, 0.438569, 0.6022, 0.700038, 0.752436, 0.577385, 0.702383, 0.725097, + 0.733754, 0.816304, 0.23933, 0.407514, 0.337893, 0.252521, 0.474335, 0.367075, + 0.270168, 0.41051, 0.64189, 0.830777, 0.55564, 0.454295, 0.55645, 0.75015, + 0.929997, 0.66257, 0.561664, 0.481275, 0.495449, 0.666306, 0.663573, 0.372107, + 0.205603, 0.192776, 0.247849}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } + + { + auto p = create_program("output_half_pixel", migraphx::op::pooling_mode::max, 0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = { + 0.819145, 0.373103, 0.258302, 0.515419, 0.726104, 0.540536, 0.545512, 0.38511, + 0.376545, 0.274635, 0.22341, 0.184511, 0.230843, 0.404869, 0.29546, 0.540409, + 0.265838, 0.409324, 0.213915, 0.708654, 0.687264, 0.580821, 0.461283, 0.462879, + 0.709632, 0.27873, 0.083619, 0.22428, 0.313992, 0.410508, 0.0929099, 0.415373, + 0.296695, 0.231574, 0.136836, 0.0683, 0.296695, 0.211925, 0.245385, 0.28053, + 0.17091, 0.179879, 0.245385, 0.343539, 0.392742, 0.51273, 0.536193, 0.382995, + 0.422793, 0.761886, 0.0839429, 0.276444, 0.19746, 0.126117, 0.378351, 0.254646, + 0.092148, 0.272825, 0.381955, 0.626599, 0.251325, 0.244475, 0.194875, 0.272825, + 0.44757, 0.351855, 0.342265, 0.244475, 0.274841, 0.553644, 0.607176, 0.202392, + 0.07425, 0.066087, 0.126279}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} diff --git a/test/ref/round.cpp b/test/ref/round.cpp new file mode 100644 index 00000000000..4e060e04288 --- /dev/null +++ b/test/ref/round.cpp @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(round_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {9}}; + auto l = + mm->add_literal(migraphx::literal{s, {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}}); + mm->add_instruction(migraphx::make_op("round"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {1.0, 2.0, 2.0, -1.0, -2.0, -2.0, 0.0, 2.0, -2.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(round_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{4, 10}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("round"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {1.0, 2.0, 2.0, -1.0, -2.0, -2.0, 0.0, 2.0, -2.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/rsqrt.cpp b/test/ref/rsqrt.cpp new file mode 100644 index 00000000000..2664a7c9deb --- /dev/null +++ b/test/ref/rsqrt.cpp @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(rsqrt_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l = mm->add_literal(migraphx::literal{s, {4.0, 16.0, 64.0}}); + mm->add_instruction(migraphx::make_op("rsqrt"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.5, 0.25, 0.125}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(rsqrt_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("rsqrt"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{4.0, 16.0, 64.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.5, 0.25, 0.125}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/scalar.cpp b/test/ref/scalar.cpp new file mode 100644 index 00000000000..c128e420f69 --- /dev/null +++ b/test/ref/scalar.cpp @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(imagescaler_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {1, 3, 2, 2}}; + auto img = mm->add_literal(migraphx::literal{s, + {0.2, + 0.3, + 0.5, + 0.4, + + 0.7, + 0.8, + 0.1, + 0.9, + + 0.15, + 0.25, + 0.35, + 0.45}}); + auto scale_val = mm->add_literal(2.f); + auto scaled_tensor = mm->add_instruction( + migraphx::make_op("scalar", {{"scalar_bcst_dims", s.lens()}}), scale_val); + auto img_scaled = mm->add_instruction(migraphx::make_op("mul"), img, scaled_tensor); + auto bias_vals = mm->add_literal( + migraphx::literal{migraphx::shape{migraphx::shape::float_type, {3}}, {0.01, 0.02, 0.03}}); + auto bias_bcast = mm->add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", s.lens()}}), bias_vals); + mm->add_instruction(migraphx::make_op("add"), img_scaled, bias_bcast); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0.41, + 0.61, + 1.01, + 0.81, + + 1.42, + 1.62, + 0.22, + 1.82, + + 0.33, + 0.53, + 0.73, + 0.93}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/scatter.cpp b/test/ref/scatter.cpp new file mode 100644 index 00000000000..5fce7b9fe73 --- /dev/null +++ b/test/ref/scatter.cpp @@ -0,0 +1,255 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +// reduction_mode: "scatter_none", "scatter_add", "scatter_mul" +migraphx::program create_scatter_program(const std::string& reduction_mode, int axis) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; + std::vector vd(sd.elements(), 0.0f); + + migraphx::shape si{migraphx::shape::int32_type, {2, 3}}; + std::vector vi = {1, 0, 2, 0, 2, 1}; + + migraphx::shape su{migraphx::shape::float_type, {2, 3}}; + std::vector vu = {1.0, 1.1, 1.2, 2.0, 2.1, 2.2}; + + auto ld = mm->add_literal(migraphx::literal{sd, vd}); + auto li = mm->add_literal(migraphx::literal{si, vi}); + auto lu = mm->add_literal(migraphx::literal{su, vu}); + // scatter_none, formerly the scatter op + auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); + mm->add_return({r}); + return p; +} + +TEST_CASE(scatter_ax0_test) +{ + // this tests what used to be the only scatter op, now changed to 3 sub-ops + // which have their own test case + { + migraphx::program p = create_scatter_program("scatter_none", 0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {2.0, 1.1, 0.0, 1.0, 0.0, 2.2, 0.0, 2.1, 1.2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} + +TEST_CASE(scatter_ax_neg_test) +{ + { + migraphx::program p = create_scatter_program("scatter_none", -2); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {2.0, 1.1, 0.0, 1.0, 0.0, 2.2, 0.0, 2.1, 1.2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} + +TEST_CASE(scatter_ax1_test) +{ + { + migraphx::program p = create_scatter_program("scatter_none", 1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {1.1, 1.0, 1.2, 2.0, 2.2, 2.1, 0.0, 0.0, 0.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} + +// similar to create_scatter_program but with different tensor values +// reduction_mode: "scatter_none", "scatter_add", "scatter_mul" +migraphx::program create_scatter_program2(const std::string& reduction_mode, int axis) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sd{migraphx::shape::float_type, {1, 5}}; + std::vector vd({1., 2., 3., 4., 5.}); + + migraphx::shape si{migraphx::shape::int32_type, {1, 2}}; + std::vector vi = {1, 3}; + + migraphx::shape su{migraphx::shape::float_type, {1, 2}}; + std::vector vu = {1.1, 2.1}; + + auto ld = mm->add_literal(migraphx::literal{sd, vd}); + auto li = mm->add_literal(migraphx::literal{si, vi}); + auto lu = mm->add_literal(migraphx::literal{su, vu}); + auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); + mm->add_return({r}); + return p; +} +TEST_CASE(scatter_reduction1_test) +{ + { + // Test sub-ops for the three reduction values scatter_none, scatter_add, scatter_mul + migraphx::program p = create_scatter_program2("scatter_none", 1); + + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_none = {1.0, 1.1, 3.0, 2.1, 5.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold_none)); + } +} + +TEST_CASE(scatter_reduction2_test) +{ + { + migraphx::program p = create_scatter_program2("scatter_mul", 1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_mul = {1.0, 2.2, 3.0, 8.4, 5.0}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold_mul)); + } +} +TEST_CASE(scatter_reduction3_test) +{ + { + migraphx::program p = create_scatter_program2("scatter_add", 1); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_add = {1.0, 3.1, 3.0, 6.1, 5.0}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold_add)); + } +} + +TEST_CASE(scatter_reduction_3x3_test) +{ + { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; + std::vector vd(sd.elements(), 3.0f); + + migraphx::shape si{migraphx::shape::int32_type, {2, 3}}; + std::vector vi = {1, 0, 2, 0, 2, 1}; + + migraphx::shape su{migraphx::shape::float_type, {2, 3}}; + std::vector vu = {1.0, 1.1, 1.2, 7.0, 7.1, 7.2}; + + auto ld = mm->add_literal(migraphx::literal{sd, vd}); + auto li = mm->add_literal(migraphx::literal{si, vi}); + auto lu = mm->add_literal(migraphx::literal{su, vu}); + auto r = mm->add_instruction(migraphx::make_op("scatter_add", {{"axis", 1}}), ld, li, lu); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_a2 = {4.1, 4.0, 4.2, 10.0, 10.2, 10.1, 3.0, 3.0, 3.0}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold_a2)); + } +} + +// create a test scatter program with a 3x3 tensor; +// su and si are transposed from previous case +migraphx::program create_scatter_program_3x3(const std::string& reduction_mode, int axis) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; + std::vector vd(sd.elements(), 3.0f); + + migraphx::shape si{migraphx::shape::int32_type, {3, 2}}; + std::vector vi = {1, 0, 0, 2, 2, 1}; + + migraphx::shape su{migraphx::shape::float_type, {3, 2}}; + std::vector vu = {1.0, 7.0, 1.1, 7.1, 1.2, 7.2}; + + auto ld = mm->add_literal(migraphx::literal{sd, vd}); + auto li = mm->add_literal(migraphx::literal{si, vi}); + auto lu = mm->add_literal(migraphx::literal{su, vu}); + auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); + mm->add_return({r}); + return p; +} + +TEST_CASE(scatter_reduction_3x3_xpose1_test) +{ + // test on vertical (0) axis. su and si are transposed from previous case + { + migraphx::program p = create_scatter_program_3x3("scatter_none", 0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_none2 = {1.1, 7.0, 3.0, 1.0, 7.2, 3.0, 1.2, 7.1, 3.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold_none2)); + } +} + +TEST_CASE(scatter_reduction_3x3_xpose2_test) +{ + // test on vertical (0) axis. + { + migraphx::program p = create_scatter_program_3x3("scatter_add", 0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_a3 = {4.1, 10.0, 3.0, 4.0, 10.2, 3.0, 4.2, 10.1, 3.0}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold_a3)); + } +} + +TEST_CASE(scatter_reduction_3x3_xpose3_test) +{ + { + migraphx::program p = create_scatter_program_3x3("scatter_mul", 0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold_mul2 = {3.3, 21.0, 3.0, 3.0, 21.6, 3.0, 3.6, 21.3, 3.0}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold_mul2)); + } +} diff --git a/test/ref/scatternd_add.cpp b/test/ref/scatternd_add.cpp new file mode 100644 index 00000000000..2c551c978d8 --- /dev/null +++ b/test/ref/scatternd_add.cpp @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(scatternd_add_reduction_test) +{ + // reduction = add + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {8}}; + migraphx::shape is{itype, {8, 1}}; + migraphx::shape us{dtype, {8}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{4, 3, 1, 7, 4, 3, 1, 7}; + std::vector upd_vec{9, 10, 11, 12, -8, -9, -10, -11}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_add"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 3, 3, 5, 6, 6, 7, 9}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_reduction_dyn_test) +{ + // reduction = add, with dynamic input shapes + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape::dynamic_dimension dd{3, 6}; + migraphx::shape ds{migraphx::shape::float_type, {dd, dd, dd}}; + migraphx::shape is{itype, {2, 1}}; + migraphx::shape us{dtype, {{2, 2}, dd, dd}}; + + auto xdata = mm->add_parameter("X", ds); + auto xindex = mm->add_parameter("I", is); + auto xupdates = mm->add_parameter("U", us); + + auto scatternd_add_op = migraphx::make_op("scatternd_add"); + auto scatternd = mm->add_instruction(scatternd_add_op, xdata, xindex, xupdates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 4, 4}}; // data + std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, + 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, + 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector input_index{0, 2}; + migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {2, 4, 4}}; // updates + std::vector input_updates{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; + + params["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + params["I"] = migraphx::argument(is, input_index.data()); + params["U"] = migraphx::argument(input_fixed_shape1, input_updates.data()); + + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{6, 7, 8, 9, 11, 12, 13, 14, 15, 14, 13, 12, 12, 11, 10, 9, + 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, + 9, 8, 7, 6, 6, 5, 4, 3, 4, 5, 6, 7, 9, 10, 11, 12, + 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/scatternd_mul.cpp b/test/ref/scatternd_mul.cpp new file mode 100644 index 00000000000..73b1dd59d28 --- /dev/null +++ b/test/ref/scatternd_mul.cpp @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(scatternd_mul_reduction_test) +{ + // reduction = mul + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {8}}; + migraphx::shape is{itype, {4, 1}}; + migraphx::shape us{dtype, {4}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{4, 3, 1, 7}; + std::vector upd_vec{9, 10, 11, 12}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_mul"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 22, 3, 40, 45, 6, 7, 96}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/scatternd_none.cpp b/test/ref/scatternd_none.cpp new file mode 100644 index 00000000000..6e4d1287803 --- /dev/null +++ b/test/ref/scatternd_none.cpp @@ -0,0 +1,277 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(scatternd_shapes_test_1) +{ + // broadcasted input + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape is{itype, {4, 1}}; + migraphx::shape us{dtype, {4}}; + + std::vector ind_vec{4, 3, 1, 7}; + std::vector upd_vec{9, 10, 11, 12}; + + auto data = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {8}}}), + mm->add_literal(migraphx::literal{0.0f})); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{0, 11, 0, 10, 9, 0, 0, 12}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_shapes_test_2) +{ + // non-standard shape input + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {2, 2}}; + migraphx::shape is{itype, {2, 2}}; + migraphx::shape us{dtype, {2}}; + + std::vector data_vec{1, 2, 3, 4}; + std::vector ind_vec{0, 0, 0, 1}; + std::vector upd_vec{5, 6}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto td = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), data); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = mm->add_instruction(migraphx::make_op("scatternd_none"), td, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{5, 6, 2, 4}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_shapes_test_3) +{ + // non-standard updates shape + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {2, 2, 2}}; + migraphx::shape is{itype, {2, 1, 3}}; + migraphx::shape us{dtype, {1, 2}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{0, 0, 0, 1, 1, 1}; + std::vector upd_vec{9, 10}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto tu = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), updates); + auto scatternd = mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, tu); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{9, 2, 3, 4, 5, 6, 7, 10}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_test_1) +{ + // r=1, q=2, k=1 + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {8}}; + migraphx::shape is{itype, {4, 1}}; + migraphx::shape us{dtype, {4}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{4, 3, 1, 7}; + std::vector upd_vec{9, 10, 11, 12}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 11, 3, 10, 9, 6, 7, 12}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_test_2) +{ + // r=2, q=2, k=2 + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {2, 2}}; + migraphx::shape is{itype, {2, 2}}; + migraphx::shape us{dtype, {2}}; + + std::vector data_vec{1, 2, 3, 4}; + std::vector ind_vec{0, 0, 0, 1}; + std::vector upd_vec{5, 6}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{5, 6, 3, 4}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_test_3) +{ + // r=3, q=3, k=3 + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {2, 2, 2}}; + migraphx::shape is{itype, {2, 1, 3}}; + migraphx::shape us{dtype, {2, 1}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{0, 0, 0, 1, 1, 1}; + std::vector upd_vec{9, 10}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{9, 2, 3, 4, 5, 6, 7, 10}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_test_4) +{ + // r=3, q=2, k=1 + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {4, 4, 4}}; + migraphx::shape is{itype, {2, 1}}; + migraphx::shape us{dtype, {2, 4, 4}}; + + std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, + 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, + 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector ind_vec{0, 2}; + std::vector upd_vec{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 1, 2, 3, 4, 5, 6, + 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(scatternd_test_5) +{ + // r=5, q=1, k=1 + migraphx::program p; + auto* mm = p.get_main_module(); + auto dtype = migraphx::shape::float_type; + auto itype = migraphx::shape::int64_type; + migraphx::shape ds{dtype, {2, 2, 2, 2, 2}}; + migraphx::shape is{itype, {1}}; + migraphx::shape us{dtype, {2, 2, 2, 2}}; + + std::vector data_vec(32, 1); + std::vector ind_vec{1}; + std::vector upd_vec(16, 0); + + auto data = mm->add_literal(migraphx::literal{ds, data_vec}); + auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); + auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); + auto scatternd = + mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); + mm->add_return({scatternd}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold(32, 0); + std::copy(data_vec.begin(), data_vec.begin() + 16, gold.begin()); + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/select_module.cpp b/test/ref/select_module.cpp new file mode 100644 index 00000000000..30353d867cb --- /dev/null +++ b/test/ref/select_module.cpp @@ -0,0 +1,213 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(select_module_add_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape lit_s{migraphx::shape{migraphx::shape::float_type, {1}}}; + auto literal_ins = mm->add_literal(migraphx::literal{lit_s, {6}}); + + // create batch submodules + auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { + auto* submod = p.create_module(module_name); + migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 4}}; + auto sm_input = submod->add_parameter("data", sm_shape); + auto broadcast_lit = + submod->add_instruction(migraphx::make_op("multibroadcast"), literal_ins, sm_input); + auto add_ins = submod->add_instruction(migraphx::make_op("add"), sm_input, broadcast_lit); + submod->add_return({add_ins}); + return submod; + }; + auto* batch1 = create_submodule(1, "batch_1"); + auto* batch2 = create_submodule(2, "batch_2"); + auto* batch3 = create_submodule(3, "batch_3"); + auto* batch4 = create_submodule(4, "batch_4"); + + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {4, 4}}}; + auto input = mm->add_parameter("data", s); + std::vector sub_shapes = {}; + sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}}}); + migraphx::shape out_attr = migraphx::shape{sub_shapes}; + auto sm_ins = mm->add_instruction( + migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), + {input}, + {batch1, batch2, batch3, batch4}); + auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 4}}; + params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{2, 14, 5, 10, 5, 14, 14, 2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(select_module_reduce_test0) +{ + migraphx::program p; + + // create batch submodules + auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { + auto* submod = p.create_module(module_name); + migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; + auto sm_input = submod->add_parameter("data", sm_shape); + auto reduce_ins = + submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); + auto squeeze_ins = + submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); + submod->add_return({squeeze_ins}); + return submod; + }; + auto* batch1 = create_submodule(1, "batch_1"); + auto* batch2 = create_submodule(2, "batch_2"); + auto* batch3 = create_submodule(3, "batch_3"); + auto* batch4 = create_submodule(4, "batch_4"); + + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; + auto input = mm->add_parameter("data", s); + std::vector sub_shapes = {}; + sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); + migraphx::shape out_attr = migraphx::shape{sub_shapes}; + auto sm_ins = mm->add_instruction( + migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), + {input}, + {batch1, batch2, batch3, batch4}); + auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 2, 2}}; + params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-5, 12, 7, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(select_module_reduce_test1) +{ + migraphx::program p; + + // create batch submodules + auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { + auto* submod = p.create_module(module_name); + migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; + auto sm_input = submod->add_parameter("data", sm_shape); + auto reduce_ins = + submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); + auto squeeze_ins = + submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); + submod->add_return({squeeze_ins}); + return submod; + }; + auto* batch1 = create_submodule(1, "batch_1"); + auto* batch2 = create_submodule(2, "batch_2"); + auto* batch3 = create_submodule(3, "batch_3"); + auto* batch4 = create_submodule(4, "batch_4"); + + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; + auto input = mm->add_parameter("data", s); + std::vector sub_shapes = {}; + sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); + migraphx::shape out_attr = migraphx::shape{sub_shapes}; + auto sm_ins = mm->add_instruction( + migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), + {input}, + {batch1, batch2, batch3, batch4}); + auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4, -4, 8, -1, 4, -1, 8, 8, -4}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {4, 2, 2}}; + params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); + auto result = p.eval(params).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{-5, 12, 7, 4, -5, 12, 7, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(select_module_not_found_error) +{ + migraphx::program p; + + // create batch submodules + auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { + auto* submod = p.create_module(module_name); + migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; + auto sm_input = submod->add_parameter("data", sm_shape); + auto reduce_ins = + submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); + auto squeeze_ins = + submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); + submod->add_return({squeeze_ins}); + return submod; + }; + auto* batch1 = create_submodule(1, "batch_1"); + auto* batch2 = create_submodule(2, "batch_2"); + auto* batch3 = create_submodule(3, "batch_3"); + auto* batch4 = create_submodule(4, "batch_4"); + + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; + auto input = mm->add_parameter("data", s); + std::vector sub_shapes = {}; + sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); + migraphx::shape out_attr = migraphx::shape{sub_shapes}; + auto sm_ins = mm->add_instruction( + migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), + {input}, + {batch1, batch2, batch3, batch4}); + auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); + mm->add_return({ret}); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4, -4, 8, + -1, 4, -1, 8, 8, -4, -1, 8, 8, -4}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {5, 2, 2}}; + params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); + EXPECT(test::throws([&] { std::ignore = p.eval(params).back(); })); +} diff --git a/test/ref/sigmoid.cpp b/test/ref/sigmoid.cpp new file mode 100644 index 00000000000..45e1f71c7e7 --- /dev/null +++ b/test/ref/sigmoid.cpp @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +float sigmoid(float x) { return 1 / (1 + expf(-x)); } + +TEST_CASE(sigmoid_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + auto l = mm->add_literal(migraphx::literal{s, {-1, 2, -3, 4}}); + mm->add_instruction(migraphx::make_op("sigmoid"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{sigmoid(-1), sigmoid(2), sigmoid(-3), sigmoid(4)}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sigmoid_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 2}}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("sigmoid"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{-1, 2, -3, 4}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{sigmoid(-1), sigmoid(2), sigmoid(-3), sigmoid(4)}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/sign.cpp b/test/ref/sign.cpp new file mode 100644 index 00000000000..910848518af --- /dev/null +++ b/test/ref/sign.cpp @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sign_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {5}}; + auto l = mm->add_literal( + migraphx::literal{s, {1.02481645, 0.85643062, -0.03404123, -0.92791926, 0.0}}); + mm->add_instruction(migraphx::make_op("sign"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {1.0, 1.0, -1.0, -1.0, 0.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sign_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("sign"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data{1.02481645, 0.85643062, -0.03404123, -0.92791926, 0.0}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {5}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {1.0, 1.0, -1.0, -1.0, 0.0}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/sin.cpp b/test/ref/sin.cpp new file mode 100644 index 00000000000..aa6a13139a9 --- /dev/null +++ b/test/ref/sin.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sin_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data = {-1, 0, 1}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("sin"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sin_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + mm->add_instruction(migraphx::make_op("sin"), input); + p.compile(migraphx::make_target("ref")); + + std::vector input_data = {-1, 0, 1}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/sinh.cpp b/test/ref/sinh.cpp new file mode 100644 index 00000000000..5942876de31 --- /dev/null +++ b/test/ref/sinh.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sinh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data{-1.0, 2.0, -3.0, 4.0}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("sinh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sinh_dynamic_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 4}}}; + auto input = mm->add_parameter("X", s); + std::vector input_data{-1.0, 2.0, -3.0, 4.0}; + mm->add_instruction(migraphx::make_op("sinh"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/slice.cpp b/test/ref/slice.cpp new file mode 100644 index 00000000000..e27f28f4496 --- /dev/null +++ b/test/ref/slice.cpp @@ -0,0 +1,249 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(slice_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + migraphx::shape s{migraphx::shape::int32_type, {2, 2, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("slice", {{"axes", {2}}, {"starts", {1}}, {"ends", {3}}}), + l0); + migraphx::shape s2{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; + EXPECT(p.get_output_shapes().back() == s2); + p.compile(migraphx::make_target("ref")); + migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {4, 2, 1}}; + auto result = p.eval({}).back(); + std::vector gold = {1, 2, 4, 5, 7, 8, 10, 11}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(result.get_shape() == sresult); +} + +TEST_CASE(slice_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + migraphx::shape s{migraphx::shape::int32_type, {2, 2, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction( + migraphx::make_op("slice", + {{"axes", {0, 1, 2}}, {"starts", {0, 0, 0}}, {"ends", {2, 2, 2}}}), + l0); + migraphx::shape s2{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; + EXPECT(p.get_output_shapes().back() == s2); + p.compile(migraphx::make_target("ref")); + migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {4, 2, 1}}; + auto result = p.eval({}).back(); + std::vector gold = {0, 1, 3, 4, 6, 7, 9, 10}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(result.get_shape() == sresult); +} + +TEST_CASE(slice_var_inputs_static0) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + migraphx::shape s0{migraphx::shape::int32_type, {2, 2, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data}); + migraphx::shape s1{migraphx::shape::int32_type, {1}}; + auto starts = mm->add_parameter("starts", s1); + auto ends = mm->add_parameter("ends", s1); + mm->add_instruction(migraphx::make_op("slice", {{"axes", {2}}}), l0, starts, ends); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + std::vector start_data = {1}; + std::vector end_data = {3}; + params["starts"] = migraphx::argument(s1, start_data.data()); + params["ends"] = migraphx::argument(s1, end_data.data()); + auto result = p.eval(params).back(); + std::vector gold = {1, 2, 4, 5, 7, 8, 10, 11}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(slice_var_inputs_static1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + migraphx::shape s0{migraphx::shape::int32_type, {2, 2, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data}); + migraphx::shape s1{migraphx::shape::int32_type, {1}}; + auto starts = mm->add_parameter("starts", s1); + auto ends = mm->add_parameter("ends", s1); + mm->add_instruction(migraphx::make_op("slice", {{"axes", {2}}}), l0, starts, ends); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + std::vector start_data = {-2}; + std::vector end_data = {2831}; + params["starts"] = migraphx::argument(s1, start_data.data()); + params["ends"] = migraphx::argument(s1, end_data.data()); + auto result = p.eval(params).back(); + std::vector gold = {1, 2, 4, 5, 7, 8, 10, 11}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(slice_var_inputs_static2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + migraphx::shape s0{migraphx::shape::float_type, {2, 2, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s0, data}); + migraphx::shape s1{migraphx::shape::int64_type, {3}}; + auto starts = mm->add_parameter("starts", s1); + auto ends = mm->add_parameter("ends", s1); + auto axes = mm->add_parameter("axes", s1); + mm->add_instruction(migraphx::make_op("slice"), l0, starts, ends, axes); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + std::vector start_data = {0, 0, 0}; + std::vector end_data = {2, 2, 2}; + std::vector axes_data = {0, 1, 2}; + params["starts"] = migraphx::argument(s1, start_data.data()); + params["ends"] = migraphx::argument(s1, end_data.data()); + params["axes"] = migraphx::argument(s1, axes_data.data()); + auto result = p.eval(params).back(); + std::vector gold = {0, 1, 3, 4, 6, 7, 9, 10}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(slice_var_inputs_dyn) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s0{migraphx::shape::int32_type, {{2, 4, {2, 4}}, {2, 4, {2, 4}}, {3, 8}}}; + auto input = mm->add_parameter("input", s0); + migraphx::shape s1{migraphx::shape::int32_type, {1}}; + auto starts = mm->add_parameter("starts", s1); + auto ends = mm->add_parameter("ends", s1); + mm->add_instruction(migraphx::make_op("slice", {{"axes", {2}}}), input, starts, ends); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params; + migraphx::shape s2{migraphx::shape::int32_type, {2, 2, 3}}; + std::vector input_data(2 * 2 * 3); + std::iota(input_data.begin(), input_data.end(), 0); + std::vector start_data = {1}; + std::vector end_data = {3}; + params["input"] = migraphx::argument(s2, input_data.data()); + params["starts"] = migraphx::argument(s1, start_data.data()); + params["ends"] = migraphx::argument(s1, end_data.data()); + auto result = p.eval(params).back(); + std::vector gold = {1, 2, 4, 5, 7, 8, 10, 11}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(slice_dyn_test0) +{ + // Slice a single dynamic dimension. ax1 slice limits are smaller than min; ax2 "ends" is + // too large + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {{2, 3}, {2, 2}, {3, 3}}}; + auto x = mm->add_parameter("x", s); + mm->add_instruction( + migraphx::make_op("slice", {{"axes", {1, 2}}, {"starts", {0, 1}}, {"ends", {1, 6}}}), x); + migraphx::shape s2{migraphx::shape::int32_type, {{2, 3}, {1, 1}, {2, 2}}}; + EXPECT(p.get_output_shapes().back() == s2); + p.compile(migraphx::make_target("ref")); + + // the strides of sresult are those of the original shape, not + // reduced to sliced size. + migraphx::shape sresult{migraphx::shape::int32_type, {2, 1, 2}, {6, 3, 1}}; + migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 2, 3}}; + migraphx::parameter_map params; + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + params["x"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + + std::vector gold = {1, 2, 7, 8}; + std::vector results_vector(2 * 1 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(result.get_shape() == sresult); +} + +TEST_CASE(slice_dyn_test1) +{ + // Slice all three dynamic dimensions + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::int32_type, {{2, 2}, {2, 2}, {3, 3}}}; + auto x = mm->add_parameter("x", s); + mm->add_instruction( + migraphx::make_op("slice", + {{"axes", {0, 1, 2}}, {"starts", {0, 0, 0}}, {"ends", {2, 2, 2}}}), + x); + + migraphx::shape s2{migraphx::shape::int32_type, {{2, 2}, {2, 2}, {2, 2}}}; + EXPECT(p.get_output_shapes().back() == s2); + p.compile(migraphx::make_target("ref")); + migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; + + migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 2, 3}}; + migraphx::parameter_map params; + std::vector data(2 * 2 * 3); + std::iota(data.begin(), data.end(), 0); + params["x"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + + std::vector gold = {0, 1, 3, 4, 6, 7, 9, 10}; + std::vector results_vector(2 * 2 * 2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + EXPECT(result.get_shape() == sresult); +} diff --git a/test/ref/softmax.cpp b/test/ref/softmax.cpp new file mode 100644 index 00000000000..ad5df4e7693 --- /dev/null +++ b/test/ref/softmax.cpp @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(softmax_simple_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = {0.25, 0.75}; + std::vector s = {0.377541, 0.622459}; + migraphx::shape a_shape{migraphx::shape::float_type, {1, 2}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(2); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(softmax_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector a = { + -5.61869681e-01, 9.07827199e-01, 1.29255986e+00, 3.18533443e-02, -1.22183852e-03, + -2.83830553e-01, -1.03245842e+00, -9.28322077e-01, -8.82696748e-01, 1.11327164e-01, + -9.20038462e-01, 8.47388089e-01, 2.51734018e-01, 1.50563884e+00, 2.23056650e+00, + -6.17576987e-02, -1.00264274e-01, -6.10369384e-01, 1.17537189e+00, -2.51560897e-01, + -8.50333512e-01, -8.03578615e-01, -6.51194930e-01, -2.58137047e-01, 4.65528190e-01, + 3.23284641e-02, -1.54700470e+00, 1.38096774e+00, 5.39869189e-01, -7.56884992e-01, + 1.81503093e+00, -2.11269641e+00, 1.92466557e+00, 1.77230799e+00, 2.21660900e+00, + 1.56777036e+00, -2.08995026e-03, 3.50566894e-01, -1.15042710e+00, -1.18577778e+00, + 8.90633047e-01, -6.63949102e-02, 1.44661188e+00, 1.59215283e+00, -2.56262213e-01, + 9.39079225e-01, 4.07298543e-02, 3.86590779e-01, 6.09607756e-01, 8.22331488e-01, + -2.82126725e-01, -9.49052632e-01, -4.24012303e-01, -5.32990396e-01, -3.18386006e+00, + 3.27092171e-01, -1.33315325e+00, 3.62459183e-01, 3.74710828e-01, -1.30302286e+00, + 1.79680198e-01, -4.51832324e-01, 4.34282750e-01, -7.09520102e-01, 6.20333970e-01, + -1.28712380e+00, 2.04130828e-01, -7.70607769e-01, 1.61889160e+00, -1.50951004e+00, + -4.10505563e-01, -3.56566496e-02, -1.29747534e+00, -1.49967879e-01, 7.77626812e-01, + -8.28408226e-02, 2.73412596e-02, 5.79780899e-03, 9.87900198e-02, -7.95276761e-01, + -1.38536084e+00, -6.63573861e-01, 3.89783204e-01, -1.30670881e+00, -7.62425125e-01, + -4.04883057e-01, 6.24344349e-01, 3.68128955e-01, -1.01577950e+00, -3.06715906e-01, + 5.67961395e-01, 2.98198581e-01, -1.63613629e+00, -3.75131965e-01, -6.75393403e-01, + 2.59172034e+00, 6.75538957e-01, 9.07939598e-02, 1.92257717e-01, -1.21592450e+00, + -2.73682117e-01, 1.25232983e+00, -1.39969170e+00, -1.91483587e-01, 2.57732719e-01, + 3.10056299e-01, 1.41833842e+00, -1.81386679e-01, 3.92868072e-01, -8.14771175e-01, + 2.02392387e+00, -9.42091495e-02, -3.77683818e-01, 2.05638766e+00, 2.93796062e-01, + -6.02131486e-01, 2.70461679e-01, -8.92358482e-01, 1.04388881e+00, 2.66154885e-01}; + + std::vector s = { + 0.30191708, 0.59879845, 0.50029165, 0.24915339, 0.36823985, 0.13190967, 0.0349741, + 0.18750034, 0.21905553, 0.27000085, 0.0547399, 0.56318235, 0.47422904, 0.78964758, + 0.91381913, 0.44601166, 0.47902739, 0.13120073, 0.4449684, 0.18766427, 0.15753111, + 0.07844277, 0.05120674, 0.36648798, 0.14637007, 0.13152322, 0.01560997, 0.29065287, + 0.49196178, 0.10550152, 0.81890774, 0.06369215, 0.62972021, 0.74931765, 0.67285055, + 0.35034987, 0.28612873, 0.31931475, 0.04220394, 0.16093165, 0.22390974, 0.11915915, + 0.3115395, 0.35899726, 0.22190949, 0.57518375, 0.13888834, 0.7753762, 0.4642328, + 0.57055861, 0.21954368, 0.34515455, 0.09486015, 0.40631217, 0.01842281, 0.48770609, + 0.06652815, 0.36023033, 0.42343026, 0.24226256, 0.17348589, 0.44066274, 0.6865865, + 0.17296699, 0.46923906, 0.06921105, 0.3570261, 0.4125829, 0.73165393, 0.15302512, + 0.29499072, 0.33932695, 0.30852377, 0.40762195, 0.40170741, 0.36259529, 0.60848355, + 0.42618036, 0.31721094, 0.02960522, 0.28256637, 0.24389413, 0.2725659, 0.10663581, + 0.27622163, 0.28264219, 0.53652936, 0.09476089, 0.40890986, 0.34848392, 0.32572666, + 0.53076893, 0.11529481, 0.29117745, 0.14625968, 0.8756339, 0.49818122, 0.10656087, + 0.1813329, 0.17664003, 0.21410346, 0.80408043, 0.02315119, 0.27155462, 0.32804728, + 0.13268511, 0.61795473, 0.49703068, 0.41696799, 0.10175809, 0.71028161, 0.29929739, + 0.17377149, 0.76075399, 0.20071237, 0.32632929, 0.36892858, 0.09416146, 0.26656723, + 0.42914796}; + + migraphx::shape a_shape{migraphx::shape::float_type, {5, 3, 4, 2}}; + auto al = mm->add_literal(migraphx::literal{a_shape, a}); + mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(120); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} + +TEST_CASE(softmax_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape a_shape{migraphx::shape::float_type, + {{1, 10}, {1, 3, {3}}, {4, 4}, {2, 2, {2}}}}; + auto al = mm->add_parameter("a", a_shape); + mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); + p.compile(migraphx::make_target("ref")); + + std::vector a = { + -5.61869681e-01, 9.07827199e-01, 1.29255986e+00, 3.18533443e-02, -1.22183852e-03, + -2.83830553e-01, -1.03245842e+00, -9.28322077e-01, -8.82696748e-01, 1.11327164e-01, + -9.20038462e-01, 8.47388089e-01, 2.51734018e-01, 1.50563884e+00, 2.23056650e+00, + -6.17576987e-02, -1.00264274e-01, -6.10369384e-01, 1.17537189e+00, -2.51560897e-01, + -8.50333512e-01, -8.03578615e-01, -6.51194930e-01, -2.58137047e-01, 4.65528190e-01, + 3.23284641e-02, -1.54700470e+00, 1.38096774e+00, 5.39869189e-01, -7.56884992e-01, + 1.81503093e+00, -2.11269641e+00, 1.92466557e+00, 1.77230799e+00, 2.21660900e+00, + 1.56777036e+00, -2.08995026e-03, 3.50566894e-01, -1.15042710e+00, -1.18577778e+00, + 8.90633047e-01, -6.63949102e-02, 1.44661188e+00, 1.59215283e+00, -2.56262213e-01, + 9.39079225e-01, 4.07298543e-02, 3.86590779e-01, 6.09607756e-01, 8.22331488e-01, + -2.82126725e-01, -9.49052632e-01, -4.24012303e-01, -5.32990396e-01, -3.18386006e+00, + 3.27092171e-01, -1.33315325e+00, 3.62459183e-01, 3.74710828e-01, -1.30302286e+00, + 1.79680198e-01, -4.51832324e-01, 4.34282750e-01, -7.09520102e-01, 6.20333970e-01, + -1.28712380e+00, 2.04130828e-01, -7.70607769e-01, 1.61889160e+00, -1.50951004e+00, + -4.10505563e-01, -3.56566496e-02, -1.29747534e+00, -1.49967879e-01, 7.77626812e-01, + -8.28408226e-02, 2.73412596e-02, 5.79780899e-03, 9.87900198e-02, -7.95276761e-01, + -1.38536084e+00, -6.63573861e-01, 3.89783204e-01, -1.30670881e+00, -7.62425125e-01, + -4.04883057e-01, 6.24344349e-01, 3.68128955e-01, -1.01577950e+00, -3.06715906e-01, + 5.67961395e-01, 2.98198581e-01, -1.63613629e+00, -3.75131965e-01, -6.75393403e-01, + 2.59172034e+00, 6.75538957e-01, 9.07939598e-02, 1.92257717e-01, -1.21592450e+00, + -2.73682117e-01, 1.25232983e+00, -1.39969170e+00, -1.91483587e-01, 2.57732719e-01, + 3.10056299e-01, 1.41833842e+00, -1.81386679e-01, 3.92868072e-01, -8.14771175e-01, + 2.02392387e+00, -9.42091495e-02, -3.77683818e-01, 2.05638766e+00, 2.93796062e-01, + -6.02131486e-01, 2.70461679e-01, -8.92358482e-01, 1.04388881e+00, 2.66154885e-01}; + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {5, 3, 4, 2}}; + params["a"] = migraphx::argument(input_fixed_shape, a.data()); + auto result = p.eval(params).back(); + std::vector results_vector(120); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector s = { + 0.30191708, 0.59879845, 0.50029165, 0.24915339, 0.36823985, 0.13190967, 0.0349741, + 0.18750034, 0.21905553, 0.27000085, 0.0547399, 0.56318235, 0.47422904, 0.78964758, + 0.91381913, 0.44601166, 0.47902739, 0.13120073, 0.4449684, 0.18766427, 0.15753111, + 0.07844277, 0.05120674, 0.36648798, 0.14637007, 0.13152322, 0.01560997, 0.29065287, + 0.49196178, 0.10550152, 0.81890774, 0.06369215, 0.62972021, 0.74931765, 0.67285055, + 0.35034987, 0.28612873, 0.31931475, 0.04220394, 0.16093165, 0.22390974, 0.11915915, + 0.3115395, 0.35899726, 0.22190949, 0.57518375, 0.13888834, 0.7753762, 0.4642328, + 0.57055861, 0.21954368, 0.34515455, 0.09486015, 0.40631217, 0.01842281, 0.48770609, + 0.06652815, 0.36023033, 0.42343026, 0.24226256, 0.17348589, 0.44066274, 0.6865865, + 0.17296699, 0.46923906, 0.06921105, 0.3570261, 0.4125829, 0.73165393, 0.15302512, + 0.29499072, 0.33932695, 0.30852377, 0.40762195, 0.40170741, 0.36259529, 0.60848355, + 0.42618036, 0.31721094, 0.02960522, 0.28256637, 0.24389413, 0.2725659, 0.10663581, + 0.27622163, 0.28264219, 0.53652936, 0.09476089, 0.40890986, 0.34848392, 0.32572666, + 0.53076893, 0.11529481, 0.29117745, 0.14625968, 0.8756339, 0.49818122, 0.10656087, + 0.1813329, 0.17664003, 0.21410346, 0.80408043, 0.02315119, 0.27155462, 0.32804728, + 0.13268511, 0.61795473, 0.49703068, 0.41696799, 0.10175809, 0.71028161, 0.29929739, + 0.17377149, 0.76075399, 0.20071237, 0.32632929, 0.36892858, 0.09416146, 0.26656723, + 0.42914796}; + EXPECT(migraphx::verify::verify_range(results_vector, s)); +} diff --git a/test/ref/sqdiff.cpp b/test/ref/sqdiff.cpp new file mode 100644 index 00000000000..180e84ec2bb --- /dev/null +++ b/test/ref/sqdiff.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sqdiff_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); + auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); + mm->add_instruction(migraphx::make_op("sqdiff"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {4, 4, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sqdiff_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + mm->add_instruction(migraphx::make_op("sqdiff"), x, y); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1, 0, 1}; + std::vector y_data{1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {4, 4, 4}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/sqrt.cpp b/test/ref/sqrt.cpp new file mode 100644 index 00000000000..5760091bdb2 --- /dev/null +++ b/test/ref/sqrt.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sqrt_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {5}}; + std::vector data{1.02481645, 0.85643062, 0.03404123, 0.92791926, 0.10569184}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("sqrt"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sqrtf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sqrt_dynamic_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + std::vector input_data{1.02481645, 0.85643062, 0.03404123, 0.92791926, 0.10569184}; + mm->add_instruction(migraphx::make_op("sqrt"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {5}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector; + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sqrtf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/squeeze.cpp b/test/ref/squeeze.cpp new file mode 100644 index 00000000000..174d4e17eba --- /dev/null +++ b/test/ref/squeeze.cpp @@ -0,0 +1,153 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(squeeze_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(4 * 3 * 3); + migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; + migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(squeeze_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(4 * 3 * 3); + migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; + migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {3}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(squeeze_test_3) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(4 * 3 * 3); + migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; + migraphx::shape s2{migraphx::shape::float_type, {4, 3, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + mm->add_instruction(migraphx::make_op("squeeze"), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(squeeze_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s1{migraphx::shape::float_type, {{1, 4}, {1, 1}, {3, 3}, {1, 1}, {3, 3}}}; + auto p0 = mm->add_parameter("x", s1); + mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), p0); + p.compile(migraphx::make_target("ref")); + + std::vector input_data(4 * 3 * 3); + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(squeeze_transpose_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = + mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {4, 1, 3, 1, 3}})); + auto l0_trans = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 3, 0, 4}}}), l0); + mm->add_instruction(migraphx::make_op("squeeze"), l0_trans); + auto p_uncompiled = p; + // contiguous is required to read the values in standard shaped order + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 4, 3}}); + EXPECT(result == expected_result); +} + +TEST_CASE(squeeze_multibroadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = + mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {1, 3, 1, 3}})); + auto l0_brcst = mm->add_instruction( + migraphx::make_op("multibroadcast", {{"out_lens", {4, 1, 3, 4, 3}}}), l0); + mm->add_instruction(migraphx::make_op("squeeze"), l0_brcst); + auto p_uncompiled = p; + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {4, 3, 4, 3}}); + EXPECT(result == expected_result); +} + +TEST_CASE(squeeze_slice_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = + mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {1, 3, 4, 3}})); + auto l0_slice = mm->add_instruction( + migraphx::make_op("slice", {{"axes", {2}}, {"starts", {2}}, {"ends", {3}}}), l0); + mm->add_instruction(migraphx::make_op("squeeze"), l0_slice); + auto p_uncompiled = p; + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 3}}); + EXPECT(result == expected_result); +} diff --git a/test/ref/step.cpp b/test/ref/step.cpp new file mode 100644 index 00000000000..834f3f8f683 --- /dev/null +++ b/test/ref/step.cpp @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(step_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 4 * 6); + std::iota(data.begin(), data.end(), 2); + migraphx::shape s1{migraphx::shape::float_type, {2, 1, 4, 6}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + auto r = mm->add_instruction( + migraphx::make_op("step", {{"axes", {0, 2, 3}}, {"steps", {2, 2, 3}}}), l0); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + migraphx::shape s2{migraphx::shape::float_type, {1, 1, 2, 2}}; + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(step_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(2 * 4 * 6); + std::iota(data.begin(), data.end(), 2); + migraphx::shape s1{migraphx::shape::float_type, {2, 1, 4, 6}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + auto tl = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 3, 1}}}), l0); + auto r = mm->add_instruction( + migraphx::make_op("step", {{"axes", {0, 1, 2}}, {"steps", {2, 2, 3}}}), tl); + mm->add_return({r}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + migraphx::shape s2{migraphx::shape::float_type, {1, 2, 2, 1}}; + EXPECT(result.get_shape() == s2); +} diff --git a/test/ref/sub.cpp b/test/ref/sub.cpp new file mode 100644 index 00000000000..80ba868fc51 --- /dev/null +++ b/test/ref/sub.cpp @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(sub_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); + auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); + mm->add_instruction(migraphx::make_op("sub"), l1, l2); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2, -2, -2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(sub_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector dd{{2, 6}}; + migraphx::shape s{migraphx::shape::float_type, dd}; + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + mm->add_instruction(migraphx::make_op("sub"), x, y); + p.compile(migraphx::make_target("ref")); + + std::vector x_data{-1, 0, 1}; + std::vector y_data{1, 2, 3}; + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); + params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {-2, -2, -2}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/tan.cpp b/test/ref/tan.cpp new file mode 100644 index 00000000000..b40dbf74dd6 --- /dev/null +++ b/test/ref/tan.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(tan_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3}}; + std::vector data{-1, 0, 1}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("tan"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(tan_dynamic_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + std::vector input_data{-1, 0, 1}; + mm->add_instruction(migraphx::make_op("tan"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/tanh.cpp b/test/ref/tanh.cpp new file mode 100644 index 00000000000..46197312b21 --- /dev/null +++ b/test/ref/tanh.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(tanh_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {2, 2}}; + std::vector data{-1.0, 2.0, -3.0, 4.0}; + auto l = mm->add_literal(migraphx::literal{s, data}); + mm->add_instruction(migraphx::make_op("tanh"), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(tanh_dynamic_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape::dynamic_dimension dd{3, 8}; + migraphx::shape s{migraphx::shape::float_type, {dd}}; + auto input = mm->add_parameter("X", s); + std::vector input_data{-1.0, 2.0, -3.0, 4.0}; + mm->add_instruction(migraphx::make_op("tanh"), input); + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; + params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + std::vector results_vector(4); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = input_data; + std::transform( + gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanhf(n); }); + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/topk.cpp b/test/ref/topk.cpp new file mode 100644 index 00000000000..385bc4ff97d --- /dev/null +++ b/test/ref/topk.cpp @@ -0,0 +1,83 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(topk_test) +{ + auto create_program = [](int64_t k, int64_t axis, int largest) { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 5}}; + auto data = mm->add_parameter("data", s); + auto r = mm->add_instruction( + migraphx::make_op("topk", {{"axis", axis}, {"k", k}, {"largest", largest}}), data); + auto r0 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), r); + auto r1 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 1}}), r); + mm->add_return({r0, r1}); + + return p; + }; + + auto run_program = [&](int64_t k, int64_t axis, int largest) { + auto p = create_program(k, axis, largest); + p.compile(migraphx::make_target("ref")); + std::vector data = { + 2.1, 2.3, 2.0, 2.5, 1.9, 3.3, 0.2, 4.5, 0.1, 0.8, 1.0, 4.5, 2.1, 0.8, 1.5}; + migraphx::shape s{migraphx::shape::float_type, {3, 5}}; + migraphx::parameter_map pp; + pp["data"] = migraphx::argument(s, data.data()); + auto rets = p.eval(pp); + std::vector ret_val; + rets.front().visit([&](auto v) { ret_val.assign(v.begin(), v.end()); }); + std::vector ret_ind; + rets.back().visit([&](auto v) { ret_ind.assign(v.begin(), v.end()); }); + + return std::make_pair(ret_val, ret_ind); + }; + + // case 1 + { + auto results = run_program(4, 1, 1); + std::vector gold_val = {2.5, 2.3, 2.1, 2, 4.5, 3.3, 0.8, 0.2, 4.5, 2.1, 1.5, 1}; + EXPECT(results.first == gold_val); + std::vector gold_ind = {3, 1, 0, 2, 2, 0, 4, 1, 1, 2, 4, 0}; + EXPECT(results.second == gold_ind); + } + + // case 2 + { + auto results = run_program(4, 1, 0); + std::vector gold_val = {1.9, 2, 2.1, 2.3, 0.1, 0.2, 0.8, 3.3, 0.8, 1, 1.5, 2.1}; + EXPECT(results.first == gold_val); + std::vector gold_ind = {4, 2, 0, 1, 3, 1, 4, 0, 3, 0, 4, 2}; + EXPECT(results.second == gold_ind); + } +} diff --git a/test/ref/transpose.cpp b/test/ref/transpose.cpp new file mode 100644 index 00000000000..336faf9c514 --- /dev/null +++ b/test/ref/transpose.cpp @@ -0,0 +1,90 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(transpose_test) +{ + migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 2, 3}}; + std::vector data(12); + std::iota(data.begin(), data.end(), 0); + + { + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + std::vector perm = {0, 3, 1, 2}; + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + } + { + migraphx::program p; + auto* mm = p.get_main_module(); + auto l = mm->add_literal(migraphx::literal{a_shape, data}); + std::vector perm = {0, 3, 1, 2}; + auto result = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); + mm->add_instruction(migraphx::make_op("contiguous"), result); + p.compile(migraphx::make_target("ref")); + auto result2 = p.eval({}).back(); + + std::vector results_vector(12); + result2.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); + } +} + +TEST_CASE(transpose_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}, {3, 3}}}; + auto l = mm->add_parameter("X", s); + std::vector perm = {0, 3, 1, 2}; + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); + p.compile(migraphx::make_target("ref")); + + std::vector data(12); + std::iota(data.begin(), data.end(), 0); + migraphx::parameter_map params; + migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 2, 2, 3}}; + params["X"] = migraphx::argument(input_fixed_shape, data.data()); + auto result = p.eval(params).back(); + + std::vector new_lens = {1, 3, 2, 2}; + EXPECT(result.get_shape().lens() == new_lens); + + std::vector results_vector(12); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} diff --git a/test/ref/unsqueeze.cpp b/test/ref/unsqueeze.cpp new file mode 100644 index 00000000000..7cec82055ef --- /dev/null +++ b/test/ref/unsqueeze.cpp @@ -0,0 +1,139 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(unsqueeze_test_1) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(4 * 3 * 3); + migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; + migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(unsqueeze_test_2) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + std::vector data(4 * 3 * 3); + migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; + migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; + auto l0 = mm->add_literal(migraphx::literal{s1, data}); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(unsqueeze_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + + migraphx::shape s1{migraphx::shape::float_type, {{1, 4}, {3, 3}, {3, 3}}}; + auto p0 = mm->add_parameter("x", s1); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), p0); + p.compile(migraphx::make_target("ref")); + + std::vector input_data(4 * 3 * 3); + migraphx::parameter_map params0; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 3, 3}}; + params0["x"] = migraphx::argument(input_fixed_shape0, input_data.data()); + auto result = p.eval(params0).back(); + migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; + EXPECT(result.get_shape() == s2); +} + +TEST_CASE(unsqueeze_transpose_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; + auto l0 = mm->add_literal(migraphx::generate_literal(s1)); + auto l0_trans = + mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {2, 0, 1}}}), l0); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0_trans); + auto p_uncompiled = p; + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 4, 1, 3}}); + EXPECT(result == expected_result); +} + +TEST_CASE(unsqueeze_multibroadcast_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3}}; + auto l0 = mm->add_literal(migraphx::generate_literal(s1)); + auto l0_brcst = + mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {4, 4, 3, 3}}}), l0); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0_brcst); + auto p_uncompiled = p; + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {4, 4, 1, 3, 3}}); + EXPECT(result == expected_result); +} + +TEST_CASE(unsqueeze_slice_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s1{migraphx::shape::float_type, {2, 3, 4, 4}}; + auto l0 = mm->add_literal(migraphx::generate_literal(s1)); + auto l0_slice = mm->add_instruction( + migraphx::make_op("slice", {{"axes", {3}}, {"starts", {2}}, {"ends", {3}}}), l0); + mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), l0_slice); + auto p_uncompiled = p; + auto* mm_uncompiled = p_uncompiled.get_main_module(); + mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), + std::prev(mm_uncompiled->end())); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + auto expected_result = p_uncompiled.eval({}).back(); + EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {2, 1, 3, 4, 1}}); + EXPECT(result == expected_result); +} diff --git a/test/ref/where.cpp b/test/ref/where.cpp new file mode 100644 index 00000000000..ebeac6822ba --- /dev/null +++ b/test/ref/where.cpp @@ -0,0 +1,117 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include + +TEST_CASE(where_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sb{migraphx::shape::bool_type, {3, 3}}; + migraphx::shape sx{migraphx::shape::float_type, {3, 3}}; + + std::vector b{true, true, true, false, false, false, true, false, true}; + std::vector x(9, 1.0); + std::vector y(9, 2.0); + + auto lb = mm->add_literal(migraphx::literal{sb, b}); + auto lx = mm->add_literal(migraphx::literal{sx, x}); + auto ly = mm->add_literal(migraphx::literal{sx, y}); + auto w = mm->add_instruction(migraphx::make_op("where"), lb, lx, ly); + mm->add_return({w}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + std::vector gold(9); + for(int i = 0; i < gold.size(); ++i) + gold[i] = b[i] ? x[i] : y[i]; + + EXPECT(migraphx::verify::verify_range(result_vec, gold)); +} + +TEST_CASE(where_dyn_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sb{migraphx::shape::bool_type, {{2, 3}, {2, 3}}}; + migraphx::shape sx{migraphx::shape::float_type, {{2, 3}, {2, 3}}}; + + auto lb = mm->add_parameter("predicate", sb); + auto lx = mm->add_parameter("X", sx); + auto ly = mm->add_parameter("Y", sx); + mm->add_instruction(migraphx::make_op("where"), lb, lx, ly); + p.compile(migraphx::make_target("ref")); + + std::vector b{1, 1, 1, 0, 0, 0, 1, 0, 1}; + std::vector x(9, 1.0); + std::vector y(9, 2.0); + migraphx::parameter_map params; + migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3, 3}}; + migraphx::shape input_fixed_shape1{migraphx::shape::uint8_type, {3, 3}}; + params["X"] = migraphx::argument(input_fixed_shape0, x.data()); + params["Y"] = migraphx::argument(input_fixed_shape0, y.data()); + + params["predicate"] = migraphx::argument(input_fixed_shape1, b.data()); + + auto result = p.eval(params).back(); + std::vector results_vector(3 * 3); + result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); + std::vector gold{1, 1, 1, 2, 2, 2, 1, 2, 1}; + EXPECT(migraphx::verify::verify_range(results_vector, gold)); +} + +TEST_CASE(where_broadcasted_inputs_test) +{ + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape sb{migraphx::shape::bool_type, {3, 3}}; + + std::vector b{true, true, true, false, false, false, true, false, true}; + + auto lb = mm->add_literal(migraphx::literal{sb, b}); + auto lx = mm->add_literal(migraphx::literal(1.0f)); + auto ly = mm->add_literal(migraphx::literal(2.0f)); + auto mbx = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), lx); + auto mby = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), ly); + auto w = mm->add_instruction(migraphx::make_op("where"), lb, mbx, mby); + mm->add_return({w}); + p.compile(migraphx::make_target("ref")); + auto result = p.eval({}).back(); + std::vector result_vec; + result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); + std::vector gold(9); + std::vector x(9, 1.0); + std::vector y(9, 2.0); + for(int i = 0; i < gold.size(); ++i) + gold[i] = b[i] ? x[i] : y[i]; + + EXPECT(migraphx::verify::verify_range(result_vec, gold)); +} diff --git a/test/ref_dot_op_test.cpp b/test/ref_dot_op_test.cpp deleted file mode 100644 index 7143717882b..00000000000 --- a/test/ref_dot_op_test.cpp +++ /dev/null @@ -1,1758 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.hpp" -#include - -template -void dot_2d_test() -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, - 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, - -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, - -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; - std::vector b = {6.09568541e-01, - -6.10527007e-01, - 3.66646462e-01, - 1.18951101e-01, - 5.58777432e-01, - -3.21296298e-01, - -5.95997198e-01, - -5.01425721e-01, - -2.84606807e-01, - -5.73673557e-01, - -8.99430260e-01, - -4.25103093e-01, - 1.53027987e+00, - -3.81407415e-04, - -3.29650255e-01}; - std::vector c = {-1.56327541e+00, - -7.09570140e-01, - -5.37424982e-01, - -2.22994831e-01, - -2.15586437e+00, - 2.09177941e-03, - -1.47279677e+00, - 2.02627040e-01, - -6.04527691e-01, - -1.29885596e+00, - 2.16294914e+00, - -1.48101497e-01}; - migraphx::shape a_shape{migraphx::shape::get_type{}, {4, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::get_type{}, {5, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), al, bl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(c, results_vector)); -} -TEST_CASE_REGISTER(dot_2d_test) -TEST_CASE_REGISTER(dot_2d_test) - -template -void dot_4d_test() -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, - 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, - -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, - -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; - std::vector b = {6.09568541e-01, - -6.10527007e-01, - 3.66646462e-01, - 1.18951101e-01, - 5.58777432e-01, - -3.21296298e-01, - -5.95997198e-01, - -5.01425721e-01, - -2.84606807e-01, - -5.73673557e-01, - -8.99430260e-01, - -4.25103093e-01, - 1.53027987e+00, - -3.81407415e-04, - -3.29650255e-01}; - std::vector c = {-1.56327541e+00, - -7.09570140e-01, - -5.37424982e-01, - -2.22994831e-01, - -2.15586437e+00, - 2.09177941e-03, - -1.47279677e+00, - 2.02627040e-01, - -6.04527691e-01, - -1.29885596e+00, - 2.16294914e+00, - -1.48101497e-01}; - migraphx::shape a_shape{migraphx::shape::get_type{}, {1, 1, 4, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::get_type{}, {1, 1, 5, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), al, bl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(c, results_vector)); -} -TEST_CASE_REGISTER(dot_4d_test) -TEST_CASE_REGISTER(dot_4d_test) - -TEST_CASE(dot_3D_test) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = {-0.76234141, - 0.01368910, - -0.86343423, - -0.99465282, - 0.76133268, - 0.96507140, - -0.55893585, - 0.02625652, - 0.75171776, - 0.23112578, - 0.25624787, - -1.50442161}; - migraphx::shape m1_shape{migraphx::shape::float_type, {2, 2, 3}}; - std::vector m2 = {-0.15933632, -0.69594712, -0.06198966, -1.23905184, -0.83672704, - -1.06971832, -0.12272917, 1.07094116, -0.08346820, 1.16820693, - -0.95700874, 0.24059691, 0.43326023, 0.78305235, -0.53506601, - -0.69359678, -0.26334436, 1.56292796, -0.33629175, -1.72693469, - 0.41435494, 1.52136843, -0.40699791, -1.59839430}; - migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - - mm->add_instruction(migraphx::make_op("dot"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {0.18208394, - -0.49276402, - 0.87189133, - 0.75150114, - -0.55909610, - 1.00521735, - -0.95536130, - 2.27996211, - 0.06239879, - 0.74700068, - -0.01570983, - -0.85920856, - -0.59070835, - -1.70729902, - 0.40245487, - 1.80182751}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_3D_C_test0) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = {-0.76234141, - 0.01368910, - -0.86343423, - -0.99465282, - 0.76133268, - 0.96507140, - -0.55893585, - 0.02625652, - 0.75171776, - 0.23112578, - 0.25624787, - -1.50442161}; - migraphx::shape m1_shape{migraphx::shape::float_type, {2, 2, 3}}; - std::vector m2 = {-0.15933632, -0.69594712, -0.06198966, -1.23905184, -0.83672704, - -1.06971832, -0.12272917, 1.07094116, -0.08346820, 1.16820693, - -0.95700874, 0.24059691, 0.43326023, 0.78305235, -0.53506601, - -0.69359678, -0.26334436, 1.56292796, -0.33629175, -1.72693469, - 0.41435494, 1.52136843, -0.40699791, -1.59839430}; - migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 4}}; - std::vector m3 = {0.18208394, - -0.49276402, - 0.87189133, - 0.75150114, - -0.55909610, - 1.00521735, - -0.95536130, - 2.27996211, - 0.06239879, - 0.74700068, - -0.01570983, - -0.85920856, - -0.59070835, - -1.70729902, - 0.40245487, - 1.80182751}; - migraphx::shape m3_shape{migraphx::shape::float_type, {2, 2, 4}}; - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); - float alpha = 1.0f; - float beta = 0.0f; - migraphx::add_apply_alpha_beta(*mm, - std::vector{l1, l2, l3}, - migraphx::make_op("dot"), - alpha, - beta); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {0.18208394, - -0.49276402, - 0.87189133, - 0.75150114, - -0.55909610, - 1.00521735, - -0.95536130, - 2.27996211, - 0.06239879, - 0.74700068, - -0.01570983, - -0.85920856, - -0.59070835, - -1.70729902, - 0.40245487, - 1.80182751}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_3D_C_test1) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = { - -0.76234141, 0.01368910, -0.86343423, -0.99465282, 0.76133268, 0.96507140}; - migraphx::shape m1_shape{migraphx::shape::float_type, {1, 2, 3}}; - std::vector m2 = {-0.15933632, - -0.69594712, - -0.06198966, - -1.23905184, - -0.83672704, - -1.06971832, - -0.12272917, - 1.07094116, - -0.08346820, - 1.16820693, - -0.95700874, - 0.24059691}; - migraphx::shape m2_shape{migraphx::shape::float_type, {1, 3, 4}}; - - migraphx::shape m3_shape{migraphx::shape::float_type, {1, 2, 4}}; - std::vector m3 = {0.18208394, - -0.49276402, - 0.87189133, - 0.75150114, - -0.55909610, - 1.00521735, - -0.95536130, - 2.27996211}; - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); - - float alpha = 1.0f; - float beta = 0.0f; - migraphx::add_apply_alpha_beta(*mm, - std::vector{l1, l2, l3}, - migraphx::make_op("dot"), - alpha, - beta); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {0.18208394, - -0.49276402, - 0.87189133, - 0.75150114, - -0.55909610, - 1.00521735, - -0.95536130, - 2.27996211}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_4D_test1) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = { - -1.93300070, 0.33902698, -0.45173527, -0.72283069, -0.17177134, 1.62199882, - 0.87052847, 0.14989811, -0.88969184, -0.18131398, 0.72654339, -0.57123693, - 0.03852506, -0.72332085, -1.81844083, -0.33465167, -0.71400352, 0.36883161, - 0.08698452, 0.94974586, 0.40087323, -0.05448534, 0.03220677, -1.22494296, - 0.97938472, -1.43714454, -0.80430904, -0.08098728, 0.31520301, 0.49642169, - -1.63471091, 0.34390096, 2.81292176, -0.22666528, 1.54559556, -1.51075762}; - migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; - std::vector m2 = { - -0.33170529, 2.26325120, -0.50639461, 0.64802947, 0.44748888, 0.33768068, - -0.53621075, 0.34341460, 0.58742520, -1.13995790, -0.99322535, 0.35447353, - 0.01977110, -0.10155016, -1.02288245, -0.16575791, -1.47870374, 0.29300008, - -0.39112198, 1.42303608, -0.02853060, 1.52610164, 0.53540909, 0.75618998, - -0.26877787, -1.90886366, 0.30622790, 0.59794535, 1.29795331, -0.37805803, - -1.58167176, -1.26966832, 0.27435891, 0.89430347, 0.22854926, -0.50317658}; - migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - - mm->add_instruction(migraphx::make_op("dot"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {0.26735861, -4.30770895, 1.05257728, -1.19954265, 0.50493170, - -0.18729756, 1.09137941, -1.09298312, 3.42956915, -0.41681939, - 0.17833257, 0.26040336, 0.15351280, 1.87632715, -0.63545406, - -0.95467340, -1.74728628, -2.42477030, 0.76262372, 0.15539164, - 3.32281958, 0.96769613, 0.43727545, 2.43019906}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_4D_alpha_beta_test) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = { - 1.23636469, -0.47041261, -0.14375651, -0.48371852, 1.16479301, -0.89361055, - -0.18569086, 1.10700457, -1.02632638, 0.82277012, 0.33525769, 0.52825145, - -1.00141689, 0.45510090, -0.02675039, -0.60454439, 0.38551153, -0.01658514, - 0.93059292, -0.54595188, -0.04911005, -0.91397221, -0.83127477, -1.57685603, - -1.36200452, 2.25822236, -1.23416970, 0.12312496, 0.76232760, -0.83594234, - 1.67418145, -0.19412936, 1.05261378, 0.66246074, -1.15233398, 0.16429736}; - migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; - std::vector m2 = { - -0.87300530, -0.07112838, 0.19196860, -1.04986840, 1.20348200, 0.31966893, - 1.04805440, -2.04777729, -0.67906052, -1.17250760, 0.34305044, -1.01957785, - -1.12694862, 0.18431338, -1.63712290, 0.27566931, -1.11282021, 1.41738919, - 0.47871283, -1.01980420, 1.00212436, -0.78740444, -1.65636133, 1.51466547, - -0.12470397, 0.70404393, -0.15244797, 0.74288871, 0.07339926, -1.45811623, - 0.27185845, 0.08804596, 0.99061977, -1.61752428, 0.29191159, 0.87271953}; - migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; - std::vector m3 = {-1.07692443, 0.85223457, -0.37266530, 2.31511577, 0.04227017, - 1.13229428, -0.52769242, 0.27307182, -0.47779843, -0.08023168, - -0.22862823, 0.81489871, 1.13139581, 1.13860467, 0.24309065, - 0.26533729, 0.49106772, -1.18860493, 0.27842449, 1.03568141, - 0.49759611, 0.10021662, 0.00592602, 0.90862000}; - migraphx::shape m3_shape{migraphx::shape::float_type, {2, 3, 2, 2}}; - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); - float alpha = 0.35; - float beta = 0.41; - auto m12_alpha = migraphx::add_apply_alpha_beta( - *mm, std::vector{l1, l2}, migraphx::make_op("dot"), alpha); - auto l_beta = mm->add_literal(beta); - auto b_beta = mm->add_instruction( - migraphx::make_op("scalar", {{"scalar_bcst_dims", m12_alpha->get_shape().lens()}}), l_beta); - auto m3_beta = mm->add_instruction(migraphx::make_op("mul"), b_beta, l3); - mm->add_instruction(migraphx::make_op("add"), m3_beta, m12_alpha); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {-0.91147203, 0.47540785, -0.30313587, 0.43325099, -0.43711586, - 0.50928632, 0.06919868, -0.80382802, -0.05125718, -0.06685650, - -0.06972163, 0.32407764, 0.45677396, 0.25909489, 0.56911252, - -0.17183724, 0.10858734, 0.39406289, 0.04662959, 1.07979824, - 0.40355016, 0.52410648, -0.31728447, 1.09550845}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_4D_alpha_beta_C_test) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector m1 = { - 1.23636469, -0.47041261, -0.14375651, -0.48371852, 1.16479301, -0.89361055, - -0.18569086, 1.10700457, -1.02632638, 0.82277012, 0.33525769, 0.52825145, - -1.00141689, 0.45510090, -0.02675039, -0.60454439, 0.38551153, -0.01658514, - 0.93059292, -0.54595188, -0.04911005, -0.91397221, -0.83127477, -1.57685603, - -1.36200452, 2.25822236, -1.23416970, 0.12312496, 0.76232760, -0.83594234, - 1.67418145, -0.19412936, 1.05261378, 0.66246074, -1.15233398, 0.16429736}; - migraphx::shape m1_shape{migraphx::shape::float_type, {2, 3, 2, 3}}; - std::vector m2 = { - -0.87300530, -0.07112838, 0.19196860, -1.04986840, 1.20348200, 0.31966893, - 1.04805440, -2.04777729, -0.67906052, -1.17250760, 0.34305044, -1.01957785, - -1.12694862, 0.18431338, -1.63712290, 0.27566931, -1.11282021, 1.41738919, - 0.47871283, -1.01980420, 1.00212436, -0.78740444, -1.65636133, 1.51466547, - -0.12470397, 0.70404393, -0.15244797, 0.74288871, 0.07339926, -1.45811623, - 0.27185845, 0.08804596, 0.99061977, -1.61752428, 0.29191159, 0.87271953}; - migraphx::shape m2_shape{migraphx::shape::float_type, {2, 3, 3, 2}}; - std::vector m3 = {-1.07692443, 0.85223457, -0.37266530, 2.31511577, 0.04227017, - 1.13229428, -0.52769242, 0.27307182, -0.47779843, -0.08023168, - -0.22862823, 0.81489871, 1.13139581, 1.13860467, 0.24309065, - 0.26533729, 0.49106772, -1.18860493, 0.27842449, 1.03568141, - 0.49759611, 0.10021662, 0.00592602, 0.90862000}; - migraphx::shape m3_shape{migraphx::shape::float_type, {2, 3, 2, 2}}; - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, m1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, m2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, m3}); - float alpha = 0.35; - float beta = 0.41; - migraphx::add_apply_alpha_beta(*mm, - std::vector{l1, l2, l3}, - migraphx::make_op("dot"), - alpha, - beta); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - - std::vector m_res = {-0.91147203, 0.47540785, -0.30313587, 0.43325099, -0.43711586, - 0.50928632, 0.06919868, -0.80382802, -0.05125718, -0.06685650, - -0.06972163, 0.32407764, 0.45677396, 0.25909489, 0.56911252, - -0.17183724, 0.10858734, 0.39406289, 0.04662959, 1.07979824, - 0.40355016, 0.52410648, -0.31728447, 1.09550845}; - - EXPECT(migraphx::verify::verify_range(m, m_res)); -} - -TEST_CASE(dot_2D_C_test0) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {-0.86217194, - -1.04129542, - -0.64850364, - -0.97078327, - -0.40516386, - 0.83136927, - 0.37717502, - 0.42271939, - 1.10062165, - -0.92239359, - 0.40403076, - -0.43935377}; - std::vector b = {0.76084386, - 1.89201125, - 1.73218067, - 0.7148568, - -0.55578914, - 0.05799101, - -1.24090721, - -0.51151978, - 1.13255803, - 0.21540723, - -1.10459009, - 0.45580331}; - std::vector c = {-0.80473623, - 0.35154171, - -2.73077756, - -0.09093885, - -1.88850472, - -0.03375556, - -0.41798276, - 2.87368099, - 2.11031439}; - - migraphx::shape a_shape{migraphx::shape::float_type, {3, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {4, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - migraphx::shape c_shape{migraphx::shape::float_type, {3, 3}}; - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - migraphx::add_apply_alpha_beta(*mm, {al, bl, cl}, migraphx::make_op("dot"), 1.0f, 1.0f); - std::vector gold = {-1.60947, - 0.703083, - -5.46156, - -0.181878, - -3.77701, - -0.0675112, - -0.835966, - 5.74736, - 4.22063}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_vv_inner_product) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {0.7481789, - 0.02906279, - 1.01193836, - 1.60222907, - 1.89135978, - 0.30054158, - -0.4892588, - -0.27027533}; - std::vector b = {-0.25829116, - 0.27908929, - -1.27888957, - 0.21152361, - 0.08593658, - 0.52163899, - 1.38343824, - -0.2342857}; - migraphx::shape a_shape{migraphx::shape::float_type, {8}}; - migraphx::shape b_shape{migraphx::shape::float_type, {8}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); - mm->add_instruction(migraphx::make_op("dot"), ual, ubl); - std::vector gold = {-1.43461}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {0.7481789, - 0.02906279, - 1.01193836, - 1.60222907, - 1.89135978, - 0.30054158, - -0.4892588, - -0.27027533}; - std::vector b = {-0.25829116, - 0.27908929, - -1.27888957, - 0.21152361, - 0.08593658, - 0.52163899, - 1.38343824, - -0.2342857}; - migraphx::shape a_shape{migraphx::shape::float_type, {8}}; - migraphx::shape b_shape{migraphx::shape::float_type, {8}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); - float alpha = 0.32f; - migraphx::add_apply_alpha_beta( - *mm, std::vector{ual, ubl}, migraphx::make_op("dot"), alpha); - std::vector gold = {-0.4590752}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_vm) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {1.49530002, - -0.07181969, - 0.44593846, - -0.8645019, - 0.52992304, - -0.4910338, - -2.12179422, - -0.45962977}; - std::vector b = {-0.06210242, 0.0187149, 1.47482984, -1.19590602, -0.45601701, - 0.36934488, -0.83913193, 0.75350964, 0.80707019, 0.35923582, - -2.18480722, -0.85608682, 0.75849199, 0.49103473, -0.91329477, - -0.36364322, -0.69688937, 0.07165814, -0.15505523, 0.52221663, - -0.98631192, -0.37353654, -1.89818706, -0.87209739, -0.33942003, - 0.11390353, 0.78181162, -0.18395337, -0.34743419, -0.08091231, - 1.21119765, 1.23869861, 1.42169414, 0.86412382, 1.05898002, - -0.31918307, 1.08546695, 1.50682711, -0.66083538, -0.32683929}; - migraphx::shape a_shape{migraphx::shape::float_type, {8}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - migraphx::shape b_shape{migraphx::shape::float_type, {8, 5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), ual, bl); - std::vector gold = {-3.78111, -3.40007, -2.1972, -3.31448, -3.80326}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {1.49530002, - -0.07181969, - 0.44593846, - -0.8645019, - 0.52992304, - -0.4910338, - -2.12179422, - -0.45962977}; - std::vector b = {-0.06210242, 0.0187149, 1.47482984, -1.19590602, -0.45601701, - 0.36934488, -0.83913193, 0.75350964, 0.80707019, 0.35923582, - -2.18480722, -0.85608682, 0.75849199, 0.49103473, -0.91329477, - -0.36364322, -0.69688937, 0.07165814, -0.15505523, 0.52221663, - -0.98631192, -0.37353654, -1.89818706, -0.87209739, -0.33942003, - 0.11390353, 0.78181162, -0.18395337, -0.34743419, -0.08091231, - 1.21119765, 1.23869861, 1.42169414, 0.86412382, 1.05898002, - -0.31918307, 1.08546695, 1.50682711, -0.66083538, -0.32683929}; - migraphx::shape a_shape{migraphx::shape::float_type, {8}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - migraphx::shape b_shape{migraphx::shape::float_type, {8, 5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - float alpha = 0.5f; - migraphx::add_apply_alpha_beta( - *mm, std::vector{ual, bl}, migraphx::make_op("dot"), alpha); - std::vector gold = {-1.89056, -1.70003, -1.0986, -1.65724, -1.90163}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -1.7468318, -0.38900251, 1.00183915, 0.06016438, 0.08295905, 1.5830535}; - std::vector b = { - 1.2459538, 0.39586199, -0.77035574, 0.22689828, 0.3289835, 1.02804361, - -0.22941113, -0.33940324, 0.80078249, 1.0319152, 0.80034948, -0.11631159, - 0.36899208, -0.28506697, -1.2211584, -0.55678377, -0.3618498, 0.34857264, - -0.38700147, -0.43434611, 1.73029783, -0.71578372, 0.09777723, 0.06616614, - -1.66721186, -0.16046032, -1.64581663, 1.09373609, -0.14127692, -0.01938473, - -0.67310303, -1.56154787, -1.0665462, 0.68538535, -1.53920085, -0.35710272, - 0.06887234, 0.17474616, 1.08194804, -0.19990148, -0.91149488, 0.95303646, - 0.95448717, -0.49332393, -1.762213, -0.56571194, -1.69704968, -0.82798066, - 0.65531872, 1.5007798, 0.99877355, 0.53386114, -0.88150609, -1.0756985, - 0.50962511, -0.68019002, 0.1583068, 2.83988407, -1.10292457, 0.02126969, - 0.21129951, 0.25690146, -1.6490316, 0.55261771, -1.70504303, -0.02870394, - -0.18205627, 0.29446203, -1.91360924, 0.46102174, 0.44977568, -0.48113321}; - - migraphx::shape a_shape{migraphx::shape::float_type, {6}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - auto bual = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {3, 1, 6}}}), ual); - migraphx::shape b_shape{migraphx::shape::float_type, {3, 6, 4}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), bual, bl); - std::vector gold = {1.22914, - -1.17896, - 2.28596, - -0.345637, - -0.962362, - 0.168508, - -0.947471, - -3.02458, - -3.80131, - 1.38484, - -2.45019, - -1.35064}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -1.7468318, -0.38900251, 1.00183915, 0.06016438, 0.08295905, 1.5830535}; - std::vector b = { - 1.2459538, 0.39586199, -0.77035574, 0.22689828, 0.3289835, 1.02804361, - -0.22941113, -0.33940324, 0.80078249, 1.0319152, 0.80034948, -0.11631159, - 0.36899208, -0.28506697, -1.2211584, -0.55678377, -0.3618498, 0.34857264, - -0.38700147, -0.43434611, 1.73029783, -0.71578372, 0.09777723, 0.06616614, - -1.66721186, -0.16046032, -1.64581663, 1.09373609, -0.14127692, -0.01938473, - -0.67310303, -1.56154787, -1.0665462, 0.68538535, -1.53920085, -0.35710272, - 0.06887234, 0.17474616, 1.08194804, -0.19990148, -0.91149488, 0.95303646, - 0.95448717, -0.49332393, -1.762213, -0.56571194, -1.69704968, -0.82798066, - 0.65531872, 1.5007798, 0.99877355, 0.53386114, -0.88150609, -1.0756985, - 0.50962511, -0.68019002, 0.1583068, 2.83988407, -1.10292457, 0.02126969, - 0.21129951, 0.25690146, -1.6490316, 0.55261771, -1.70504303, -0.02870394, - -0.18205627, 0.29446203, -1.91360924, 0.46102174, 0.44977568, -0.48113321}; - - migraphx::shape a_shape{migraphx::shape::float_type, {6}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto ual = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0}}}), al); - auto bual = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {3, 1, 6}}}), ual); - migraphx::shape b_shape{migraphx::shape::float_type, {3, 6, 4}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - migraphx::add_apply_alpha_beta( - *mm, std::vector{bual, bl}, migraphx::make_op("dot"), 0.21f); - std::vector gold = {0.25812, - -0.247582, - 0.480051, - -0.0725837, - -0.202096, - 0.0353867, - -0.198969, - -0.635161, - -0.798275, - 0.290817, - -0.514539, - -0.283635}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_mv) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {0.1612524, - 0.61266466, - -0.19212896, - 1.34228825, - -1.09746949, - 0.4680955, - -0.431748, - -0.89791241, - -2.19078702, - -0.13767058, - -1.66105228, - -0.91834613, - 0.59199744, - 1.41967261, - 0.76237423}; - - std::vector b = {0.14365572, 0.23401411, -0.8970094, -0.12526676, -1.04703286}; - - migraphx::shape a_shape{migraphx::shape::float_type, {3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); - mm->add_instruction(migraphx::make_op("dot"), al, ubl); - std::vector gold = {1.31982, 1.19022, -1.96062}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {0.1612524, - 0.61266466, - -0.19212896, - 1.34228825, - -1.09746949, - 0.4680955, - -0.431748, - -0.89791241, - -2.19078702, - -0.13767058, - -1.66105228, - -0.91834613, - 0.59199744, - 1.41967261, - 0.76237423}; - - std::vector b = {0.14365572, 0.23401411, -0.8970094, -0.12526676, -1.04703286}; - - migraphx::shape a_shape{migraphx::shape::float_type, {3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); - float alpha = 0.3f; - migraphx::add_apply_alpha_beta( - *mm, std::vector{al, ubl}, migraphx::make_op("dot"), alpha); - std::vector gold = {0.395946, 0.357067, -0.588187}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - 1.24593227, -0.84351316, 0.27882229, -0.42518484, -1.11391528, 0.59141834, - 1.34198714, 2.25884063, -1.32093452, 0.44766336, -0.09306479, 0.47526699, - 0.25858488, 1.30820392, 1.17186787, 0.31530864, -1.19159424, -0.24100903, - -1.03857886, 1.54453427, 0.05041654, 1.67108177, 0.965805, 0.52958924, - -1.61243992, 0.02941846, 0.77523836, 1.97963853, -2.51093596, 0.21882645, - -2.60193574, 1.1899952, 1.70883519, 0.94586745, 2.65002512, -1.42427102, - 1.0143951, -1.34115312, 1.63833732, -1.46477355, 0.44014877, 0.58032696, - -1.63874372, -0.82834423, 1.81131778, -0.52393379, 1.16721943, 0.39488835, - 0.23947128, -0.15733194, 0.19451158, 1.21315445, 0.44594897, 0.40809135, - -0.64252994, 0.7541716, -0.97203195, 0.69208485, 0.34350988, 0.9836842}; - std::vector b = {0.05013914, 1.39932885, 2.56616476, 1.02225623, -0.03977829}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto ubl = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), bl); - auto bubl = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 1}}}), ubl); - mm->add_instruction(migraphx::make_op("dot"), al, bubl); - std::vector gold = {-0.792717, - 6.33595, - 2.61466, - -3.39322, - 5.42485, - 3.59084, - 6.78139, - -0.360492, - -4.28998, - 2.87146, - 3.29447, - 0.765651}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_mm1) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -0.49450006, -1.07431991, -0.02796692, -0.99631927, 0.20040449, -1.39709437, - -0.15695328, 0.08208373, -0.09746386, 0.77923021, -0.1849151, 0.14419043, - -0.25798175, -0.2504807, -1.11134383, -0.71030613, -0.20234025, 0.90229168, - 0.62643053, -0.83512638, 1.66051254, 0.05941673, 0.73081559, 0.27111867, - 0.55060745, 0.34999583, 1.02236619, 0.60178395, 1.49646162, 1.93255155, - -3.65357913, -1.38059906, -0.46302398, 0.19847152, 0.39785875, 1.47004861, - -1.24482133, -0.01954702, 0.36073898, 1.56055978, -0.10344603, -0.34283135, - -0.56482649, 1.80861249, -0.92268202, 0.94371182, -0.02373232, -0.75441145, - 0.43325034, 0.4057425, -0.48844822, -0.36390512, 0.74110406, 1.25158366, - 0.52196654, 1.43461691, -0.57530864, -0.66716206, -1.76516289, 0.96582849}; - std::vector b = {0.49899375, - -2.20168661, - 1.08895066, - -0.01135643, - 0.90570669, - -1.43550963, - -1.73033377, - 0.21338776, - 0.96962508, - 0.38913968, - -0.32822861, - 0.88222863, - 0.93330718, - -1.24265228, - -1.62587164}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {5, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto bbl = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); - mm->add_instruction(migraphx::make_op("dot"), al, bbl); - std::vector gold = {-0.386828, 0.187735, -0.22822, -0.148057, 2.015, -2.56938, - -0.782212, 1.9459, 0.927426, -2.44907, 2.40531, 2.30232, - 0.182745, -4.21937, 1.77551, 1.50775, -2.60888, -2.32484, - -0.557691, 6.13527, -2.91743, 2.37836, -6.42584, 1.14979, - 0.77227, 0.349659, 2.92759, 2.32384, -2.90664, 0.0527679, - -0.547761, -0.155467, 0.964619, 2.09133, -4.44281, -1.3864}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {-0.0309568, - -1.57294749, - -0.00768606, - 1.5786921, - 0.50519718, - 0.10530702, - -0.05302112, - -0.06503757, - 0.4079716, - 0.0799132, - -0.82624962, - 0.49341502}; - - std::vector b = { - 0.3664867, 0.24649534, 1.14728076, 1.09911548, -1.23711247, -0.49436419, - -0.67557879, -0.84180575, -1.09754376, 0.07807351, 0.74349043, -0.92084701, - 0.50267885, 0.78709401, 0.80598159, -0.51269589, -0.40337193, 0.29457878, - 1.25447301, -1.66251457, -1.54652239, -0.35067765, -0.5214464, -0.7866878, - 1.11128573, 0.26927291, -0.0929818, 0.07523954, 0.3256776, -1.08617826, - 0.89294253, -0.91007619, -2.42825765, -1.76805581, 1.08136334, -0.14521253, - -1.32061148, 0.60663124, -1.19835255, -0.98803563, -1.06927896, -0.51967419, - -0.98974639, 1.01287011, 1.34910394, 0.1203349, 0.67387452, -0.32447465, - 1.15187449, -0.82253807, 0.22302433, 0.46434695, 0.319647, 1.56459445, - 0.15664012, 0.03998102, 0.62981041, 0.11831296, 0.47824434, -0.93941882, - -0.34674036, 1.17071104, 0.59203806, 2.75817738, -0.69300013, 1.30971899, - -0.14231862, -1.90915568, -0.06895489, 0.20160375, 0.01945916, 0.03586956}; - - migraphx::shape a_shape{migraphx::shape::float_type, {3, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto bal = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 3, 3, 4}}}), al); - migraphx::shape b_shape{migraphx::shape::float_type, {2, 3, 4, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), bal, bl); - std::vector gold = { - -1.61175, 3.11849, -0.703205, 0.331635, -0.00946922, 0.645626, 0.834069, 1.06409, - 0.881037, 0.227628, -0.200308, -1.71836, 0.156255, 0.477222, 0.571363, -1.04543, - 1.40524, 1.24201, -2.95083, 1.19352, 1.5008, 0.636987, 0.148256, -0.0231631, - -1.15079, 1.42139, 1.80996, 1.79259, 2.7192, 0.331902, -0.726565, 0.0963351, - -0.710558, 0.259424, -0.342345, -1.80522, -0.580476, 0.277368, -3.95582, 0.614823, - -0.415107, 0.305138, 0.435993, -0.107089, -0.767885, -4.00837, 1.09921, -2.02129, - 0.109717, 0.618422, 0.438342, 0.29602, 2.00928, 0.420871}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_mm2) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -0.49450006, -1.07431991, -0.02796692, -0.99631927, 0.20040449, -1.39709437, - -0.15695328, 0.08208373, -0.09746386, 0.77923021, -0.1849151, 0.14419043, - -0.25798175, -0.2504807, -1.11134383, -0.71030613, -0.20234025, 0.90229168, - 0.62643053, -0.83512638, 1.66051254, 0.05941673, 0.73081559, 0.27111867, - 0.55060745, 0.34999583, 1.02236619, 0.60178395, 1.49646162, 1.93255155, - -3.65357913, -1.38059906, -0.46302398, 0.19847152, 0.39785875, 1.47004861, - -1.24482133, -0.01954702, 0.36073898, 1.56055978, -0.10344603, -0.34283135, - -0.56482649, 1.80861249, -0.92268202, 0.94371182, -0.02373232, -0.75441145, - 0.43325034, 0.4057425, -0.48844822, -0.36390512, 0.74110406, 1.25158366, - 0.52196654, 1.43461691, -0.57530864, -0.66716206, -1.76516289, 0.96582849}; - std::vector b = {-1.12211357, 1.74720423, 0.60382572, -0.61090125, -0.3315936, - 0.30924675, -0.28906435, 0.64039247, -1.2822253, 0.55899286, - 2.14013013, 1.00944809, 0.21660017, -0.75465098, 0.12097934, - -1.64006315, 0.43582108, -0.64348541, 0.43101069, 1.30191386, - 1.7746011, 0.24935804, 0.42830791, -0.13593643, 0.38749427, - 1.39776254, -0.42911717, -1.3537624, -0.81999648, -0.1754485}; - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {2, 1, 5, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto bbl = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); - std::vector gold = { - 0.70574512, -2.80915314, -1.57644969, 1.75415381, -3.13303087, -1.00150259, - -0.18675123, -0.23349122, -0.12357225, 0.82911538, 1.37473744, -1.11709934, - -1.84001907, 3.51427391, 0.42425673, 0.0638482, 2.40210271, 1.50027643, - 4.81988916, -3.63687142, -0.19101717, -4.92522092, -1.76377022, -3.58095615, - 1.83096922, 2.5512663, -1.07926588, -2.12749134, 0.33014536, -0.80393025, - 0.60740202, 0.95217761, -1.06087445, -4.75868152, -3.6687713, -1.26539821}; - mm->add_instruction(migraphx::make_op("dot"), al, bbl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = {-0.19276159, -1.2568421, -0.321242, 1.21471077, -0.4927751, - 0.69446894, -0.1786371, -1.00763473, -0.10279314, 3.02931355, - 1.08359235, -0.35190132, -0.00639111, 0.78989113, 1.23538029, - 0.4590747, 0.17304142, 0.42512412, 0.21076913, -0.01724556, - -0.17763898, 0.12852236, -0.00459301, 1.34498824, 0.02907823, - 0.1784464, -0.20790355, -0.52336699, 0.45804085, 1.06025801}; - - std::vector b = {-1.12211357, 1.74720423, 0.60382572, -0.61090125, -0.3315936, - 0.30924675, -0.28906435, 0.64039247, -1.2822253, 0.55899286, - 2.14013013, 1.00944809, 0.21660017, -0.75465098, 0.12097934, - -1.64006315, 0.43582108, -0.64348541, 0.43101069, 1.30191386, - 1.7746011, 0.24935804, 0.42830791, -0.13593643, 0.38749427, - 1.39776254, -0.42911717, -1.3537624, -0.81999648, -0.1754485}; - migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 3, 5}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - auto bal = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3, 5}}}), al); - migraphx::shape b_shape{migraphx::shape::float_type, {2, 1, 5, 3}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto bbl = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 5, 3}}}), bl); - mm->add_instruction(migraphx::make_op("dot"), bal, bbl); - std::vector gold = { - 1.64924590e+00, 2.84575831e+00, 1.07340773e+00, 2.19817080e-01, -1.87873283e+00, - 1.91883003e+00, -2.89962196e-01, 2.76404142e+00, 1.50048102e+00, -6.29650347e-01, - 1.48105185e+00, -3.71716505e-03, 8.80281500e-01, 2.50057585e+00, 1.29958508e+00, - 5.63751779e-01, 2.25703781e-01, 1.30516919e+00, 8.32118386e-01, 2.44050864e-01, - -2.49748221e+00, -5.60803176e+00, -2.98919069e+00, -1.11429417e+00, -3.29675989e+00, - 1.02442564e-01, -1.87659303e+00, -4.67302454e-01, 9.16189968e-01, -1.33537175e-01, - 8.27398578e-01, 1.94406914e+00, -2.39250915e-01, -1.77062701e+00, -6.46239534e-01, - -7.95202750e-01}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -0.55248691, 0.70275958, 0.56967633, 0.88206033, -0.85088547, 0.05689149, - -0.20084703, 0.18024434, 1.0730491, 0.15913531, 0.93621628, 0.35072771, - 1.28616952, 1.55384379, 0.30376261, -1.12356544, -0.64271552, -2.50703079, - -0.23994372, 0.8166084, 0.06542249, -0.17472336, -0.37665211, 0.16342699, - 0.07645941, 0.65024333, -1.19883423, -0.40536776, -0.31132765, 0.78113691, - -0.16887638, 2.30797418, -0.36241233, 0.33552153, -1.05343996, -0.16909699, - -1.22608815, 1.64165613, 0.96260828, -0.16733976, 0.84211199, 1.31243813, - 0.89258549, -0.48250384, -1.06005206, 1.37021342, -0.35658565, 0.26879188}; - - std::vector b = { - 0.17111129, -0.82134741, -1.58001178, -1.46759447, 0.31522514, -0.11567352, - -0.038978, -0.3601414, -0.84379876, 0.24848939, -0.37080544, 0.00838631, - 1.51316241, 0.42385344, 2.06043846, 1.82348849, 1.07180434, 0.6567393, - 1.41164561, 0.73091185, -0.33541302, -0.98082287, -0.06605479, 0.82219717, - -1.41619634, 0.51326658, 0.26916313, 0.79819769, 0.85583702, 0.07876046, - -0.42375545, -0.7758751, 1.14334296, -0.14211708, -1.54520411, -0.55244869, - -0.48478899, 0.10782164, -0.20879552, -0.99019754, 1.78783102, -1.31610052, - 1.73510175, -0.48360172, 0.62367417, -1.34180545, -0.37512931, -1.50521357, - 0.08383314, 0.76165608, -0.4961646, 0.95821311, -0.68407191, 0.48299435, - -0.24323988, 0.34793412, 0.37908669, 1.19083454, 1.30218795, -0.26731035, - -0.34544132, -0.09595373, 0.50951334, 0.48896956, 0.38753818, -0.4939919, - 0.02352126, 0.42013764, 0.07027765, 0.21169851, -0.24411376, -1.77793736, - -0.88370924, 0.95294025, -0.08208804, -0.95943892, 0.30280474, 1.1967013, - -1.17700948, 0.29533973}; - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {2, 2, 4, 5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - mm->add_instruction(migraphx::make_op("dot"), al, bl); - std::vector gold = { - 1.22136035, 1.3765651, 2.0611395, 1.70445494, 1.8189619, 0.2509717, - 0.88815736, 1.13837946, 1.37006127, -0.53617378, 0.45759693, -0.503786, - -0.10575749, -0.81715738, 2.56316255, 0.85812927, -0.53425671, 1.38147704, - 2.57874755, -1.05591061, -1.42065674, -0.25412658, -2.14494165, -2.81045272, - 0.27491485, -0.04229986, 0.10181043, -0.55680682, -0.07633866, 0.313767, - -0.28202571, -1.64696179, -0.50872733, -1.08935912, 0.94291084, -0.71792156, - 0.82981387, 1.14797592, 3.13989358, -0.17507726, -0.63429162, -0.72241531, - -0.61459168, -0.52561056, 0.3309648, -0.46185697, -1.60586695, -0.98590829, - 0.63012062, -0.25606052, -0.69419352, -1.78299913, -0.38572706, 1.92249442, - 0.3884186, -0.48153048, 0.84932351, 0.67234919, -1.07821322, -0.01208216}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - std::vector a = { - -0.55248691, 0.70275958, 0.56967633, 0.88206033, -0.85088547, 0.05689149, - -0.20084703, 0.18024434, 1.0730491, 0.15913531, 0.93621628, 0.35072771, - 1.28616952, 1.55384379, 0.30376261, -1.12356544, -0.64271552, -2.50703079, - -0.23994372, 0.8166084, 0.06542249, -0.17472336, -0.37665211, 0.16342699, - 0.07645941, 0.65024333, -1.19883423, -0.40536776, -0.31132765, 0.78113691, - -0.16887638, 2.30797418, -0.36241233, 0.33552153, -1.05343996, -0.16909699, - -1.22608815, 1.64165613, 0.96260828, -0.16733976, 0.84211199, 1.31243813, - 0.89258549, -0.48250384, -1.06005206, 1.37021342, -0.35658565, 0.26879188}; - - std::vector b = {-0.33734601, 0.66386073, 0.41425048, 0.40190389, -0.99645073, - -0.10017067, -0.58542118, 0.48636962, 0.06301405, 1.14669128, - -0.06526677, 0.23172741, -1.49693143, -0.44464233, -0.12775566, - -1.32038007, 1.1812471, 1.22362746, -0.49013843, 0.25339836, - 1.31698705, 1.54256669, 0.11211132, -0.18005487, 0.36730145, - 0.97705953, -0.18909084, 0.544932, 0.32891878, 0.64250015, - -0.41381398, 0.47402562, 1.22286761, 1.07573211, -0.92988077, - -0.36340925, -1.76152377, -0.96642674, -0.79231929, 0.11517073}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape b_shape{migraphx::shape::float_type, {2, 4, 5}}; - auto bl = mm->add_literal(migraphx::literal{b_shape, b}); - auto bbl = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 4, 5}}}), bl); - mm->add_instruction(migraphx::make_op("dot"), al, bbl); - std::vector gold = { - -1.08585245, 0.39575611, 0.33947977, -0.86339678, 1.50710753, 0.05646156, - -0.43180359, 0.19639674, -0.33742881, 0.98443538, -0.9021272, 1.25043704, - -0.45038184, -0.14689614, -0.91749459, 3.49467934, 3.81336312, 2.4482385, - 1.49649707, 1.05889193, -3.49343731, -2.06958956, -2.52082858, -1.61401519, - -1.52966956, 0.01191848, -0.33246613, -0.70641362, -0.60391255, 0.28083355, - 0.52255496, -1.08655006, 1.64648546, 0.80344255, 0.71987865, -3.00960296, - 2.02318221, 3.32785057, -1.13203844, 1.81235734, 0.38067585, -0.88086897, - 1.38307367, 0.42677257, 0.83759966, -0.34827442, -1.45067092, 2.09599671, - 1.92882983, -0.30996324, 2.19736278, 2.32389426, 2.36741832, 1.62253915, - 0.26698225, -0.00741609, -2.53680983, -0.0679954, 0.04499683, 0.85354276}; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(dot_dyn_2D_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, {{1, 4}, {5, 5}}}; - auto ap = mm->add_parameter("a", a_shape); - migraphx::shape b_shape{migraphx::shape::float_type, {5, 3}}; - auto bp = mm->add_parameter("b", b_shape); - mm->add_instruction(migraphx::make_op("dot"), ap, bp); - p.compile(migraphx::make_target("ref")); - - std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, - 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, - -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, - -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; - std::vector b = {6.09568541e-01, - -6.10527007e-01, - 3.66646462e-01, - 1.18951101e-01, - 5.58777432e-01, - -3.21296298e-01, - -5.95997198e-01, - -5.01425721e-01, - -2.84606807e-01, - -5.73673557e-01, - -8.99430260e-01, - -4.25103093e-01, - 1.53027987e+00, - -3.81407415e-04, - -3.29650255e-01}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {4, 5}}; - migraphx::parameter_map params; - params["a"] = migraphx::argument(input_fixed_shape, a.data()); - params["b"] = migraphx::argument(b_shape, b.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector c = {-1.56327541e+00, - -7.09570140e-01, - -5.37424982e-01, - -2.22994831e-01, - -2.15586437e+00, - 2.09177941e-03, - -1.47279677e+00, - 2.02627040e-01, - -6.04527691e-01, - -1.29885596e+00, - 2.16294914e+00, - -1.48101497e-01}; - EXPECT(migraphx::verify::verify_range(c, results_vector)); -} - -TEST_CASE(dot_dyn_4D_test) -{ - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, {{1, 1}, {1, 1}, {4, 6, {4}}, {5, 5}}}; - auto al = mm->add_parameter("a", a_shape); - migraphx::shape b_shape{migraphx::shape::float_type, {1, 1, 5, 3}}; - auto bl = mm->add_parameter("b", b_shape); - mm->add_instruction(migraphx::make_op("dot"), al, bl); - p.compile(migraphx::make_target("ref")); - - std::vector a = {-0.00925222, 0.56250403, 0.70107397, 0.75402161, -0.505885, - 1.33628943, -0.11413, -0.31270559, 1.59336732, -0.19361027, - -0.91620867, 0.40108416, -0.06969921, 0.68483471, -0.39906632, - -1.66423624, 0.69040076, -1.31490171, -0.11282616, -0.79391814}; - std::vector b = {6.09568541e-01, - -6.10527007e-01, - 3.66646462e-01, - 1.18951101e-01, - 5.58777432e-01, - -3.21296298e-01, - -5.95997198e-01, - -5.01425721e-01, - -2.84606807e-01, - -5.73673557e-01, - -8.99430260e-01, - -4.25103093e-01, - 1.53027987e+00, - -3.81407415e-04, - -3.29650255e-01}; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 1, 4, 5}}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 1, 5, 3}}; - migraphx::parameter_map params; - params["a"] = migraphx::argument(input_fixed_shape0, a.data()); - params["b"] = migraphx::argument(input_fixed_shape1, b.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector c = {-1.56327541e+00, - -7.09570140e-01, - -5.37424982e-01, - -2.22994831e-01, - -2.15586437e+00, - 2.09177941e-03, - -1.47279677e+00, - 2.02627040e-01, - -6.04527691e-01, - -1.29885596e+00, - 2.16294914e+00, - -1.48101497e-01}; - EXPECT(migraphx::verify::verify_range(c, results_vector)); -} - -TEST_CASE(quant_dot_2args_multi4) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 8}}; - std::vector data1(4 * 4); - std::vector data2(4 * 8); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); - - std::vector gold = {112, 118, 124, 130, 136, 142, 148, 154, 304, 326, 348, - 370, 392, 414, 436, 458, 496, 534, 572, 610, 648, 686, - 724, 762, 688, 742, 796, 850, 904, 958, 1012, 1066}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 8}}; - std::vector data1(4 * 4); - std::vector data2(4 * 8); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - mm->add_instruction(migraphx::make_op("quant_dot"), tl1, l2); - - std::vector gold = {448, 472, 496, 520, 544, 568, 592, 616, 496, 524, 552, - 580, 608, 636, 664, 692, 544, 576, 608, 640, 672, 704, - 736, 768, 592, 628, 664, 700, 736, 772, 808, 844}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 4}}; - std::vector data1(4 * 4); - std::vector data2(4 * 8); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - mm->add_instruction(migraphx::make_op("quant_dot"), l1, tl2); - - std::vector gold = {14, 38, 62, 86, 110, 134, 158, 182, 38, 126, 214, - 302, 390, 478, 566, 654, 62, 214, 366, 518, 670, 822, - 974, 1126, 86, 302, 518, 734, 950, 1166, 1382, 1598}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 4}}; - std::vector data1(4 * 4); - std::vector data2(4 * 8); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - mm->add_instruction(migraphx::make_op("quant_dot"), tl1, tl2); - - std::vector gold = {56, 152, 248, 344, 440, 536, 632, 728, 62, 174, 286, - 398, 510, 622, 734, 846, 68, 196, 324, 452, 580, 708, - 836, 964, 74, 218, 362, 506, 650, 794, 938, 1082}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(quant_dot_2args_general) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; - std::vector data1(3 * 4); - std::vector data2(4 * 5); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); - - std::vector gold = { - 70, 76, 82, 88, 94, 190, 212, 234, 256, 278, 310, 348, 386, 424, 462}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 3}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; - std::vector data1(4 * 3); - std::vector data2(4 * 5); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - mm->add_instruction(migraphx::make_op("quant_dot"), tl1, l2); - - std::vector gold = { - 210, 228, 246, 264, 282, 240, 262, 284, 306, 328, 270, 296, 322, 348, 374}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {5, 4}}; - std::vector data1(3 * 4); - std::vector data2(4 * 5); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - - migraphx::add_apply_alpha_beta(*mm, {l1, tl2}, migraphx::make_op("quant_dot"), 2); - - std::vector gold = { - 28, 76, 124, 172, 220, 76, 252, 428, 604, 780, 124, 428, 732, 1036, 1340}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {4, 3}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {5, 4}}; - std::vector data1(4 * 3); - std::vector data2(4 * 5); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - migraphx::add_apply_alpha_beta(*mm, {tl1, tl2}, migraphx::make_op("quant_dot"), 3); - - std::vector gold = { - 126, 342, 558, 774, 990, 144, 408, 672, 936, 1200, 162, 474, 786, 1098, 1410}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(quant_dot_3args_general) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 8}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 7}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; - std::vector data1(2 * 8); - std::vector data2(8 * 7); - std::vector data3(2 * 7); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {l1, l2, l3}, migraphx::make_op("quant_dot"), 1, 1); - - std::vector gold = { - 982, 1011, 1040, 1069, 1098, 1127, 1156, 2557, 2650, 2743, 2836, 2929, 3022, 3115}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {3, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {4, 5}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {3, 5}}; - std::vector data1(3 * 4); - std::vector data2(4 * 5); - std::vector data3(3 * 5); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 0); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - mm->add_instruction(migraphx::make_op("quant_dot"), l1, l2); - - std::vector gold = { - 70, 76, 82, 88, 94, 190, 212, 234, 256, 278, 310, 348, 386, 424, 462}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {8, 2}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {8, 7}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; - std::vector data1(2 * 8); - std::vector data2(8 * 7); - std::vector data3(2 * 7); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {tl1, l2, l3}, migraphx::make_op("quant_dot"), 1, 3); - - std::vector gold = { - 1966, 2025, 2084, 2143, 2202, 2261, 2320, 2183, 2250, 2317, 2384, 2451, 2518, 2585}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 8}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; - std::vector data1(2 * 8); - std::vector data2(8 * 7); - std::vector data3(2 * 7); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {l1, tl2, l3}, migraphx::make_op("quant_dot"), 2, 3); - - std::vector gold = { - 286, 737, 1188, 1639, 2090, 2541, 2992, 755, 2230, 3705, 5180, 6655, 8130, 9605}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {8, 2}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}}; - std::vector data1(2 * 8); - std::vector data2(8 * 7); - std::vector data3(2 * 7); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l2); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {tl1, tl2, l3}, migraphx::make_op("quant_dot"), 3, 2); - - std::vector gold = { - 844, 2190, 3536, 4882, 6228, 7574, 8920, 942, 2480, 4018, 5556, 7094, 8632, 10170}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -TEST_CASE(quant_dot_3args_batch) -{ - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 2, 2, 4}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {2, 2, 4, 7}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 2, 2, 7}}; - std::vector data1(4 * 2 * 4); - std::vector data2(4 * 4 * 7); - std::vector data3(4 * 2 * 7); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {l1, l2, l3}, migraphx::make_op("quant_dot"), 1, 2); - - std::vector gold = { - 102, 110, 118, 126, 134, 142, 150, 284, 308, 332, 356, 380, - 404, 428, 1530, 1570, 1610, 1650, 1690, 1730, 1770, 2160, 2216, 2272, - 2328, 2384, 2440, 2496, 4750, 4822, 4894, 4966, 5038, 5110, 5182, 5828, - 5916, 6004, 6092, 6180, 6268, 6356, 9762, 9866, 9970, 10074, 10178, 10282, - 10386, 11288, 11408, 11528, 11648, 11768, 11888, 12008}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } - - { - migraphx::program p; - - auto* mm = p.get_main_module(); - migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 2, 4, 3}}; - migraphx::shape m2_shape{migraphx::shape::int8_type, {2, 2, 6, 4}}; - migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 2, 3, 6}}; - std::vector data1(48); - std::vector data2(96); - std::vector data3(72); - std::iota(data1.begin(), data1.end(), 0); - std::iota(data2.begin(), data2.end(), 0); - std::iota(data3.begin(), data3.end(), 2); - - auto l1 = mm->add_literal(migraphx::literal{m1_shape, data1}); - auto tl1 = mm->add_instruction( - migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1); - auto l2 = mm->add_literal(migraphx::literal{m2_shape, data2}); - auto tl2 = mm->add_instruction( - migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2); - auto l3 = mm->add_literal(migraphx::literal{m3_shape, data3}); - migraphx::add_apply_alpha_beta(*mm, {tl1, tl2, l3}, migraphx::make_op("quant_dot"), 2, 3); - - std::vector gold = { - 90, 237, 384, 531, 678, 825, 120, 299, 478, 657, 836, 1015, - 150, 361, 572, 783, 994, 1205, 3456, 3987, 4518, 5049, 5580, 6111, - 3678, 4241, 4804, 5367, 5930, 6493, 3900, 4495, 5090, 5685, 6280, 6875, - 11430, 12345, 13260, 14175, 15090, 16005, 11844, 12791, 13738, 14685, 15632, 16579, - 12258, 13237, 14216, 15195, 16174, 17153, 24012, 25311, 26610, 27909, 29208, 30507, - 24618, 25949, 27280, 28611, 29942, 31273, 25224, 26587, 27950, 29313, 30676, 32039}; - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector m; - result.visit([&](auto output) { m.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(m, gold)); - } -} - -int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/ref_ops_nonstd_shape_test.cpp b/test/ref_ops_nonstd_shape_test.cpp deleted file mode 100644 index c77dec43779..00000000000 --- a/test/ref_ops_nonstd_shape_test.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.hpp" - -TEST_CASE(argmax_test_nonstd_shape) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto dl = mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {2, 3, 4}})); - auto dl_trans = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), dl); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", -3}}), dl_trans); - auto p_uncompiled = p; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto res_gold = p_uncompiled.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - std::vector res_gold_vec; - res_gold.visit([&](auto output) { res_gold_vec.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(result_vec, res_gold_vec)); -} - -TEST_CASE(argmin_test_nonstd_shape) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto dl = mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {2, 3, 4}})); - auto dl_trans = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), dl); - mm->add_instruction(migraphx::make_op("argmin", {{"axis", -1}}), dl_trans); - auto p_uncompiled = p; - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto res_gold = p_uncompiled.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - std::vector res_gold_vec; - res_gold.visit([&](auto output) { res_gold_vec.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(result_vec, res_gold_vec)); -} - -TEST_CASE(isnan_broadcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s0{migraphx::shape::float_type, {3}}; - migraphx::shape s1{migraphx::shape::float_type, {3, 2}}; - auto nan_val = std::numeric_limits::quiet_NaN(); - std::vector data0 = {1.2, 5.2, nan_val}; - auto l0 = mm->add_literal(migraphx::literal{s0, data0}); - auto l1 = mm->add_instruction( - migraphx::make_op("broadcast", {{"axis", 0}, {"out_lens", s1.lens()}}), l0); - mm->add_instruction(migraphx::make_op("isnan"), l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector correct = {0, 0, 0, 0, 1, 1}; - EXPECT(migraphx::verify::verify_range(results_vector, correct)); -} - -TEST_CASE(squeeze_transpose_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto l0 = - mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {4, 1, 3, 1, 3}})); - auto l0_trans = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 2, 3, 0, 4}}}), l0); - mm->add_instruction(migraphx::make_op("squeeze"), l0_trans); - auto p_uncompiled = p; - // contiguous is required to read the values in standard shaped order - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 4, 3}}); - EXPECT(result == expected_result); -} - -TEST_CASE(squeeze_multibroadcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto l0 = - mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {1, 3, 1, 3}})); - auto l0_brcst = mm->add_instruction( - migraphx::make_op("multibroadcast", {{"out_lens", {4, 1, 3, 4, 3}}}), l0); - mm->add_instruction(migraphx::make_op("squeeze"), l0_brcst); - auto p_uncompiled = p; - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {4, 3, 4, 3}}); - EXPECT(result == expected_result); -} - -TEST_CASE(squeeze_slice_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto l0 = - mm->add_literal(migraphx::generate_literal({migraphx::shape::float_type, {1, 3, 4, 3}})); - auto l0_slice = mm->add_instruction( - migraphx::make_op("slice", {{"axes", {2}}, {"starts", {2}}, {"ends", {3}}}), l0); - mm->add_instruction(migraphx::make_op("squeeze"), l0_slice); - auto p_uncompiled = p; - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 3}}); - EXPECT(result == expected_result); -} - -TEST_CASE(unsqueeze_transpose_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; - auto l0 = mm->add_literal(migraphx::generate_literal(s1)); - auto l0_trans = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {2, 0, 1}}}), l0); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0_trans); - auto p_uncompiled = p; - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {3, 4, 1, 3}}); - EXPECT(result == expected_result); -} - -TEST_CASE(unsqueeze_multibroadcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3}}; - auto l0 = mm->add_literal(migraphx::generate_literal(s1)); - auto l0_brcst = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {4, 4, 3, 3}}}), l0); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0_brcst); - auto p_uncompiled = p; - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {4, 4, 1, 3, 3}}); - EXPECT(result == expected_result); -} - -TEST_CASE(unsqueeze_slice_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s1{migraphx::shape::float_type, {2, 3, 4, 4}}; - auto l0 = mm->add_literal(migraphx::generate_literal(s1)); - auto l0_slice = mm->add_instruction( - migraphx::make_op("slice", {{"axes", {3}}, {"starts", {2}}, {"ends", {3}}}), l0); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), l0_slice); - auto p_uncompiled = p; - auto* mm_uncompiled = p_uncompiled.get_main_module(); - mm_uncompiled->add_instruction(migraphx::make_op("contiguous"), - std::prev(mm_uncompiled->end())); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto expected_result = p_uncompiled.eval({}).back(); - EXPECT(result.get_shape() == migraphx::shape{migraphx::shape::float_type, {2, 1, 3, 4, 1}}); - EXPECT(result == expected_result); -} - -int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/ref_ops_test.cpp b/test/ref_ops_test.cpp deleted file mode 100644 index 07ad39cbde5..00000000000 --- a/test/ref_ops_test.cpp +++ /dev/null @@ -1,8901 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test.hpp" -#include -#include - -float sigmoid(float x) { return 1 / (1 + expf(-x)); } - -float elu(float a, float x) { return x > 0 ? x : a * std::expm1(x); } - -TEST_CASE(abs_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - auto l = mm->add_literal(migraphx::literal{s, {-1, 2, -3, 4}}); - mm->add_instruction(migraphx::make_op("abs"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 2, 3, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(abs_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 8}, {2, 2}}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("abs"), input); - p.compile(migraphx::make_target("ref")); - - std::vector a = {-1, 2, -3, 4}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 2, 3, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(acos_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {3}}; - std::vector data{-0.8f, 0.0f, 1.0f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("acos"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acosf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(acos_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("acos"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-0.8f, 0.0f, 1.0f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acosf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(acosh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {3}}; - std::vector data{1.1f, 1.2f, 2.0f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("acosh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acoshf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(acosh_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - std::vector input_data{1.1f, 1.2f, 2.0f}; - mm->add_instruction(migraphx::make_op("acosh"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return acoshf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(add_broadcast_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3}}; - std::vector a_data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - migraphx::shape b_shape{migraphx::shape::float_type, {2, 2}}; - std::vector b_data{0, -1, -2, -3}; - uint64_t axis = 0; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - auto l3 = mm->add_instruction( - migraphx::make_op("broadcast", {{"axis", axis}, {"out_lens", l1->get_shape().lens()}}), - l2); - mm->add_instruction(migraphx::make_op("add"), l1, l3); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape().packed()); - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, {2, 2, 3}}; - std::vector a_data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - migraphx::shape b_shape{migraphx::shape::float_type, {2, 2, 1}}; - std::vector b_data{0, -1, -2, -3}; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - auto l3 = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3}}}), l1); - auto l4 = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2, 3}}}), l2); - mm->add_instruction(migraphx::make_op("add"), l3, l4); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape().packed()); - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(add_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); - auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); - mm->add_instruction(migraphx::make_op("add"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 2, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(add_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - mm->add_instruction(migraphx::make_op("add"), x, y); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1, 0, 1}; - std::vector y_data{1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 2, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(argmax_test_0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", 0}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmax_test_1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {0, 0, 2, 1, 2, 0, 0, 2}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", 1}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmax_test_2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {1, 3, 2, 2, 2, 3}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", 2}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmax_test_neg_2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {0, 0, 2, 1, 2, 0, 0, 2}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", -2}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmax_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 2}, {3, 6}, {3, 6}}}; - auto dl = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("argmax", {{"axis", 0}}), dl); - p.compile(migraphx::make_target("ref")); - - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 3, 4}}; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - std::vector res_gold = {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1}; - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmin_test_0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmin", {{"axis", 0}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmin_test_1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {2, 2, 0, 2, 0, 1, 2, 0}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmin", {{"axis", 1}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmin_test_2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {2, 1, 0, 3, 3, 2}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmin", {{"axis", 2}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(argmin_test_neg_1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data = {1.2255, 1.6834, -2.0305, -0.3221, 0.4701, 0.2583, 0.7545, 2.5758, - -1.6849, 0.0928, 0.9022, -0.8765, -0.4090, 0.9301, 2.0724, -1.5706, - 0.4867, -0.1493, 0.6957, -0.2179, 0.7142, 0.7177, 0.0183, 1.3497}; - std::vector res_gold = {2, 1, 0, 3, 3, 2}; - migraphx::shape data_shape{migraphx::shape::float_type, {2, 3, 4}}; - auto dl = mm->add_literal(migraphx::literal{data_shape, data}); - mm->add_instruction(migraphx::make_op("argmin", {{"axis", -1}}), dl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(result_vec, res_gold)); -} - -TEST_CASE(asin_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data{-0.5f, 0.0f, 0.9f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("asin"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(asin_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("asin"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-0.5f, 0.0f, 0.9f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(asinh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data{-0.5f, 0.0f, 0.9f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("asinh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(asinh_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("asinh"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-0.5f, 0.0f, 0.9f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return asinhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(atan_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {3}}; - std::vector data{-1.0f, 0.0f, 1.0f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("atan"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(atan_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("atan"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1.0f, 0.0f, 1.0f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(atanh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {3}}; - std::vector data{0.4435683f, 0.6223626f, 0.316958f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("atanh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(atanh_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("atanh"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{0.4435683f, 0.6223626f, 0.316958f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return atanhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_rank3_test) -{ - // 1D case 1, input is 3D - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {1}; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.25, 0.3, 0.25, 0.65, 0.7, 0.5, 0.4, 0.4, 0.35}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, - {"lengths", {2}}, - {"padding", {0}}, - {"stride", {1}}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.25, 0.3, 0.25, 0.65, 0.7, 0.5, 0.4, 0.4, 0.35}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_dyn_pad_test) -{ - // pooling with dynamic input and padding, ceiling mode for output size - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {1, 3}, {2, 4}, {2, 4}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, - {"lengths", {2, 2}}, - {"padding", {1, 0}}, - {"ceil_mode", true}, - {"stride", {2, 2}}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{1, 2, 3, 4, 5, 6}; - - // * * * - // 1 2 3 padding will look like this - // 4 5 6 The * are used when tiling the kernel - // * * * but are ignored in averaging - - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 2, 3}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.5, 3.0, 4.5, 6.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_dyn_pad_ceil_test) -{ - // pooling with dynamic input and padding - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {1, 3}, {2, 4}, {2, 4}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, - {"lengths", {2, 3}}, - {"padding", {1, 2}}, - {"ceil_mode", true}, - {"stride", {1, 1}}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{1, 2, 3, 4}; - - // * * * * * * - // * * 1 2 * * padded input will look like this - // * * 3 4 * * but the * are ignored in averaging - // * * * * * * - - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 2, 2}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - // clang-format off - std::vector gold{1.0, 1.5, 1.5, 2.0, - 2.0, 2.5, 2.5, 3.0, - 3.0, 3.5, 3.5, 4.0}; - // clang-format on - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_rank3_stride2_test) -{ - // 1D case 2, stride 2 - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 4}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; - op.lengths = {2}; - op.padding = {1}; - op.stride = {2}; - - // clang-format off - std::vector data{1.6321, -2.4186, 0.2239, -1.4232, - 0.8158, 0.4103, -0.3149, -0.1361, - -0.3442, 2.007, 0.4331, 1.5295, - 0.9965, 0.4766, 1.0942, -0.2915}; - // clang-format on - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - // clang-format off - std::vector gold{1.6321, -1.09735, -1.4232, - 0.8158, 0.0477, -0.1361, - -0.3442, 1.22005, 1.5295, - 0.9965, 0.7854, -0.2915}; - // clang-format on - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(avgpool_rank5_test) -{ - // 3D, input is 5D - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 3, 3, 3}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; - op.lengths = {2, 2, 2}; - op.padding = {0, 0, 0}; - op.stride = {1, 1, 1}; - - std::vector data{ - -0.179, -1.756, 0.651, 1.955, 1.87, -0.604, 0.247, 0.449, -0.137, 1.187, 1.593, - 0.424, 2.698, -0.104, -0.069, -1.293, 0.538, 1.291, 0.974, 1.096, 0.74, -0.669, - -1.08, -1.041, -1.407, 1.43, -0.211, -0.017, 0.532, 1.276, 0.627, 0.236, -0.396, - -0.204, 0.501, -0.599, -1.414, -0.615, -0.274, 0.168, -0.144, 0.5, 1.42, 1.082, - -0.952, -0.846, -1.244, 1.475, 1.246, 1.344, -1.722, -1.24, -0.851, 0.06, 0.507, - 0.762, -0.007, -1.484, 1.028, 0.317, 1.077, -1.289, 0.875, -0.417, -0.673, 1.715, - -0.307, 0.264, -0.973, 1.412, 2.561, -0.515, -0.201, 0.827, -1.231, 1.958, -0.552, - 0.036, -0.993, -0.859, -1.458, -0.575, 0.048, -0.779, -1.025, -1.135, 1.166, -0.131, - 0.726, 0.52, 0.467, -0.494, 0.675, 0.203, -0.63, -0.918, -0.5, -1.395, 1.39, - 1.705, 0.444, -0.835, -0.506, 0.101, 0.602, 0.543, 0.357, 1.042}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{ - 0.908, 0.250625, 0.795, 0.40425, 0.711875, 0.194875, 0.014125, 0.09425, - -0.078375, 0.139375, 0.46075, 0.0285, -0.188125, -0.085, 0.378125, -0.085375, - -0.04, 0.304125, 0.40775, 0.2835, 0.112375, -0.073375, 0.4355, -0.187, - -0.392625, -0.258375, -0.485875, -0.0345, 0.16125, -0.131875, -0.228375, 0.068625}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(broadcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; - std::vector a_data{0, 0, 0, 0}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - uint64_t axis = 0; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction( - migraphx::make_op("broadcast", {{"axis", axis}, {"out_lens", l1->get_shape().lens()}}), l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -2); - EXPECT(output(1, 0) == -3); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(broadcast_2in_static_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; - std::vector a_data{0, 0, 0, 0}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - uint64_t axis = 0; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction(migraphx::make_op("broadcast", {{"axis", axis}}), l2, l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -2); - EXPECT(output(1, 0) == -3); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(broadcast_2in_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 2}, {2, 4}}}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - uint64_t axis = 0; - auto pa = mm->add_parameter("a", a_shape); - auto lb = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction(migraphx::make_op("broadcast", {{"axis", axis}}), lb, pa); - p.compile(migraphx::make_target("ref")); - - std::vector a_data{0, 0, 0, 0}; - migraphx::shape input_fixed_shape0{migraphx::shape::int32_type, {2, 2}}; - migraphx::parameter_map params0; - params0["a"] = migraphx::argument(input_fixed_shape0, a_data.data()); - auto result = p.eval(params0).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -2); - EXPECT(output(1, 0) == -3); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(ceil_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - std::vector data = {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("ceil"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::ceil(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(ceil_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{4, 12}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("ceil"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::ceil(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(clip_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l = mm->add_literal(migraphx::literal{s, {-1.0, 0.0, 10.0}}); - auto min_val = mm->add_literal(0.0f); - auto max_val = mm->add_literal(6.0f); - min_val = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3}}}), min_val); - max_val = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3}}}), max_val); - mm->add_instruction(migraphx::make_op("clip"), l, min_val, max_val); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.0, 0.0, 6.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(clip_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dds = {{2, 8, {3}}}; - migraphx::shape s{migraphx::shape::float_type, dds}; - auto l = mm->add_parameter("X", s); - auto min_val = mm->add_literal(0.0f); - auto max_val = mm->add_literal(6.0f); - min_val = mm->add_instruction(migraphx::make_op("multibroadcast"), min_val, l); - max_val = mm->add_instruction(migraphx::make_op("multibroadcast"), max_val, l); - mm->add_instruction(migraphx::make_op("clip"), l, min_val, max_val); - p.compile(migraphx::make_target("ref")); - - migraphx::shape static_shape{migraphx::shape::float_type, {3}}; - migraphx::parameter_map params; - std::vector data = {-1.0, 0.0, 10.0}; - params["X"] = migraphx::argument(static_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.0, 0.0, 6.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(concat_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - int axis = 1; - std::vector data0 = {0, 1, 5, 6}; - std::vector data1 = {2, 3, 4, 7, 8, 9}; - std::vector data2 = {10, 20}; - migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; - migraphx::shape s1{migraphx::shape::int32_type, {2, 3}}; - migraphx::shape s2{migraphx::shape::int32_type, {2, 1}}; - auto l0 = mm->add_literal(migraphx::literal{s0, data0}); - auto l1 = mm->add_literal(migraphx::literal{s1, data1}); - auto l2 = mm->add_literal(migraphx::literal{s2, data2}); - mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector gold = {0, 1, 2, 3, 4, 10, 5, 6, 7, 8, 9, 20}; - std::vector results_vector(2 * 6); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), - std::vector({2, 6}))); - EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), - std::vector({6, 1}))); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - int axis = -1; - std::vector data0 = {0, 1, 5, 6}; - std::vector data1 = {2, 3, 4, 7, 8, 9}; - std::vector data2 = {10, 20}; - migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; - migraphx::shape s1{migraphx::shape::int32_type, {2, 3}}; - migraphx::shape s2{migraphx::shape::int32_type, {2, 1}}; - auto l0 = mm->add_literal(migraphx::literal{s0, data0}); - auto l1 = mm->add_literal(migraphx::literal{s1, data1}); - auto l2 = mm->add_literal(migraphx::literal{s2, data2}); - mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector gold = {0, 1, 2, 3, 4, 10, 5, 6, 7, 8, 9, 20}; - std::vector results_vector(2 * 6); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), - std::vector({2, 6}))); - EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), - std::vector({6, 1}))); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - int axis = 0; - std::vector data0 = {0, 1, 2, 3}; - std::vector data1 = {4, 5, 6, 7, 8, 9}; - std::vector data2 = {10, 11}; - migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; - migraphx::shape s1{migraphx::shape::int32_type, {3, 2}}; - migraphx::shape s2{migraphx::shape::int32_type, {1, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s0, data0}); - auto l1 = mm->add_literal(migraphx::literal{s1, data1}); - auto l2 = mm->add_literal(migraphx::literal{s2, data2}); - mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - std::vector results_vector(6 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), - std::vector({6, 2}))); - EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), - std::vector({2, 1}))); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - int axis = -2; - std::vector data0 = {0, 1, 2, 3}; - std::vector data1 = {4, 5, 6, 7, 8, 9}; - std::vector data2 = {10, 11}; - migraphx::shape s0{migraphx::shape::int32_type, {2, 2}}; - migraphx::shape s1{migraphx::shape::int32_type, {3, 2}}; - migraphx::shape s2{migraphx::shape::int32_type, {1, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s0, data0}); - auto l1 = mm->add_literal(migraphx::literal{s1, data1}); - auto l2 = mm->add_literal(migraphx::literal{s2, data2}); - mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), l0, l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - std::vector results_vector(6 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), - std::vector({6, 2}))); - EXPECT(migraphx::verify::verify_range(result.get_shape().strides(), - std::vector({2, 1}))); - } -} - -TEST_CASE(concat_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - int axis = 0; - migraphx::shape s0{migraphx::shape::int32_type, {{2, 4, {2}}, {2, 3, {2}}}}; - migraphx::shape s1{migraphx::shape::int32_type, {{3, 4, {4}}, {2, 3, {2}}}}; - migraphx::shape s2{migraphx::shape::int32_type, {{1, 5, {3}}, {2, 3, {2}}}}; - - auto input0 = mm->add_parameter("X", s0); - auto input1 = mm->add_parameter("Y", s1); - auto input2 = mm->add_parameter("Z", s2); - mm->add_instruction(migraphx::make_op("concat", {{"axis", axis}}), input0, input1, input2); - p.compile(migraphx::make_target("ref")); - - migraphx::shape static_shape0{migraphx::shape::int32_type, {2, 2}}; - migraphx::shape static_shape1{migraphx::shape::int32_type, {3, 2}}; - migraphx::shape static_shape2{migraphx::shape::int32_type, {1, 2}}; - std::vector data0 = {0, 1, 2, 3}; - std::vector data1 = {4, 5, 6, 7, 8, 9}; - std::vector data2 = {10, 11}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(static_shape0, data0.data()); - params["Y"] = migraphx::argument(static_shape1, data1.data()); - params["Z"] = migraphx::argument(static_shape2, data2.data()); - auto result = p.eval(params).back(); - - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(migraphx::verify::verify_range(result.get_shape().lens(), - std::vector({6, 2}))); -} - -TEST_CASE(contiguous_test) -{ - migraphx::shape a_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; - std::vector data(12); - std::iota(data.begin(), data.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - mm->add_instruction(migraphx::make_op("contiguous"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector new_strides = {12, 4, 2, 1}; - EXPECT(result.get_shape().strides() == new_strides); - - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - std::vector gold = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(contiguous_param_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; - auto a = mm->add_parameter("X", a_shape); - mm->add_instruction(migraphx::make_op("contiguous"), a); - p.compile(migraphx::make_target("ref")); - - std::vector data(12); - std::iota(data.begin(), data.end(), 0); - migraphx::parameter_map params; - params["X"] = migraphx::argument(a_shape, data.data()); - auto result = p.eval(params).back(); - - std::vector new_strides = {12, 4, 2, 1}; - EXPECT(result.get_shape().strides() == new_strides); - - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(contiguous_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape dyn_shape{migraphx::shape::float_type, {{1, 1}, {2, 6}, {2, 2}, {2, 2}}}; - auto input = mm->add_parameter("X", dyn_shape); - mm->add_instruction(migraphx::make_op("contiguous"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::shape static_shape{migraphx::shape::float_type, {1, 3, 2, 2}, {12, 1, 6, 3}}; - std::vector data(12); - std::iota(data.begin(), data.end(), 0); - migraphx::parameter_map params; - params["X"] = migraphx::argument(static_shape, data.data()); - auto result = p.eval(params).back(); - - std::vector new_strides = {12, 4, 2, 1}; - EXPECT(result.get_shape().strides() == new_strides); - - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(conv_dyn_batch_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_dyn_shape{migraphx::shape::float_type, - {{1, 100}, {3, 3}, {4, 4}, {4, 4}}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - - auto input = mm->add_parameter("X", input_dyn_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction(migraphx::make_op("convolution", {{"padding", {1, 1}}, {"stride", {2, 2}}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = { - 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, - -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, - 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, - 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, - -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, - 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, - 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, - 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, - 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, - 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, - 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, - -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, - 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, - -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; - - std::vector c = { - -0.14601797, -0.13000923, 0.06521662, 0.06178288, -0.11083675, 0.10154136, 0.09990512, - 0.06030385, -0.11374587, -0.17523311, -0.14344215, 0.17802463, 0.06300922, -0.15325832, - 0.07066704, 0.05166031, 0.00615084, -0.02606523, 0.08083995, -0.17913306, 0.0624622, - 0.0735731, -0.04198661, -0.0164391, -0.06374192, 0.16569914, 0.10681538, 0.07370754, - 0.02802075, 0.00282027, 0.15104802, -0.11084409, -0.00197773, 0.07924436, 0.03528272, - 0.04765259, -0.15896152, 0.07917164, 0.12125669, -0.1154705, -0.11999125, 0.12749968, - -0.06269585, 0.18658121, -0.03944227, 0.0111798, -0.17731084, 0.11789055, -0.09982193, - 0.08142821, 0.0729029, 0.11303909, 0.12735154, 0.03885292}; - - std::vector sol = {-0.20817225, - 0.87965256, - 0.14958936, - -1.24887264, - -0.06540672, - 0.20778663, - 0.40456355, - -0.99900877, - 0.4917807, - 0.1994698, - 0.64205718, - 0.37798831, - -0.25315839, - 0.44276932, - -0.16138598, - 0.79344082}; - - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 4, 4}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - params0["W"] = migraphx::argument(weights_shape, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(64); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv_dyn_img_shape_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_dyn_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {4, 6}, {4, 6}}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {1, 3, 3, 3}}; - - auto input = mm->add_parameter("X", input_dyn_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction(migraphx::make_op("convolution", {{"padding", {0, 0}}, {"stride", {1, 1}}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = {0.28007596, 0.46114671, 0.12171969, 0.52260835, 0.40916841, 0.07163955, - 0.09896668, 0.98628836, 0.69406788, 0.44868846, 0.64017681, 0.27048886, - 0.30187397, 0.07334207, 0.05258557, 0.80747513, 0.81330534, 0.00497161, - 0.33005534, 0.08908686, 0.46794691, 0.61768946, 0.55104806, 0.13406187, - 0.70244284, 0.61296941, 0.46742536, 0.29712714, 0.91839388, 0.0834397, - 0.14476327, 0.37857075, 0.25922384, 0.61620963, 0.69455439, 0.70389431, - 0.77388606, 0.1752363, 0.74631394, 0.24604889, 0.53600244, 0.22116457, - 0.81217463, 0.10789447, 0.43083784, 0.63371852, 0.69742316, 0.09536905}; - - std::vector c = {0.98411968, 0.2899219, 0.44638833, 0.30390816, 0.03989896, 0.2445332, - 0.32700131, 0.57517075, 0.06956476, 0.93079306, 0.19882314, 0.52940601, - 0.35624753, 0.35938406, 0.9111428, 0.88923574, 0.61040283, 0.2797513, - 0.15479768, 0.46534674, 0.16970931, 0.49704618, 0.07062198, 0.01678321, - 0.53150934, 0.39244495, 0.9963813}; - - std::vector sol = {6.1329393, 4.3199925, 5.448438, 3.8497565}; - - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 3, 4, 4}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - params0["W"] = migraphx::argument(weights_shape, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(72); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, sol)); - - a = {0.95600171, 0.20768181, 0.82844489, 0.14928212, 0.51280462, 0.1359196, 0.68903648, - 0.84174772, 0.425509, 0.956926, 0.82533291, 0.33821531, 0.57576055, 0.75330186, - 0.82710394, 0.93343847, 0.14499469, 0.74558021, 0.13935139, 0.90652876, 0.22611443, - 0.85323975, 0.30631787, 0.96983037, 0.51783421, 0.32247456, 0.28243352, 0.605865, - 0.33376446, 0.67864877, 0.15442507, 0.24977552, 0.86989425, 0.60036782, 0.26198306, - 0.1494149, 0.13678915, 0.24892094, 0.38282467, 0.64907906, 0.83756376, 0.77603195, - 0.33951558, 0.14856874, 0.45701939, 0.43786436, 0.57421759, 0.37326922, 0.63382506, - 0.11464436, 0.23309047, 0.76724102, 0.98712427, 0.80800108, 0.84296564, 0.79568268, - 0.45684131, 0.73867068, 0.57845499, 0.45073557, 0.27102442, 0.86460315, 0.06865567, - 0.81673446, 0.881835, 0.42351639, 0.83322931, 0.34101671, 0.51979151, 0.54920645, - 0.19287718, 0.33321689, 0.27752456, 0.45755893, 0.67484562, 0.68383122, 0.52361312, - 0.46437257, 0.50862936, 0.32460429, 0.1726007, 0.29933345, 0.64856728, 0.06471591, - 0.63370843, 0.27900152, 0.18595992, 0.48904812, 0.35368508, 0.09620202}; - - c = {0.709561, 0.7916206, 0.0443115, 0.62592275, 0.2498623, 0.42725624, 0.7905135, - 0.53160169, 0.01303743, 0.01987505, 0.39041803, 0.89530203, 0.23155373, 0.44435213, - 0.14407301, 0.80968594, 0.38216188, 0.35692557, 0.2568538, 0.83587388, 0.43654904, - 0.04974508, 0.80375029, 0.25350374, 0.1820275, 0.23369029, 0.54358755}; - - sol = {6.305986, - 5.564665, - 6.122996, - 5.7262855, - 5.5546584, - 5.779489, - 5.798161, - 5.160476, - 6.702436, - 5.4851074, - 6.227567, - 5.2016754}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 3, 6, 5}}; - - migraphx::parameter_map params1; - params1["X"] = migraphx::argument(input_fixed_shape1, a.data()); - params1["W"] = migraphx::argument(weights_shape, c.data()); - - result = p.eval(params1).back(); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv_dyn_weights_shape_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; - - auto input = mm->add_parameter("X", input_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction(migraphx::make_op("convolution", {{"padding", {0, 0}}, {"stride", {1, 1}}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = {0.28007596, 0.46114671, 0.12171969, 0.52260835, 0.40916841, 0.07163955, - 0.09896668, 0.98628836, 0.69406788, 0.44868846, 0.64017681, 0.27048886, - 0.30187397, 0.07334207, 0.05258557, 0.80747513, 0.81330534, 0.00497161, - 0.33005534, 0.08908686, 0.46794691, 0.61768946, 0.55104806, 0.13406187, - 0.70244284, 0.61296941, 0.46742536, 0.29712714, 0.91839388, 0.0834397, - 0.14476327, 0.37857075, 0.25922384, 0.61620963, 0.69455439, 0.70389431, - 0.77388606, 0.1752363, 0.74631394, 0.24604889, 0.53600244, 0.22116457, - 0.81217463, 0.10789447, 0.43083784, 0.63371852, 0.69742316, 0.09536905}; - - std::vector c = {0.98411968, - 0.2899219, - 0.44638833, - 0.30390816, - 0.03989896, - 0.2445332, - 0.32700131, - 0.57517075, - 0.06956476, - 0.93079306, - 0.19882314, - 0.52940601}; - std::vector sol = {1.9939406, - 2.2703054, - 1.8896171, - 2.062202, - 2.3035214, - 1.629366, - 2.1606991, - 2.1917608, - 1.6797699}; - - migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_shape, a.data()); - params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(72); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, sol)); - - c = {0.98411968, 0.2899219, 0.44638833, 0.30390816, 0.03989896, 0.2445332, 0.32700131, - 0.57517075, 0.06956476, 0.93079306, 0.19882314, 0.52940601, 0.35624753, 0.35938406, - 0.9111428, 0.88923574, 0.61040283, 0.2797513, 0.15479768, 0.46534674, 0.16970931, - 0.49704618, 0.07062198, 0.01678321, 0.53150934, 0.39244495, 0.9963813}; - sol = {6.1329393, 4.3199925, 5.448438, 3.8497565}; - migraphx::shape weights_fixed_shape1{migraphx::shape::float_type, {1, 3, 3, 3}}; - - migraphx::parameter_map params1; - params1["X"] = migraphx::argument(input_shape, a.data()); - params1["W"] = migraphx::argument(weights_fixed_shape1, c.data()); - - result = p.eval(params1).back(); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv_dyn_img_same_upper_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_dyn_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {4, 6}, {4, 6}}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {1, 3, 3, 3}}; - - auto input = mm->add_parameter("X", input_dyn_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction( - migraphx::make_op( - "convolution", - {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_upper}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, - 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, - 0.24401724, 0.8815178, 0.4222333, 0.27191755, - - 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, - 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, - 0.80087787, 0.12776066, 0.26566318, 0.46569306, - - 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, - 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, - 0.6870904, 0.30701008, 0.314684, 0.91075855}; - - std::vector c = { - 2.8150102e-01, 3.3198616e-01, 9.5149356e-01, 7.4039467e-02, 9.6555042e-01, - 2.8815505e-01, 2.5100240e-01, 5.2186239e-01, 2.3850012e-01, - - 8.2963020e-01, 3.0763101e-04, 6.7026985e-01, 1.4260857e-01, 9.7517288e-01, - 3.6847427e-02, 8.5804445e-01, 7.3440993e-01, 6.7948365e-01, - - 7.9253986e-02, 7.3943835e-01, 1.7813577e-01, 1.0780835e-01, 4.2304707e-01, - 4.0084350e-01, 1.1114500e-01, 4.4846520e-01, 5.0109702e-01}; - - std::vector sol = {3.013387, - 3.7111127, - 4.2946506, - 3.579301, - 4.5306826, - 6.1262493, - 6.332169, - 4.495293, - 4.46013, - 6.0938954, - 5.848162, - 4.514299, - 2.9587686, - 4.117671, - 3.5187216, - 2.3236327}; - - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 3, 4, 4}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - params0["W"] = migraphx::argument(weights_shape, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv_dyn_kernel_same_upper_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; - - auto input = mm->add_parameter("X", input_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction( - migraphx::make_op( - "convolution", - {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_upper}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, - 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, - 0.24401724, 0.8815178, 0.4222333, 0.27191755, - - 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, - 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, - 0.80087787, 0.12776066, 0.26566318, 0.46569306, - - 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, - 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, - 0.6870904, 0.30701008, 0.314684, 0.91075855}; - std::vector c = {2.8150102e-01, - 3.3198616e-01, - 9.5149356e-01, - 7.4039467e-02, - - 9.6555042e-01, - 2.8815505e-01, - 2.5100240e-01, - 5.2186239e-01, - - 2.3850012e-01, - 8.2963020e-01, - 3.0763101e-04, - 6.7026985e-01}; - std::vector sol = {2.453681, - 2.536207, - 3.0187201, - 1.7912633, - 2.1738236, - 2.9695358, - 3.2319589, - 1.859269, - 2.5953722, - 2.50734, - 2.7736917, - 1.2229807, - 1.5900216, - 0.9225286, - 1.43048, - 0.74341124}; - - migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_shape, a.data()); - params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv_dyn_kernel_same_lower_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape input_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; - migraphx::shape weights_shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 3}, {2, 3}}}; - - auto input = mm->add_parameter("X", input_shape); - auto weights = mm->add_parameter("W", weights_shape); - mm->add_instruction( - migraphx::make_op( - "convolution", - {{"stride", {1, 1}}, {"padding_mode", migraphx::op::padding_mode_t::same_lower}}), - input, - weights); - - p.compile(migraphx::make_target("ref")); - - std::vector a = {0.63321185, 0.6466339, 0.8515352, 0.44240063, 0.5018913, 0.5068494, - 0.75330657, 0.7383877, 0.15870683, 0.8171611, 0.56118083, 0.87004256, - 0.24401724, 0.8815178, 0.4222333, 0.27191755, - - 0.41633207, 0.2460619, 0.32004243, 0.6962248, 0.12284133, 0.2620491, - 0.96931046, 0.6030955, 0.7623861, 0.2395751, 0.61440414, 0.577285, - 0.80087787, 0.12776066, 0.26566318, 0.46569306, - - 0.96701574, 0.3850145, 0.14165345, 0.5887347, 0.7152134, 0.5295342, - 0.6303507, 0.4037548, 0.18556239, 0.79416305, 0.29107493, 0.18770285, - 0.6870904, 0.30701008, 0.314684, 0.91075855}; - std::vector c = {2.8150102e-01, - 3.3198616e-01, - 9.5149356e-01, - 7.4039467e-02, - - 9.6555042e-01, - 2.8815505e-01, - 2.5100240e-01, - 5.2186239e-01, - - 2.3850012e-01, - 8.2963020e-01, - 3.0763101e-04, - 6.7026985e-01}; - std::vector sol = {0.91231215, - 1.1416453, - 1.00216, - 1.6813052, - 1.7131033, - 2.453681, - 2.536207, - 3.0187201, - 1.3293691, - 2.1738236, - 2.9695358, - 3.2319589, - 1.3228729, - 2.5953722, - 2.50734, - 2.7736917}; - - migraphx::shape weight_fixed_shape0{migraphx::shape::float_type, {1, 3, 2, 2}}; - - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_shape, a.data()); - params0["W"] = migraphx::argument(weight_fixed_shape0, c.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, sol)); -} - -TEST_CASE(conv2d_padding_stride_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, - -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, - 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, - 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, - -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, - 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, - 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, - 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, - 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, - 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, - 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, - -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, - 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, - -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; - - std::vector c = { - -0.14601797, -0.13000923, 0.06521662, 0.06178288, -0.11083675, 0.10154136, 0.09990512, - 0.06030385, -0.11374587, -0.17523311, -0.14344215, 0.17802463, 0.06300922, -0.15325832, - 0.07066704, 0.05166031, 0.00615084, -0.02606523, 0.08083995, -0.17913306, 0.0624622, - 0.0735731, -0.04198661, -0.0164391, -0.06374192, 0.16569914, 0.10681538, 0.07370754, - 0.02802075, 0.00282027, 0.15104802, -0.11084409, -0.00197773, 0.07924436, 0.03528272, - 0.04765259, -0.15896152, 0.07917164, 0.12125669, -0.1154705, -0.11999125, 0.12749968, - -0.06269585, 0.18658121, -0.03944227, 0.0111798, -0.17731084, 0.11789055, -0.09982193, - 0.08142821, 0.0729029, 0.11303909, 0.12735154, 0.03885292}; - - std::vector s = {-0.20817225, - 0.87965256, - 0.14958936, - -1.24887264, - -0.06540672, - 0.20778663, - 0.40456355, - -0.99900877, - 0.4917807, - 0.1994698, - 0.64205718, - 0.37798831, - -0.25315839, - 0.44276932, - -0.16138598, - 0.79344082}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - - migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - - mm->add_instruction( - migraphx::make_op("convolution", {{"padding", {1, 1}}, {"stride", {2, 2}}}), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(conv2d_padding_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, - -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, - 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, - 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, - -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, - 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, - 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, - 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, - 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, - 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, - 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, - -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, - 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, - -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; - - std::vector c = { - -0.16115488, -0.09800646, -0.05412646, 0.10475694, 0.00555485, -0.12667653, 0.0458357, - -0.02656217, -0.16338061, 0.15037455, 0.0102711, 0.01303349, 0.05242859, 0.02034754, - 0.04751867, -0.17038961, -0.1434752, -0.10770349, 0.05676742, -0.15838449, 0.10128359, - -0.18958683, 0.11954515, 0.10758857, -0.01058291, -0.12797487, 0.08971019, 0.18793164, - -0.00881396, -0.06588994, -0.13321903, -0.03300409, 0.01439607, 0.07618178, -0.11556662, - 0.00764295, 0.12956454, -0.08937147, -0.12763587, 0.04674943, 0.05765297, 0.11336918, - 0.14747436, -0.06199479, -0.01166052, -0.12432006, -0.04494537, -0.17581205, 0.09475745, - 0.1149437, -0.1014564, 0.0274073, -0.01323579, -0.11092556}; - - std::vector s = { - -0.0201216, 0.40407312, -0.39005592, -0.0631946, 0.37963012, -0.64611685, 0.1349397, - -0.54113752, 0.28533003, 0.27667275, -0.16442731, -0.181494, 0.30564839, 0.58744538, - 0.32015014, 0.24969585, -0.27367792, -0.53308117, 0.41236052, 0.26136363, -0.01489828, - 0.57652152, -0.38506854, 0.119615, 0.0437076, 0.04779706, 0.57887721, 0.23126155, - 0.05695833, -0.68200272, 0.02063358, -0.10267162, 0.8062973, -0.38149622, -0.40134856, - -0.03353126, 0.38991132, -0.3478111, 0.03661491, 0.25783631, 0.62772679, -0.1961118, - 0.76423508, -0.36241418, -0.20994355, -0.12368261, -0.9406727, 0.02340185, -0.08793129, - -0.02471633, -0.58163726, -0.02211772, -0.42014724, 0.77525634, 0.504951, -0.20537445, - -0.20369984, -0.83037728, -1.40423918, -0.46160448, -0.22944322, 0.36074194, 0.49579027, - 0.46527559}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - - migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - - mm->add_instruction( - migraphx::make_op("convolution", {{"padding", {1, 1}}, {"stride", {1, 1}}}), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(64); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(conv2d_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, - -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, - 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, - 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, - -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, - 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, - 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, - 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, - 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, - 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, - 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, - -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, - 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, - -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; - - std::vector c = { - 2.82721668e-02, 6.44195229e-02, 1.53499246e-02, 1.72468081e-01, -6.33238107e-02, - 9.49496776e-02, 1.40258059e-01, -7.92879611e-02, -1.29301161e-01, 3.11307609e-03, - -1.90624535e-01, 1.13238767e-01, -2.80647576e-02, 3.12882811e-02, -3.52091640e-02, - 3.33581865e-02, 6.43158704e-02, 7.40238279e-02, -1.00106120e-01, -9.56912562e-02, - 1.44342467e-01, 9.40258950e-02, 6.36333972e-02, 1.66158378e-03, -8.91554281e-02, - 2.58734226e-02, 1.70919895e-02, 1.78214177e-01, 8.84564668e-02, 8.98126513e-02, - -1.63809001e-01, 1.37802169e-01, 1.66439757e-01, -1.45631135e-02, 1.88469887e-04, - 4.76950556e-02, -1.91969007e-01, -1.76233292e-01, -7.70473927e-02, 1.14828631e-01, - 1.76608220e-01, -1.50728196e-01, 1.99946314e-02, -5.88052124e-02, 1.31612435e-01, - 1.61106288e-02, -1.35080189e-01, 1.49512306e-01, 3.86456847e-02, 1.29330024e-01, - -3.22975963e-02, -5.60784787e-02, -5.41997552e-02, 4.78562862e-02}; - - std::vector s = {0.27039781, - 0.19105849, - -0.06339942, - -0.65087199, - 0.40867025, - 0.05063812, - -0.14907975, - 0.49018705, - -0.49197209, - 0.33236548, - -0.39374301, - 0.16012701, - 0.06574871, - 0.71606487, - -0.55201721, - -0.46427044}; - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - - migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - - mm->add_instruction(migraphx::make_op("convolution"), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(conv3d_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 2.71567607, -0.9960829, 0.91671127, 0.28140706, 0.63235772, 0.08077253, 0.80927712, - -0.59108931, -1.05421555, -2.76622486, -0.85044265, -0.52049929, 0.67726439, -0.65290606, - 0.02345525, -0.33579525, 0.38901961, 1.05473483, -1.31188095, 1.8963089, -0.07265259, - 0.947339, 0.41949373, -0.70814759, 0.25892952, 1.07311416, 1.2571274, -0.62318051, - -0.19951548, -0.94232577, -0.29393643, 0.42292568, -0.80230367, 1.40909171, 0.63617158, - 0.13900366, 1.09253144, -0.15265895, 1.54781747, 0.72780299, 1.09189606, -0.38068101, - 0.97057933, -0.58958799, 1.56188643, 0.21474874, 0.58725154, -1.27097559, -0.03024297, - 1.09437096, -0.4897908, 0.34838957, -1.31042492, -1.69069934, 0.86956722, -0.40457946, - 0.46691212, 1.29273605, 0.26464137, 0.22073045, -1.02178168, 0.22163901, -1.84387338, - 0.75522131, -0.45775682, -0.42241111, -1.50944722, 1.07256448, -1.95876884, -0.28106022, - 0.3341668, 2.13129425, -1.14728117, -1.06555498, -0.298444, -0.88322699, -0.65866792, - -2.06007552, 0.01374334, 0.45612028, 0.52715492, 1.01914406, -1.72659791, 0.80650896, - 0.16860051, 2.24112225, -0.78620857, 0.36566174, -0.07020134, -0.47976932, -0.68230027, - -0.94711417, -0.54506505, 1.66504931, -0.71860826, 0.61132306}; - - std::vector c = { - 2.82721668e-02, 6.44195229e-02, 1.53499246e-02, 1.72468081e-01, -6.33238107e-02, - 9.49496776e-02, 1.40258059e-01, -7.92879611e-02, -1.29301161e-01, 3.11307609e-03, - -1.90624535e-01, 1.13238767e-01, -2.80647576e-02, 3.12882811e-02, -3.52091640e-02, - 3.33581865e-02, 6.43158704e-02, 7.40238279e-02, -1.00106120e-01, -9.56912562e-02, - 1.44342467e-01, 9.40258950e-02, 6.36333972e-02, 1.66158378e-03, -8.91554281e-02, - 2.58734226e-02, 1.70919895e-02, 1.78214177e-01, 8.84564668e-02, 8.98126513e-02, - -1.63809001e-01, 1.37802169e-01, 1.66439757e-01, -1.45631135e-02, 1.88469887e-04, - 4.76950556e-02, -1.91969007e-01, -1.76233292e-01, -7.70473927e-02, 1.14828631e-01, - 1.76608220e-01, -1.50728196e-01, 1.99946314e-02, -5.88052124e-02, 1.31612435e-01, - 1.61106288e-02, -1.35080189e-01, 1.49512306e-01, 3.86456847e-02, 1.29330024e-01, - -3.22975963e-02, -5.60784787e-02, -5.41997552e-02, 4.78562862e-02}; - - std::vector s = {0.27039781, - 0.19105849, - -0.06339942, - -0.65087199, - 0.40867025, - 0.05063812, - -0.14907975, - 0.49018705, - -0.49197209, - 0.33236548, - -0.39374301, - 0.16012701, - 0.06574871, - 0.71606487, - -0.55201721, - -0.46427044}; - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 4, 4, 1}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - - migraphx::shape c_shape{migraphx::shape::float_type, {2, 3, 3, 3, 1}}; - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - - mm->add_instruction( - migraphx::make_op("convolution", - {{"padding", {0, 0, 0}}, {"stride", {1, 1, 1}}, {"dilation", {1, 1, 1}}}), - al, - cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(cos_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data{-1, 0, 1}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("cos"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return cosf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(cos_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("cos"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1, 0, 1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return cosf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(cosh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data = {-1.0, 2.0, -3.0, 4.0}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("cosh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return coshf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(cosh_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("cosh"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {-1.0, 2.0, -3.0, 4.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return coshf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convert_downcast_overflow_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data(4, 2 * std::numeric_limits::max()); - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), - l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of(results_vector.begin(), results_vector.end(), [](const auto& x) { - return x == std::numeric_limits::max(); - })); -} - -TEST_CASE(convert_downcast_underflow_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data(4, 2 * std::numeric_limits::lowest()); - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), - l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of(results_vector.begin(), results_vector.end(), [](const auto& x) { - return x == std::numeric_limits::lowest(); - })); -} - -TEST_CASE(convert_nan_upcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::half_type, {2, 2}}; - std::vector data(4, std::numeric_limits::quiet_NaN()); - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4, -1); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of( - results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); -} - -TEST_CASE(convert_nan_downcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {2, 2}}; - std::vector data(4, std::numeric_limits::quiet_NaN()); - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4, -1); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of( - results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); -} - -TEST_CASE(convert_nan_double_convert_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {2, 2}}; - std::vector data(4, std::numeric_limits::quiet_NaN()); - auto l = mm->add_literal(migraphx::literal{s, data}); - auto f_l = mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); - mm->add_instruction(migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), - f_l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of( - results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); -} - -TEST_CASE(convert_nan_convert_updown_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data(4, std::numeric_limits::quiet_NaN()); - auto l = mm->add_literal(migraphx::literal{s, data}); - auto f_l = mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), l); - auto h_l = mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::half_type}}), f_l); - mm->add_instruction( - migraphx::make_op("convert", {{"target_type", migraphx::shape::float_type}}), h_l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::all_of( - results_vector.begin(), results_vector.end(), [](const auto& x) { return std::isnan(x); })); -} - -TEST_CASE(convolution_backwards_1d) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3}}; - std::vector x_data{0, 0.5, 1}; - std::vector w_data{0.5, 0.5, 0.5}; - - std::vector gold{0, 0.25, 0.75, 0.75, 0.5}; - - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction(migraphx::make_op("convolution_backwards", - {{"padding", {0}}, {"stride", {1}}, {"dilation", {1}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_2d) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - - std::vector gold{0, 1, 3, 3, 2, 3, 8, 15, 12, 7, 9, 21, 36, - 27, 15, 9, 20, 33, 24, 13, 6, 13, 21, 15, 8}; - - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction(migraphx::make_op("convolution_backwards"), x, w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_3d) -{ - migraphx::shape s_1{migraphx::shape::float_type, {1, 1, 1, 2, 3}}; - migraphx::shape s_2{migraphx::shape::float_type, {1, 1, 3, 2, 3}}; - - // clang-format off - std::vector x_data{0.8471, -0.4195, -2.2749, 1.2491, 0.1722, 0.3246}; - std::vector w_data{ - 0.6478, -0.1985, 0.0633, -0.3479, 2.7056, -0.1440, - -1.1229, -0.7507, -1.3151, 0.8884, -0.1859, -0.3407, - -1.1544, -1.5893, 1.6265, -1.4624, 0.3812, -1.5378 - }; - std::vector gold{0.5488, -0.4399, -1.3369, 0.4251, -0.1439, 0.5145, 2.3015, -0.2104, - -6.1482, 0.3482, -0.4346, 3.3197, 0.1731, 0.8533, -0.0467, -0.9512, - -0.1649, 1.7553, 2.2594, 2.9917, -0.6500, -1.6612, -4.3680, 0.0957, - 0.3482, 1.1097, -0.0792, -0.1692, -0.1190, -0.1106, -0.9779, -0.8621, - 4.6707, 2.9332, -3.7001, -2.6808, -1.2476, 3.2475, -0.4578, 4.0263, - -1.8267, 0.2243, -2.3299, -0.1411, -0.4991}; - // clang-format on - - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s_1, x_data}); - auto w = mm->add_literal(migraphx::literal{s_2, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {0, 0, 0}}, {"stride", {1, 1, 1}}, {"dilation", {1, 1, 1}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_padding1) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - - std::vector gold{8, 15, 12, 21, 36, 27, 20, 33, 24}; - - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {1, 1}}, {"stride", {1, 1}}, {"dilation", {1, 1}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_padding2) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - - std::vector gold{3., 8., 15., 12., 7., 9., 21., 36., 27., 15., 9., 20., 33., 24., 13.}; - - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {1, 0}}, {"stride", {1, 1}}, {"dilation", {1, 1}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_2stride) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - std::vector gold{0., 0., 1., 1., 3., 2., 2., 0., 0., 1., 1., 3., 2., - 2., 3., 3., 8., 5., 12., 7., 7., 3., 3., 7., 4., 9., - 5., 5., 9., 9., 20., 11., 24., 13., 13., 6., 6., 13., 7., - 15., 8., 8., 6., 6., 13., 7., 15., 8., 8.}; - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {0, 0}}, {"stride", {2, 2}}, {"dilation", {1, 1}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_2dilation) -{ - migraphx::shape s{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - std::vector gold{0., 1., 2., 1., 2., 1., 2., 3., 4., 8., 4., 8., 4., - 5., 6., 8., 16., 8., 16., 8., 10., 3., 4., 8., 4., 8., - 4., 5., 6., 8., 16., 8., 16., 8., 10., 3., 4., 8., 4., - 8., 4., 5., 6., 7., 14., 7., 14., 7., 8.}; - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(migraphx::literal{s, x_data}); - auto w = mm->add_literal(migraphx::literal{s, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {0, 0}}, {"stride", {1, 1}}, {"dilation", {2, 2}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_dyn_batch1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - // clang-format off - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {1, 1}, {3, 3}, {3, 3}}}; - // clang-format on - auto x = mm->add_parameter("x", s); - auto w = mm->add_parameter("w", s); - - mm->add_instruction(migraphx::make_op("convolution_backwards"), x, w); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector w_data{1, 1, 1, 1, 1, 1, 1, 1, 1}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 3, 3}}; - params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); - params["w"] = migraphx::argument(input_fixed_shape, w_data.data()); - auto result = p.eval(params).back(); - - std::vector gold{0, 1, 3, 3, 2, 3, 8, 15, 12, 7, 9, 21, 36, - 27, 15, 9, 20, 33, 24, 13, 6, 13, 21, 15, 8}; - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(convolution_backwards_dyn_batch2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - // clang-format off - migraphx::shape x_shape{migraphx::shape::float_type, - {{1, 4}, {1, 1}, {5, 5}, {5, 5}}}; - // clang-format on - auto x = mm->add_parameter("x", x_shape); - migraphx::shape w_shape{migraphx::shape::float_type, {1, 1, 3, 3}}; - std::vector w_data(9, 1.); - auto w = mm->add_literal(migraphx::literal{w_shape, w_data}); - - mm->add_instruction( - migraphx::make_op("convolution_backwards", - {{"padding", {2, 2}}, {"stride", {2, 2}}, {"dilation", {2, 2}}}), - x, - w); - p.compile(migraphx::make_target("ref")); - - std::vector x_data(25); - std::iota(x_data.begin(), x_data.end(), 0.); - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 1, 5, 5}}; - params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); - auto result = p.eval(params).back(); - - //clang-format off - std::vector gold{12., 0., 21., 0., 27., 0., 33., 0., 24., 0., 0., 0., 0., 0., - 0., 0., 0., 0., 33., 0., 54., 0., 63., 0., 72., 0., 51., 0., - 0., 0., 0., 0., 0., 0., 0., 0., 63., 0., 99., 0., 108., 0., - 117., 0., 81., 0., 0., 0., 0., 0., 0., 0., 0., 0., 93., 0., - 144., 0., 153., 0., 162., 0., 111., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 72., 0., 111., 0., 117., 0., 123., 0., 84.}; - //clang-format on - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(dequantizelinear) -{ - { /*uint8*/ - migraphx::shape xs{migraphx::shape::uint8_type, {1, 3, 3}}; - std::vector xv = {0, 1, 2, 5, 10, 50, 100, 150, 250}; - migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}}; - std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2}; - migraphx::shape zs{migraphx::shape::uint8_type, {1, 3, 3}}; - std::vector zv = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - auto create_program = [&]() { - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(xs, xv); - auto s = mm->add_literal(ss, sv); - auto z = mm->add_literal(zs, zv); - mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s, z); - return p; - }; - - migraphx::program p1 = create_program(); - p1.compile(migraphx::make_target("ref")); - auto result = p1.eval({}).back(); - std::vector results_vector(9); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 2, 4, 10, 20, 100, 200, 300, 500}; - EXPECT(results_vector == gold); - } - - { /*int8*/ - migraphx::shape xs{migraphx::shape::int8_type, {1, 3, 3}}; - std::vector xv = {-128, -100, -50, -1, 0, 1, 50, 100, 127}; - migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}}; - std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2}; - auto create_program = [&]() { - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(xs, xv); - auto s = mm->add_literal(ss, sv); - mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s); - return p; - }; - - migraphx::program p1 = create_program(); - p1.compile(migraphx::make_target("ref")); - auto result = p1.eval({}).back(); - std::vector results_vector(9); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-256, -200, -100, -2, 0, 2, 100, 200, 254}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(dimensions_of_test0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4, {2, 4}}, {3, 3}, {4, 4}}}; - auto p1 = mm->add_parameter("x", s); - mm->add_instruction(migraphx::make_op("dimensions_of", {{"end", 3}}), p1); - p.compile(migraphx::make_target("ref")); - - std::vector x_data(24, 1.0); - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 3, 4}}; - migraphx::parameter_map params; - params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {2, 3, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(dimensions_of_test1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {3, 3}, {3, 8}, {3, 8}}}; - auto p1 = mm->add_parameter("x", s); - mm->add_instruction(migraphx::make_op("dimensions_of", {{"start", 2}, {"end", 4}}), p1); - p.compile(migraphx::make_target("ref")); - - std::vector x_data(48, 1.0); - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4, 4}}; - migraphx::parameter_map params; - params["x"] = migraphx::argument(input_fixed_shape, x_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {4, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(div_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data1 = {-1.0f, 0.5f, 1.0f}; - std::vector data2 = {1.0f, 2.0f, 4.0f}; - auto l1 = mm->add_literal(migraphx::literal{s, data1}); - auto l2 = mm->add_literal(migraphx::literal{s, data2}); - mm->add_instruction(migraphx::make_op("div"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data1.size()); - std::transform(data1.begin(), data1.end(), data2.begin(), gold.begin(), std::divides()); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(div_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6, {3}}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - mm->add_instruction(migraphx::make_op("div"), x, y); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1.0f, 0.5f, 1.0f}; - std::vector y_data{1.0f, 2.0f, 4.0f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(x_data.size()); - std::transform( - x_data.begin(), x_data.end(), y_data.begin(), gold.begin(), std::divides()); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(elu_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - auto l = mm->add_literal(migraphx::literal{s, {-1.0, 2.0, -3.0, 4.0}}); - float alpha = 0.5; - mm->add_instruction(migraphx::make_op("elu", {{"alpha", alpha}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{elu(alpha, -1), elu(alpha, 2), elu(alpha, -3), elu(alpha, 4)}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(elu_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - float alpha = 0.5; - mm->add_instruction(migraphx::make_op("elu", {{"alpha", alpha}}), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1.0, 2.0, -3.0, 4.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{elu(alpha, -1), elu(alpha, 2), elu(alpha, -3), elu(alpha, 4)}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(equal_brcst_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; - auto l0 = - mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); - migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; - auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); - auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); - auto eq = mm->add_instruction(migraphx::make_op("equal"), l0, bl1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - eq); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {true, false, false, false, true, false, true, false, false}; - EXPECT(results_vector == gold); -} - -TEST_CASE(equal_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - auto l0 = - mm->add_literal(migraphx::literal{s, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); - auto l1 = - mm->add_literal(migraphx::literal{s, {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}}); - auto eq = mm->add_instruction(migraphx::make_op("equal"), l0, l1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - eq); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {true, false, false, false, true, false, true, false, false}; - EXPECT(results_vector == gold); -} - -TEST_CASE(equal_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{6, 12, {9}}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto p0 = mm->add_parameter("l", s); - auto p1 = mm->add_parameter("r", s); - auto eq = mm->add_instruction(migraphx::make_op("equal"), p0, p1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - eq); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - - std::vector l_data{1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - std::vector r_data{1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["l"] = migraphx::argument(input_fixed_shape0, l_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, r_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {true, false, false, false, true, false, true, false, false}; - EXPECT(results_vector == gold); -} - -TEST_CASE(erf_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {4}}; - std::vector data = {0.73785057, 1.58165966, -0.43597795, -0.01677432}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("erf"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return erff(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(erf_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("erf"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {0.73785057, 1.58165966, -0.43597795, -0.01677432}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return erff(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(exp_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data{-1, 0, 1}; - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("exp"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return expf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(exp_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("exp"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1, 0, 1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return expf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(floor_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - std::vector data = {1.1, 1.5, 0.6, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("floor"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return floor(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(floor_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{5, 12}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("floor"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {1.1, 1.5, 0.6, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return floor(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(fp16_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::half_type, {1}}; - migraphx::half a{1.5}; - migraphx::half b{2.5}; - migraphx::half c{4.0}; - auto l0 = mm->add_literal(migraphx::literal{s, {a}}); - auto l1 = mm->add_literal(migraphx::literal{s, {b}}); - mm->add_instruction(migraphx::make_op("add"), l0, l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(1); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{c}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(fp32_fp16_test) -{ - auto create_program = [] { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3}}; - std::vector data(2 * 3); - std::iota(data.begin(), data.end(), 1.0f); - auto l1 = mm->add_literal(migraphx::literal(s, data)); - auto l2 = mm->add_literal(migraphx::literal(s, data)); - mm->add_instruction(migraphx::make_op("add"), l1, l2); - return p; - }; - - auto test_case = [&](std::vector&& op_names) { - std::vector gold_res = {2.0, 4.0, 6.0, 8.0, 10.0, 12.0}; - auto p = create_program(); - migraphx::quantize_fp16(p, op_names); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res; - result.visit([&](auto output) { res.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res, gold_res)); - }; - - test_case({"all"}); - test_case({"add"}); -} - -TEST_CASE(gather_non_std_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data = {0.5f, 3.5f, 6.5f, 1.5f, 4.5f, 7.5f, 2.5f, 2.5f, 8.5f}; - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto d = mm->add_literal(migraphx::literal{s, data}); - migraphx::shape s_indices{migraphx::shape::int32_type, {2, 2}}; - std::vector indices{-3, -3, -1, -1}; - auto ind = mm->add_literal(migraphx::literal{s_indices, indices}); - auto td = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), d); - auto tind = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), ind); - - mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), td, tind); - auto result = p.eval({}).back(); - std::vector golden = { - 0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f, 0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; - std::vector res_data; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } -} - -TEST_CASE(gather_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; - std::vector indices{0, 2}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = 0; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data(4 * 5); - std::vector golden = {0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; - std::vector indices{-3, -1}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = 0; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data(4 * 5); - std::vector golden = {0.5f, 1.5f, 2.5f, 6.5f, 7.5f, 8.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; - std::vector indices{0, 2}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = 1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data(4 * 5); - std::vector golden = {0.5f, 2.5f, 3.5f, 5.5f, 6.5f, 8.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - migraphx::shape s_indices{migraphx::shape::int32_type, {1, 2}}; - std::vector indices{0, 2}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = -1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data(4 * 5); - std::vector golden = {0.5f, 2.5f, 3.5f, 5.5f, 6.5f, 8.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - // scalar index - migraphx::shape s_indices{migraphx::shape::int32_type}; - std::vector indices{0}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = -1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector golden = {0.5f, 3.5f, 6.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3 * 3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - // scalar index - migraphx::shape s_indices{migraphx::shape::int32_type}; - std::vector indices{-3}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = -1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector golden = {0.5f, 3.5f, 6.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - std::vector data(3); - std::iota(data.begin(), data.end(), 0.5); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto a0 = mm->add_literal(migraphx::literal{s, data}); - // scalar index - migraphx::shape s_indices{migraphx::shape::int32_type}; - std::vector indices{0}; - auto a1 = mm->add_literal(migraphx::literal{s_indices, indices}); - int axis = -1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), a0, a1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector golden = {0.5f}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, golden)); - } -} - -TEST_CASE(gather_dyn_test0) -{ - // Dynamic data, static indices - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {{2, 5}, {3, 3}}}; - - auto x = mm->add_parameter("x", s); - std::vector indices{1, 2}; - - migraphx::shape s_ind{migraphx::shape::int32_type, {1, 2}}; - auto ind = mm->add_parameter("indices", s_ind); - mm->add_instruction(migraphx::make_op("gather", {{"axis", 1}}), x, ind); - - migraphx::shape sresult{migraphx::shape::int32_type, {{2, 5}, {1, 1}, {2, 2}}}; - EXPECT(p.get_output_shapes().back() == sresult); - p.compile(migraphx::make_target("ref")); - - migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 3}}; - migraphx::shape input_indices{migraphx::shape::int32_type, {1, 2}}; - migraphx::parameter_map params; - std::vector data(2 * 3); - std::iota(data.begin(), data.end(), 0); - params["x"] = migraphx::argument(input_fixed_shape, data.data()); - params["indices"] = migraphx::argument(input_indices, indices.data()); - auto result = p.eval(params).back(); - - std::vector gold = {1, 2, 4, 5}; - std::vector results_vector(2 * 1 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - migraphx::shape sfinal{migraphx::shape::int32_type, {2, 1, 2}}; - EXPECT(result.get_shape() == sfinal); -} - -TEST_CASE(gather_dyn_test1) -{ - // Dynamic data, dynamic indices - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {{2, 5}, {4, 4}}}; - - auto x = mm->add_parameter("x", s); - - migraphx::shape s_ind{migraphx::shape::int32_type, {{1, 8, {7}}, {2, 3, {3}}}}; - auto ind = mm->add_parameter("indices", s_ind); - mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), x, ind); - - migraphx::shape sresult{migraphx::shape::int32_type, {{1, 8, {7}}, {2, 3, {3}}, {4, 4}}}; - EXPECT(p.get_output_shapes().back() == sresult); - p.compile(migraphx::make_target("ref")); - - migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {3, 4}}; - migraphx::shape input_indices_shape{migraphx::shape::int32_type, {1, 2}}; - std::vector indices{2, 0}; - migraphx::parameter_map params; - - std::vector data(3 * 4); - std::iota(data.begin(), data.end(), 0); - params["x"] = migraphx::argument(input_fixed_shape, data.data()); - params["indices"] = migraphx::argument(input_indices_shape, indices.data()); - auto result = p.eval(params).back(); - - std::vector gold = {8, 9, 10, 11, 0, 1, 2, 3}; - std::vector results_vector(1 * 2 * 4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - migraphx::shape sfinal{migraphx::shape::int32_type, {1, 2, 4}}; - EXPECT(result.get_shape() == sfinal); -} - -TEST_CASE(gathernd_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 2}}; - - std::vector data_vec(2 * 2); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{0, 0, 1, 1}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction(migraphx::make_op("gathernd"), data, indices); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{0, 3}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 1}}; - - std::vector data_vec(2 * 2); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction(migraphx::make_op("gathernd"), data, indices); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{2, 3, 0, 1}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; - - std::vector data_vec(2 * 3 * 1); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0, 0, 1}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction(migraphx::make_op("gathernd"), data, indices); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 3, 2, 3}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 2, 2}}; - - std::vector data_vec(2 * 3 * 2 * 3); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{0, 0, 0, 1, 0, 0, 0, 1}; - const int batch_dims = 1; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction( - migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{0, 1, 2, 3, 4, 5, 18, 19, 20, 21, 22, 23}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1, 3}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 3, 2}}; - - std::vector data_vec(2 * 3 * 1 * 3); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{0, 0, 0, 1, 0, 2, 0, 2, 0, 1, 0, 0}; - const int batch_dims = 2; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction( - migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{0, 4, 8, 11, 13, 15}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - // k > r - batch_dims - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1, 3}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 3, 3}}; - - std::vector data_vec(2 * 3 * 1 * 3); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec(2 * 3 * 3, 0); - const int batch_dims = 2; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - EXPECT(test::throws([&] { - mm->add_instruction( - migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), data, indices); - })); - } -} - -TEST_CASE(gathernd_dynamic0) -{ - // dynamic data, all dimensions fixed - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {{2, 2, {2}}, {3, 3}, {1, 1}}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - - auto gathernd_op = migraphx::make_op("gathernd"); - auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); - - mm->add_return({gathernd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data - migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index - - std::vector data_vec(2 * 3 * 1); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0, 0, 1}; - - params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); - params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); - - auto result = p.eval(params).back(); - std::vector res_data{}; - std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); -} - -TEST_CASE(gathernd_dynamic1) -{ - // dynamic data, dims not fixed - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {{2, 5, {2}}, {1, 5}, {1, 5}}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 2, 1}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - - auto gathernd_op = migraphx::make_op("gathernd"); - auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); - - mm->add_return({gathernd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data - migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index - - std::vector data_vec(2 * 3 * 1); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0, 0, 1}; - params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); - params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); - - auto result = p.eval(params).back(); - std::vector res_data{}; - std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); -} - -TEST_CASE(gathernd_dynamic2) -{ - // dynamic both index and data - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {{2, 5, {2}}, {1, 5}, {1, 5}}}; - migraphx::shape is{migraphx::shape::int64_type, {{2, 5, {3}}, {2, 3, {3}}, {1, 1}}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - - auto gathernd_op = migraphx::make_op("gathernd"); - auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); - - mm->add_return({gathernd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data - migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index - - std::vector data_vec(2 * 3 * 1); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0, 0, 1}; - params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); - params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); - - auto result = p.eval(params).back(); - std::vector res_data{}; - std::vector gold{3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); -} - -TEST_CASE(gathernd_dynamic3) -{ - // dynamic index, static data and a batch_dims input - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 3, 1}}; - migraphx::shape is{migraphx::shape::int64_type, {{2, 5, {3}}, {2, 3, {3}}, {1, 1}}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - - int batch_dims{1}; - auto gathernd_op = migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}); - auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); - - mm->add_return({gathernd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3, 1}}; // data - migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {2, 2, 1}}; // index - - std::vector data_vec(2 * 3 * 1); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{1, 0, 0, 1}; - params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); - params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); - - auto result = p.eval(params).back(); - std::vector res_data{}; - std::vector gold{1, 0, 3, 4}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, gold)); -} - -TEST_CASE(gathernd_dynamic4) -{ - // int(q) + r - k - batch_dims - 1 = 0 => returns a scalar - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {migraphx::shape::dynamic_dimension({2, 2})}}; - migraphx::shape is{migraphx::shape::int64_type, {1}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - - auto gathernd_op = migraphx::make_op("gathernd"); - auto gathernd = mm->add_instruction(gathernd_op, xdata, xindex); - - mm->add_return({gathernd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2}}; // data - migraphx::shape input_fixed_shape1{migraphx::shape::int64_type, {1}}; // index - - std::vector data_vec(2); - std::iota(data_vec.begin(), data_vec.end(), 4); - std::vector indices_vec{1}; - params["X"] = migraphx::argument(input_fixed_shape0, data_vec.data()); - params["I"] = migraphx::argument(input_fixed_shape1, indices_vec.data()); - - auto result = p.eval(params).back(); - std::vector res_data{}; - std::vector gold{5}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(res_data, gold)); -} - -TEST_CASE(gathernd_negative_index_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 1, 1}}; - - std::vector data_vec(2 * 2); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{-1, 0}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction(migraphx::make_op("gathernd"), data, indices); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector res_data{}; - std::vector gold{2, 3, 0, 1}; - result.visit([&](auto output) { res_data.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(res_data, gold)); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape ds{migraphx::shape::float_type, {2, 2}}; - migraphx::shape is{migraphx::shape::int64_type, {2, 1, 1}}; - - std::vector data_vec(2 * 2); - std::iota(data_vec.begin(), data_vec.end(), 0); - std::vector indices_vec{-3, 0}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, indices_vec}); - - mm->add_instruction(migraphx::make_op("gathernd"), data, indices); - p.compile(migraphx::make_target("ref")); - - EXPECT(test::throws([&] { p.eval({}); })); - } -} - -TEST_CASE(globalavgpool_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::average}; - auto lens = s.lens(); - op.lengths = {lens[2], lens[3]}; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.25, 0.575, 0.375}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(globalavgpool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6}, {2, 6, {2}}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction( - migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::average}, {"dyn_global", true}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.25, 0.575, 0.375}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(globallppool_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; - auto lens = s.lens(); - op.lengths = {lens[2], lens[3]}; - op.lp_order = 2; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.5477225575051662, 1.307669683062202, 0.9327379053088815}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(globallppool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = - migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6, {2}}, {2, 6, {2}}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction( - migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::lpnorm}, {"dyn_global", true}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.5477225575051662, 1.307669683062202, 0.9327379053088815}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(globalmaxpool_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; - auto lens = s.lens(); - op.lengths = {lens[2], lens[3]}; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.4, 0.9, 0.7}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(globalmaxpool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = - migraphx::shape{migraphx::shape::float_type, {{1, 1}, {3, 3}, {2, 6, {2}}, {2, 6, {2}}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction( - migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::max}, {"dyn_global", true}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 2, 2}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.4, 0.9, 0.7}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(greater_brcst_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; - auto l0 = - mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); - migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; - auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); - auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); - auto gr = mm->add_instruction(migraphx::make_op("greater"), l0, bl1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - gr); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, true, false, true, false, true, false, true, false}; - EXPECT(results_vector == gold); -} - -TEST_CASE(greater_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - auto l0 = - mm->add_literal(migraphx::literal{s, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); - auto l1 = - mm->add_literal(migraphx::literal{s, {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}}); - auto gr = mm->add_instruction(migraphx::make_op("greater"), l0, l1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - gr); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, false, true, true, false, true, false, false, true}; - EXPECT(results_vector == gold); -} - -TEST_CASE(greater_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{8, 10, {9}}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto left = mm->add_parameter("l", s); - auto right = mm->add_parameter("r", s); - auto gr = mm->add_instruction(migraphx::make_op("greater"), left, right); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - gr); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - - std::vector left_data{1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - std::vector right_data{1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, false, true, true, false, true, false, false, true}; - EXPECT(results_vector == gold); -} - -TEST_CASE(identity_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data{1, 2, 3, 4}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("identity"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::equal(data.begin(), data.end(), results_vector.begin())); -} - -TEST_CASE(identity_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 4}}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("identity"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{1, 2, 3, 4}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::int32_type, {2, 2}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(std::equal(input_data.begin(), input_data.end(), results_vector.begin())); -} - -TEST_CASE(if_literal_test) -{ - auto create_program = [] { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape cond_s{migraphx::shape::bool_type}; - auto cond = mm->add_parameter("cond", cond_s); - - migraphx::shape s{migraphx::shape::float_type, {5}}; - - auto* then_mod = p.create_module("If_0_if"); - std::vector data1 = {1, 2, 3, 4, 5}; - auto l1 = then_mod->add_literal(migraphx::literal(s, data1)); - then_mod->add_return({l1}); - - auto* else_mod = p.create_module("If_0_else"); - std::vector data2 = {5, 4, 3, 2, 1}; - auto l2 = else_mod->add_literal(migraphx::literal(s, data2)); - else_mod->add_return({l2}); - - auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod}); - auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); - mm->add_return({r}); - - return p; - }; - - auto run_prog = [&](bool cond) { - auto p = create_program(); - p.compile(migraphx::make_target("ref")); - std::vector c_data = {static_cast(cond)}; - migraphx::shape cs{migraphx::shape::bool_type}; - migraphx::parameter_map m; - m["cond"] = migraphx::argument(cs, c_data.data()); - - auto res = p.eval(m).back(); - std::vector ret; - res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); - - return ret; - }; - - // then branch - { - std::vector gold_ret = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - auto ret = run_prog(true); - EXPECT(gold_ret == ret); - } - - // else branch - { - std::vector gold_ret = {5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; - auto ret = run_prog(false); - EXPECT(gold_ret == ret); - } -} - -TEST_CASE(if_param_test) -{ - auto create_program = [] { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape cond_s{migraphx::shape::bool_type}; - auto cond = mm->add_parameter("cond", cond_s); - migraphx::shape ds{migraphx::shape::float_type, {2, 3}}; - auto x = mm->add_parameter("x", ds); - auto y = mm->add_parameter("y", ds); - std::vector data2 = {-0.258047, 0.360394, 0.536804, -0.577762, 1.0217, 1.02442}; - auto l2 = mm->add_literal(migraphx::literal(ds, data2)); - auto sum = mm->add_instruction(migraphx::make_op("add"), x, l2); - - auto* then_mod = p.create_module("If_0_if"); - std::vector data1 = {0.384804, -1.77948, -0.453775, 0.477438, -1.06333, -1.12893}; - auto l1 = then_mod->add_literal(migraphx::literal(ds, data1)); - auto tx = then_mod->add_parameter("x", ds); - auto a1 = then_mod->add_instruction(migraphx::make_op("add"), tx, l1); - then_mod->add_return({a1}); - - auto* else_mod = p.create_module("If_0_else"); - auto ey = else_mod->add_parameter("y", ds); - auto a2 = else_mod->add_instruction(migraphx::make_op("mul"), ey, sum); - else_mod->add_return({a2}); - - auto ret = mm->add_instruction(migraphx::make_op("if"), {cond, x, y}, {then_mod, else_mod}); - auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); - mm->add_return({r}); - - return p; - }; - - auto run_prog = [&](bool cond) { - auto p = create_program(); - p.compile(migraphx::make_target("ref")); - std::vector c_data = {static_cast(cond)}; - migraphx::shape cs{migraphx::shape::bool_type}; - migraphx::parameter_map m; - m["cond"] = migraphx::argument(cs, c_data.data()); - migraphx::shape ds{migraphx::shape::float_type, {2, 3}}; - std::vector data_x(ds.elements(), 1); - m["x"] = migraphx::argument(ds, data_x.data()); - std::vector data_y(ds.elements(), 2); - m["y"] = migraphx::argument(ds, data_y.data()); - - auto res = p.eval(m).back(); - std::vector ret; - res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); - return ret; - }; - - // then branch - { - std::vector gold_ret = { - 1.384804, -0.77947998, 0.54622501, 1.477438, -0.063330054, -0.12892997}; - auto ret = run_prog(true); - EXPECT(gold_ret == ret); - } - - // else branch - { - std::vector gold_ret = { - 1.483906, 2.720788, 3.0736079, 0.84447598, 4.0433998, 4.04884}; - auto ret = run_prog(false); - EXPECT(gold_ret == ret); - } -} - -TEST_CASE(if_pl_test) -{ - auto create_program = [] { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape cond_s{migraphx::shape::bool_type}; - migraphx::shape s{migraphx::shape::float_type, {5}}; - auto cond = mm->add_parameter("cond", cond_s); - auto x = mm->add_parameter("x", s); - - auto* then_mod = p.create_module("If_0_if"); - std::vector data1 = {1, 2, 3, 4, 5}; - auto l1 = then_mod->add_literal(migraphx::literal(s, data1)); - then_mod->add_return({l1, x}); - - auto* else_mod = p.create_module("If_0_else"); - std::vector data2 = {5, 4, 3, 2, 1}; - auto l2 = else_mod->add_literal(migraphx::literal(s, data2)); - auto s2 = else_mod->add_instruction(migraphx::make_op("add"), x, l2); - else_mod->add_return({s2, l2}); - - auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod}); - auto outline = mm->add_outline(s); - auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret); - mm->add_return({outline, r}); - - return p; - }; - - auto run_prog = [&](bool cond) { - auto p = create_program(); - p.compile(migraphx::make_target("ref")); - std::vector c_data = {static_cast(cond)}; - migraphx::shape cs{migraphx::shape::bool_type}; - migraphx::parameter_map m; - m["cond"] = migraphx::argument(cs, c_data.data()); - migraphx::shape ds{migraphx::shape::float_type, {5}}; - std::vector data(ds.elements(), 1); - m["x"] = migraphx::argument(ds, data.data()); - - auto res = p.eval(m).back(); - std::vector ret; - res.visit([&](auto v) { ret.assign(v.begin(), v.end()); }); - - return ret; - }; - - // then branch - { - std::vector gold_ret = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - auto ret = run_prog(true); - EXPECT(gold_ret == ret); - } - - // else branch - { - std::vector gold_ret = {6.0f, 5.0f, 4.0f, 3.0f, 2.0f}; - auto ret = run_prog(false); - EXPECT(gold_ret == ret); - } -} - -TEST_CASE(isnan_test) -{ - // float test - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3}}; - auto nan_val = std::numeric_limits::quiet_NaN(); - std::vector data0 = {1.2, 5.2, nan_val, nan_val, 0., 100.}; - auto l1 = mm->add_literal(migraphx::literal{s, data0}); - mm->add_instruction(migraphx::make_op("isnan"), l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector correct = {0, 0, 1, 1, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, correct)); - } - - // half test - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::half_type, {2, 3}}; - auto nan_val = std::numeric_limits::quiet_NaN(); - migraphx::half a{1.2}; - migraphx::half b{5.2}; - std::vector data0 = {a, b, nan_val, nan_val, b, a}; - auto l1 = mm->add_literal(migraphx::literal{s, data0}); - mm->add_instruction(migraphx::make_op("isnan"), l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector correct = {0, 0, 1, 1, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, correct)); - } -} - -TEST_CASE(isnan_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 2}, {3, 8}}}; - auto input = mm->add_parameter("X", s); - auto nan_val = std::numeric_limits::quiet_NaN(); - mm->add_instruction(migraphx::make_op("isnan"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {1.2, 5.2, nan_val, nan_val, 0., 100.}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector correct = {0, 0, 1, 1, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, correct)); -} - -TEST_CASE(im2col_3x3_no_pad_identity_test) -{ - std::size_t f[2] = {3, 3}; - std::size_t size[2] = {3, 3}; - std::vector padding{0, 0}; - std::vector stride{1, 1}; - std::vector dilation{1, 1}; - std::size_t channels = 1; - - std::vector weights(channels * f[0] * f[1]); - std::vector input(channels * size[0] * size[1]); - std::iota(input.begin(), input.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; - migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; - auto l_image = mm->add_literal(migraphx::literal{s_image, input}); - auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); - mm->add_instruction( - migraphx::make_op("im2col", - {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), - l_image, - l_weights); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; - std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; - std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, input)); -} - -TEST_CASE(im2col_3x3_no_pad_test) -{ - std::size_t f[2] = {3, 3}; - std::size_t size[2] = {4, 4}; - std::vector padding{0, 0}; - std::vector stride{1, 1}; - std::vector dilation{1, 1}; - std::size_t channels = 1; - - std::vector weights(channels * f[0] * f[1]); - std::vector input(channels * size[0] * size[1]); - std::iota(input.begin(), input.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; - migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; - auto l_image = mm->add_literal(migraphx::literal{s_image, input}); - auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); - mm->add_instruction( - migraphx::make_op("im2col", - {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), - l_image, - l_weights); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector correct = {0, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 3, 5, 6, 7, 9, 10, 11, - 4, 5, 6, 8, 9, 10, 12, 13, 14, 5, 6, 7, 9, 10, 11, 13, 14, 15}; - - std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; - std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; - std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, correct)); -} - -TEST_CASE(im2col_3x3_stride_2_no_pad_test) -{ - std::size_t f[2] = {3, 3}; - std::size_t size[2] = {6, 6}; - std::vector padding{0, 0}; - std::vector stride{2, 2}; - std::vector dilation{1, 1}; - std::size_t channels = 1; - - std::vector weights(channels * f[0] * f[1]); - std::vector input(channels * size[0] * size[1]); - std::iota(input.begin(), input.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; - migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; - auto l_image = mm->add_literal(migraphx::literal{s_image, input}); - auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); - mm->add_instruction( - migraphx::make_op("im2col", - {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), - l_image, - l_weights); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector correct = {0, 1, 2, 6, 7, 8, 12, 13, 14, 2, 3, 4, - 8, 9, 10, 14, 15, 16, 12, 13, 14, 18, 19, 20, - 24, 25, 26, 14, 15, 16, 20, 21, 22, 26, 27, 28}; - - std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; - std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; - std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, correct)); -} - -TEST_CASE(im2col_3x3_with_channels_identity_test) -{ - std::size_t f[2] = {3, 3}; - std::size_t size[2] = {3, 3}; - std::vector padding{0, 0}; - std::vector stride{1, 1}; - std::vector dilation{1, 1}; - std::size_t channels = 2; - - std::vector weights(channels * f[0] * f[1]); - std::vector input(channels * size[0] * size[1]); - std::iota(input.begin(), input.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; - migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; - auto l_image = mm->add_literal(migraphx::literal{s_image, input}); - auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); - mm->add_instruction( - migraphx::make_op("im2col", - {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), - l_image, - l_weights); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; - std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; - std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, input)); -} - -TEST_CASE(im2col_3x3_with_padding_test) -{ - std::size_t f[2] = {3, 3}; - std::size_t size[2] = {2, 2}; - std::vector padding{1, 1}; - std::vector stride{1, 1}; - std::vector dilation{1, 1}; - std::size_t channels = 1; - - std::vector weights(channels * f[0] * f[1]); - std::vector input(channels * size[0] * size[1]); - std::iota(input.begin(), input.end(), 0); - - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s_image{migraphx::shape::int32_type, {1, channels, size[0], size[1]}}; - migraphx::shape s_weights{migraphx::shape::int32_type, {1, channels, f[0], f[1]}}; - auto l_image = mm->add_literal(migraphx::literal{s_image, input}); - auto l_weights = mm->add_literal(migraphx::literal{s_weights, weights}); - mm->add_instruction( - migraphx::make_op("im2col", - {{"padding", padding}, {"stride", stride}, {"dilation", dilation}}), - l_image, - l_weights); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector correct = {0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, - 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0}; - - std::size_t col_height = (size[0] - f[0] + 2 * padding[0]) / stride[0] + 1; - std::size_t col_width = (size[1] - f[1] + 2 * padding[1]) / stride[1] + 1; - std::vector results_vector(channels * f[0] * f[1] * col_height * col_width); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, correct)); -} - -TEST_CASE(imagescaler_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {1, 3, 2, 2}}; - auto img = mm->add_literal(migraphx::literal{s, - {0.2, - 0.3, - 0.5, - 0.4, - - 0.7, - 0.8, - 0.1, - 0.9, - - 0.15, - 0.25, - 0.35, - 0.45}}); - auto scale_val = mm->add_literal(2.f); - auto scaled_tensor = mm->add_instruction( - migraphx::make_op("scalar", {{"scalar_bcst_dims", s.lens()}}), scale_val); - auto img_scaled = mm->add_instruction(migraphx::make_op("mul"), img, scaled_tensor); - auto bias_vals = mm->add_literal( - migraphx::literal{migraphx::shape{migraphx::shape::float_type, {3}}, {0.01, 0.02, 0.03}}); - auto bias_bcast = mm->add_instruction( - migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", s.lens()}}), bias_vals); - mm->add_instruction(migraphx::make_op("add"), img_scaled, bias_bcast); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.41, - 0.61, - 1.01, - 0.81, - - 1.42, - 1.62, - 0.22, - 1.82, - - 0.33, - 0.53, - 0.73, - 0.93}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(leaky_relu_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l = mm->add_literal(migraphx::literal{s, {-1.f, 0.f, 1.f}}); - mm->add_instruction(migraphx::make_op("leaky_relu", {{"alpha", 0.01}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-0.01f, 0.f, 1.f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(less_brcst_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s0{migraphx::shape::float_type, {3, 3}}; - auto l0 = - mm->add_literal(migraphx::literal{s0, {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}}); - migraphx::shape s1{migraphx::shape::float_type, {3, 1}}; - auto l1 = mm->add_literal(migraphx::literal{s1, {1.1, -1.5, 0.0}}); - auto bl1 = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), l1); - auto le = mm->add_instruction(migraphx::make_op("less"), l0, bl1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - le); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, false, true, false, false, false, false, false, true}; - EXPECT(results_vector == gold); -} - -TEST_CASE(less_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - std::vector data1 = {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - std::vector data2 = {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; - auto l0 = mm->add_literal(migraphx::literal{s, data1}); - auto l1 = mm->add_literal(migraphx::literal{s, data2}); - auto le = mm->add_instruction(migraphx::make_op("less"), l0, l1); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - le); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data1.size()); - std::transform( - data1.begin(), data1.end(), data2.begin(), gold.begin(), [](float n1, float n2) -> bool { - return n1 < n2; - }); - EXPECT(results_vector == gold); -} - -TEST_CASE(less_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{8, 10, {9}}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto left = mm->add_parameter("l", s); - auto right = mm->add_parameter("r", s); - auto le = mm->add_instruction(migraphx::make_op("less"), left, right); - auto r = mm->add_instruction( - migraphx::make_op("convert", - {{"target_type", migraphx::to_value(migraphx::shape::bool_type)}}), - le); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - - std::vector left_data = {1.1, 1.5, 0.1, -1.1, -1.5, -0.6, 0.0, 2.0, -2.0}; - std::vector right_data = {1.1, 1.6, -0.1, -1.2, -1.5, -0.7, 0.0, 2.3, -2.1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(left_data.size()); - std::transform(left_data.begin(), - left_data.end(), - right_data.begin(), - gold.begin(), - [](float n1, float n2) -> bool { return n1 < n2; }); - EXPECT(results_vector == gold); -} - -TEST_CASE(log_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data = {1, 2, 3}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("log"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return logf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(log_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("log"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return logf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_and_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::bool_type, {4}}; - std::vector data1{true, false, true, false}; - std::vector data2{true, true, false, false}; - auto l1 = mm->add_literal(migraphx::literal{s, data1}); - auto l2 = mm->add_literal(migraphx::literal{s, data2}); - mm->add_instruction(migraphx::make_op("logical_and"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data2.size()); - std::transform( - data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { - return n1 and n2; - }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_and_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6, {4}}}; - migraphx::shape s{migraphx::shape::bool_type, dd}; - auto left = mm->add_parameter("l", s); - auto right = mm->add_parameter("r", s); - mm->add_instruction(migraphx::make_op("logical_and"), left, right); - p.compile(migraphx::make_target("ref")); - - std::vector left_data{1, 0, 1, 0}; - std::vector right_data{1, 1, 0, 0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; - params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(left_data.size()); - std::transform(left_data.begin(), - left_data.end(), - right_data.begin(), - gold.begin(), - [](bool n1, bool n2) -> bool { return n1 and n2; }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_or_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::bool_type, {4}}; - std::vector data1{true, false, true, false}; - std::vector data2{true, true, false, false}; - auto l1 = mm->add_literal(migraphx::literal{s, data1}); - auto l2 = mm->add_literal(migraphx::literal{s, data2}); - mm->add_instruction(migraphx::make_op("logical_or"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data1.size()); - std::transform( - data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { - return n1 or n2; - }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_or_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6, {4}}}; - migraphx::shape s{migraphx::shape::bool_type, dd}; - auto left = mm->add_parameter("l", s); - auto right = mm->add_parameter("r", s); - mm->add_instruction(migraphx::make_op("logical_or"), left, right); - p.compile(migraphx::make_target("ref")); - - std::vector left_data{1, 0, 1, 0}; - std::vector right_data{1, 1, 0, 0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; - params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(left_data.size()); - std::transform(left_data.begin(), - left_data.end(), - right_data.begin(), - gold.begin(), - [](bool n1, bool n2) -> bool { return n1 or n2; }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_xor_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::bool_type, {4}}; - std::vector data1{true, false, true, false}; - std::vector data2{true, true, false, false}; - auto l1 = mm->add_literal(migraphx::literal{s, data1}); - auto l2 = mm->add_literal(migraphx::literal{s, data2}); - mm->add_instruction(migraphx::make_op("logical_xor"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, true, true, false}; - std::transform( - data1.begin(), data1.end(), data2.begin(), gold.begin(), [](bool n1, bool n2) -> bool { - return n1 ^ n2; - }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logical_xor_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6, {4}}}; - migraphx::shape s{migraphx::shape::bool_type, dd}; - auto left = mm->add_parameter("l", s); - auto right = mm->add_parameter("r", s); - mm->add_instruction(migraphx::make_op("logical_xor"), left, right); - p.compile(migraphx::make_target("ref")); - - std::vector left_data{1, 0, 1, 0}; - std::vector right_data{1, 1, 0, 0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::bool_type, {4}}; - params0["l"] = migraphx::argument(input_fixed_shape0, left_data.data()); - params0["r"] = migraphx::argument(input_fixed_shape0, right_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {false, true, true, false}; - std::transform(left_data.begin(), - left_data.end(), - right_data.begin(), - gold.begin(), - [](bool n1, bool n2) -> bool { return n1 ^ n2; }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(logsoftmax_test_axis_0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, - -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, - -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, - -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, - 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, - -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, - -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, - -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; - - std::vector s = { - -0.135261, -2.843968, -0.659995, -0.488413, -1.051857, -2.812936, -0.250956, -0.353985, - -1.155980, -0.603651, -0.211969, -0.175371, -1.336552, -3.885010, -1.871544, -0.837083, - -0.887745, -0.433338, -1.158864, -4.911197, -1.147972, -0.666711, -0.996874, -0.981418, - -0.851145, -0.853988, -0.858112, -2.067420, -0.059956, -0.727436, -0.950881, -0.429689, - -0.061906, -1.505332, -1.210277, -0.377970, -0.791448, -1.655428, -1.827253, -0.304828, - -0.020762, -0.167101, -0.567346, -0.530319, -1.045094, -0.376648, -0.007391, -0.381670, - -0.720302, -0.460499, -0.469651, -0.556740, -0.554628, -0.551582}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - int axis = 0; - mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(logsoftmax_test_axis_1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, - -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, - -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, - -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, - 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, - -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, - -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, - -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; - - std::vector s = { - -0.550468, -2.132973, -1.549746, -0.650533, -1.051529, -2.248570, -0.141017, -2.028357, - -1.947730, -1.511324, -0.166597, -0.379726, -1.965689, -1.172109, -1.475721, -2.700831, - -1.537011, -0.658754, -1.596017, -3.353137, -2.266743, -1.084197, -1.076214, -0.406712, - -2.743019, -0.425526, -1.079083, -2.139486, -1.270584, -1.024088, -1.154231, -3.201762, - -0.888957, -0.532855, -3.103583, -1.221339, -1.355980, -3.531678, -1.438510, -0.975194, - -0.080261, -1.162697, -1.568557, -1.398519, -1.322129, -0.470660, -0.370953, -0.907343, - -1.179017, -3.312239, -1.286363, -1.586076, -0.345100, -0.824173}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - int axis = 1; - mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(logsoftmax_test_axis_2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, - -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, - -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, - -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, - 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, - -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, - -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, - -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; - - std::vector s = { - -0.495957, -1.031212, -0.245531, -2.013726, -1.339125, -2.465619, -1.356652, -0.964037, - -2.019250, -0.214522, -0.289569, -0.234392, -2.086591, -2.684439, -2.851651, -2.674176, - -1.697424, -1.889155, -0.401029, -3.064586, -1.173030, -1.306912, -2.177020, -0.834262, - -2.818177, -0.174415, -1.361105, -1.024571, -0.106766, -1.167645, -1.072650, -2.576522, - -0.569261, -1.207483, -3.679894, -2.095913, -0.504264, -3.039291, -1.290559, -1.156812, - -0.126453, -0.551493, -2.506384, -2.646261, -1.905195, -0.206994, -0.191369, -0.959754, - -1.948685, -3.671233, -0.875521, -3.111952, -1.905644, -1.6076011}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - int axis = 2; - mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(logsoftmax_test_axis_3) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - 1.93885877, -1.20006269, 0.90960855, 0.42108916, -1.50797544, -1.31047913, 1.07816336, - -1.13288733, -0.86411064, 0.97800238, 0.76631385, 2.07962834, -0.8940665, -1.62855592, - -0.53763057, -1.48165117, -0.64154112, 0.42486547, 0.89330917, -2.42022666, 0.192611, - -0.01257413, -1.5326607, 0.53137897, -1.52383859, 0.46994381, 0.00453619, 0.0066996, - 1.58394908, 0.84216752, -0.04137941, -0.88580789, 1.44055158, -0.17621241, -1.98917923, - -0.08610038, 0.79020567, -0.67714548, 0.42774631, 0.1376574, 2.23569227, 1.16681234, - -1.21191456, -0.28411502, -0.18688975, 1.67552548, 2.48357974, 0.95891282, -0.06616535, - -0.99628491, 1.04314606, -1.22943315, 0.76930403, 0.31106618}; - - std::vector s = { - -0.336904, -3.475825, -1.366154, -0.279366, -2.208430, -2.010934, -0.225511, -2.436562, - -2.167785, -1.572415, -1.784104, -0.470789, -1.067459, -1.801948, -0.711023, -2.307197, - -1.467087, -0.400681, -0.426983, -3.740518, -1.127681, -1.078919, -2.599005, -0.534965, - -2.561400, -0.567617, -1.033025, -2.097713, -0.520463, -1.262245, -1.763230, -2.607658, - -0.281299, -0.814243, -2.627210, -0.724131, -0.655704, -2.123055, -1.018163, -2.480634, - -0.382599, -1.451479, -1.843102, -0.915303, -0.818078, -1.316929, -0.508875, -2.033541, - -1.487672, -2.417791, -0.378360, -2.568531, -0.569794, -1.028032}; - - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 3, 3}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - int axis = 3; - mm->add_instruction(migraphx::make_op("logsoftmax", {{"axis", axis}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(lppool_l1_norm_test) -{ - // L1 norm test - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {1}; - op.lp_order = 1; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.5, 0.6, 0.5, 1.3, 1.4, 1.0, 0.8, 0.8, 0.7}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -// TODO: this tests compliance with a oneDNN rule and a feature that's commented out -// in pooling.hpp -// TEST_CASE(lppool_l1_norm_err_test) -// { -// // padding too large for kernel size -// migraphx::program p; -// auto* mm = p.get_main_module(); -// auto s = migraphx::shape{migraphx::shape::float_type, {1, 2, 5}}; -// auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; -// op.lengths = {3}; -// op.padding = {2}; -// op.stride = {1}; -// op.lp_order = 1; - -// std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7}; -// auto l0 = mm->add_literal(migraphx::literal{s, data}); -// EXPECT(test::throws([&] { -// mm->add_instruction(op, l0); -// })); -// } - -TEST_CASE(lppool_l2_norm_test) -{ - // L2 norm test - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::lpnorm}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {1}; - op.lp_order = 2; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.36055512754639896, - 0.447213595499958, - 0.4123105625617661, - 0.9433981132056605, - 1.0295630140987, - 0.9055385138137417, - 0.7071067811865475, - 0.7071067811865475, - 0.6082762530298219}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(lppool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::lpnorm}, - {"lengths", {2}}, - {"padding", {0}}, - {"stride", {1}}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.36055512754639896, - 0.447213595499958, - 0.4123105625617661, - 0.9433981132056605, - 1.0295630140987, - 0.9055385138137417, - 0.7071067811865475, - 0.7071067811865475, - 0.6082762530298219}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(lrn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {1, 5, 1, 1}}; - auto l = mm->add_literal(migraphx::literal{s, {-2.0f, 1.0f, 0.f, 1.0f, 2.0f}}); - mm->add_instruction( - migraphx::make_op("lrn", {{"alpha", 0.0001}, {"beta", 0.75}, {"bias", 1}, {"size", 5}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(5); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2 / 1.000075, 1 / 1.00009, 0 / 1.000145, 1 / 1.00009, 2 / 1.000075}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(max_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 4, 3}}); - auto l1 = mm->add_literal(migraphx::literal{s, {2, 8, 6}}); - auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); - auto curr_max = mm->add_instruction(migraphx::make_op("max"), l0, l1); - mm->add_instruction(migraphx::make_op("max"), curr_max, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{7, 8, 9}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(max_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - auto z = mm->add_parameter("z", s); - auto curr_max = mm->add_instruction(migraphx::make_op("max"), x, y); - mm->add_instruction(migraphx::make_op("max"), curr_max, z); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{1, 4, 3}; - std::vector y_data{2, 8, 6}; - std::vector z_data{7, 5, 9}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{7, 8, 9}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(maxpool_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - -2.1314404, -1.63041711, 1.54562736, 1.04625261, -1.42931843, -0.48703974, 0.4065806, - -0.1524526, 1.30775225, 0.45538983, -0.06631992, -1.75332725, 1.33493888, 0.47327688, - 0.36873096, 1.18358743, -0.34640595, 1.22098756, 0.01946825, -0.20238149, 0.43348005, - -0.67991608, -0.83041084, 0.93537551, 0.70241445, -0.5654031, -1.30899191, -0.26735824, - -0.52444768, 1.99097753, 1.86504853, -0.26506025, 0.26236168, 0.43763575, 0.95300823, - -1.02733946, -0.74655169, -0.5374338, -0.28901565, -0.59789604, 0.5310151, 0.99125904, - 0.40609556, -1.57175648, 0.22031412, 1.45862222, 0.53217483, 1.39087725, 1.00170159, - -0.87175864, -1.7204628, -1.72008383, -0.38656762, -0.01443311, 1.46645272, -1.39995027, - 0.22505587, -0.43461126, -0.05511411, -0.79950953, -0.01439556, 0.08795211, 1.18943918, - -0.84079367, -1.73383629, -0.55662078, -0.30626822, -0.67339015, 0.44179603, 0.54316711, - 0.40899998, -0.27831686, -1.11900508, -0.0881724, 0.35483059, 2.36277103, -0.04765317, - -0.36865309, 0.73814237, 1.47151589, 1.36546791, -0.32649881, -1.0517807, 2.24768877, - 0.68883753, 0.58646208, -0.91017133, -0.50462508, -0.4013325, -0.72348958, -0.47368807, - 0.35285577, -1.01817429, -0.5152272, 0.60321307, 0.43521205, -0.23733577, 0.66427642, - 0.82949388, 0.82443929, 0.71550399, 0.34561086, 0.68570769, -0.40718508, -1.20350206, - 0.15793853, -2.31013632, -0.07934658, -0.09348056, 0.36576006, 2.46601582, 0.11090943, - 0.9144392, 0.56759721, -0.22112127, -0.21955389, 0.72474903, -1.28448462, 1.53285873, - 0.37437943, 0.31409341, 1.95433736, 0.91620457, 0.86205518, 1.24365854, 0.19248386, - 0.22526583, 0.13462132, -0.27561715, -2.06446075, -0.02306402, -1.38278747, 1.1411345, - 1.31293464, -1.86041689, 1.06763375, -0.26541466, 1.4545635, 1.11430049, -0.66491818, - 0.87101674, 0.67768967, -1.02062869, -1.05031872, -2.2764678, -2.0200038, 0.37592548, - -0.26701379, -0.83388507, 0.19403623, 1.00968623, 0.11020003, 1.16736257, -1.1160326, - 0.47346735, 0.6126079, -0.19135755, 1.33624589, -0.29802522, -0.57873946, -1.06555879, - -0.20686582, 1.36892557, -0.19937795, 0.8649236, -1.40126073, 1.53441942, 0.34682792, - -1.31724346, -1.32898355, 2.40126371, 0.07845283, 1.35732043, -0.63678312, 0.39429256, - -1.36487007, -0.31026676, -0.44981545, -0.28994772, -0.14657612, -1.75206447, -0.70612341, - 1.20071781, -1.64647579, -0.7133292, 0.88494766, 0.52119428, -2.77387547, 2.07681108, - -0.90133125, 0.2847338, 0.6174528, -0.20616426, -0.64263535, -1.08496261, 0.54275119, - -0.88503587, 0.6629802, 1.47319221, -1.05829155, -0.97027361, -0.93187737, -1.39954746, - -0.52359426, -0.14743951, 1.51522756, 0.2078452, -1.28156149, -1.19363916, -0.78680223, - -0.89094824, 1.30212069, -0.77974445, -0.58411664, 0.48764706, -0.67132682}; - std::vector c = {1.33493888, 1.54562736, 1.22098756, 1.33493888, 1.18358743, 1.99097753, - 1.00170159, 1.45862222, 1.39087725, 1.46645272, 1.18943918, -0.01443311, - 1.47151589, 2.36277103, 2.24768877, 0.68883753, 0.82949388, 0.71550399, - 1.95433736, 2.46601582, 1.53285873, 1.95433736, 1.06763375, 1.4545635, - 1.33624589, 1.16736257, 0.6126079, 1.36892557, 2.40126371, 1.53441942, - 0.52119428, 2.07681108, 0.88494766, 1.51522756, 0.54275119, 0.6629802}; - migraphx::shape a_shape{migraphx::shape::float_type, {2, 3, 6, 6}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::max}, - {"padding", {0, 0}}, - {"stride", {2, 2}}, - {"lengths", {3, 2}}}), - al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(36); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, c)); -} - -TEST_CASE(maxpool_pad_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = {-6, -5, -4, -3, -5, -1, 0, 1, 2, 3, 4, 5}; - std::vector c = {-4, -3, -4, -1, 2, 3, 4, 5}; - migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 3, 2}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::max}, - {"padding", {1, 1}}, - {"stride", {2, 2}}, - {"lengths", {3, 2}}}), - al); - - // * * * * * * * * - // * -6 -5 * * 0 1 * - // * -4 -3 * padding will look like this * 2 3 * - // * -5 -1 * and this * 4 5 * - // * * * * The * values are actually -INF * * * * - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(8); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, c)); -} - -TEST_CASE(maxpool_rank3_test0) -{ - // 1D case 1, input is 3D - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {1, 3, 4}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {1}; - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.3, 0.4, 0.4, 0.8, 0.9, 0.9, 0.7, 0.7, 0.6}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(maxpool_rank3_test1) -{ - // 1D case 2, input is 3D - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 5}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {2}; - - std::vector data{0.4975, -0.1226, -0.0405, -0.2861, -0.1227, -0.6186, -0.9618, - 0.6022, -0.1912, 1.1925, 0.5493, 0.1692, -0.8039, -1.0281, - 0.9907, 0.477, 1.5001, -1.1603, -1.361, 1.2556}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.4975, -0.0405, -0.6186, 0.6022, 0.5493, -0.8039, 1.5001, -1.1603}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(maxpool_rank3_ceil_test) -{ - // 1D case 2, input is 3D, ceil mode - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 5}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; - op.lengths = {2}; - op.padding = {0}; - op.stride = {2}; - op.ceil_mode = true; - - // clang-format off - std::vector data{0.4975, -0.1226, -0.0405, -0.2861, -0.1227, - -0.6186, -0.9618, 0.6022, -0.1912, 1.1925, - 0.5493, 0.1692, -0.8039, -1.0281, 0.9907, - 0.477, 1.5001, -1.1603, -1.361, 1.2556}; - // clang-format on - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - // clang-format off - std::vector gold{0.4975, -0.0405, -0.1227, -0.6186, - 0.6022, 1.1925, 0.5493, -0.8039, - 0.9907, 1.5001, -1.1603, 1.2556}; - // clang-format on - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(maxpool_rank5_test) -{ - // 3D, input is 5D - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {2, 2, 3, 3, 3}}; - auto op = migraphx::op::pooling{migraphx::op::pooling_mode::max}; - op.lengths = {2, 2, 2}; - op.padding = {0, 0, 0}; - op.stride = {2, 2, 2}; - - std::vector data{ - -2.8029, 0.5861, 0.7015, 0.1297, -1.44, -1.9472, 0.7812, 2.408, -0.3145, 0.3405, - -0.9146, 0.0624, 1.5064, -0.8345, 1.7977, 1.8949, 1.0073, -0.2102, -0.042, -0.7146, - 0.6227, -0.5263, -2.2598, 0.1713, 0.449, 0.5303, -0.8622, -0.5691, 0.907, -0.0569, - -1.5348, -0.4109, -0.1461, -0.5445, 0.4266, 0.2282, 1.3655, -2.1519, 0.6068, -0.2001, - -0.4702, 0.3864, 1.7083, 0.9096, 0.4286, -1.8866, 0.7034, 0.0293, 1.4587, 0.7672, - -2.8614, 0.8124, -0.053, 1.0449, 0.845, -0.0131, 0.1139, -0.859, -1.2681, -0.6337, - -0.4644, 0.1938, 0.2889, 0.9035, 0.7118, -0.5767, 0.4577, -0.0549, 0.2237, 0.5756, - 0.0677, -0.0223, -0.329, 0.2364, 2.7666, -0.7417, -1.3196, -0.2655, 0.1698, -0.1777, - -0.9427, 2.6859, -0.7501, 0.5175, 1.0029, -2.6436, -0.4388, -1.2348, -0.1539, -0.6229, - -0.4136, 0.5085, 0.4136, -0.6439, -1.1953, -0.406, -0.0195, 0.1869, -0.8664, 1.1364, - 0.5041, 0.0647, 0.1941, -1.0819, -0.4629, -0.5107, 0.3612, -0.3583}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(op, l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.5064, 1.3655, 0.9035, 2.6859}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(maxpool_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - auto s = migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}}}; - auto x = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("pooling", - {{"mode", migraphx::op::pooling_mode::max}, - {"lengths", {2}}, - {"padding", {0}}, - {"stride", {1}}}), - x); - p.compile(migraphx::make_target("ref")); - - std::vector data{0.3, 0.2, 0.4, 0.1, 0.8, 0.5, 0.9, 0.1, 0.1, 0.7, 0.1, 0.6}; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 3, 4}}; - migraphx::parameter_map params; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.3, 0.4, 0.4, 0.8, 0.9, 0.9, 0.7, 0.7, 0.6}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(min_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 4, 3}}); - auto l1 = mm->add_literal(migraphx::literal{s, {2, 8, 6}}); - auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); - auto curr_min = mm->add_instruction(migraphx::make_op("min"), l0, l1); - mm->add_instruction(migraphx::make_op("min"), curr_min, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 4, 3}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(min_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - auto z = mm->add_parameter("z", s); - auto curr_min = mm->add_instruction(migraphx::make_op("min"), x, y); - mm->add_instruction(migraphx::make_op("min"), curr_min, z); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{1, 4, 3}; - std::vector y_data{2, 8, 6}; - std::vector z_data{7, 5, 9}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 4, 3}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(fmod_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {-7, 8, -3}}); - auto l1 = mm->add_literal(migraphx::literal{s, {2, 4, 6}}); - auto l2 = mm->add_literal(migraphx::literal{s, {7, 5, 9}}); - auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), l0, l1); - mm->add_instruction(migraphx::make_op("fmod"), curr_mod, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-1, 0, -3}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(fmod_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - auto z = mm->add_parameter("z", s); - auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), x, y); - mm->add_instruction(migraphx::make_op("fmod"), curr_mod, z); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-7, 8, -3}; - std::vector y_data{2, 4, 6}; - std::vector z_data{7, 5, 9}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-1, 0, -3}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(fmod_float_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {-7.2f, 8.5f, -3.3f}}); - auto l1 = mm->add_literal(migraphx::literal{s, {2.0f, 4.0f, 6.0f}}); - auto l2 = mm->add_literal(migraphx::literal{s, {7.0f, 5.0f, 9.0f}}); - auto curr_mod = mm->add_instruction(migraphx::make_op("fmod"), l0, l1); - mm->add_instruction(migraphx::make_op("fmod"), curr_mod, l2); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-1.2f, 0.5f, -3.3f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(mod_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {-3, 8, -7}}); - auto l1 = mm->add_literal(migraphx::literal{s, {3, 3, 3}}); - auto l2 = mm->add_literal(migraphx::literal{s, {10, 2, 9}}); - auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), l0, l1); - mm->add_instruction(migraphx::make_op("mod"), curr_mod, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 0, 2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(mod_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - auto z = mm->add_parameter("z", s); - auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), x, y); - mm->add_instruction(migraphx::make_op("mod"), curr_mod, z); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-3, 8, -7}; - std::vector y_data{3, 3, 3}; - std::vector z_data{10, 2, 9}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - params0["z"] = migraphx::argument(input_fixed_shape0, z_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 0, 2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(mod_float_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l0 = mm->add_literal(migraphx::literal{s, {-3.0f, 8.5f, -7.0f}}); - auto l1 = mm->add_literal(migraphx::literal{s, {2.0f, 3.0f, 3.0f}}); - auto l2 = mm->add_literal(migraphx::literal{s, {3.0f, 3.0f, 4.0f}}); - auto curr_mod = mm->add_instruction(migraphx::make_op("mod"), l0, l1); - mm->add_instruction(migraphx::make_op("mod"), curr_mod, l2); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0f, 2.5f, 2.0f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(mul_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data1{-1, 0, 1}; - std::vector data2{1, 2, 3}; - auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); - auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); - mm->add_instruction(migraphx::make_op("mul"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data1.size()); - std::transform( - data1.begin(), data1.end(), data2.begin(), gold.begin(), [](float n1, float n2) -> float { - return n1 * n2; - }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(mul_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - mm->add_instruction(migraphx::make_op("mul"), x, y); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1, 0, 1}; - std::vector y_data{1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(x_data.size()); - std::transform(x_data.begin(), - x_data.end(), - y_data.begin(), - gold.begin(), - [](float n1, float n2) -> float { return n1 * n2; }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(multibroadcast_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; - std::vector a_data{0, 0, 0, 0}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", l1->get_shape().lens()}}), - l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -3); - EXPECT(output(1, 0) == -2); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(multibroadcast_2in_static_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {2, 2}}; - std::vector a_data{0, 0, 0, 0}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - auto l1 = mm->add_literal(migraphx::literal{a_shape, a_data}); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -3); - EXPECT(output(1, 0) == -2); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(multibroadcast_2in_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 4}, {2, 2}}}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - std::vector b_data{-2, -3}; - auto l1 = mm->add_parameter("a", a_shape); - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1); - p.compile(migraphx::make_target("ref")); - - std::vector a_data{0, 0, 0, 0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; - params0["a"] = migraphx::argument(input_fixed_shape0, a_data.data()); - auto result = p.eval(params0).back(); - auto output = result.get(); - EXPECT(output(0, 0) == -2); - EXPECT(output(0, 1) == -3); - EXPECT(output(1, 0) == -2); - EXPECT(output(1, 1) == -3); -} - -TEST_CASE(multibroadcast_3in_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int32_type, {{2, 4}, {2, 2}}}; - migraphx::shape b_shape{migraphx::shape::int32_type, {2}}; - migraphx::shape c_shape{migraphx::shape::int32_type, {{1, 4, {2, 4}}, {2, 4}, {2, 2}}}; - auto l1 = mm->add_parameter("a", a_shape); - std::vector b_data{-2, -3}; - auto l2 = mm->add_literal(migraphx::literal{b_shape, b_data}); - auto l3 = mm->add_parameter("c", c_shape); - mm->add_instruction(migraphx::make_op("multibroadcast"), l2, l1, l3); - p.compile(migraphx::make_target("ref")); - - std::vector a_data(4, 0); - std::vector c_data(8, 0); - migraphx::parameter_map params; - migraphx::shape input_fixed_shape_a{migraphx::shape::float_type, {2, 2}}; - migraphx::shape input_fixed_shape_c{migraphx::shape::float_type, {2, 2, 2}}; - params["a"] = migraphx::argument(input_fixed_shape_a, a_data.data()); - params["c"] = migraphx::argument(input_fixed_shape_c, c_data.data()); - auto result = p.eval(params).back(); - auto output = result.get(); - EXPECT(output(0, 0, 0) == -2); - EXPECT(output(0, 0, 1) == -3); - EXPECT(output(0, 1, 0) == -2); - EXPECT(output(0, 1, 1) == -3); - EXPECT(output(1, 0, 0) == -2); - EXPECT(output(1, 0, 1) == -3); - EXPECT(output(1, 1, 0) == -2); - EXPECT(output(1, 1, 1) == -3); -} - -TEST_CASE(multinomial_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - size_t sample_size = 100000; - float seed = 0.0f; - std::mt19937 gen(seed); - std::uniform_real_distribution<> dis(0.0, 1.0); - std::vector rand_samples(sample_size); - std::generate(rand_samples.begin(), rand_samples.end(), [&]() { return dis(gen); }); - migraphx::shape rs{migraphx::shape::float_type, {1, sample_size}}; - auto rs_lit = mm->add_literal(migraphx::literal{rs, rand_samples}); - - migraphx::shape s{migraphx::shape::float_type, {1, 5}}; - std::vector dist{15, 25, 15, 25, 20}; - std::vector data(5); - std::transform(dist.begin(), dist.end(), data.begin(), [&](auto d) { return std::log(d); }); - auto input = mm->add_literal(migraphx::literal(s, data)); - - auto maxes = mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {1}}}), input); - auto mb_maxes = - mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {1, 5}}}), maxes); - auto cdf = mm->add_instruction(migraphx::make_op("sub"), input, mb_maxes); - cdf = mm->add_instruction(migraphx::make_op("exp"), cdf); - cdf = mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), cdf); - - mm->add_instruction(migraphx::make_op("multinomial"), cdf, rs_lit); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec(sample_size); - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - - std::vector res_dist(5, 0); - for(const auto& r : result_vec) - res_dist[r]++; - auto dist_sum = std::accumulate(dist.begin(), dist.end(), 0); - auto res_dist_sum = std::accumulate(res_dist.begin(), res_dist.end(), 0); - std::vector norm(5); - std::vector res_norm(5); - std::transform(dist.begin(), dist.end(), norm.begin(), [&](auto n) { - return static_cast(n) / dist_sum; - }); - std::transform(res_dist.begin(), res_dist.end(), res_norm.begin(), [&](auto n) { - return static_cast(n) / res_dist_sum; - }); - EXPECT(migraphx::verify::verify_range(norm, res_norm, 100000)); -} - -TEST_CASE(neg_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3}}; - std::vector data = {1.0f, 1.3f, -1.2f, 0.0f, -100.f, 200.f}; - auto input = mm->add_literal(migraphx::literal(s, data)); - auto ret = mm->add_instruction(migraphx::make_op("neg"), input); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vector; - result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform(gold.begin(), gold.end(), gold.begin(), std::negate()); - EXPECT(migraphx::verify::verify_range(result_vector, gold)); -} - -TEST_CASE(neg_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {3, 3}}}; - auto input = mm->add_parameter("X", s); - auto ret = mm->add_instruction(migraphx::make_op("neg"), input); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - - std::vector a = {1.0f, 1.3f, -1.2f, 0.0f, -100.f, 200.f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - auto result = p.eval(params0).back(); - std::vector result_vector; - result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); - std::vector gold = a; - std::transform(gold.begin(), gold.end(), gold.begin(), std::negate()); - EXPECT(migraphx::verify::verify_range(result_vector, gold)); -} - -TEST_CASE(nms_dyn_out_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; - std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, - 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; - - migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); - auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto r = mm->add_instruction( - migraphx::make_op("nonmaxsuppression", - {{"center_point_box", true}, {"use_dyn_output", true}}), - boxes_l, - scores_l, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto output = p.eval({}).back(); - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_dyn_batch_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 3}, {6, 6}, {4, 4}}}; - - migraphx::shape scores_s{migraphx::shape::float_type, {{1, 3}, {1, 1}, {6, 6}}}; - - auto boxes_p = mm->add_parameter("boxes", boxes_s); - auto scores_p = mm->add_parameter("scores", scores_s); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto r = mm->add_instruction( - migraphx::make_op("nonmaxsuppression", - {{"center_point_box", true}, {"use_dyn_output", true}}), - boxes_p, - scores_p, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - - std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, - 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0, - 0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, - 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; - std::vector scores_vec = { - 0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 6, 4}}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {2, 1, 6}}; - migraphx::parameter_map params0; - params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); - params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); - auto output = p.eval(params0).back(); - - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 1, 0, 3, 1, 0, 0, 1, 0, 5}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_dyn_boxes_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 1}, {4, 20}, {4, 4}}}; - - migraphx::shape scores_s{migraphx::shape::float_type, {{1, 1}, {1, 1}, {4, 20}}}; - - auto boxes_p = mm->add_parameter("boxes", boxes_s); - auto scores_p = mm->add_parameter("scores", scores_s); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto r = mm->add_instruction( - migraphx::make_op("nonmaxsuppression", - {{"center_point_box", true}, {"use_dyn_output", true}}), - boxes_p, - scores_p, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - - std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, - 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 6, 4}}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 1, 6}}; - migraphx::parameter_map params0; - params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); - params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); - auto output = p.eval(params0).back(); - - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_dyn_classes_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {{1, 1}, {6, 6}, {4, 4}}}; - - migraphx::shape scores_s{migraphx::shape::float_type, {{1, 1}, {1, 3}, {6, 6}}}; - - auto boxes_p = mm->add_parameter("boxes", boxes_s); - auto scores_p = mm->add_parameter("scores", scores_s); - auto max_out_l = mm->add_literal(int64_t{2}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto r = mm->add_instruction( - migraphx::make_op("nonmaxsuppression", - {{"center_point_box", true}, {"use_dyn_output", true}}), - boxes_p, - scores_p, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - - std::vector boxes_vec = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, - 0.0, -0.1, 1.0, 0.9, 0.0, 10.0, 1.0, 11.0, - 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; - std::vector scores_vec = { - 0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {1, 6, 4}}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {1, 2, 6}}; - migraphx::parameter_map params0; - params0["boxes"] = migraphx::argument(input_fixed_shape0, boxes_vec.data()); - params0["scores"] = migraphx::argument(input_fixed_shape1, scores_vec.data()); - auto output = p.eval(params0).back(); - - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 1, 3, 0, 1, 0}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_not_center_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; - std::vector boxes_vec = {1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, - 0.0, 0.9, 1.0, -0.1, 0.0, 10.0, 1.0, 11.0, - 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0}; - - migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); - auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - // set use_dyn_output back to false in operator map - auto r = - mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"use_dyn_output", false}}), - boxes_l, - scores_l, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto output = p.eval({}).back(); - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {1, 6, 4}}; - std::vector boxes_vec = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0, - 0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}; - - migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - auto boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); - auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto r = - mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), - boxes_l, - scores_l, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto output = p.eval({}).back(); - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_transpose1_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {1, 4, 6}}; - std::vector boxes_vec = { - 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6, 0.4, 10.5, 10.6, 100.5, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - }; - - migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - auto t_boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); - auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto transpose_boxes = mm->add_instruction( - migraphx::make_op("transpose", {{"permutation", {0, 2, 1}}}), t_boxes_l); - auto r = - mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), - transpose_boxes, - scores_l, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto output = p.eval({}).back(); - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nms_transpose2_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape boxes_s{migraphx::shape::float_type, {4, 1, 6}}; - std::vector boxes_vec = { - 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6, 0.4, 10.5, 10.6, 100.5, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - }; - - migraphx::shape scores_s{migraphx::shape::float_type, {1, 1, 6}}; - std::vector scores_vec = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3}; - - auto t_boxes_l = mm->add_literal(migraphx::literal(boxes_s, boxes_vec)); - auto scores_l = mm->add_literal(migraphx::literal(scores_s, scores_vec)); - auto max_out_l = mm->add_literal(int64_t{4}); - auto iou_threshold = mm->add_literal(0.5f); - auto score_threshold = mm->add_literal(0.0f); - - auto transpose_boxes = mm->add_instruction( - migraphx::make_op("transpose", {{"permutation", {1, 2, 0}}}), t_boxes_l); - auto r = - mm->add_instruction(migraphx::make_op("nonmaxsuppression", {{"center_point_box", true}}), - transpose_boxes, - scores_l, - max_out_l, - iou_threshold, - score_threshold); - mm->add_return({r}); - - p.compile(migraphx::make_target("ref")); - auto output = p.eval({}).back(); - std::vector result; - output.visit([&](auto out) { result.assign(out.begin(), out.end()); }); - std::vector gold = {0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(result, gold)); -} - -TEST_CASE(nonzero_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2, 3}}; - std::vector data = { - 1.0f, 1.3f, 0.0f, -1.2f, 0.0f, -100.f, 200.f, 0.0f, 0.1f, 0.2f, 0.0f, 0.5f}; - auto input = mm->add_literal(migraphx::literal(s, data)); - auto ret = mm->add_instruction(migraphx::make_op("nonzero"), input); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vector; - result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(result_vector, gold)); -} - -TEST_CASE(not_test) -{ - // int32 - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {4}}; - std::vector data{0, 8, 1, -32}; - auto l1 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("not"), l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - // bool - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::bool_type, {4}}; - std::vector data{false, false, true, true}; - auto l1 = mm->add_literal(migraphx::literal{s, {0, 0, 1, 1}}); - mm->add_instruction(migraphx::make_op("not"), l1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(data.size()); - std::transform( - data.begin(), data.end(), gold.begin(), [](bool n) -> bool { return not n; }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(not_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("not"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{0, 8, 1, -32}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pad_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); - mm->add_instruction(migraphx::make_op("pad", {{"pads", {1, 1, 1, 1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pad_test_asym) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); - mm->add_instruction(migraphx::make_op("pad", {{"pads", {0, 0, 1, 1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(9); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 2, 0, 3, 4, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pad_test_highest_half) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::half_type, {2, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); - mm->add_instruction( - migraphx::make_op("pad", - {{"pads", {1, 1, 1, 1}}, {"value", std::numeric_limits::max()}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - const float x = std::numeric_limits::max(); - std::vector gold{x, x, x, x, x, 1, 2, x, x, 3, 4, x, x, x, x, x}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pad_test_lowest_half) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::half_type, {2, 2}}; - auto l0 = mm->add_literal(migraphx::literal{s, {1, 2, 3, 4}}); - mm->add_instruction( - migraphx::make_op( - "pad", {{"pads", {1, 1, 1, 1}}, {"value", std::numeric_limits::lowest()}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - const float x = std::numeric_limits::lowest(); - std::vector gold{x, x, x, x, x, 1, 2, x, x, 3, 4, x, x, x, x, x}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pad_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4, {2}}, {2, 4, {2}}}}; - auto x = mm->add_parameter("x", s); - mm->add_instruction(migraphx::make_op("pad", {{"pads", {1, 1, 1, 1}}}), x); - p.compile(migraphx::make_target("ref")); - - std::vector data = {1, 2, 3, 4}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 2}}; - params["x"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector(16); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pointwise_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); - auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); - auto* pm = p.create_module("pointwise"); - auto x1 = pm->add_parameter("x1", {migraphx::shape::float_type}); - auto x2 = pm->add_parameter("x2", {migraphx::shape::float_type}); - pm->add_instruction(migraphx::make_op("add"), x1, x2); - mm->add_instruction(migraphx::make_op("pointwise"), {l1, l2}, {pm}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 2, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pow_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data = {1, 2, 3}; - auto b = mm->add_literal(migraphx::literal{s, data}); - auto e = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("pow"), b, e); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::pow(n, n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(pow_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto b = mm->add_parameter("b", s); - auto e = mm->add_parameter("e", s); - mm->add_instruction(migraphx::make_op("pow"), b, e); - p.compile(migraphx::make_target("ref")); - - std::vector data = {1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["b"] = migraphx::argument(input_fixed_shape0, data.data()); - params0["e"] = migraphx::argument(input_fixed_shape0, data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return std::pow(n, n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(prefix_scan_sum_1d) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {6}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, 3.0, 6.0, 10.0, 15.0, 21.0}; - EXPECT(results_vector == gold); -} - -TEST_CASE(prefix_scan_sum_dyn_1d) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{5, 8}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), - input); - p.compile(migraphx::make_target("ref")); - - std::vector a = {1, 2, 3, 4, 5, 6}; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {6}}; - migraphx::parameter_map params0; - params0["X"] = migraphx::argument(input_fixed_shape0, a.data()); - - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, 3.0, 6.0, 10.0, 15.0, 21.0}; - EXPECT(results_vector == gold); -} - -TEST_CASE(prefix_scan_sum_2d) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, 2.0, 3.0, 2.0, 4.0, 6.0, 3.0, 6.0, 9.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, 3.0, 6.0, 1.0, 3.0, 6.0, 1.0, 3.0, 6.0}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(prefix_scan_sum_3d) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 2.0, - 3.0, - 1.0, - 2.0, - 3.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 2.0, - 4.0, - 6.0, - 2.0, - 4.0, - 6.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 3.0, - 6.0, - 9.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 3.0, - 6.0, - 9.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 2}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(prefix_scan_sum_exclusive) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {8}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", true}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.0, 1.0, 3.0, 6.0, 10.0, 11.0, 13.0, 16.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 1}, {"exclusive", true}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0.0, - 0.0, - 0.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 0.0, - 0.0, - 0.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(prefix_scan_sum_exclusive_reverse) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {6}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", 0}, {"exclusive", true}, {"reverse", true}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{20.0, 18.0, 15.0, 11.0, 6.0, 0.0}; - EXPECT(results_vector == gold); -} - -TEST_CASE(prefix_scan_sum_negative_axis) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", -3}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 2.0, - 3.0, - 1.0, - 2.0, - 3.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 2.0, - 4.0, - 6.0, - 2.0, - 4.0, - 6.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", -2}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 3.0, - 6.0, - 9.0, - 1.0, - 2.0, - 3.0, - 2.0, - 4.0, - 6.0, - 3.0, - 6.0, - 9.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 3, 3}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", {{"axis", -1}, {"exclusive", false}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0, - 1.0, - 3.0, - 6.0}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(prefix_scan_sum_reverse) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {8}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", - {{"axis", 0}, {"exclusive", false}, {"reverse", true}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{20.0, 19.0, 17.0, 14.0, 10.0, 9.0, 7.0, 4.0}; - EXPECT(results_vector == gold); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 1, 2, 3, 4}}; - auto l0 = mm->add_literal(input); - mm->add_instruction( - migraphx::make_op("prefix_scan_sum", - {{"axis", 0}, {"exclusive", false}, {"reverse", true}}), - l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{2.0, 4.0, 6.0, 8.0, 1.0, 2.0, 3.0, 4.0}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(prelu_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto x = mm->add_literal(migraphx::literal{s, {-1, 0, 2}}); - auto slope = mm->add_literal(migraphx::literal{s, {2, 1, 2}}); - mm->add_instruction(migraphx::make_op("prelu"), x, slope); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2.0f, 0.0f, 2.0f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(prelu_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto slope = mm->add_parameter("slope", s); - mm->add_instruction(migraphx::make_op("prelu"), x, slope); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1, 0, 2}; - std::vector slope_data{2, 1, 2}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["slope"] = migraphx::argument(input_fixed_shape0, slope_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2.0f, 0.0f, 2.0f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(quant_conv2d_padding_stride_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; - std::vector a(2 * 3 * 4 * 4); - std::iota(a.begin(), a.end(), 0); - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; - std::vector c(2 * 3 * 3 * 3); - std::iota(c.begin(), c.end(), 0); - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - mm->add_instruction( - migraphx::make_op("quant_convolution", {{"padding", {1, 1}}, {"stride", {2, 2}}}), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector s = {4521, - 7014, - 7830, - 11952, - 10515, - 16734, - 19737, - 30906, - 13161, - 19542, - 19494, - 28800, - 34707, - 52590, - 54729, - 82746}; - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(quant_conv2d_padding_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; - std::vector a(2 * 3 * 4 * 4); - std::iota(a.begin(), a.end(), 0); - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; - std::vector c(2 * 3 * 3 * 3); - std::iota(c.begin(), c.end(), 0); - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - mm->add_instruction( - migraphx::make_op("quant_convolution", {{"padding", {1, 1}}, {"stride", {1, 1}}}), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector s = { - 4521, 6753, 7014, 4635, 6858, 10197, 10548, 6939, 7830, 11601, 11952, 7839, 5007, - 7383, 7590, 4953, 10515, 15987, 16734, 11277, 16821, 25506, 26586, 17874, 19737, 29826, - 30906, 20718, 13593, 20505, 21198, 14187, 13161, 19281, 19542, 12699, 18522, 27045, 27396, - 17739, 19494, 28449, 28800, 18639, 11919, 17319, 17526, 11289, 34707, 51843, 52590, 34893, - 51813, 77346, 78426, 52002, 54729, 81666, 82746, 54846, 36057, 53769, 54462, 36075}; - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(quant_conv2d_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::int8_type, {2, 3, 4, 4}}; - std::vector a(2 * 3 * 4 * 4); - std::iota(a.begin(), a.end(), 0); - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - - migraphx::shape c_shape{migraphx::shape::int8_type, {2, 3, 3, 3}}; - std::vector c(2 * 3 * 3 * 3); - std::iota(c.begin(), c.end(), 0); - auto cl = mm->add_literal(migraphx::literal{c_shape, c}); - - mm->add_instruction(migraphx::make_op("quant_convolution"), al, cl); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - - std::vector s = {10197, - 10548, - 11601, - 11952, - 25506, - 26586, - 29826, - 30906, - 27045, - 27396, - 28449, - 28800, - 77346, - 78426, - 81666, - 82746}; - - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(quantizelinear) -{ - { - migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}}; - std::vector xv = { - -300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550}; - migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}}; - std::vector sv = {2, 2, 2, 4, 4, 4, 6, 6, 6, 2, 2, 2, 4, 4, 4, 6, 6, 6}; - migraphx::shape zs{migraphx::shape::int8_type, {2, 3, 3}}; - std::vector zv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - auto create_program = [&]() { - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(xs, xv); - auto s = mm->add_literal(ss, sv); - auto z = mm->add_literal(zs, zv); - mm->add_instruction(migraphx::make_op("quantizelinear"), x, s, z); - return p; - }; - - migraphx::program p1 = create_program(); - p1.compile(migraphx::make_target("ref")); - auto result = p1.eval({}).back(); - std::vector results_vector(18); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{ - -128, 127, 65, -128, 1, 1, -1, 100, 92, -128, 127, 65, -128, 1, 1, -1, 100, 92}; - EXPECT(results_vector == gold); - } - - { - migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}}; - std::vector xv = { - -300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550}; - migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}}; - std::vector sv = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; - auto create_program = [&]() { - migraphx::program p; - auto* mm = p.get_main_module(); - auto x = mm->add_literal(xs, xv); - auto s = mm->add_literal(ss, sv); - mm->add_instruction(migraphx::make_op("quantizelinear"), x, s); - return p; - }; - - migraphx::program p1 = create_program(); - p1.compile(migraphx::make_target("ref")); - auto result = p1.eval({}).back(); - std::vector results_vector(18); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 255, 65, 0, 2, 2, 0, 255, 255, 0, 255, 65, 0, 2, 2, 0, 255, 255}; - EXPECT(results_vector == gold); - } -} - -TEST_CASE(recip_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::double_type, {3}}; - std::vector data{-0.5f, 0.1f, 0.5f}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("recip"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2.0f, 10.0f, 2.0f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(recip_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("recip"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-0.5f, 0.1f, 0.5f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2.0f, 10.0f, 2.0f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(reduce_max_axis0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{9, 10, 11, 12}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_max_dynamic_axis0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4, {2}}, {3, 5, {3}}}}; - auto input = mm->add_parameter("X", s); - auto reduce_max_op = migraphx::make_op("reduce_max", {{"axes", {0}}}); - mm->add_instruction(reduce_max_op, input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 5}}; - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - params["X"] = migraphx::argument(input_fixed_shape, input_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {6, 7, 8, 9, 10}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(reduce_max_axis01) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0, 1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{11, 12}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_max_axis02) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_max", {{"axes", {0, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{10, 12}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_mean_axis02) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {0, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{5.5, 7.5}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_mean_axis1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{2, 3, 6, 7, 10, 11}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_mean_axis12) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{2.5f, 6.5f, 10.5f}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_mean_axis2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1.5f, 3.5f, 5.5f, 7.5f, 9.5f, 11.5f}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_mean_int) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{2, 6, 10}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_min_axis02) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {0, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 3}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_min_axis1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 2, 5, 6, 9, 10}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_min_axis12) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_min", {{"axes", {1, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 5, 9}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_prod_axis0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {4, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 3, 2, 3}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_prod", {{"axes", {0}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{6, 18, 12, 18}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_sum_axis0) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {0}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{15, 18, 21, 24}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_sum_axis02) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {0, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{33, 45}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_sum_axis1) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{4, 6, 12, 14, 20, 22}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_sum_axis12) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1, 2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{10, 26, 42}; - EXPECT(results_vector == gold); -} - -TEST_CASE(reduce_sum_axis2) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 2, 2}}; - auto input = migraphx::literal{s, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; - auto l0 = mm->add_literal(input); - mm->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{3, 7, 11, 15, 19, 23}; - EXPECT(results_vector == gold); -} - -TEST_CASE(relu_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l = mm->add_literal(migraphx::literal{s, {-1.f, 0.f, 1.f}}); - mm->add_instruction(migraphx::make_op("relu"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.f, 0.f, 1.f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(relu_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("relu"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1.f, 0.f, 1.f}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.f, 0.f, 1.f}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(reshape_test0) -{ - migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; - std::vector data(24); - std::iota(data.begin(), data.end(), -3); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - std::vector new_shape = {8, 3, 1, 1}; - mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector{}; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, data)); -} - -TEST_CASE(reshape_test1) -{ - migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; - std::vector data(24); - std::iota(data.begin(), data.end(), -3); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - std::vector new_shape = {1, 3, 4, 2}; - mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector{}; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, data)); -} - -TEST_CASE(reshape_test2) -{ - migraphx::shape a_shape{migraphx::shape::float_type, {24, 1, 1, 1}}; - std::vector data(24); - std::iota(data.begin(), data.end(), -3); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - std::vector new_shape = {1, 2, 3, 4}; - mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector{}; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, data)); -} - -TEST_CASE(reshape_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {24, 24}, {1, 1}, {1, 1}}}; - std::vector new_shape = {0, 8, 3, 1}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("reshape", {{"dims", new_shape}}), input); - p.compile(migraphx::make_target("ref")); - - std::vector data(48); - std::iota(data.begin(), data.end(), -3); - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 24, 1, 1}}; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - std::vector results_vector{}; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, data)); -} - -TEST_CASE(reverse_test_axis0) -{ - migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; - std::vector data(32); - std::iota(data.begin(), data.end(), 1); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{in_shape, data}); - std::vector axes = {0}; - mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector target_data = data; - std::swap_ranges(target_data.begin(), target_data.begin() + 16, target_data.begin() + 16); - EXPECT(migraphx::verify::verify_range(results_vector, target_data)); -} - -TEST_CASE(reverse_test_axis1) -{ - migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; - std::vector data(32); - std::iota(data.begin(), data.end(), 1); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{in_shape, data}); - std::vector axes = {1}; - mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector target_data = data; - std::reverse(target_data.begin(), target_data.begin() + 16); - std::reverse(target_data.end() - 16, target_data.end()); - EXPECT(migraphx::verify::verify_range(results_vector, target_data)); -} - -TEST_CASE(reverse_test_axis10) -{ - migraphx::shape in_shape{migraphx::shape::float_type, {2, 16}}; - std::vector data(32); - std::iota(data.begin(), data.end(), 1); - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{in_shape, data}); - std::vector axes = {1, 0}; - mm->add_instruction(migraphx::make_op("reverse", {{"axes", axes}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector target_data = data; - std::reverse(target_data.begin(), target_data.begin() + 16); - std::reverse(target_data.end() - 16, target_data.end()); - std::swap_ranges(target_data.begin(), target_data.begin() + 16, target_data.begin() + 16); - EXPECT(migraphx::verify::verify_range(results_vector, target_data)); -} - -TEST_CASE(roialign_out_of_bound_test) -{ - auto create_program = [](const std::string& trans_mode = "half_pixel") { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape x_s{migraphx::shape::float_type, {1, 1, 10, 10}}; - std::vector x_vec = { - 0.2764, 0.7150, 0.1958, 0.3416, 0.4638, 0.0259, 0.2963, 0.6518, 0.4856, 0.7250, - 0.9637, 0.0895, 0.2919, 0.6753, 0.0234, 0.6132, 0.8085, 0.5324, 0.8992, 0.4467, - 0.3265, 0.8479, 0.9698, 0.2471, 0.9336, 0.1878, 0.4766, 0.4308, 0.3400, 0.2162, - 0.0206, 0.1720, 0.2155, 0.4394, 0.0653, 0.3406, 0.7724, 0.3921, 0.2541, 0.5799, - 0.4062, 0.2194, 0.4473, 0.4687, 0.7109, 0.9327, 0.9815, 0.6320, 0.1728, 0.6119, - 0.3097, 0.1283, 0.4984, 0.5068, 0.4279, 0.0173, 0.4388, 0.0430, 0.4671, 0.7119, - 0.1011, 0.8477, 0.4726, 0.1777, 0.9923, 0.4042, 0.1869, 0.7795, 0.9946, 0.9689, - 0.1366, 0.3671, 0.7011, 0.6234, 0.9867, 0.5585, 0.6985, 0.5609, 0.8788, 0.9928, - 0.5697, 0.8511, 0.6711, 0.9406, 0.8751, 0.7496, 0.1650, 0.1049, 0.1559, 0.2514, - 0.7012, 0.4056, 0.7879, 0.3461, 0.0415, 0.2998, 0.5094, 0.3727, 0.5482, 0.0502}; - - migraphx::shape roi_s{migraphx::shape::float_type, {3, 4}}; - std::vector roi_vec = {0, 0, 9.99, 9.99, 0, 5, 4, 9, 5, 5, 9.9, 9.9}; - - migraphx::shape ind_s{migraphx::shape::int64_type, {3}}; - std::vector ind_vec = {0, 0, 0}; - - auto x = mm->add_literal(migraphx::literal(x_s, x_vec)); - auto roi = mm->add_literal(migraphx::literal(roi_s, roi_vec)); - auto ind = mm->add_literal(migraphx::literal(ind_s, ind_vec)); - auto r = - mm->add_instruction(migraphx::make_op("roialign", - {{"coordinate_transformation_mode", trans_mode}, - {"spatial_scale", 5.0}, - {"output_height", 1}, - {"output_width", 1}, - {"sampling_ratio", 1}}), - x, - roi, - ind); - mm->add_return({r}); - return p; - }; - - { - auto p = create_program("output_half_pixel"); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.0f, 0.0f, 0.0f}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(roialign_test) -{ - auto create_program = [](const std::string& trans_mode = "half_pixel", - const migraphx::op::pooling_mode pooling_mode = - migraphx::op::pooling_mode::average, - int64_t sampling_ratio = 2) { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape x_s{migraphx::shape::float_type, {1, 1, 10, 10}}; - std::vector x_vec = { - 0.2764, 0.7150, 0.1958, 0.3416, 0.4638, 0.0259, 0.2963, 0.6518, 0.4856, 0.7250, - 0.9637, 0.0895, 0.2919, 0.6753, 0.0234, 0.6132, 0.8085, 0.5324, 0.8992, 0.4467, - 0.3265, 0.8479, 0.9698, 0.2471, 0.9336, 0.1878, 0.4766, 0.4308, 0.3400, 0.2162, - 0.0206, 0.1720, 0.2155, 0.4394, 0.0653, 0.3406, 0.7724, 0.3921, 0.2541, 0.5799, - 0.4062, 0.2194, 0.4473, 0.4687, 0.7109, 0.9327, 0.9815, 0.6320, 0.1728, 0.6119, - 0.3097, 0.1283, 0.4984, 0.5068, 0.4279, 0.0173, 0.4388, 0.0430, 0.4671, 0.7119, - 0.1011, 0.8477, 0.4726, 0.1777, 0.9923, 0.4042, 0.1869, 0.7795, 0.9946, 0.9689, - 0.1366, 0.3671, 0.7011, 0.6234, 0.9867, 0.5585, 0.6985, 0.5609, 0.8788, 0.9928, - 0.5697, 0.8511, 0.6711, 0.9406, 0.8751, 0.7496, 0.1650, 0.1049, 0.1559, 0.2514, - 0.7012, 0.4056, 0.7879, 0.3461, 0.0415, 0.2998, 0.5094, 0.3727, 0.5482, 0.0502}; - - migraphx::shape roi_s{migraphx::shape::float_type, {3, 4}}; - std::vector roi_vec = {0, 0, 9, 9, 0, 5, 4, 9, 5, 5, 9, 9}; - - migraphx::shape ind_s{migraphx::shape::int64_type, {3}}; - std::vector ind_vec = {0, 0, 0}; - - auto x = mm->add_literal(migraphx::literal(x_s, x_vec)); - auto roi = mm->add_literal(migraphx::literal(roi_s, roi_vec)); - auto ind = mm->add_literal(migraphx::literal(ind_s, ind_vec)); - auto r = - mm->add_instruction(migraphx::make_op("roialign", - {{"coordinate_transformation_mode", trans_mode}, - {"spatial_scale", 1.0}, - {"output_height", 5}, - {"output_width", 5}, - {"sampling_ratio", sampling_ratio}, - {"mode", pooling_mode}}), - x, - roi, - ind); - mm->add_return({r}); - return p; - }; - - { - auto p = create_program(); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = { - 0.466421425, 0.446552634, 0.340521216, 0.568848491, 0.606780827, 0.371379346, - 0.429571986, 0.383519977, 0.556241512, 0.351050019, 0.27680251, 0.488286227, - 0.522200167, 0.552770197, 0.417057365, 0.471240699, 0.4844096, 0.690457463, - 0.492039412, 0.877398551, 0.623889625, 0.712461948, 0.628926516, 0.335504025, - 0.349469036, 0.302179992, 0.43046391, 0.469585985, 0.39774403, 0.542259991, - 0.365552008, 0.704923987, 0.516481996, 0.317131996, 0.701444089, 0.291239977, - 0.505897999, 0.647610962, 0.623489916, 0.829879999, 0.591567993, 0.738860011, - 0.704825997, 0.837148011, 0.889315963, 0.622680008, 0.615276039, 0.709713995, - 0.615356028, 0.458524048, 0.238451958, 0.337952018, 0.371693879, 0.609999895, - 0.760059953, 0.376724035, 0.378532052, 0.71468991, 0.924308002, 0.972783983, - 0.574903965, 0.582623959, 0.570936024, 0.761904061, 0.876998067, 0.535508037, - 0.256580025, 0.214098021, 0.279604018, 0.360000014, 0.436488032, 0.350427985, - 0.288755983, 0.366139978, 0.234920025}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - auto p = create_program("output_half_pixel"); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = { - 0.517783, 0.343411, 0.322905, 0.447362, 0.634375, 0.40308, 0.536647, 0.442791, - 0.486144, 0.402313, 0.251194, 0.400154, 0.515524, 0.695369, 0.346537, 0.33504, - 0.460099, 0.588069, 0.343863, 0.684932, 0.49319, 0.714058, 0.821744, 0.471935, - 0.403946, 0.306955, 0.218678, 0.33369, 0.488001, 0.486962, 0.18709, 0.49142, - 0.55611, 0.419167, 0.368608, 0.143278, 0.460835, 0.597125, 0.53096, 0.498207, - 0.278818, 0.438569, 0.6022, 0.700038, 0.752436, 0.577385, 0.702383, 0.725097, - 0.733754, 0.816304, 0.23933, 0.407514, 0.337893, 0.252521, 0.474335, 0.367075, - 0.270168, 0.41051, 0.64189, 0.830777, 0.55564, 0.454295, 0.55645, 0.75015, - 0.929997, 0.66257, 0.561664, 0.481275, 0.495449, 0.666306, 0.663573, 0.372107, - 0.205603, 0.192776, 0.247849}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - auto p = create_program("output_half_pixel", migraphx::op::pooling_mode::max, 0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = { - 0.819145, 0.373103, 0.258302, 0.515419, 0.726104, 0.540536, 0.545512, 0.38511, - 0.376545, 0.274635, 0.22341, 0.184511, 0.230843, 0.404869, 0.29546, 0.540409, - 0.265838, 0.409324, 0.213915, 0.708654, 0.687264, 0.580821, 0.461283, 0.462879, - 0.709632, 0.27873, 0.083619, 0.22428, 0.313992, 0.410508, 0.0929099, 0.415373, - 0.296695, 0.231574, 0.136836, 0.0683, 0.296695, 0.211925, 0.245385, 0.28053, - 0.17091, 0.179879, 0.245385, 0.343539, 0.392742, 0.51273, 0.536193, 0.382995, - 0.422793, 0.761886, 0.0839429, 0.276444, 0.19746, 0.126117, 0.378351, 0.254646, - 0.092148, 0.272825, 0.381955, 0.626599, 0.251325, 0.244475, 0.194875, 0.272825, - 0.44757, 0.351855, 0.342265, 0.244475, 0.274841, 0.553644, 0.607176, 0.202392, - 0.07425, 0.066087, 0.126279}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(round_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {9}}; - auto l = - mm->add_literal(migraphx::literal{s, {1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}}); - mm->add_instruction(migraphx::make_op("round"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {1.0, 2.0, 2.0, -1.0, -2.0, -2.0, 0.0, 2.0, -2.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(round_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{4, 10}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("round"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{1.1, 1.5, 1.6, -1.1, -1.5, -1.6, 0.0, 2.0, -2.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {9}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {1.0, 2.0, 2.0, -1.0, -2.0, -2.0, 0.0, 2.0, -2.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(rsqrt_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l = mm->add_literal(migraphx::literal{s, {4.0, 16.0, 64.0}}); - mm->add_instruction(migraphx::make_op("rsqrt"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.5, 0.25, 0.125}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(rsqrt_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("rsqrt"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{4.0, 16.0, 64.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0.5, 0.25, 0.125}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -// reduction_mode: "scatter_none", "scatter_add", "scatter_mul" -migraphx::program create_scatter_program(const std::string& reduction_mode, int axis) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; - std::vector vd(sd.elements(), 0.0f); - - migraphx::shape si{migraphx::shape::int32_type, {2, 3}}; - std::vector vi = {1, 0, 2, 0, 2, 1}; - - migraphx::shape su{migraphx::shape::float_type, {2, 3}}; - std::vector vu = {1.0, 1.1, 1.2, 2.0, 2.1, 2.2}; - - auto ld = mm->add_literal(migraphx::literal{sd, vd}); - auto li = mm->add_literal(migraphx::literal{si, vi}); - auto lu = mm->add_literal(migraphx::literal{su, vu}); - // scatter_none, formerly the scatter op - auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); - mm->add_return({r}); - return p; -} - -TEST_CASE(scatter_ax0_test) -{ - // this tests what used to be the only scatter op, now changed to 3 sub-ops - // which have their own test case - { - migraphx::program p = create_scatter_program("scatter_none", 0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {2.0, 1.1, 0.0, 1.0, 0.0, 2.2, 0.0, 2.1, 1.2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(scatter_ax_neg_test) -{ - { - migraphx::program p = create_scatter_program("scatter_none", -2); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {2.0, 1.1, 0.0, 1.0, 0.0, 2.2, 0.0, 2.1, 1.2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(scatter_ax1_test) -{ - { - migraphx::program p = create_scatter_program("scatter_none", 1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {1.1, 1.0, 1.2, 2.0, 2.2, 2.1, 0.0, 0.0, 0.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -// similar to create_scatter_program but with different tensor values -// reduction_mode: "scatter_none", "scatter_add", "scatter_mul" -migraphx::program create_scatter_program2(const std::string& reduction_mode, int axis) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sd{migraphx::shape::float_type, {1, 5}}; - std::vector vd({1., 2., 3., 4., 5.}); - - migraphx::shape si{migraphx::shape::int32_type, {1, 2}}; - std::vector vi = {1, 3}; - - migraphx::shape su{migraphx::shape::float_type, {1, 2}}; - std::vector vu = {1.1, 2.1}; - - auto ld = mm->add_literal(migraphx::literal{sd, vd}); - auto li = mm->add_literal(migraphx::literal{si, vi}); - auto lu = mm->add_literal(migraphx::literal{su, vu}); - auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); - mm->add_return({r}); - return p; -} -TEST_CASE(scatter_reduction1_test) -{ - { - // Test sub-ops for the three reduction values scatter_none, scatter_add, scatter_mul - migraphx::program p = create_scatter_program2("scatter_none", 1); - - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_none = {1.0, 1.1, 3.0, 2.1, 5.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold_none)); - } -} - -TEST_CASE(scatter_reduction2_test) -{ - { - migraphx::program p = create_scatter_program2("scatter_mul", 1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_mul = {1.0, 2.2, 3.0, 8.4, 5.0}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold_mul)); - } -} -TEST_CASE(scatter_reduction3_test) -{ - { - migraphx::program p = create_scatter_program2("scatter_add", 1); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_add = {1.0, 3.1, 3.0, 6.1, 5.0}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold_add)); - } -} - -TEST_CASE(scatter_reduction_3x3_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; - std::vector vd(sd.elements(), 3.0f); - - migraphx::shape si{migraphx::shape::int32_type, {2, 3}}; - std::vector vi = {1, 0, 2, 0, 2, 1}; - - migraphx::shape su{migraphx::shape::float_type, {2, 3}}; - std::vector vu = {1.0, 1.1, 1.2, 7.0, 7.1, 7.2}; - - auto ld = mm->add_literal(migraphx::literal{sd, vd}); - auto li = mm->add_literal(migraphx::literal{si, vi}); - auto lu = mm->add_literal(migraphx::literal{su, vu}); - auto r = mm->add_instruction(migraphx::make_op("scatter_add", {{"axis", 1}}), ld, li, lu); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_a2 = {4.1, 4.0, 4.2, 10.0, 10.2, 10.1, 3.0, 3.0, 3.0}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold_a2)); - } -} - -// create a test scatter program with a 3x3 tensor; -// su and si are transposed from previous case -migraphx::program create_scatter_program_3x3(const std::string& reduction_mode, int axis) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sd{migraphx::shape::float_type, {3, 3}}; - std::vector vd(sd.elements(), 3.0f); - - migraphx::shape si{migraphx::shape::int32_type, {3, 2}}; - std::vector vi = {1, 0, 0, 2, 2, 1}; - - migraphx::shape su{migraphx::shape::float_type, {3, 2}}; - std::vector vu = {1.0, 7.0, 1.1, 7.1, 1.2, 7.2}; - - auto ld = mm->add_literal(migraphx::literal{sd, vd}); - auto li = mm->add_literal(migraphx::literal{si, vi}); - auto lu = mm->add_literal(migraphx::literal{su, vu}); - auto r = mm->add_instruction(migraphx::make_op(reduction_mode, {{"axis", axis}}), ld, li, lu); - mm->add_return({r}); - return p; -} - -TEST_CASE(scatter_reduction_3x3_xpose1_test) -{ - // test on vertical (0) axis. su and si are transposed from previous case - { - migraphx::program p = create_scatter_program_3x3("scatter_none", 0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_none2 = {1.1, 7.0, 3.0, 1.0, 7.2, 3.0, 1.2, 7.1, 3.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold_none2)); - } -} - -TEST_CASE(scatter_reduction_3x3_xpose2_test) -{ - // test on vertical (0) axis. - { - migraphx::program p = create_scatter_program_3x3("scatter_add", 0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_a3 = {4.1, 10.0, 3.0, 4.0, 10.2, 3.0, 4.2, 10.1, 3.0}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold_a3)); - } -} - -TEST_CASE(scatter_reduction_3x3_xpose3_test) -{ - { - migraphx::program p = create_scatter_program_3x3("scatter_mul", 0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold_mul2 = {3.3, 21.0, 3.0, 3.0, 21.6, 3.0, 3.6, 21.3, 3.0}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold_mul2)); - } -} - -TEST_CASE(scatternd_shapes_test) -{ - { - // broadcasted input - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape is{itype, {4, 1}}; - migraphx::shape us{dtype, {4}}; - - std::vector ind_vec{4, 3, 1, 7}; - std::vector upd_vec{9, 10, 11, 12}; - - auto data = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {8}}}), - mm->add_literal(migraphx::literal{0.0f})); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{0, 11, 0, 10, 9, 0, 0, 12}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // non-standard shape input - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {2, 2}}; - migraphx::shape is{itype, {2, 2}}; - migraphx::shape us{dtype, {2}}; - - std::vector data_vec{1, 2, 3, 4}; - std::vector ind_vec{0, 0, 0, 1}; - std::vector upd_vec{5, 6}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto td = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), data); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), td, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{5, 6, 2, 4}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // non-standard updates shape - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {2, 2, 2}}; - migraphx::shape is{itype, {2, 1, 3}}; - migraphx::shape us{dtype, {1, 2}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{0, 0, 0, 1, 1, 1}; - std::vector upd_vec{9, 10}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto tu = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), updates); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, tu); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{9, 2, 3, 4, 5, 6, 7, 10}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(scatternd_test) -{ - { - // r=1, q=2, k=1 - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {8}}; - migraphx::shape is{itype, {4, 1}}; - migraphx::shape us{dtype, {4}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{4, 3, 1, 7}; - std::vector upd_vec{9, 10, 11, 12}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 11, 3, 10, 9, 6, 7, 12}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // r=2, q=2, k=2 - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {2, 2}}; - migraphx::shape is{itype, {2, 2}}; - migraphx::shape us{dtype, {2}}; - - std::vector data_vec{1, 2, 3, 4}; - std::vector ind_vec{0, 0, 0, 1}; - std::vector upd_vec{5, 6}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{5, 6, 3, 4}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // r=3, q=3, k=3 - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {2, 2, 2}}; - migraphx::shape is{itype, {2, 1, 3}}; - migraphx::shape us{dtype, {2, 1}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{0, 0, 0, 1, 1, 1}; - std::vector upd_vec{9, 10}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{9, 2, 3, 4, 5, 6, 7, 10}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // r=3, q=2, k=1 - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {4, 4, 4}}; - migraphx::shape is{itype, {2, 1}}; - migraphx::shape us{dtype, {2, 4, 4}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, - 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, - 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8, - 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{0, 2}; - std::vector upd_vec{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 1, 2, 3, 4, 5, 6, - 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // r=5, q=1, k=1 - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {2, 2, 2, 2, 2}}; - migraphx::shape is{itype, {1}}; - migraphx::shape us{dtype, {2, 2, 2, 2}}; - - std::vector data_vec(32, 1); - std::vector ind_vec{1}; - std::vector upd_vec(16, 0); - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_none"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold(32, 0); - std::copy(data_vec.begin(), data_vec.begin() + 16, gold.begin()); - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(scatternd_reduction_test) -{ - { - // reduction = add - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {8}}; - migraphx::shape is{itype, {8, 1}}; - migraphx::shape us{dtype, {8}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{4, 3, 1, 7, 4, 3, 1, 7}; - std::vector upd_vec{9, 10, 11, 12, -8, -9, -10, -11}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_add"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 3, 3, 5, 6, 6, 7, 9}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } - - { - // reduction = mul - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape ds{dtype, {8}}; - migraphx::shape is{itype, {4, 1}}; - migraphx::shape us{dtype, {4}}; - - std::vector data_vec{1, 2, 3, 4, 5, 6, 7, 8}; - std::vector ind_vec{4, 3, 1, 7}; - std::vector upd_vec{9, 10, 11, 12}; - - auto data = mm->add_literal(migraphx::literal{ds, data_vec}); - auto indices = mm->add_literal(migraphx::literal{is, ind_vec}); - auto updates = mm->add_literal(migraphx::literal{us, upd_vec}); - auto scatternd = - mm->add_instruction(migraphx::make_op("scatternd_mul"), data, indices, updates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 22, 3, 40, 45, 6, 7, 96}; - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(select_module_add_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape lit_s{migraphx::shape{migraphx::shape::float_type, {1}}}; - auto literal_ins = mm->add_literal(migraphx::literal{lit_s, {6}}); - - // create batch submodules - auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { - auto* submod = p.create_module(module_name); - migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 4}}; - auto sm_input = submod->add_parameter("data", sm_shape); - auto broadcast_lit = - submod->add_instruction(migraphx::make_op("multibroadcast"), literal_ins, sm_input); - auto add_ins = submod->add_instruction(migraphx::make_op("add"), sm_input, broadcast_lit); - submod->add_return({add_ins}); - return submod; - }; - auto* batch1 = create_submodule(1, "batch_1"); - auto* batch2 = create_submodule(2, "batch_2"); - auto* batch3 = create_submodule(3, "batch_3"); - auto* batch4 = create_submodule(4, "batch_4"); - - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {4, 4}}}; - auto input = mm->add_parameter("data", s); - std::vector sub_shapes = {}; - sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}}}); - migraphx::shape out_attr = migraphx::shape{sub_shapes}; - auto sm_ins = mm->add_instruction( - migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), - {input}, - {batch1, batch2, batch3, batch4}); - auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 4}}; - params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{2, 14, 5, 10, 5, 14, 14, 2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(select_module_reduce_test0) -{ - migraphx::program p; - - // create batch submodules - auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { - auto* submod = p.create_module(module_name); - migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; - auto sm_input = submod->add_parameter("data", sm_shape); - auto reduce_ins = - submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); - auto squeeze_ins = - submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); - submod->add_return({squeeze_ins}); - return submod; - }; - auto* batch1 = create_submodule(1, "batch_1"); - auto* batch2 = create_submodule(2, "batch_2"); - auto* batch3 = create_submodule(3, "batch_3"); - auto* batch4 = create_submodule(4, "batch_4"); - - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; - auto input = mm->add_parameter("data", s); - std::vector sub_shapes = {}; - sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); - migraphx::shape out_attr = migraphx::shape{sub_shapes}; - auto sm_ins = mm->add_instruction( - migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), - {input}, - {batch1, batch2, batch3, batch4}); - auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {2, 2, 2}}; - params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-5, 12, 7, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(select_module_reduce_test1) -{ - migraphx::program p; - - // create batch submodules - auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { - auto* submod = p.create_module(module_name); - migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; - auto sm_input = submod->add_parameter("data", sm_shape); - auto reduce_ins = - submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); - auto squeeze_ins = - submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); - submod->add_return({squeeze_ins}); - return submod; - }; - auto* batch1 = create_submodule(1, "batch_1"); - auto* batch2 = create_submodule(2, "batch_2"); - auto* batch3 = create_submodule(3, "batch_3"); - auto* batch4 = create_submodule(4, "batch_4"); - - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; - auto input = mm->add_parameter("data", s); - std::vector sub_shapes = {}; - sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); - migraphx::shape out_attr = migraphx::shape{sub_shapes}; - auto sm_ins = mm->add_instruction( - migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), - {input}, - {batch1, batch2, batch3, batch4}); - auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4, -4, 8, -1, 4, -1, 8, 8, -4}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {4, 2, 2}}; - params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{-5, 12, 7, 4, -5, 12, 7, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(select_module_not_found_error) -{ - migraphx::program p; - - // create batch submodules - auto create_submodule = [&](std::size_t batch_size, const std::string& module_name) { - auto* submod = p.create_module(module_name); - migraphx::shape sm_shape{migraphx::shape::float_type, {batch_size, 2, 2}}; - auto sm_input = submod->add_parameter("data", sm_shape); - auto reduce_ins = - submod->add_instruction(migraphx::make_op("reduce_sum", {{"axes", {1}}}), sm_input); - auto squeeze_ins = - submod->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), reduce_ins); - submod->add_return({squeeze_ins}); - return submod; - }; - auto* batch1 = create_submodule(1, "batch_1"); - auto* batch2 = create_submodule(2, "batch_2"); - auto* batch3 = create_submodule(3, "batch_3"); - auto* batch4 = create_submodule(4, "batch_4"); - - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}}}; - auto input = mm->add_parameter("data", s); - std::vector sub_shapes = {}; - sub_shapes.push_back(migraphx::shape{migraphx::shape::float_type, {{1, 4}, {2, 2}}}); - migraphx::shape out_attr = migraphx::shape{sub_shapes}; - auto sm_ins = mm->add_instruction( - migraphx::make_op("select_module", {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), - {input}, - {batch1, batch2, batch3, batch4}); - auto ret = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), sm_ins); - mm->add_return({ret}); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-4, 8, -1, 4, -1, 8, 8, -4, -4, 8, - -1, 4, -1, 8, 8, -4, -1, 8, 8, -4}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {5, 2, 2}}; - params["data"] = migraphx::argument(input_fixed_shape, input_data.data()); - EXPECT(test::throws([&] { std::ignore = p.eval(params).back(); })); -} - -TEST_CASE(scatternd_reduction_dyn_test) -{ - // reduction = add, with dynamic input shapes - migraphx::program p; - auto* mm = p.get_main_module(); - auto dtype = migraphx::shape::float_type; - auto itype = migraphx::shape::int64_type; - migraphx::shape::dynamic_dimension dd{3, 6}; - migraphx::shape ds{migraphx::shape::float_type, {dd, dd, dd}}; - migraphx::shape is{itype, {2, 1}}; - migraphx::shape us{dtype, {{2, 2}, dd, dd}}; - - auto xdata = mm->add_parameter("X", ds); - auto xindex = mm->add_parameter("I", is); - auto xupdates = mm->add_parameter("U", us); - - auto scatternd_add_op = migraphx::make_op("scatternd_add"); - auto scatternd = mm->add_instruction(scatternd_add_op, xdata, xindex, xupdates); - mm->add_return({scatternd}); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 4, 4}}; // data - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, - 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, - 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector input_index{0, 2}; - migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {2, 4, 4}}; // updates - std::vector input_updates{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; - - params["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - params["I"] = migraphx::argument(is, input_index.data()); - params["U"] = migraphx::argument(input_fixed_shape1, input_updates.data()); - - auto result = p.eval(params).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{6, 7, 8, 9, 11, 12, 13, 14, 15, 14, 13, 12, 12, 11, 10, 9, - 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1, - 9, 8, 7, 6, 6, 5, 4, 3, 4, 5, 6, 7, 9, 10, 11, 12, - 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sigmoid_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - auto l = mm->add_literal(migraphx::literal{s, {-1, 2, -3, 4}}); - mm->add_instruction(migraphx::make_op("sigmoid"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{sigmoid(-1), sigmoid(2), sigmoid(-3), sigmoid(4)}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sigmoid_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 2}}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("sigmoid"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{-1, 2, -3, 4}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {2, 2}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{sigmoid(-1), sigmoid(2), sigmoid(-3), sigmoid(4)}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sign_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {5}}; - auto l = mm->add_literal( - migraphx::literal{s, {1.02481645, 0.85643062, -0.03404123, -0.92791926, 0.0}}); - mm->add_instruction(migraphx::make_op("sign"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {1.0, 1.0, -1.0, -1.0, 0.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sign_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("sign"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data{1.02481645, 0.85643062, -0.03404123, -0.92791926, 0.0}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {5}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {1.0, 1.0, -1.0, -1.0, 0.0}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sin_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data = {-1, 0, 1}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("sin"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sin_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - mm->add_instruction(migraphx::make_op("sin"), input); - p.compile(migraphx::make_target("ref")); - - std::vector input_data = {-1, 0, 1}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sinh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data{-1.0, 2.0, -3.0, 4.0}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("sinh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sinh_dynamic_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{2, 4}, {2, 4}}}; - auto input = mm->add_parameter("X", s); - std::vector input_data{-1.0, 2.0, -3.0, 4.0}; - mm->add_instruction(migraphx::make_op("sinh"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sinhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(slice_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(2 * 2 * 3); - std::iota(data.begin(), data.end(), 0); - migraphx::shape s{migraphx::shape::int32_type, {2, 2, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction( - migraphx::make_op("slice", {{"axes", {2}}, {"starts", {1}}, {"ends", {3}}}), l0); - migraphx::shape s2{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; - EXPECT(p.get_output_shapes().back() == s2); - p.compile(migraphx::make_target("ref")); - migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {4, 2, 1}}; - auto result = p.eval({}).back(); - std::vector gold = {1, 2, 4, 5, 7, 8, 10, 11}; - std::vector results_vector(2 * 2 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(result.get_shape() == sresult); - } - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(2 * 2 * 3); - std::iota(data.begin(), data.end(), 0); - migraphx::shape s{migraphx::shape::int32_type, {2, 2, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction( - migraphx::make_op("slice", - {{"axes", {0, 1, 2}}, {"starts", {0, 0, 0}}, {"ends", {2, 2, 2}}}), - l0); - migraphx::shape s2{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; - EXPECT(p.get_output_shapes().back() == s2); - p.compile(migraphx::make_target("ref")); - migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {4, 2, 1}}; - auto result = p.eval({}).back(); - std::vector gold = {0, 1, 3, 4, 6, 7, 9, 10}; - std::vector results_vector(2 * 2 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(result.get_shape() == sresult); - } -} - -TEST_CASE(slice_dyn_test0) -{ - // Slice a single dynamic dimension. ax1 slice limits are smaller than min; ax2 "ends" is - // too large - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {{2, 3}, {2, 2}, {3, 3}}}; - auto x = mm->add_parameter("x", s); - mm->add_instruction( - migraphx::make_op("slice", {{"axes", {1, 2}}, {"starts", {0, 1}}, {"ends", {1, 6}}}), x); - migraphx::shape s2{migraphx::shape::int32_type, {{2, 3}, {1, 1}, {2, 2}}}; - EXPECT(p.get_output_shapes().back() == s2); - p.compile(migraphx::make_target("ref")); - - // the strides of sresult are those of the original shape, not - // reduced to sliced size. - migraphx::shape sresult{migraphx::shape::int32_type, {2, 1, 2}, {6, 3, 1}}; - migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 2, 3}}; - migraphx::parameter_map params; - std::vector data(2 * 2 * 3); - std::iota(data.begin(), data.end(), 0); - params["x"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - - std::vector gold = {1, 2, 7, 8}; - std::vector results_vector(2 * 1 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(result.get_shape() == sresult); -} - -TEST_CASE(slice_dyn_test1) -{ - // Slice all three dynamic dimensions - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::int32_type, {{2, 2}, {2, 2}, {3, 3}}}; - auto x = mm->add_parameter("x", s); - mm->add_instruction( - migraphx::make_op("slice", - {{"axes", {0, 1, 2}}, {"starts", {0, 0, 0}}, {"ends", {2, 2, 2}}}), - x); - - migraphx::shape s2{migraphx::shape::int32_type, {{2, 2}, {2, 2}, {2, 2}}}; - EXPECT(p.get_output_shapes().back() == s2); - p.compile(migraphx::make_target("ref")); - migraphx::shape sresult{migraphx::shape::int32_type, {2, 2, 2}, {6, 3, 1}}; - - migraphx::shape input_fixed_shape{migraphx::shape::int32_type, {2, 2, 3}}; - migraphx::parameter_map params; - std::vector data(2 * 2 * 3); - std::iota(data.begin(), data.end(), 0); - params["x"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - - std::vector gold = {0, 1, 3, 4, 6, 7, 9, 10}; - std::vector results_vector(2 * 2 * 2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - EXPECT(result.get_shape() == sresult); -} - -TEST_CASE(softmax_simple_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = {0.25, 0.75}; - std::vector s = {0.377541, 0.622459}; - migraphx::shape a_shape{migraphx::shape::float_type, {1, 2}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(2); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(softmax_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector a = { - -5.61869681e-01, 9.07827199e-01, 1.29255986e+00, 3.18533443e-02, -1.22183852e-03, - -2.83830553e-01, -1.03245842e+00, -9.28322077e-01, -8.82696748e-01, 1.11327164e-01, - -9.20038462e-01, 8.47388089e-01, 2.51734018e-01, 1.50563884e+00, 2.23056650e+00, - -6.17576987e-02, -1.00264274e-01, -6.10369384e-01, 1.17537189e+00, -2.51560897e-01, - -8.50333512e-01, -8.03578615e-01, -6.51194930e-01, -2.58137047e-01, 4.65528190e-01, - 3.23284641e-02, -1.54700470e+00, 1.38096774e+00, 5.39869189e-01, -7.56884992e-01, - 1.81503093e+00, -2.11269641e+00, 1.92466557e+00, 1.77230799e+00, 2.21660900e+00, - 1.56777036e+00, -2.08995026e-03, 3.50566894e-01, -1.15042710e+00, -1.18577778e+00, - 8.90633047e-01, -6.63949102e-02, 1.44661188e+00, 1.59215283e+00, -2.56262213e-01, - 9.39079225e-01, 4.07298543e-02, 3.86590779e-01, 6.09607756e-01, 8.22331488e-01, - -2.82126725e-01, -9.49052632e-01, -4.24012303e-01, -5.32990396e-01, -3.18386006e+00, - 3.27092171e-01, -1.33315325e+00, 3.62459183e-01, 3.74710828e-01, -1.30302286e+00, - 1.79680198e-01, -4.51832324e-01, 4.34282750e-01, -7.09520102e-01, 6.20333970e-01, - -1.28712380e+00, 2.04130828e-01, -7.70607769e-01, 1.61889160e+00, -1.50951004e+00, - -4.10505563e-01, -3.56566496e-02, -1.29747534e+00, -1.49967879e-01, 7.77626812e-01, - -8.28408226e-02, 2.73412596e-02, 5.79780899e-03, 9.87900198e-02, -7.95276761e-01, - -1.38536084e+00, -6.63573861e-01, 3.89783204e-01, -1.30670881e+00, -7.62425125e-01, - -4.04883057e-01, 6.24344349e-01, 3.68128955e-01, -1.01577950e+00, -3.06715906e-01, - 5.67961395e-01, 2.98198581e-01, -1.63613629e+00, -3.75131965e-01, -6.75393403e-01, - 2.59172034e+00, 6.75538957e-01, 9.07939598e-02, 1.92257717e-01, -1.21592450e+00, - -2.73682117e-01, 1.25232983e+00, -1.39969170e+00, -1.91483587e-01, 2.57732719e-01, - 3.10056299e-01, 1.41833842e+00, -1.81386679e-01, 3.92868072e-01, -8.14771175e-01, - 2.02392387e+00, -9.42091495e-02, -3.77683818e-01, 2.05638766e+00, 2.93796062e-01, - -6.02131486e-01, 2.70461679e-01, -8.92358482e-01, 1.04388881e+00, 2.66154885e-01}; - - std::vector s = { - 0.30191708, 0.59879845, 0.50029165, 0.24915339, 0.36823985, 0.13190967, 0.0349741, - 0.18750034, 0.21905553, 0.27000085, 0.0547399, 0.56318235, 0.47422904, 0.78964758, - 0.91381913, 0.44601166, 0.47902739, 0.13120073, 0.4449684, 0.18766427, 0.15753111, - 0.07844277, 0.05120674, 0.36648798, 0.14637007, 0.13152322, 0.01560997, 0.29065287, - 0.49196178, 0.10550152, 0.81890774, 0.06369215, 0.62972021, 0.74931765, 0.67285055, - 0.35034987, 0.28612873, 0.31931475, 0.04220394, 0.16093165, 0.22390974, 0.11915915, - 0.3115395, 0.35899726, 0.22190949, 0.57518375, 0.13888834, 0.7753762, 0.4642328, - 0.57055861, 0.21954368, 0.34515455, 0.09486015, 0.40631217, 0.01842281, 0.48770609, - 0.06652815, 0.36023033, 0.42343026, 0.24226256, 0.17348589, 0.44066274, 0.6865865, - 0.17296699, 0.46923906, 0.06921105, 0.3570261, 0.4125829, 0.73165393, 0.15302512, - 0.29499072, 0.33932695, 0.30852377, 0.40762195, 0.40170741, 0.36259529, 0.60848355, - 0.42618036, 0.31721094, 0.02960522, 0.28256637, 0.24389413, 0.2725659, 0.10663581, - 0.27622163, 0.28264219, 0.53652936, 0.09476089, 0.40890986, 0.34848392, 0.32572666, - 0.53076893, 0.11529481, 0.29117745, 0.14625968, 0.8756339, 0.49818122, 0.10656087, - 0.1813329, 0.17664003, 0.21410346, 0.80408043, 0.02315119, 0.27155462, 0.32804728, - 0.13268511, 0.61795473, 0.49703068, 0.41696799, 0.10175809, 0.71028161, 0.29929739, - 0.17377149, 0.76075399, 0.20071237, 0.32632929, 0.36892858, 0.09416146, 0.26656723, - 0.42914796}; - - migraphx::shape a_shape{migraphx::shape::float_type, {5, 3, 4, 2}}; - auto al = mm->add_literal(migraphx::literal{a_shape, a}); - mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(120); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(softmax_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape a_shape{migraphx::shape::float_type, - {{1, 10}, {1, 3, {3}}, {4, 4}, {2, 2, {2}}}}; - auto al = mm->add_parameter("a", a_shape); - mm->add_instruction(migraphx::make_op("softmax", {{"axis", 1}}), al); - p.compile(migraphx::make_target("ref")); - - std::vector a = { - -5.61869681e-01, 9.07827199e-01, 1.29255986e+00, 3.18533443e-02, -1.22183852e-03, - -2.83830553e-01, -1.03245842e+00, -9.28322077e-01, -8.82696748e-01, 1.11327164e-01, - -9.20038462e-01, 8.47388089e-01, 2.51734018e-01, 1.50563884e+00, 2.23056650e+00, - -6.17576987e-02, -1.00264274e-01, -6.10369384e-01, 1.17537189e+00, -2.51560897e-01, - -8.50333512e-01, -8.03578615e-01, -6.51194930e-01, -2.58137047e-01, 4.65528190e-01, - 3.23284641e-02, -1.54700470e+00, 1.38096774e+00, 5.39869189e-01, -7.56884992e-01, - 1.81503093e+00, -2.11269641e+00, 1.92466557e+00, 1.77230799e+00, 2.21660900e+00, - 1.56777036e+00, -2.08995026e-03, 3.50566894e-01, -1.15042710e+00, -1.18577778e+00, - 8.90633047e-01, -6.63949102e-02, 1.44661188e+00, 1.59215283e+00, -2.56262213e-01, - 9.39079225e-01, 4.07298543e-02, 3.86590779e-01, 6.09607756e-01, 8.22331488e-01, - -2.82126725e-01, -9.49052632e-01, -4.24012303e-01, -5.32990396e-01, -3.18386006e+00, - 3.27092171e-01, -1.33315325e+00, 3.62459183e-01, 3.74710828e-01, -1.30302286e+00, - 1.79680198e-01, -4.51832324e-01, 4.34282750e-01, -7.09520102e-01, 6.20333970e-01, - -1.28712380e+00, 2.04130828e-01, -7.70607769e-01, 1.61889160e+00, -1.50951004e+00, - -4.10505563e-01, -3.56566496e-02, -1.29747534e+00, -1.49967879e-01, 7.77626812e-01, - -8.28408226e-02, 2.73412596e-02, 5.79780899e-03, 9.87900198e-02, -7.95276761e-01, - -1.38536084e+00, -6.63573861e-01, 3.89783204e-01, -1.30670881e+00, -7.62425125e-01, - -4.04883057e-01, 6.24344349e-01, 3.68128955e-01, -1.01577950e+00, -3.06715906e-01, - 5.67961395e-01, 2.98198581e-01, -1.63613629e+00, -3.75131965e-01, -6.75393403e-01, - 2.59172034e+00, 6.75538957e-01, 9.07939598e-02, 1.92257717e-01, -1.21592450e+00, - -2.73682117e-01, 1.25232983e+00, -1.39969170e+00, -1.91483587e-01, 2.57732719e-01, - 3.10056299e-01, 1.41833842e+00, -1.81386679e-01, 3.92868072e-01, -8.14771175e-01, - 2.02392387e+00, -9.42091495e-02, -3.77683818e-01, 2.05638766e+00, 2.93796062e-01, - -6.02131486e-01, 2.70461679e-01, -8.92358482e-01, 1.04388881e+00, 2.66154885e-01}; - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {5, 3, 4, 2}}; - params["a"] = migraphx::argument(input_fixed_shape, a.data()); - auto result = p.eval(params).back(); - std::vector results_vector(120); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector s = { - 0.30191708, 0.59879845, 0.50029165, 0.24915339, 0.36823985, 0.13190967, 0.0349741, - 0.18750034, 0.21905553, 0.27000085, 0.0547399, 0.56318235, 0.47422904, 0.78964758, - 0.91381913, 0.44601166, 0.47902739, 0.13120073, 0.4449684, 0.18766427, 0.15753111, - 0.07844277, 0.05120674, 0.36648798, 0.14637007, 0.13152322, 0.01560997, 0.29065287, - 0.49196178, 0.10550152, 0.81890774, 0.06369215, 0.62972021, 0.74931765, 0.67285055, - 0.35034987, 0.28612873, 0.31931475, 0.04220394, 0.16093165, 0.22390974, 0.11915915, - 0.3115395, 0.35899726, 0.22190949, 0.57518375, 0.13888834, 0.7753762, 0.4642328, - 0.57055861, 0.21954368, 0.34515455, 0.09486015, 0.40631217, 0.01842281, 0.48770609, - 0.06652815, 0.36023033, 0.42343026, 0.24226256, 0.17348589, 0.44066274, 0.6865865, - 0.17296699, 0.46923906, 0.06921105, 0.3570261, 0.4125829, 0.73165393, 0.15302512, - 0.29499072, 0.33932695, 0.30852377, 0.40762195, 0.40170741, 0.36259529, 0.60848355, - 0.42618036, 0.31721094, 0.02960522, 0.28256637, 0.24389413, 0.2725659, 0.10663581, - 0.27622163, 0.28264219, 0.53652936, 0.09476089, 0.40890986, 0.34848392, 0.32572666, - 0.53076893, 0.11529481, 0.29117745, 0.14625968, 0.8756339, 0.49818122, 0.10656087, - 0.1813329, 0.17664003, 0.21410346, 0.80408043, 0.02315119, 0.27155462, 0.32804728, - 0.13268511, 0.61795473, 0.49703068, 0.41696799, 0.10175809, 0.71028161, 0.29929739, - 0.17377149, 0.76075399, 0.20071237, 0.32632929, 0.36892858, 0.09416146, 0.26656723, - 0.42914796}; - EXPECT(migraphx::verify::verify_range(results_vector, s)); -} - -TEST_CASE(sqdiff_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); - auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); - mm->add_instruction(migraphx::make_op("sqdiff"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {4, 4, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sqdiff_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - mm->add_instruction(migraphx::make_op("sqdiff"), x, y); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1, 0, 1}; - std::vector y_data{1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {4, 4, 4}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sqrt_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {5}}; - std::vector data{1.02481645, 0.85643062, 0.03404123, 0.92791926, 0.10569184}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("sqrt"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sqrtf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sqrt_dynamic_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - std::vector input_data{1.02481645, 0.85643062, 0.03404123, 0.92791926, 0.10569184}; - mm->add_instruction(migraphx::make_op("sqrt"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {5}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector; - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return sqrtf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(squeeze_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(4 * 3 * 3); - migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; - migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape() == s2); - } - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(4 * 3 * 3); - migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; - migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {3}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape() == s2); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(4 * 3 * 3); - migraphx::shape s1{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; - migraphx::shape s2{migraphx::shape::float_type, {4, 3, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - mm->add_instruction(migraphx::make_op("squeeze"), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape() == s2); - } -} - -TEST_CASE(squeeze_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s1{migraphx::shape::float_type, {{1, 4}, {1, 1}, {3, 3}, {1, 1}, {3, 3}}}; - auto p0 = mm->add_parameter("x", s1); - mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {1}}}), p0); - p.compile(migraphx::make_target("ref")); - - std::vector input_data(4 * 3 * 3); - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 1, 3, 1, 3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; - EXPECT(result.get_shape() == s2); -} - -TEST_CASE(step_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(2 * 4 * 6); - std::iota(data.begin(), data.end(), 2); - migraphx::shape s1{migraphx::shape::float_type, {2, 1, 4, 6}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - auto r = mm->add_instruction( - migraphx::make_op("step", {{"axes", {0, 2, 3}}, {"steps", {2, 2, 3}}}), l0); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - migraphx::shape s2{migraphx::shape::float_type, {1, 1, 2, 2}}; - EXPECT(result.get_shape() == s2); - } - - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(2 * 4 * 6); - std::iota(data.begin(), data.end(), 2); - migraphx::shape s1{migraphx::shape::float_type, {2, 1, 4, 6}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - auto tl = mm->add_instruction( - migraphx::make_op("transpose", {{"permutation", {0, 2, 3, 1}}}), l0); - auto r = mm->add_instruction( - migraphx::make_op("step", {{"axes", {0, 1, 2}}, {"steps", {2, 2, 3}}}), tl); - mm->add_return({r}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - migraphx::shape s2{migraphx::shape::float_type, {1, 2, 2, 1}}; - EXPECT(result.get_shape() == s2); - } -} - -TEST_CASE(sub_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}}); - auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}}); - mm->add_instruction(migraphx::make_op("sub"), l1, l2); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2, -2, -2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(sub_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector dd{{2, 6}}; - migraphx::shape s{migraphx::shape::float_type, dd}; - auto x = mm->add_parameter("x", s); - auto y = mm->add_parameter("y", s); - mm->add_instruction(migraphx::make_op("sub"), x, y); - p.compile(migraphx::make_target("ref")); - - std::vector x_data{-1, 0, 1}; - std::vector y_data{1, 2, 3}; - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, x_data.data()); - params0["y"] = migraphx::argument(input_fixed_shape0, y_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {-2, -2, -2}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(tan_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3}}; - std::vector data{-1, 0, 1}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("tan"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(tan_dynamic_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - std::vector input_data{-1, 0, 1}; - mm->add_instruction(migraphx::make_op("tan"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(tanh_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {2, 2}}; - std::vector data{-1.0, 2.0, -3.0, 4.0}; - auto l = mm->add_literal(migraphx::literal{s, data}); - mm->add_instruction(migraphx::make_op("tanh"), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(tanh_dynamic_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape::dynamic_dimension dd{3, 8}; - migraphx::shape s{migraphx::shape::float_type, {dd}}; - auto input = mm->add_parameter("X", s); - std::vector input_data{-1.0, 2.0, -3.0, 4.0}; - mm->add_instruction(migraphx::make_op("tanh"), input); - p.compile(migraphx::make_target("ref")); - - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4}}; - params0["X"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - std::vector results_vector(4); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = input_data; - std::transform( - gold.begin(), gold.end(), gold.begin(), [](float n) -> float { return tanhf(n); }); - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(topk_test) -{ - auto create_program = [](int64_t k, int64_t axis, int largest) { - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {3, 5}}; - auto data = mm->add_parameter("data", s); - auto r = mm->add_instruction( - migraphx::make_op("topk", {{"axis", axis}, {"k", k}, {"largest", largest}}), data); - auto r0 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), r); - auto r1 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 1}}), r); - mm->add_return({r0, r1}); - - return p; - }; - - auto run_program = [&](int64_t k, int64_t axis, int largest) { - auto p = create_program(k, axis, largest); - p.compile(migraphx::make_target("ref")); - std::vector data = { - 2.1, 2.3, 2.0, 2.5, 1.9, 3.3, 0.2, 4.5, 0.1, 0.8, 1.0, 4.5, 2.1, 0.8, 1.5}; - migraphx::shape s{migraphx::shape::float_type, {3, 5}}; - migraphx::parameter_map pp; - pp["data"] = migraphx::argument(s, data.data()); - auto rets = p.eval(pp); - std::vector ret_val; - rets.front().visit([&](auto v) { ret_val.assign(v.begin(), v.end()); }); - std::vector ret_ind; - rets.back().visit([&](auto v) { ret_ind.assign(v.begin(), v.end()); }); - - return std::make_pair(ret_val, ret_ind); - }; - - // case 1 - { - auto results = run_program(4, 1, 1); - std::vector gold_val = {2.5, 2.3, 2.1, 2, 4.5, 3.3, 0.8, 0.2, 4.5, 2.1, 1.5, 1}; - EXPECT(results.first == gold_val); - std::vector gold_ind = {3, 1, 0, 2, 2, 0, 4, 1, 1, 2, 4, 0}; - EXPECT(results.second == gold_ind); - } - - // case 2 - { - auto results = run_program(4, 1, 0); - std::vector gold_val = {1.9, 2, 2.1, 2.3, 0.1, 0.2, 0.8, 3.3, 0.8, 1, 1.5, 2.1}; - EXPECT(results.first == gold_val); - std::vector gold_ind = {4, 2, 0, 1, 3, 1, 4, 0, 3, 0, 4, 2}; - EXPECT(results.second == gold_ind); - } -} - -TEST_CASE(transpose_test) -{ - migraphx::shape a_shape{migraphx::shape::float_type, {1, 2, 2, 3}}; - std::vector data(12); - std::iota(data.begin(), data.end(), 0); - - { - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - std::vector perm = {0, 3, 1, 2}; - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - } - { - migraphx::program p; - auto* mm = p.get_main_module(); - auto l = mm->add_literal(migraphx::literal{a_shape, data}); - std::vector perm = {0, 3, 1, 2}; - auto result = - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); - mm->add_instruction(migraphx::make_op("contiguous"), result); - p.compile(migraphx::make_target("ref")); - auto result2 = p.eval({}).back(); - - std::vector results_vector(12); - result2.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); - } -} - -TEST_CASE(transpose_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape s{migraphx::shape::float_type, {{1, 4}, {2, 2}, {2, 2}, {3, 3}}}; - auto l = mm->add_parameter("X", s); - std::vector perm = {0, 3, 1, 2}; - mm->add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), l); - p.compile(migraphx::make_target("ref")); - - std::vector data(12); - std::iota(data.begin(), data.end(), 0); - migraphx::parameter_map params; - migraphx::shape input_fixed_shape{migraphx::shape::float_type, {1, 2, 2, 3}}; - params["X"] = migraphx::argument(input_fixed_shape, data.data()); - auto result = p.eval(params).back(); - - std::vector new_lens = {1, 3, 2, 2}; - EXPECT(result.get_shape().lens() == new_lens); - - std::vector results_vector(12); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(unsqueeze_test) -{ - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(4 * 3 * 3); - migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; - migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape() == s2); - } - { - migraphx::program p; - auto* mm = p.get_main_module(); - std::vector data(4 * 3 * 3); - migraphx::shape s1{migraphx::shape::float_type, {4, 3, 3}}; - migraphx::shape s2{migraphx::shape::float_type, {4, 3, 1, 3}}; - auto l0 = mm->add_literal(migraphx::literal{s1, data}); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), l0); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - EXPECT(result.get_shape() == s2); - } -} - -TEST_CASE(unsqueeze_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - - migraphx::shape s1{migraphx::shape::float_type, {{1, 4}, {3, 3}, {3, 3}}}; - auto p0 = mm->add_parameter("x", s1); - mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {1}}}), p0); - p.compile(migraphx::make_target("ref")); - - std::vector input_data(4 * 3 * 3); - migraphx::parameter_map params0; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {4, 3, 3}}; - params0["x"] = migraphx::argument(input_fixed_shape0, input_data.data()); - auto result = p.eval(params0).back(); - migraphx::shape s2{migraphx::shape::float_type, {4, 1, 3, 3}}; - EXPECT(result.get_shape() == s2); -} - -TEST_CASE(where_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sb{migraphx::shape::bool_type, {3, 3}}; - migraphx::shape sx{migraphx::shape::float_type, {3, 3}}; - - std::vector b{true, true, true, false, false, false, true, false, true}; - std::vector x(9, 1.0); - std::vector y(9, 2.0); - - auto lb = mm->add_literal(migraphx::literal{sb, b}); - auto lx = mm->add_literal(migraphx::literal{sx, x}); - auto ly = mm->add_literal(migraphx::literal{sx, y}); - auto w = mm->add_instruction(migraphx::make_op("where"), lb, lx, ly); - mm->add_return({w}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - std::vector gold(9); - for(int i = 0; i < gold.size(); ++i) - gold[i] = b[i] ? x[i] : y[i]; - - EXPECT(migraphx::verify::verify_range(result_vec, gold)); -} - -TEST_CASE(where_dyn_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sb{migraphx::shape::bool_type, {{2, 3}, {2, 3}}}; - migraphx::shape sx{migraphx::shape::float_type, {{2, 3}, {2, 3}}}; - - auto lb = mm->add_parameter("predicate", sb); - auto lx = mm->add_parameter("X", sx); - auto ly = mm->add_parameter("Y", sx); - mm->add_instruction(migraphx::make_op("where"), lb, lx, ly); - p.compile(migraphx::make_target("ref")); - - std::vector b{1, 1, 1, 0, 0, 0, 1, 0, 1}; - std::vector x(9, 1.0); - std::vector y(9, 2.0); - migraphx::parameter_map params; - migraphx::shape input_fixed_shape0{migraphx::shape::float_type, {3, 3}}; - migraphx::shape input_fixed_shape1{migraphx::shape::uint8_type, {3, 3}}; - params["X"] = migraphx::argument(input_fixed_shape0, x.data()); - params["Y"] = migraphx::argument(input_fixed_shape0, y.data()); - - params["predicate"] = migraphx::argument(input_fixed_shape1, b.data()); - - auto result = p.eval(params).back(); - std::vector results_vector(3 * 3); - result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); - std::vector gold{1, 1, 1, 2, 2, 2, 1, 2, 1}; - EXPECT(migraphx::verify::verify_range(results_vector, gold)); -} - -TEST_CASE(where_broadcasted_inputs_test) -{ - migraphx::program p; - auto* mm = p.get_main_module(); - migraphx::shape sb{migraphx::shape::bool_type, {3, 3}}; - - std::vector b{true, true, true, false, false, false, true, false, true}; - - auto lb = mm->add_literal(migraphx::literal{sb, b}); - auto lx = mm->add_literal(migraphx::literal(1.0f)); - auto ly = mm->add_literal(migraphx::literal(2.0f)); - auto mbx = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), lx); - auto mby = mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 3}}}), ly); - auto w = mm->add_instruction(migraphx::make_op("where"), lb, mbx, mby); - mm->add_return({w}); - p.compile(migraphx::make_target("ref")); - auto result = p.eval({}).back(); - std::vector result_vec; - result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); }); - std::vector gold(9); - std::vector x(9, 1.0); - std::vector y(9, 2.0); - for(int i = 0; i < gold.size(); ++i) - gold[i] = b[i] ? x[i] : y[i]; - - EXPECT(migraphx::verify::verify_range(result_vec, gold)); -} - -int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/test/rewrite_quantization_test.cpp b/test/rewrite_quantization_test.cpp index f11844c8052..282a89bf354 100644 --- a/test/rewrite_quantization_test.cpp +++ b/test/rewrite_quantization_test.cpp @@ -37,6 +37,17 @@ bool is_quantizelinear(migraphx::instruction& ins) { return ins.name() == "quantizelinear"; } bool is_dequantizelinear(migraphx::instruction& ins) { return ins.name() == "dequantizelinear"; } +bool is_clip_scalar(migraphx::instruction& ins) +{ + if(ins.name() == "clip") + { + assert(ins.inputs().size() > 1); + return (std::all_of(ins.inputs().begin() + 1, ins.inputs().end(), [](auto input) { + return input->get_shape().scalar(); + })); + } + return false; +} void run_pass(migraphx::module& m) { migraphx::run_passes(m, {migraphx::rewrite_quantization{}}); } @@ -70,6 +81,8 @@ TEST_CASE(quantizelinear) EXPECT(eval(p1) == eval(p2)); EXPECT(any_of(*p1.get_main_module(), &is_quantizelinear)); EXPECT(none_of(*p2.get_main_module(), &is_quantizelinear)); + // ensure clip literals created in quantized program are scalar + EXPECT(any_of(*p2.get_main_module(), &is_clip_scalar)); } TEST_CASE(dequantizelinear) diff --git a/test/simplify_algebra_test.cpp b/test/simplify_algebra_test.cpp index 223b7bebe9d..d09523cdee6 100644 --- a/test/simplify_algebra_test.cpp +++ b/test/simplify_algebra_test.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -153,7 +153,7 @@ TEST_CASE(simplify_add_broadcast1) { migraphx::shape inner{migraphx::shape::int32_type, {2}}; migraphx::shape outer{migraphx::shape::int32_type, {1, 2, 3, 3}}; - migraphx::op::broadcast b{1, {1, 2, 3, 3}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {1, 2, 3, 3}}}); migraphx::module m1; { auto x = m1.add_parameter("x", outer); @@ -188,7 +188,7 @@ TEST_CASE(simplify_add_broadcast2) { migraphx::shape inner{migraphx::shape::int32_type, {2}}; migraphx::shape outer{migraphx::shape::int32_type, {1, 2, 3, 3}}; - migraphx::op::broadcast b{1, {1, 2, 3, 3}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {1, 2, 3, 3}}}); auto create_program = [&] { migraphx::module m; auto x = m.add_parameter("x", outer); @@ -539,7 +539,7 @@ TEST_CASE(simplify_conv_add) TEST_CASE(simplify_inner_broadcast1) { - auto b = migraphx::op::broadcast{1, {2, 1, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 1, 4, 5}}}); migraphx::module m1; { auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1}}); @@ -564,7 +564,7 @@ TEST_CASE(simplify_inner_broadcast1) TEST_CASE(simplify_inner_broadcast2) { - auto b = migraphx::op::multibroadcast{{2, 1, 4, 5}}; + auto b = migraphx::make_op("multibroadcast", {{"out_lens", {2, 1, 4, 5}}}); migraphx::module m1; { auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1, 1, 1, 1}}); @@ -589,7 +589,7 @@ TEST_CASE(simplify_inner_broadcast2) TEST_CASE(simplify_inner_broadcast_scalar) { - auto b = migraphx::op::multibroadcast{{32, 384}}; + auto b = migraphx::make_op("multibroadcast", {{"out_lens", {32, 384}}}); migraphx::module m1; { auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1, 384}}); @@ -603,9 +603,10 @@ TEST_CASE(simplify_inner_broadcast_scalar) migraphx::module m2; { - auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1, 384}}); - auto y = m2.add_parameter("y", {migraphx::shape::int32_type, {1, 1}}); - auto yb = m2.add_instruction(migraphx::op::multibroadcast{{1, 384}}, y); + auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1, 384}}); + auto y = m2.add_parameter("y", {migraphx::shape::int32_type, {1, 1}}); + auto yb = + m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {1, 384}}}), y); auto sum = m2.add_instruction(migraphx::make_op("add"), x, yb); auto sumb = m2.add_instruction(b, sum); m2.add_instruction(pass_op{}, sumb); @@ -615,7 +616,7 @@ TEST_CASE(simplify_inner_broadcast_scalar) TEST_CASE(simplify_inner_broadcast_different_dims) { - auto b = migraphx::op::multibroadcast{{2, 384, 768}}; + auto b = migraphx::make_op("multibroadcast", {{"out_lens", {2, 384, 768}}}); migraphx::module m1; { auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {384, 768}}); @@ -629,9 +630,10 @@ TEST_CASE(simplify_inner_broadcast_different_dims) migraphx::module m2; { - auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {384, 768}}); - auto y = m2.add_parameter("y", {migraphx::shape::int32_type, {768}}); - auto yb = m2.add_instruction(migraphx::op::multibroadcast{{384, 768}}, y); + auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {384, 768}}); + auto y = m2.add_parameter("y", {migraphx::shape::int32_type, {768}}); + auto yb = + m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {384, 768}}}), y); auto sum = m2.add_instruction(migraphx::make_op("add"), x, yb); auto sumb = m2.add_instruction(b, sum); m2.add_instruction(pass_op{}, sumb); @@ -641,8 +643,8 @@ TEST_CASE(simplify_inner_broadcast_different_dims) TEST_CASE(simplify_inner_broadcast_different_broadcasts) { - auto b = migraphx::op::broadcast{1, {1, 24, 112, 112}}; - auto mb = migraphx::op::multibroadcast{{1, 24, 112, 112}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {1, 24, 112, 112}}}); + auto mb = migraphx::make_op("multibroadcast", {{"out_lens", {1, 24, 112, 112}}}); migraphx::module m1; { auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {24}}); @@ -891,7 +893,7 @@ TEST_CASE(simplify_concat_add_relu_partial_broadcast) auto s = migraphx::shape{migraphx::shape::int32_type, {2, 1, 4, 5}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {2, 1, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 1, 4, 5}}}); auto x = m1.add_parameter("x", s); auto y = m1.add_parameter("y", s); auto one = m1.add_literal(1); @@ -907,7 +909,7 @@ TEST_CASE(simplify_concat_add_relu_partial_broadcast) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {2, 2, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 2, 4, 5}}}); auto x = m2.add_parameter("x", s); auto y = m2.add_parameter("y", s); auto one = m2.add_literal(1); @@ -926,7 +928,7 @@ TEST_CASE(simplify_concat_add_relu_broadcast_different_axis) auto s = migraphx::shape{migraphx::shape::int32_type, {2, 1, 4, 5}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {2, 1, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 1, 4, 5}}}); auto x = m1.add_parameter("x", s); auto y = m1.add_parameter("y", s); auto one = m1.add_literal(1); @@ -944,7 +946,7 @@ TEST_CASE(simplify_concat_add_relu_broadcast_different_axis) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {2, 2, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 2, 4, 5}}}); auto x = m2.add_parameter("x", s); auto y = m2.add_parameter("y", s); auto one = m2.add_literal(1); @@ -964,7 +966,7 @@ TEST_CASE(simplify_concat_add_relu_broadcast_same_axis) auto s = migraphx::shape{migraphx::shape::int32_type, {2, 1, 4, 5}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {2, 1, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 1, 4, 5}}}); auto x = m1.add_parameter("x", s); auto y = m1.add_parameter("y", s); auto one = m1.add_literal(1); @@ -982,7 +984,7 @@ TEST_CASE(simplify_concat_add_relu_broadcast_same_axis) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {2, 1, 4, 5}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 1, 4, 5}}}); auto x = m2.add_parameter("x", s); auto y = m2.add_parameter("y", s); auto one = m2.add_literal(1); @@ -1695,7 +1697,7 @@ TEST_CASE(simplify_split_add_relu) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -1716,7 +1718,7 @@ TEST_CASE(simplify_split_add_relu) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {3, 2, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 2, 4}}}); auto input = m2.add_parameter("input", s); auto one = m2.add_literal(1); auto two = m2.add_literal(2); @@ -1846,8 +1848,8 @@ TEST_CASE(simplify_split_add_relu_reshape) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; - auto r = migraphx::op::reshape{{3, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); + auto r = migraphx::make_op("reshape", {{"dims", {3, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -1870,7 +1872,7 @@ TEST_CASE(simplify_split_add_relu_reshape) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {3, 2, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 2, 4}}}); auto input = m2.add_parameter("input", s); auto one = m2.add_literal(1); auto two = m2.add_literal(2); @@ -1894,7 +1896,7 @@ TEST_CASE(simplify_slice_different_axis) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4, 2}}; migraphx::module m1; { - auto r = migraphx::op::reshape{{3, 2, 4}}; + auto r = migraphx::make_op("reshape", {{"dims", {3, 2, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -1926,7 +1928,7 @@ TEST_CASE(simplify_slice_missing_begining_slice) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 3, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {2}}, {"ends", {3}}}), input); @@ -1954,7 +1956,7 @@ TEST_CASE(simplify_slice_missing_middle_slice) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 3, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {2}}, {"ends", {3}}}), input); @@ -1982,7 +1984,7 @@ TEST_CASE(simplify_slice_missing_end_slice) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 3, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2010,7 +2012,7 @@ TEST_CASE(simplify_split_add_relu_concat_same_axis) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2031,7 +2033,7 @@ TEST_CASE(simplify_split_add_relu_concat_same_axis) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {3, 2, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 2, 4}}}); auto input = m2.add_parameter("input", s); auto one = m2.add_literal(1); auto two = m2.add_literal(2); @@ -2049,7 +2051,7 @@ TEST_CASE(simplify_split_add_relu_multi_axes) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4, 6}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4, 3}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4, 3}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1, 3}}, {"starts", {0, 0}}, {"ends", {1, 3}}}), @@ -2078,7 +2080,7 @@ TEST_CASE(simplify_split_add_relu_used_multiple_split1) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2100,7 +2102,7 @@ TEST_CASE(simplify_split_add_relu_used_multiple_split1) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {3, 2, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 2, 4}}}); auto input = m2.add_parameter("input", s); auto slice = m2.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2126,7 +2128,7 @@ TEST_CASE(simplify_split_add_relu_used_multiple_split2) auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 4}}; migraphx::module m1; { - auto b = migraphx::op::broadcast{1, {3, 1, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 1, 4}}}); auto input = m1.add_parameter("input", s); auto x = m1.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2149,7 +2151,7 @@ TEST_CASE(simplify_split_add_relu_used_multiple_split2) migraphx::module m2; { - auto b = migraphx::op::broadcast{1, {3, 2, 4}}; + auto b = migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {3, 2, 4}}}); auto input = m2.add_parameter("input", s); auto slice = m2.add_instruction( migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); @@ -2189,16 +2191,16 @@ TEST_CASE(simplify_split_between_add) EXPECT(m1.sort() == m2.sort()); } -TEST_CASE(simplify_dot_horiz) +void test_dot_horiz(migraphx::shape::type_t type, const std::string& dot_type) { - auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 2}}; + auto s = migraphx::shape{type, {3, 2, 2}}; migraphx::module m1; { auto input = m1.add_parameter("input", s); auto a = m1.add_literal(migraphx::generate_literal(s, 0)); auto b = m1.add_literal(migraphx::generate_literal(s, 1)); - auto x = m1.add_instruction(migraphx::make_op("dot"), input, a); - auto y = m1.add_instruction(migraphx::make_op("dot"), input, b); + auto x = m1.add_instruction(migraphx::make_op(dot_type), input, a); + auto y = m1.add_instruction(migraphx::make_op(dot_type), input, b); auto sum = m1.add_instruction(migraphx::make_op("add"), x, y); m1.add_instruction(pass_op{}, sum); } @@ -2210,7 +2212,7 @@ TEST_CASE(simplify_dot_horiz) auto a = m2.add_literal(migraphx::generate_literal(s, 0)); auto b = m2.add_literal(migraphx::generate_literal(s, 1)); auto concat = m2.add_instruction(migraphx::make_op("concat", {{"axis", 2}}), a, b); - auto dot = m2.add_instruction(migraphx::make_op("dot"), input, concat); + auto dot = m2.add_instruction(migraphx::make_op(dot_type), input, concat); auto x = m2.add_instruction( migraphx::make_op("slice", {{"axes", {2}}, {"starts", {0}}, {"ends", {2}}}), dot); auto y = m2.add_instruction( @@ -2221,6 +2223,10 @@ TEST_CASE(simplify_dot_horiz) EXPECT(m1.sort() == m2.sort()); } +TEST_CASE(simplify_dot_horiz) { test_dot_horiz(migraphx::shape::int32_type, "dot"); } + +TEST_CASE(simplify_quant_dot_horiz) { test_dot_horiz(migraphx::shape::int8_type, "quant_dot"); } + TEST_CASE(simplify_dot_horiz_same_constant) { auto s = migraphx::shape{migraphx::shape::int32_type, {3, 2, 2}}; @@ -3029,6 +3035,36 @@ void reorder_slice_trans_diff_perm() TEST_CASE_REGISTER(reorder_slice_trans_diff_perm<1>); TEST_CASE_REGISTER(reorder_slice_trans_diff_perm<4>); +TEST_CASE(reorder_slice_trans_multi_outputs) +{ + migraphx::module m1; + { + auto s = migraphx::shape{migraphx::shape::float_type, {8, 128, 1920}}; + auto input = m1.add_parameter("input", s); + std::vector perm = {0, 2, 1}; + auto slc0 = m1.add_instruction( + migraphx::make_op("slice", {{"axes", {2}}, {"starts", {0}}, {"ends", {640}}}), input); + auto slc1 = m1.add_instruction( + migraphx::make_op("slice", {{"axes", {2}}, {"starts", {640}}, {"ends", {1280}}}), + input); + auto slc2 = m1.add_instruction( + migraphx::make_op("slice", {{"axes", {2}}, {"starts", {1280}}, {"ends", {1920}}}), + input); + + auto t0 = m1.add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), slc0); + auto t1 = m1.add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), slc1); + auto t2 = m1.add_instruction(migraphx::make_op("transpose", {{"permutation", perm}}), slc2); + + auto sum = m1.add_instruction(migraphx::make_op("add"), t0, t1); + auto dot = m1.add_instruction(migraphx::make_op("mul"), sum, t2); + auto slc_cont = m1.add_instruction(migraphx::make_op("contiguous"), slc1); + m1.add_return({slc_cont, dot}); + }; + run_pass(m1); + auto m2 = m1; + EXPECT(m1.sort() == m2.sort()); +} + TEST_CASE(reorder_slice_ins_deps) { auto create_module = [] { diff --git a/test/simplify_reshapes_test.cpp b/test/simplify_reshapes_test.cpp index 0b16b46616a..3672ab85532 100644 --- a/test/simplify_reshapes_test.cpp +++ b/test/simplify_reshapes_test.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -477,7 +476,7 @@ TEST_CASE(concat_multibroadcasts1) std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "multibroadcast"; }); auto md = std::distance(m.begin(), new_mb); EXPECT(cd == md - 1); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 1); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 1); } TEST_CASE(concat_multibroadcasts2) @@ -500,7 +499,7 @@ TEST_CASE(concat_multibroadcasts2) std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "multibroadcast"; }); auto md = std::distance(m.begin(), new_mb); EXPECT(cd == md - 1); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 0); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 0); } TEST_CASE(concat_multibroadcasts3) @@ -523,7 +522,7 @@ TEST_CASE(concat_multibroadcasts3) std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "multibroadcast"; }); auto md = std::distance(m.begin(), new_mb); EXPECT(cd == md - 1); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 2); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 2); } TEST_CASE(concat_multibroadcasts4) @@ -559,7 +558,7 @@ TEST_CASE(concat_transpose1) auto new_concat = std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "concat"; }); EXPECT(bool{new_concat != m.end()}); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 3); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 3); } TEST_CASE(concat_transpose2) @@ -583,7 +582,7 @@ TEST_CASE(concat_transpose2) auto new_concat = std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "concat"; }); EXPECT(bool{new_concat != m.end()}); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 1); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 1); } TEST_CASE(concat_transpose3) @@ -607,7 +606,7 @@ TEST_CASE(concat_transpose3) auto new_concat = std::find_if(m.begin(), m.end(), [](auto ins) { return ins.name() == "concat"; }); EXPECT(bool{new_concat != m.end()}); - EXPECT(migraphx::any_cast(new_concat->get_operator()).axis == 1); + EXPECT(new_concat->get_operator().to_value()["axis"].to() == 1); } TEST_CASE(concat_transpose4) diff --git a/test/tf/tf_test.cpp b/test/tf/tf_test.cpp index 4730e4a1080..82d5cb95e96 100644 --- a/test/tf/tf_test.cpp +++ b/test/tf/tf_test.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include @@ -840,12 +839,8 @@ TEST_CASE(slice_test) mm->add_literal(migraphx::literal{s0, {1, 0}}); mm->add_literal(migraphx::literal{s0, {2, -1}}); - migraphx::op::slice op; - op.starts = {1, 0}; - op.ends = {3, 10}; - op.axes = std::vector(num_axes); - std::iota(op.axes.begin(), op.axes.end(), 0); - mm->add_instruction(op, l0); + mm->add_instruction( + migraphx::make_op("slice", {{"starts", {1, 0}}, {"ends", {3, 10}}, {"axes", {0, 1}}}), l0); auto prog = optimize_tf("slice_test.pb", false); EXPECT(p == prog); @@ -975,13 +970,10 @@ TEST_CASE(stridedslice_test) auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {1, 10, 1, 1}}); auto l1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 3, 1}}}), l0); - std::size_t num_axes = 4; - migraphx::op::slice op; - op.starts = {0, 0, 0, 0}; - op.ends = {1, 1, 1, 5}; - op.axes = std::vector(num_axes); - std::iota(op.axes.begin(), op.axes.end(), 0); - auto l2 = mm->add_instruction(op, l1); + auto l2 = mm->add_instruction( + migraphx::make_op( + "slice", {{"starts", {0, 0, 0, 0}}, {"ends", {1, 1, 1, 5}}, {"axes", {0, 1, 2, 3}}}), + l1); auto shrink_axis = 1; mm->add_instruction(migraphx::make_op("squeeze", {{"axes", {shrink_axis}}}), l2); auto prog = optimize_tf("stridedslice_test.pb", true); @@ -995,12 +987,6 @@ TEST_CASE(stridedslice_masks_test) auto* mm = p.get_main_module(); auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {1, 10, 3, 3}}); - std::size_t num_axes = 4; - migraphx::op::slice op; - op.starts = {0, 1, 1, 0}; - op.ends = {1, 3, 3, 10}; - op.axes = std::vector(num_axes); - std::iota(op.axes.begin(), op.axes.end(), 0); // add literals for starts, ends, and strides in tf (NHWC format) mm->add_literal(migraphx::shape{migraphx::shape::int32_type, {4}}, std::vector{0, 1, 1, 0}); @@ -1011,7 +997,10 @@ TEST_CASE(stridedslice_masks_test) auto l1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 3, 1}}}), l0); - auto l2 = mm->add_instruction(op, l1); + auto l2 = mm->add_instruction( + migraphx::make_op( + "slice", {{"starts", {0, 1, 1, 0}}, {"ends", {1, 3, 3, 10}}, {"axes", {0, 1, 2, 3}}}), + l1); auto l3 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 3, 1, 2}}}), l2); mm->add_return({l3}); diff --git a/test/verify/gemm_literal.cpp b/test/verify/gemm_literal.cpp index fc2195e21cd..3ea52af477b 100644 --- a/test/verify/gemm_literal.cpp +++ b/test/verify/gemm_literal.cpp @@ -25,7 +25,7 @@ #include "verify_program.hpp" #include #include -#include +#include struct gemm_literal : verify_program { @@ -38,7 +38,7 @@ struct gemm_literal : verify_program auto a = mm->add_literal(migraphx::generate_literal(a_shape)); auto b = mm->add_parameter("b", b_shape); - mm->add_instruction(migraphx::op::dot{}, a, b); + mm->add_instruction(migraphx::make_op("dot"), a, b); return p; } diff --git a/test/verify/test_add_nhwc.cpp b/test/verify/test_add_nhwc.cpp new file mode 100644 index 00000000000..75d55172265 --- /dev/null +++ b/test/verify/test_add_nhwc.cpp @@ -0,0 +1,44 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "verify_program.hpp" +#include +#include +#include + +struct test_add_nhwc : verify_program +{ + migraphx::program create_program() const + { + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape::from_permutation( + migraphx::shape::float_type, {4, 3, 8, 8}, {0, 2, 3, 1}); + auto x = mm->add_parameter("x", s); + auto y = mm->add_parameter("y", s); + auto add = mm->add_instruction(migraphx::make_op("add"), x, y); + mm->add_return({add}); + return p; + } +}; diff --git a/test/verify/test_reduce_mean_nhwc.cpp b/test/verify/test_reduce_mean_nhwc.cpp new file mode 100644 index 00000000000..ef4251c8ab4 --- /dev/null +++ b/test/verify/test_reduce_mean_nhwc.cpp @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "verify_program.hpp" +#include +#include +#include +#include + +struct test_reduce_mean_nhwc : verify_program +{ + migraphx::program create_program() const + { + migraphx::program p; + auto* mm = p.get_main_module(); + auto s = migraphx::shape::from_permutation( + migraphx::shape::float_type, {4, 256, 2, 2}, {0, 2, 3, 1}); + auto x = mm->add_parameter("x", s); + auto reduce = mm->add_instruction(migraphx::make_op("reduce_mean", {{"axes", {1}}}), x); + auto abs = mm->add_instruction(migraphx::make_op("abs"), reduce); + auto sqrt = mm->add_instruction(migraphx::make_op("sqrt"), abs); + mm->add_return({sqrt}); + return p; + }; +}; diff --git a/tools/api.py b/tools/api.py index 9a1cee9f500..a115d2eb2ee 100755 --- a/tools/api.py +++ b/tools/api.py @@ -36,6 +36,8 @@ success_type = '' try_wrap = '' +export_c_macro = 'MIGRAPHX_C_EXPORT' + c_header_preamble: List[str] = [] c_api_body_preamble: List[str] = [] cpp_header_preamble: List[str] = [] @@ -125,7 +127,7 @@ def str(self) -> str: header_function = Template(''' -${error_type} ${name}(${params}); +${export_c_macro} ${error_type} ${name}(${params}); ''') function_pointer_typedef = Template(''' @@ -177,7 +179,7 @@ def substitute(self, form: Template, **kwargs) -> str: **kwargs) def generate_header(self) -> str: - return self.substitute(header_function) + return self.substitute(header_function, export_c_macro=export_c_macro) def generate_function_pointer(self, name: Optional[str] = None) -> str: return self.substitute(function_pointer_typedef, diff --git a/tools/api/api.cpp b/tools/api/api.cpp index 9977035829c..c9a8bf16623 100644 --- a/tools/api/api.cpp +++ b/tools/api/api.cpp @@ -44,7 +44,7 @@ namespace migraphx { static thread_local bool disable_exception_catch = false; // NOLINT -extern "C" void migraphx_test_private_disable_exception_catch(bool b) +extern "C" MIGRAPHX_C_EXPORT void migraphx_test_private_disable_exception_catch(bool b) { disable_exception_catch = b; } diff --git a/tools/api/migraphx.h b/tools/api/migraphx.h index f3156c3cd56..34ce75b7a65 100644 --- a/tools/api/migraphx.h +++ b/tools/api/migraphx.h @@ -26,6 +26,9 @@ #include #include + +#include + // Add new types here // clang-format off #define MIGRAPHX_SHAPE_VISIT_TYPES(m) \ diff --git a/tools/build_and_test_onnxrt.sh b/tools/build_and_test_onnxrt.sh index 5a8b1d8b5f2..75915b15f6e 100755 --- a/tools/build_and_test_onnxrt.sh +++ b/tools/build_and_test_onnxrt.sh @@ -31,7 +31,7 @@ pip3 install -r requirements-dev.txt # Add newer cmake to the path export PATH="/opt/cmake/bin:$PATH" export CXXFLAGS="-D__HIP_PLATFORM_AMD__=1 -w" -./build.sh --config Release --cmake_extra_defines CMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ --update --build --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) --skip_tests --rocm_home /opt/rocm --use_migraphx --migraphx_home /opt/rocm --rocm_version=`cat /opt/rocm/.info/version-dev` --allow_running_as_root +./build.sh --config Release --cmake_extra_defines CMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ --update --build --build_wheel --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) --skip_tests --rocm_home /opt/rocm --use_migraphx --migraphx_home /opt/rocm --rocm_version=`cat /opt/rocm/.info/version-dev` --allow_running_as_root cd build/Linux/Release #Add test launcher for onnxrt tests diff --git a/tools/docker/sles.docker b/tools/docker/sles.docker new file mode 100644 index 00000000000..1cc4657a13d --- /dev/null +++ b/tools/docker/sles.docker @@ -0,0 +1,51 @@ +FROM registry.suse.com/suse/sle15:15.4 + +RUN sh -c 'echo -e "\ +[rocm]\n\ +name=rocm\n\ +baseurl=https://repo.radeon.com/rocm/zyp/5.6/main\n\ +enabled=1\n\ +gpgcheck=1\n\ +gpgkey=https://repo.radeon.com/rocm/rocm.gpg.key\n\ +" > /etc/zypp/repos.d/rocm.repo' + +RUN cat /etc/zypp/repos.d/rocm.repo + +RUN zypper -n --gpg-auto-import-keys refresh + +RUN zypper install -y -t pattern devel_basis enhanced_base +RUN zypper --gpg-auto-import-keys install -y \ + doxygen \ + gcc-c++ \ + gdb \ + git \ + python3-pip \ + rpm-build + +#addition of repos for packages +RUN OPENSUSE_REPO=https://download.opensuse.org/repositories && \ + zypper addrepo ${OPENSUSE_REPO}/devel:/languages:/perl/SLE_15_SP4/devel:languages:perl.repo + +# Workaround broken rocm packages +RUN ln -s /opt/rocm-* /opt/rocm +RUN echo "/opt/rocm/lib" > /etc/ld.so.conf.d/rocm.conf +RUN echo "/opt/rocm/llvm/lib" > /etc/ld.so.conf.d/rocm-llvm.conf +RUN ldconfig + +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 + +# Install yapf +RUN pip3 install yapf==0.28.0 + +# Install doc requirements +# ADD docs/.sphinx/requirements.txt /doc-requirements.txt +# RUN pip3 install -r /doc-requirements.txt + +# Install dependencies +ADD dev-requirements.txt /dev-requirements.txt +ADD requirements.txt /requirements.txt +ADD rbuild.ini /rbuild.ini + +COPY ./tools/install_prereqs.sh / +RUN /install_prereqs.sh /usr/local / && rm /install_prereqs.sh diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh index 9d1a321f118..152ccb3527d 100755 --- a/tools/install_prereqs.sh +++ b/tools/install_prereqs.sh @@ -31,9 +31,30 @@ set -e export LC_ALL=C.UTF-8 export LANG=C.UTF-8 +source /etc/os-release + +if [[ ("${ID}" == "sles") ]]; then + zypper -n --gpg-auto-import-keys install -y \ + cmake \ + miopen-hip-devel \ + openmp-extras-devel \ + python3-devel \ + python3-pip \ + rocblas-devel \ + rocm-cmake +else + # Need pip3 and Python headers to build dependencies + apt update && apt install -y \ + cmake \ + libnuma-dev \ + miopen-hip-dev \ + openmp-extras \ + python3-dev \ + python3-pip \ + rocblas-dev \ + rocm-cmake +fi -# Need pip3 and Python headers to build dependencies -apt update && apt install -y python3-pip python3-dev cmake rocm-cmake rocblas miopen-hip openmp-extras # Needed for cmake to build various pip packages pip3 install setuptools wheel @@ -56,9 +77,11 @@ echo "Dependencies are installed at $PREFIX" # Install deps with rbuild rbuild prepare -d $PREFIX -s develop +if [[ ("${ID}" != "sles") ]]; then export CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=ON" pip3 install onnx==1.10.2 numpy==1.21.6 typing==3.7.4 pytest==6.0.1 packaging==23.0 # pin version of protobuf in Python for onnx runtime unit tests between dist versions pip3 install protobuf==3.20.0 +fi